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

SecretManagement.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: SecretManagement.cc,v 1.3 2004/05/19 15:56:25 mmarsh Exp $
00008 //
00009 // $Log: SecretManagement.cc,v $
00010 // Revision 1.3  2004/05/19 15:56:25  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 <sys/time.h>
00019 #include <errno.h>
00020 
00021 #include "SecretManagement.h"
00022 #include "StateInfo.h"
00023 #include "InitCallback.h"
00024 #include "Exceptions.h"
00025 #include "CODEX_Exceptions/POSIXExceptions.h"
00026 #include "CODEX_Server/ServerExceptions.h"
00027 
00028 #include "timing.h"
00029 #ifdef TIMING
00030 #include <sstream>
00031 #endif
00032 
00033 using namespace CODEX_APSS;
00034 
00035 SecretManagement::SecretManagement() :
00036    m_shareCallback( 0 ),
00037    m_subshareRange( 0 ),
00038    m_version( 0 ),
00039    m_num( 0 ),
00040    m_epochTime( 0 ),
00041    m_runTime( 0 )
00042 {
00043 }
00044 
00045 SecretManagement::~SecretManagement()
00046 {
00047    if ( 0 != m_shareCallback ) delete m_shareCallback;
00048    while ( ! m_sharings.empty() )
00049    {
00050       SharingList::value_type back = m_sharings.back();
00051       if ( 0 != back ) delete back;
00052       m_sharings.pop_back();
00053    }
00054    m_subsharings.clear();
00055    clearEstablishMsgs();
00056 }
00057 
00058 void
00059 SecretManagement::setSubshareRange( const CODEX_VSS::Range* subshareRange )
00060 {
00061    m_subshareRange = subshareRange;
00062 }
00063 
00064 const CODEX_VSS::Range&
00065 SecretManagement::subshareRange() const
00066 {
00067    if ( 0 == m_subshareRange )
00068    {
00069       throw MissingRangeException( __FILE__ , __LINE__ );
00070    }
00071    return *m_subshareRange;
00072 }
00073 
00074 void
00075 SecretManagement::addSharing( LSType* sharing )
00076 {
00077    if ( 0 == sharing )
00078    {
00079       return;
00080    }
00081 
00082    const CODEX_ASN1::Integer& version = sharing->label().version();
00083    if ( ! version.initialized() )
00084    {
00085       delete sharing;
00086       return;
00087    }
00088 
00089    unsigned int vnum = version.value();
00090    if ( vnum < m_version )
00091    {
00092       delete sharing;
00093       return;
00094    }
00095 
00096    // Make sure we don't already have a sharing for this version from
00097    // this coordinator.
00098    SharingList::const_iterator sItr = m_sharings.begin();
00099    SharingList::const_iterator sEnd = m_sharings.end();
00100    for ( ; sItr != sEnd ; ++sItr )
00101    {
00102       if ( ( (*sItr)->label().id().value() ==
00103              sharing->label().id().value() ) &&
00104            ( (*sItr)->label().version().value() ==
00105              sharing->label().version().value() ) )
00106       {
00107          delete sharing;
00108          return;
00109       }
00110    }
00111    m_sharings.push_back( sharing );
00112 }
00113 
00114 bool
00115 SecretManagement::labelValid( const LabelType& label ) const
00116 {
00117    for ( unsigned int i = 0 ; i < NumServers ; ++i )
00118    {
00119       if ( m_finishedLog[i].initialized() )
00120       {
00121          if ( m_finishedLog[i].message().evidence().element(0)->
00122               message().shareLabel() ==
00123               label )
00124          {
00125             return true;
00126          }
00127       }
00128    }
00129    return false;
00130 }
00131 
00132 const LSType&
00133 SecretManagement::sharing( const LSType::LabelType& label,
00134                            unsigned int server ) const
00135 {
00136    unsigned int version = label.version().value();
00137    if ( version < m_version )
00138    {
00139       // this is an expired label -- send stored "finished" messages
00140       sendFinished( server );
00141       throw CODEX_Server::InvalidLabelException( __FILE__ , __LINE__ );
00142    }
00143    if ( version > m_version )
00144    {
00145       // we're not in this epoch
00146       throw CODEX_Server::KeySharesNotFoundException( __FILE__ , __LINE__ );
00147    }
00148    SharingList::const_iterator sItr = m_sharings.begin();
00149    SharingList::const_iterator sEnd = m_sharings.end();
00150    for ( ; sItr != sEnd ; ++sItr )
00151    {
00152       if ( (*sItr)->label() == label )
00153       {
00154          return **sItr;
00155       }
00156       else if ( (*sItr)->label().id().value() == label.id().value() )
00157       {
00158          // this is a bogus label
00159          throw CODEX_Server::InvalidLabelException( __FILE__ , __LINE__ );
00160       }
00161    }
00162    if ( ! labelValid( label ) )
00163    {
00164       sendFinished( server );
00165       throw CODEX_Server::InvalidLabelException( __FILE__ , __LINE__ );
00166    }
00167    // we haven't seen this label
00168    throw CODEX_Server::KeySharesNotFoundException( __FILE__ , __LINE__ );
00169 }
00170 
00171 void
00172 SecretManagement::addSubsharing( const SublabelType& label,
00173                                  const ShareType& subsharing )
00174 {
00175    const CODEX_ASN1::Integer& version = label.label().version();
00176    if ( ! version.initialized() )
00177    {
00178       return;
00179    }
00180 
00181    unsigned int vnum = version.value();
00182    if ( vnum < m_version )
00183    {
00184       return;
00185    }
00186    m_subsharings[label].addShare( subsharing );
00187 }
00188 
00189 const ShareSetType&
00190 SecretManagement::subsharing( const SublabelType& sublabel,
00191                               unsigned int server ) const
00192 {
00193    unsigned int vnum = sublabel.label().version().value();
00194    if ( vnum < m_version )
00195    {
00196       // this is an expired label -- send stored "finished" messages
00197       sendFinished( server );
00198       throw CODEX_Server::KeySharesNotFoundException( __FILE__ , __LINE__ );
00199    }
00200    SubsharingMap::const_iterator sItr = m_subsharings.find( sublabel );
00201    if ( sItr == m_subsharings.end() )
00202    {
00203       // not found
00204       throw CODEX_Server::KeySharesNotFoundException( __FILE__ , __LINE__ );
00205    }
00206    return sItr->second;
00207 }
00208 
00209 SubshareList&
00210 SecretManagement::splittings( const LabelType& label )
00211 {
00212    return m_splittings[ label ];
00213 }
00214 
00215 bool
00216 SecretManagement::addInitMsg( const SignedInitMsg& im )
00217 {
00218    unsigned int coord = im.message().coordinator().value();
00219    int version = im.message().version().value();
00220    const InitMsg& stored = m_initLog[coord].request();
00221    // If there is no stored message, just add the new message.
00222    if ( ! stored.initialized() )
00223    {
00224       m_initLog[coord].addRequest(im.message());
00225       return true;
00226    }
00227    // If the stored message is from a previous epoch, just replace it.
00228    if ( version > stored.version().value() )
00229    {
00230       m_initLog[coord].addRequest(im.message());
00231       return true;
00232    }
00233 
00234    // The message must now be:
00235    // 1) a repeat,
00236    // 2) a bogus message, or
00237    // 3) from an earlier epoch
00238    if ( im.message().label() == stored.label() )
00239    {
00240       // Duplicate -- just return
00241       return false;
00242    }
00243 
00244    // The message is bad -- flag the error
00245    throw InitMsgConflictException( __FILE__ ,
00246                                    __LINE__ ,
00247                                    coord,
00248                                    im.message().label(),
00249                                    stored.label() );
00250    return false;
00251 }
00252 
00253 bool
00254 SecretManagement::addEstablishMsg( const SignedEstablishMsg& em )
00255 {
00256    unsigned int estab = em.message().establisher().value();
00257    unsigned int snum = em.message().sublabel().id().value();
00258    EstablishRecord& er =
00259       m_establishLog[ estab ][ snum ][ em.message().sublabel().label() ];
00260    bool retVal = false;
00261    if ( ! er.request().initialized() )
00262    {
00263       retVal = true;
00264    }
00265    else
00266    {
00267       if ( er.request().sublabel() != em.message().sublabel() )
00268       {
00269          throw EstablishMsgConflictException(
00270             __FILE__ , __LINE__ , estab, em.message().sublabel(),
00271             er.request().sublabel() );
00272       }
00273    }
00274    if (retVal)
00275    {
00276       // The version of the message stored should not have the actual
00277       // subshares in it, which makes maintenance considerably easier.
00278       er.addRequest( EstablishMsg( em.message().version(),
00279                                    em.message().sublabel(),
00280                                    em.message().establisher(),
00281                                    em.message().recipient(),
00282                                    ShareType() ) );
00283       addSubsharing( em.message().sublabel(), em.message().shares() );
00284    }
00285    return retVal;
00286 }
00287 
00288 bool
00289 SecretManagement::addComputeMsg( const SignedComputeMsg& cm )
00290 {
00291    unsigned int coord = cm.message().coordinator().value();
00292    int version = cm.message().subshareLabel(0).label().version().value();
00293    const ComputeMsg& stored = m_computeLog[coord].request();
00294    // If there is no stored message, just add the new message.
00295    if ( ! stored.initialized() )
00296    {
00297       m_computeLog[coord].addRequest(cm.message());
00298       return true;
00299    }
00300    // If the stored message is from a previous epoch, just replace it.
00301    if ( version > stored.subshareLabel(0).label().version().value() )
00302    {
00303       m_computeLog[coord].addRequest(cm.message());
00304       return true;
00305    }
00306 
00307    // The message must now be:
00308    // 1) a repeat,
00309    // 2) a bogus message, or
00310    // 3) from an earlier epoch
00311    for ( unsigned int i = 0 ; i < NumShares ; ++i )
00312    {
00313       if ( cm.message().subshareLabel(i) != stored.subshareLabel(i) )
00314       {
00315          // The message is bad -- flag the error
00316          throw ComputeMsgConflictException( __FILE__ , __LINE__ , coord,
00317                                             cm.message(), stored );
00318       }
00319    }
00320    // Duplicate
00321    return false;
00322 }
00323 
00324 bool
00325 SecretManagement::addFinishedMsg( const SignedFinishedMsg& fm )
00326 {
00327    CODEX_Server::ServerState* serverState =
00328       CODEX_Server::ServerState::instance();
00329 
00330    unsigned int coord = fm.message().coordinator().value();
00331    unsigned int version = fm.message().version().value();
00332 
00333    if ( coord >= NumServers )
00334    {
00335       throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00336    }
00337 
00338    // Does this message belong to a previous epoch?
00339    if ( version < m_version )
00340    {
00341       return false;
00342    }
00343 
00344    // Store the message.
00345    m_finishedLog[coord] = fm;
00346 
00347    // Are we beginning a new epoch?
00348    if ( version > m_version )
00349    {
00350       // If so:
00351       //  - set the new version number
00352       //  - clear the old logged message
00353       //  - delete the old shares
00354       //  - delete the old subshares
00355 
00356       m_version = version;
00357 
00358       for ( unsigned int i = 0 ; i < NumServers ; ++i )
00359       {
00360          if ( m_finishedLog[i].initialized() && ( i != coord ) )
00361          {
00362             m_finishedLog[i] = SignedFinishedMsg();
00363          }
00364       }
00365 
00366       SharingList::iterator slItr = m_sharings.begin();
00367       SharingList::iterator slEnd = m_sharings.end();
00368       SharingList tempList;
00369       for ( ; slItr != slEnd ; ++slItr )
00370       {
00371          unsigned int slVers = (*slItr)->label().version().value();
00372          if ( slVers >= m_version )
00373          {
00374             tempList.push_back( *slItr );
00375          }
00376          else
00377          {
00378             delete (*slItr);
00379          }
00380       }
00381       m_sharings = tempList;
00382 
00383       SubsharingMap::iterator sslItr = m_subsharings.begin();
00384       SubsharingMap::iterator sslEnd = m_subsharings.end();
00385       SubsharingMap tempMap;
00386 //      for ( ; sslItr != m_subsharings.end() ; ++sslItr )
00387       for ( ; sslItr != sslEnd ; ++sslItr )
00388       {
00389          // currently-relevant subshares have the previous version number.
00390          unsigned int sslVers = sslItr->first.label().version().value() + 1;
00391          if ( sslVers >= m_version )
00392          {
00393             tempMap.insert( *sslItr );
00394 //            SubsharingMap::iterator temp = sslItr;
00395 //            --sslItr;
00396 //            m_subsharings.erase( temp );
00397          }
00398       }
00399       m_subsharings = tempMap;
00400 
00401       SplittingMap::iterator smItr = m_splittings.begin();
00402       SplittingMap::iterator smEnd = m_splittings.end();
00403       SplittingMap tempSMap;
00404       for ( ; smItr != smEnd ; ++smItr )
00405       {
00406          unsigned int smVers = smItr->first.version().value() + 1;
00407          if ( smVers >= m_version )
00408          {
00409             tempSMap.insert( *smItr );
00410          }
00411       }
00412       m_splittings = tempSMap;
00413 
00414       for ( unsigned int i = 0 ; i < NumServers ; ++i )
00415       {
00416          for ( unsigned int j = 0 ; j < NumShares ; ++j )
00417          {
00418             EstablishMap tempEMap;
00419             EstablishMap::iterator emItr = m_establishLog[i][j].begin();
00420             EstablishMap::iterator emEnd = m_establishLog[i][j].end();
00421             for ( ; emItr != emEnd ; ++emItr )
00422             {
00423                unsigned int eVers = emItr->first.version().value() + 1;
00424                if ( eVers >= m_version )
00425                {
00426                   tempEMap.insert( *emItr );
00427                }
00428             }
00429             m_establishLog[i][j] = tempEMap;
00430          }
00431       }
00432 
00433       struct timeval tv;
00434       int gtod = gettimeofday( &tv, 0 );
00435       if ( 0 != gtod )
00436       {
00437          CODEX_Exceptions::GetTimeOfDayException( __FILE__ , __LINE__ ,
00438                                                   errno );
00439       }
00440       cout << "entering epoch " << m_version
00441            << " (" << tv.tv_sec - m_runTime
00442            << ")" << endl;
00443 
00444       setEpochTime();
00445 
00446 #ifdef TIMING
00447       if ( serverState->hostNum() == coord )
00448       {
00449          APSSTimer[m_num].stop();
00450       }
00451 
00452       // Now output the timing information
00453       ActiveTimer.print(cout);
00454       SSLTimer.print(cout);
00455       OneWayTimer.print(cout);
00456       SignTimer.print(cout);
00457       SignVerifyTimer.print(cout);
00458       APSSTimer[m_num].print(cout);
00459       InitTimer[m_num].print(cout);
00460       InitIdleTimer[m_num].print(cout);
00461       InitActTimer[m_num].print(cout);
00462       InitActIdleTimer[m_num].print(cout);
00463       ComputeTimer[m_num].print(cout);
00464       ComputeIdleTimer[m_num].print(cout);
00465 
00466       ActiveTimer.clear();
00467       SSLTimer.clear();
00468       OneWayTimer.clear();
00469       SignTimer.clear();
00470       SignVerifyTimer.clear();
00471       APSSTimer[m_num].clear();
00472       InitTimer[m_num].clear();
00473       InitIdleTimer[m_num].clear();
00474       InitActTimer[m_num].clear();
00475       InitActIdleTimer[m_num].clear();
00476       ComputeTimer[m_num].clear();
00477       ComputeIdleTimer[m_num].clear();
00478 #endif /* TIMING */
00479 
00480    }
00481 
00482    // See if this establishes the sharing to be used as the default.
00483    // By choosing the default sharing by coordinator rather than by
00484    // order received we decrease the likelihood of multiple sharings.
00485    for ( unsigned int i = 0 ; i < NumServers ; ++i )
00486    {
00487       // This will grab the lowest-numbered coordinator which has
00488       // established a new sharing.
00489       if ( m_finishedLog[i].initialized() )
00490       {
00491          if ( i == coord )
00492          {
00493             const SignedComputedMsg& ev =
00494                *(m_finishedLog[i].message().evidence().element(0));
00495             serverState->setDefaultLabel( &(ev.message().shareLabel()) );
00496          }
00497          break;
00498       }         
00499    }
00500 
00501    return true;
00502 }
00503 
00504 bool
00505 SecretManagement::addInitResponse( const SignedContributeMsg& cm )
00506 {
00507    unsigned int coord = cm.message().coordinator().value();
00508    if ( ! m_initLog[coord].request().initialized() )
00509    {
00510       return false;
00511    }
00512    if ( m_initLog[coord].request().version().value() !=
00513         cm.message().version().value() )
00514    {
00515       return false;
00516    }
00517    m_initLog[coord].addResponse( cm );
00518    return true;
00519 }
00520 
00521 bool
00522 SecretManagement::addEstablishResponse( const SignedEstablishedMsg& em )
00523 {
00524    unsigned int estab = em.message().establisher().value();
00525    unsigned int snum = em.message().sublabel().id().value();
00526    EstablishRecord& er =
00527       m_establishLog[ estab ][ snum ][ em.message().sublabel().label() ];
00528    if ( ! er.request().initialized() )
00529    {
00530       return false;
00531    }
00532    if ( er.request().version().value() != em.message().version().value() )
00533    {
00534       return false;
00535    }
00536    er.addResponse( em );
00537    return true;
00538 }
00539 
00540 bool
00541 SecretManagement::addComputeResponse( const SignedComputedMsg& cm )
00542 {
00543    unsigned int coord = cm.message().shareLabel().id().value();
00544    if ( ! m_computeLog[ coord ].request().initialized() )
00545    {
00546       return false;
00547    }
00548    if (
00549       m_computeLog[coord].request().subshareLabel(0).label().version().value()
00550       != (cm.message().shareLabel().version().value()-1)
00551       )
00552    {
00553       return false;
00554    }
00555    m_computeLog[ coord ].addResponse( cm );
00556    return true;
00557 }
00558 
00559 void
00560 SecretManagement::clearEstablishMsgs()
00561 {
00562    for ( unsigned int i = 0 ; i < NumServers ; ++i )
00563    {
00564       for ( unsigned int j = 0 ; j < NumShares ; ++j )
00565       {
00566          m_establishLog[i][j].clear();
00567       }
00568    }
00569 }
00570 
00571 void
00572 SecretManagement::clearEstablishMsgs( unsigned int establisher )
00573 {
00574    for ( unsigned int i = 0 ; i < NumShares ; ++i )
00575    {
00576       m_establishLog[establisher][i].clear();
00577    }
00578 }
00579 
00580 const InitRecord&
00581 SecretManagement::initRecord( unsigned int i ) const
00582 {
00583    if ( i >= NumServers )
00584    {
00585       throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00586    }
00587    return m_initLog[i];
00588 }
00589 
00590 const EstablishRecord&
00591 SecretManagement::establishRecord( unsigned int establisher,
00592                                    unsigned int shareNum,
00593                                    const LabelType& label ) const
00594 {
00595    if ( establisher >= NumServers )
00596    {
00597       throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00598    }
00599    if ( shareNum >= NumShares )
00600    {
00601       throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00602    }
00603    return m_establishLog[establisher][shareNum][label];
00604 }
00605 
00606 const ComputeRecord&
00607 SecretManagement::computeRecord( unsigned int i ) const
00608 {
00609    if ( i >= NumServers )
00610    {
00611       throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00612    }
00613    return m_computeLog[i];
00614 }
00615 
00616 const SignedFinishedMsg&
00617 SecretManagement::finishedMsg( unsigned int i ) const
00618 {
00619    if ( i >= NumServers )
00620    {
00621       throw CODEX_Exceptions::IllegalIndexException( __FILE__ , __LINE__ );
00622    }
00623    return m_finishedLog[i];
00624 }
00625 
00626 void
00627 SecretManagement::setEpochTime()
00628 {
00629    struct timeval tv;
00630    int gtod = gettimeofday( &tv, 0 );
00631    if ( 0 != gtod )
00632    {
00633       CODEX_Exceptions::GetTimeOfDayException( __FILE__ , __LINE__ , errno );
00634    }
00635    m_epochTime = tv.tv_sec;
00636 }
00637 
00638 void
00639 SecretManagement::setRunTime()
00640 {
00641    struct timeval tv;
00642    int gtod = gettimeofday( &tv, 0 );
00643    if ( 0 != gtod )
00644    {
00645       CODEX_Exceptions::GetTimeOfDayException( __FILE__ , __LINE__ , errno );
00646    }
00647    m_runTime = tv.tv_sec;
00648 }
00649 
00650 unsigned long
00651 SecretManagement::elapsed( unsigned long current ) const
00652 {
00653    if ( m_epochTime > current )
00654    {
00655       return 0;
00656    }
00657    return ( current - m_epochTime );
00658 }
00659 
00660 void
00661 SecretManagement::beginRun()
00662 {
00663    // Are we already in a run?  If so, we do *not* start a new one.
00664    if ( m_runTime >= m_epochTime )
00665    {
00666       return;
00667    }
00668 
00669    cout << "starting a run" << endl;
00670 
00671 #ifdef TIMING
00672    APSSTimer[m_num].start();
00673    InitTimer[m_num].start();
00674    ActiveTimer.start();
00675 #endif
00676 
00677    CODEX_Server::ServerState* serverState =
00678       CODEX_Server::ServerState::instance();
00679    if ( 0 == serverState )
00680    {
00681 #ifdef TIMING
00682       ActiveTimer.stop();
00683 #endif
00684       return;
00685    }
00686 
00687    StateInfo* stateInfo = StateInfo::instance();
00688    if ( 0 == stateInfo )
00689    {
00690 #ifdef TIMING
00691       ActiveTimer.stop();
00692 #endif
00693       return;
00694    }
00695 
00696    unsigned int version = m_version + 1;
00697    unsigned int coordinator = serverState->hostNum();
00698    const LabelType& label = serverState->defaultLabel( m_num );
00699    CODEX_ASN1::Integer versionInt( version );
00700    CODEX_ASN1::Integer coordInt( coordinator );
00701    InitMsg request( version, coordinator, label );
00702 
00703    BIGNUM * digest = 0;
00704    CODEX_Ciphers::RSASignature* signature = 0;
00705    try
00706    {
00707       const CODEX_Ciphers::HashFunction& hashFunc = serverState->hashFunc();
00708       digest = request.digest( hashFunc );
00709       const CODEX_Ciphers::RSAPrivateKey& key = serverState->privateKey();
00710       signature = key.sign( digest );
00711       BN_free(digest);
00712       digest = 0;
00713       if ( 0 == signature )
00714       {
00715          throw CODEX_Exceptions::BignumNullException( __FILE__ , __LINE__ );
00716       }
00717    }
00718    catch ( ... )
00719    {
00720       if ( 0 != digest ) BN_free( digest );
00721       if ( 0 != signature ) delete signature;
00722 #ifdef TIMING
00723       ActiveTimer.stop();
00724 #endif
00725       throw;
00726    }
00727    SignedInitMsg signedRequest( request, *signature );
00728    delete signature;
00729 
00730    // Send the signed request
00731    CODEX_Quorum::Message m;
00732 
00733    // Fill message headers.
00734    m.fill( coordinator | CODEX_Server::ServerState::OutgoingMask );
00735    m.fill( serverState->newSequenceNumber(), CODEX_Server::ServerState::nMID );
00736    m.fill( stateInfo->domain() );
00737    m.fill( kInitMsg | SignatureMask );
00738    int length = signedRequest.marshal(0);
00739    unsigned char* buffer = new unsigned char[length];
00740    unsigned char* pBuffer = buffer;
00741    signedRequest.marshal(&pBuffer);
00742    m.fill( buffer, length );
00743    delete [] buffer;
00744 
00745    // Create callback
00746    InitCallback* cb = new InitCallback( version, label );
00747 
00748    // Mark the beginning of the run
00749    setRunTime();
00750    stateInfo->broadcast( m, cb );
00751 #ifdef TIMING
00752    ActiveTimer.stop();
00753 #endif
00754 }
00755 
00757 void
00758 SecretManagement::sendFinished( unsigned int server ) const
00759 {
00760    for ( unsigned int i = 0 ; i < NumServers ; ++i )
00761    {
00762       if ( m_finishedLog[i].initialized() )
00763       {
00764          sendFinished( i, server );
00765          return;
00766       }
00767    }
00768    // throw an exception if we get here?
00769 }
00770 
00771 void
00772 SecretManagement::sendFinished( unsigned int coord, unsigned int server ) const
00773 {
00774    const SignedFinishedMsg& fm = m_finishedLog[coord];
00775    if ( ! fm.initialized() )
00776    {
00777       return;
00778    }
00779 
00780    StateInfo* stateInfo = StateInfo::instance();
00781    CODEX_Server::ServerState* serverState =
00782       CODEX_Server::ServerState::instance();
00783 
00784    CODEX_Quorum::Message m;
00785 
00786    // Set the server ID, with "outgoing" mask.
00787    unsigned char self = serverState->hostNum();
00788    m.fill( self | CODEX_Server::ServerState::OutgoingMask );
00789 
00790    // This sequence number isn't actually used for anything.
00791    const unsigned char* seqNum = serverState->newSequenceNumber();
00792    m.fill( seqNum, CODEX_Server::ServerState::nMID );
00793 
00794    // Set the domain information.
00795    m.fill( stateInfo->domain() );
00796    m.fill( kFinishedMsg | SignatureMask );
00797 
00798    // Marshal the message.
00799    int length = fm.marshal(0);
00800    unsigned char* buffer = new unsigned char[length];
00801    unsigned char* pBuffer = buffer;
00802    fm.marshal(&pBuffer);
00803    m.fill( buffer, length );
00804    delete [] buffer;
00805 
00806    stateInfo->sendTo( server, m );
00807 }

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