Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

EstablishCallback.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: EstablishCallback.cc,v 1.3 2004/05/19 15:56:23 mmarsh Exp $
00008 //
00009 // $Log: EstablishCallback.cc,v $
00010 // Revision 1.3  2004/05/19 15:56:23  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 "EstablishCallback.h"
00019 #include "CODEX_Server/ServerState.h"
00020 #include "StateInfo.h"
00021 #include "Message.h"
00022 
00023 #include "CODEX_Exceptions/BignumExceptions.h"
00024 #include "CODEX_Server/ServerExceptions.h"
00025 
00026 #include "timing.h"
00027 
00028 using namespace CODEX_APSS;
00029 
00030 EstablishCallback::EstablishCallback( InitActivity* initAct,
00031                                       unsigned int version,
00032                                       const SublabelType& label ) :
00033    m_initAct( initAct ),
00034    m_version( version ),
00035    m_label( label ),
00036    m_completed( false ),
00037    m_evidence( new EvidenceVector )
00038 {
00039 }
00040 
00041 EstablishCallback::~EstablishCallback()
00042 {
00043    if ( 0 != m_evidence ) delete m_evidence;
00044 }
00045 
00046 bool
00047 EstablishCallback::operator()( unsigned int server,
00048                                CODEX_Quorum::Message* msg )
00049 {
00050    if ( m_completed )
00051    {
00052       if ( 0 != msg ) delete msg;
00053       return true;
00054    }
00055 
00056    if ( 0 == msg )
00057    {
00058       return false;
00059    }
00060 
00061    if ( 0 == m_evidence )
00062    {
00063       // something's wrong -- disable
00064       m_completed = true;
00065       delete msg;
00066       return false;
00067    }
00068 
00069 #ifdef TIMING
00070    ActiveTimer.start();
00071 #endif
00072    CODEX_Server::ServerState* serverState =
00073       CODEX_Server::ServerState::instance();
00074    if ( 0 == serverState )
00075    {
00076       delete msg;
00077 #ifdef TIMING
00078       ActiveTimer.stop();
00079 #endif
00080       return false;
00081    }
00082 
00083    StateInfo* stateInfo = StateInfo::instance();
00084    if ( 0 == stateInfo )
00085    {
00086       delete msg;
00087 #ifdef TIMING
00088       ActiveTimer.stop();
00089 #endif
00090       return false;
00091    }
00092 
00093    // Unmarshal the message.
00094    unsigned char* data = (unsigned char*)msg->buffer();
00095    int length = msg->length();
00096 
00097    if ( length < 2 )
00098    {
00099       delete msg;
00100 #ifdef TIMING
00101       ActiveTimer.stop();
00102 #endif
00103       return false;
00104    }
00105 
00106    if ( stateInfo->domain() != data[0] )
00107    {
00108       delete msg;
00109 #ifdef TIMING
00110       ActiveTimer.stop();
00111 #endif
00112       return false;
00113    }
00114    ++data;
00115    --length;
00116 
00117    if ( ( kEstablishedMsg | SignatureMask ) != data[0] )
00118    {
00119       delete msg;
00120 #ifdef TIMING
00121       ActiveTimer.stop();
00122 #endif
00123       return false;
00124    }
00125    ++data;
00126    --length;
00127 
00128    SignedEstablishedMsg signedResponse;
00129    if ( 0 == signedResponse.unmarshal( 0, &data, length ) )
00130    {
00131       delete msg;
00132 #ifdef TIMING
00133       ActiveTimer.stop();
00134 #endif
00135       return false;
00136    }
00137    delete msg;
00138 
00139    // Make sure the response is valid.
00140    const EstablishedMsg& response = signedResponse.message();
00141    unsigned int srVersion = response.version().value();
00142    if ( srVersion != m_version )
00143    {
00144 #ifdef TIMING
00145       ActiveTimer.stop();
00146 #endif
00147       return false;
00148    }
00149 
00150    unsigned int srRecipient = response.recipient().value();
00151    if ( srRecipient != server )
00152    {
00153 #ifdef TIMING
00154       ActiveTimer.stop();
00155 #endif
00156       return false;
00157    }
00158 
00159    if ( response.establisher().value() != serverState->hostNum() )
00160    {
00161 #ifdef TIMING
00162       ActiveTimer.stop();
00163 #endif
00164       return false;
00165    }
00166 
00167    if ( response.sublabel() != m_label )
00168    {
00169 #ifdef TIMING
00170       ActiveTimer.stop();
00171 #endif
00172       return false;
00173    }
00174 
00175    // Check the signature.
00176    BIGNUM * digest = 0;
00177    try
00178    {
00179       digest = response.digest( serverState->hashFunc() );
00180       if ( 0 == digest )
00181       {
00182          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00183       }
00184       if ( ! serverState->publicKey(server).verifySignature(
00185          signedResponse.signature(),
00186          digest ) )
00187       {
00188          throw CODEX_Server::SignatureVerificationFailedException( __FILE__ ,
00189                                                                    __LINE__ );
00190       }
00191       BN_free(digest);
00192    }
00193    catch ( ... )
00194    {
00195       if ( 0 != digest ) BN_free(digest);
00196    }
00197 
00198    // Add to the evidence list.
00199    m_evidence->push_back( signedResponse );
00200 
00201    // Check to see if we have collected enough responses.
00202    CODEX_Quorum::QuorumSystem* qs = serverState->quorumSystem();
00203    if ( 0 == qs )
00204    {
00205 #ifdef TIMING
00206       ActiveTimer.stop();
00207 #endif
00208       throw CODEX_Server::NoQuorumSystemException( __FILE__ , __LINE__ );
00209    }
00210    if ( m_evidence->size() >= qs->quorumSize() )
00211    {
00212       m_initAct->addEvidence( m_label, m_evidence );
00213       m_evidence = 0;
00214       m_completed = true;
00215    }
00216 
00217 #ifdef TIMING
00218    ActiveTimer.stop();
00219 #endif
00220    return true;
00221 }
00222 
00223 void
00224 EstablishCallback::fail()
00225 {
00226    if ( 0 != m_initAct )
00227    {
00228       m_initAct->addFailure();
00229    }
00230 }

Generated on Fri May 6 17:39:12 2005 for COrnell Data EXchange (CODEX) by  doxygen 1.4.1