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

InitActivity.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: InitActivity.cc,v 1.3 2004/05/19 15:56:24 mmarsh Exp $
00008 //
00009 // $Log: InitActivity.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:04:05  mmarsh
00014 // General code cleanup.
00015 //
00016 //
00017 
00018 #include "CODEX_Server/ServerResponseEvent.h"
00019 #include "InitActivity.h"
00020 #include "InitEvent.h"
00021 #include "Message.h"
00022 #include "EstablishCallback.h"
00023 #include "CODEX_Server/UnicastRequestEvent.h"
00024 #include "StateInfo.h"
00025 #include "CODEX_Server/ServerState.h"
00026 
00027 #include "CODEX_Server/ServerExceptions.h"
00028 
00029 #include "timing.h"
00030 
00031 using namespace CODEX_APSS;
00032 
00033 InitActivity::InitActivity(
00034    CODEX_Events::DeadPileType& deadPile,
00035    CODEX_Events::QType& eventQueue,
00036    unsigned int version,
00037    unsigned int coordinator,
00038    unsigned int self,
00039    unsigned int num,
00040    const unsigned char* key,
00041    const SubshareList& subshares,
00042    CODEX_Server::ServerResponseHandler* responseHandler,
00043    CODEX_Server::UnicastRequestHandler* requestHandler ) :
00044    CODEX_Events::Activity( deadPile, eventQueue ),
00045    m_version( version ),
00046    m_coordinator( coordinator ),
00047    m_self( self ),
00048    m_num( num ),
00049    m_subshares( subshares ),
00050    m_responseHandler( responseHandler ),
00051    m_requestHandler( requestHandler ),
00052    m_failures( 0 )
00053 {
00054    memcpy( m_key, key, CODEX_Server::ServerState::nMID );
00055    m_numShares = 0;
00056    SubshareList::const_iterator itr = subshares.begin();
00057    SubshareList::const_iterator end = subshares.end();
00058    for ( ; itr != end ; ++itr )
00059    {
00060       if ( itr->second.initialized() ) ++m_numShares;
00061    }
00062 }
00063 
00064 InitActivity::~InitActivity()
00065 {
00066    EvidenceMap::iterator itr = m_evidence.begin();
00067    EvidenceMap::iterator end = m_evidence.end();
00068    for ( ; itr != end ; ++itr )
00069    {
00070       if ( 0 != itr->second )
00071       {
00072          delete itr->second;
00073       }
00074    }
00075 }
00076 
00077 bool
00078 InitActivity::handler( CODEX_Events::CloseEvent& event )
00079 {
00080    sendEvent( 0, event.source() );
00081    enableTerminate();
00082    return true;
00083 }
00084 
00085 bool
00086 InitActivity::handler( InitEvent& event )
00087 {
00088 #ifdef TIMING
00089    ActiveTimer.start();
00090 #endif
00091    CODEX_Server::ServerState* serverState =
00092       CODEX_Server::ServerState::instance();
00093    StateInfo* stateInfo = StateInfo::instance();
00094 
00095    // Loop over splittings of shares
00096    SubshareList::const_iterator listItr = m_subshares.begin();
00097    SubshareList::const_iterator listEnd = m_subshares.end();
00098    for ( ; listItr != listEnd ; ++listItr )
00099    {
00100       CODEX_Quorum::MessageVector mv;
00101       mv.resize( ShareType::NumShares );
00102 
00103       if ( ! listItr->second.initialized() )
00104       {
00105          continue;
00106       }
00107 
00108       const unsigned char* seqNum = serverState->newSequenceNumber();
00109 
00110       // Loop over recipients
00111       for ( unsigned int server = 0 ;
00112             server < CODEX_Server::ServerState::nServers ;
00113             ++server )
00114       {
00115          // Distribute appropriate subshares for this server.
00116          ShareType shares(listItr->first,server);
00117 
00118          // Compose the message.
00119          EstablishMsg em( m_version, listItr->second, m_self, server, shares );
00120 
00121          // Sign the message.
00122          BIGNUM * digest = 0;
00123          CODEX_Ciphers::RSASignature* signature = 0;
00124          try
00125          {
00126             const CODEX_Ciphers::HashFunction& hashFunc =
00127                serverState->hashFunc();
00128             digest = em.digest( hashFunc );
00129             const CODEX_Ciphers::RSAPrivateKey& key =
00130                serverState->privateKey();
00131             signature = key.sign( digest );
00132             BN_free(digest);
00133             digest = 0;
00134             if ( 0 == signature )
00135             {
00136                throw CODEX_Exceptions::BignumNullException( __FILE__ ,
00137                                                             __LINE__ );
00138             }
00139          }
00140          catch ( ... )
00141          {
00142             if ( 0 != digest ) BN_free( digest );
00143             if ( 0 != signature ) delete signature;
00144 #ifdef TIMING
00145             ActiveTimer.stop();
00146 #endif
00147             throw;
00148          }
00149          SignedEstablishMsg signedEM( em, *signature );
00150          delete signature;
00151 
00152          // Compose the request.
00153          unsigned char selfChar =
00154             m_self | CODEX_Server::ServerState::OutgoingMask;
00155          mv[server].fill( selfChar );
00156          mv[server].fill( seqNum, CODEX_Server::ServerState::nMID );
00157          mv[server].fill( stateInfo->domain() );
00158          mv[server].fill( kEstablishMsg | SignatureMask );
00159          int length = signedEM.marshal(0);
00160          unsigned char* buffer = new unsigned char[length];
00161          unsigned char* pBuffer = buffer;
00162          signedEM.marshal(&pBuffer);
00163          mv[server].fill( buffer, length );
00164          delete [] buffer;
00165       }
00166 
00167       // Create the callback for this request.
00168       EstablishCallback* cb =
00169          new EstablishCallback( this, m_version, listItr->second );
00170 
00171       // Create and send the unicast event.
00172       sendEvent( new CODEX_Server::UnicastRequestEvent( this,
00173                                                         m_requestHandler,
00174                                                         mv,
00175                                                         seqNum,
00176                                                         cb ),
00177                  0 );
00178    }
00179 
00180    sendEvent( 0, event.source() );
00181 #ifdef TIMING
00182    InitActIdleTimer[m_num].start();
00183    ActiveTimer.stop();
00184 #endif
00185    return true;
00186 }
00187 
00188 void
00189 InitActivity::addFailure()
00190 {
00191 #ifdef TIMING
00192    InitActIdleTimer[m_num].stop();
00193 #endif
00194 
00195    ++m_failures;
00196 
00197 #ifdef TIMING
00198    InitActIdleTimer[m_num].start();
00199 #endif
00200 }
00201 
00202 void
00203 InitActivity::addEvidence( const SublabelType& label,
00204                            EvidenceVector* evidence )
00205 {
00206 #ifdef TIMING
00207    InitActIdleTimer[m_num].stop();
00208 #endif
00209    if ( 0 == evidence )
00210    {
00211 #ifdef TIMING
00212       InitActIdleTimer[m_num].start();
00213 #endif
00214       return;
00215    }
00216 
00217    // Accumulate evidence
00218    EvidenceMap::iterator itr = m_evidence.find( label );
00219    if ( m_evidence.end() != itr )
00220    {
00221       // The label is already present.
00222       delete evidence;
00223 #ifdef TIMING
00224       InitActIdleTimer[m_num].start();
00225 #endif
00226       return;
00227    }
00228    m_evidence[ label ] = evidence;
00229 
00230    // Check for finished condition
00231    StateInfo* stateInfo = StateInfo::instance();
00232    CODEX_Server::ServerState* serverState =
00233       CODEX_Server::ServerState::instance();
00234    CODEX_Quorum::QuorumSystem* qs = serverState->quorumSystem();
00235    if ( 0 == qs )
00236    {
00237       throw CODEX_Server::NoQuorumSystemException( __FILE__ , __LINE__ );
00238    }
00239 //   if ( m_evidence.size() > qs->faultsTolerated() )
00240    if ( m_evidence.size() + m_failures == m_numShares )
00241    {
00242       EstablishedArray ea;
00243       EvidenceMap::const_iterator mItr = m_evidence.begin();
00244       EvidenceMap::const_iterator mEnd = m_evidence.end();
00245       for ( ; mItr != mEnd ; ++mItr )
00246       {
00247          EvidenceVector::const_iterator vItr = mItr->second->begin();
00248          EvidenceVector::const_iterator vEnd = mItr->second->end();
00249          for ( ; vItr != vEnd ; ++vItr )
00250          {
00251             ea.append( new SignedEstablishedMsg( *vItr ) );
00252          }
00253       }
00254 
00255       ContributeMsg response( m_version, m_coordinator, m_self, ea );
00256 
00257       BIGNUM * digest = 0;
00258       CODEX_Ciphers::RSASignature* signature = 0;
00259       try
00260       {
00261          const CODEX_Ciphers::HashFunction& hashFunc = serverState->hashFunc();
00262          digest = response.digest( hashFunc );
00263          const CODEX_Ciphers::RSAPrivateKey& key = serverState->privateKey();
00264          signature = key.sign( digest );
00265          BN_free(digest);
00266          digest = 0;
00267          if ( 0 == signature )
00268          {
00269             throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00270          }
00271       }
00272       catch ( ... )
00273       {
00274          if ( 0 != digest ) BN_free( digest );
00275          if ( 0 != signature ) delete signature;
00276 #ifdef TIMING
00277          InitActIdleTimer[m_num].start();
00278 #endif
00279          throw;
00280       }
00281 
00282       SignedContributeMsg signedResponse( response, *signature );
00283       delete signature;
00284 
00285       stateInfo->addInitResponse( signedResponse );
00286 
00287       CODEX_Quorum::Message m;
00288 
00289       // Fill message headers.
00290       m.fill( m_coordinator );
00291       m.fill( m_key, CODEX_Server::ServerState::nMID );
00292       m.fill( stateInfo->domain() );
00293       m.fill( kContributeMsg | SignatureMask );
00294       int length = signedResponse.marshal(0);
00295       unsigned char* buffer = new unsigned char[length];
00296       unsigned char* pBuffer = buffer;
00297       signedResponse.marshal(&pBuffer);
00298       m.fill( buffer, length );
00299       delete [] buffer;
00300 
00301       CODEX_Server::ServerResponseEvent* outEvent =
00302          new CODEX_Server::ServerResponseEvent( this,
00303                                                 m_responseHandler,
00304                                                 m,
00305                                                 m_coordinator );
00306       sendEvent( outEvent, 0 );
00307       sendEvent( new CODEX_Events::CloseEvent( this, this ), 0 );
00308 
00309 #ifdef TIMING
00310       InitActTimer[m_num].stop();
00311 #endif
00312 
00313    }
00314 #ifdef TIMING
00315    else // Only start again if we're waiting for more responses.
00316    {
00317       InitActIdleTimer[m_num].start();
00318    }
00319 #endif
00320 }

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