Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   Related Pages  

RecoverCallback.cc

00001 /*
00002  * Copyright 2003 Michael A. Marsh, Cornell University. All rights reserved.
00003  * This software is released under the modified BSD license.
00004  * See the file LICENSE in the top-level directory for details.
00005  */
00006 //
00007 // $Id: RecoverCallback.cc,v 1.3 2004/05/19 15:56:24 mmarsh Exp $
00008 //
00009 // $Log: RecoverCallback.cc,v $
00010 // Revision 1.3  2004/05/19 15:56:24  mmarsh
00011 // Added copyright and license statements.
00012 //
00013 // Revision 1.2  2003/11/04 22:31:45  mmarsh
00014 // *** empty log message ***
00015 //
00016 //
00017 
00018 #include "RecoverCallback.h"
00019 #include "Message.h"
00020 #include "Types.h"
00021 #include "StateInfo.h"
00022 #include "CODEX_Server/ServerState.h"
00023 
00024 using namespace CODEX_APSS;
00025 
00026 RecoverCallback::RecoverCallback( unsigned int version,
00027                                   const SublabelType& label ) :
00028    m_version( version ),
00029    m_label( label ),
00030    m_completed( false )
00031 {
00032 }
00033 
00034 RecoverCallback::~RecoverCallback()
00035 {
00036    // Whether recovery was successful or not, we need to clean up.
00037    StateInfo::instance()->markRecovered( m_label );
00038 }
00039 
00040 bool
00041 RecoverCallback::operator()( unsigned int server, CODEX_Quorum::Message* msg )
00042 {
00043    if ( m_completed )
00044    {
00045       if ( 0 != msg ) delete msg;
00046       return true;
00047    }
00048 
00049    if ( 0 == msg )
00050    {
00051       return false;
00052    }
00053 
00054    CODEX_Server::ServerState* serverState =
00055       CODEX_Server::ServerState::instance();
00056    if ( 0 == serverState )
00057    {
00058       delete msg;
00059       return false;
00060    }
00061 
00062    StateInfo* stateInfo = StateInfo::instance();
00063    if ( 0 == stateInfo )
00064    {
00065       delete msg;
00066       return false;
00067    }
00068 
00069    // Unmarshal the message.
00070    unsigned char* data = (unsigned char*)msg->buffer();
00071    int length = msg->length();
00072 
00073    if ( length < 2 )
00074    {
00075       delete msg;
00076       return false;
00077    }
00078 
00079    if ( stateInfo->domain() != data[0] )
00080    {
00081       delete msg;
00082       return false;
00083    }
00084    ++data;
00085    --length;
00086 
00087    if ( ( kRecoveredMsg | SignatureMask ) != data[0] )
00088    {
00089       delete msg;
00090       return false;
00091    }
00092    ++data;
00093    --length;
00094 
00095    SignedRecoveredMsg signedResponse;
00096    if ( 0 == signedResponse.unmarshal( 0, &data, length ) )
00097    {
00098       delete msg;
00099       return false;
00100    }
00101    delete msg;
00102 
00103    // Make sure the response is valid.  We ignore the "responder" field.
00104    const RecoveredMsg& response = signedResponse.message();
00105    unsigned int srVersion = response.version().value();
00106    if ( srVersion != m_version )
00107    {
00108       return false;
00109    }
00110 
00111    if ( response.requester().value() != serverState->hostNum() )
00112    {
00113       return false;
00114    }
00115 
00116    if ( response.sublabel() != m_label )
00117    {
00118       return false;
00119    }
00120 
00121    // Check the signature.
00122    BIGNUM * digest = 0;
00123    try
00124    {
00125       digest = response.digest( serverState->hashFunc() );
00126       if ( 0 == digest )
00127       {
00128          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00129       }
00130       if ( ! serverState->publicKey(server).verifySignature(
00131          signedResponse.signature(),
00132          digest ) )
00133       {
00134          throw CODEX_Server::SignatureVerificationFailedException( __FILE__ ,
00135                                                                    __LINE__ );
00136       }
00137       BN_free(digest);
00138    }
00139    catch ( ... )
00140    {
00141       if ( 0 != digest ) BN_free(digest);
00142       return false;
00143    }
00144 
00145    // Check the validity of the subshares returned.
00146    unsigned int num = m_label.label().num().value();
00147    OneWay oneWay( stateInfo->witness(num).args() );
00148    if ( ! m_label.check( response.shares(), oneWay ) )
00149    {
00150       return false;
00151    }
00152 
00153    // Store these subshares.
00154    stateInfo->addSubsharing( m_label, response.shares() );
00155 
00156    // Check whether all subshares are now present.
00157    unsigned int self = serverState->hostNum();
00158    bool haveAll = true;
00159    const ShareSetType& subsharing =
00160       stateInfo->subsharing( m_label, self );
00161    for ( unsigned int i = 0 ; i < ShareType::NumShares ; ++i )
00162    {
00163       if ( subsharing.shouldHave( i, self ) &&
00164            (!subsharing(i).initialized()) )
00165       {
00166          haveAll = false;
00167          break;
00168       }
00169    }
00170    if ( haveAll )
00171    {
00172       // That's all we need to do.
00173       stateInfo->markRecovered( m_label );
00174       m_completed = true;
00175    }
00176    return true;
00177 }

Generated on Wed Jun 2 16:32:55 2004 for COrnell Data EXchange (CODEX) by doxygen1.2.18