00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "QuorumBuilderAct.h"
00019 #include "QuorumBuilderEvent.h"
00020 #include "QuorumBuilderExpectNonceEvent.h"
00021
00022 #include "CODEX_ASN1/Integer.h"
00023 #include "CODEX_Exceptions/BignumExceptions.h"
00024 #include "ServerExceptions.h"
00025
00026 using namespace CODEX_Server;
00027
00028 QuorumBuilderAct::QuorumBuilderAct( CODEX_Events::DeadPileType& deadPile,
00029 CODEX_Events::QType& eventQueue ) :
00030 CODEX_Events::Activity( deadPile, eventQueue )
00031 {
00032 sendEvent( new QuorumBuilderEvent(this), 0 );
00033 for ( unsigned int i = 0 ; i < ServerState::nServers ; ++i )
00034 {
00035 m_pending[i] = NULL;
00036 }
00037 }
00038
00039 QuorumBuilderAct::~QuorumBuilderAct()
00040 {
00041 for ( unsigned int i = 0 ; i < ServerState::nServers ; ++i )
00042 {
00043 if ( NULL != m_pending[i] )
00044 {
00045 delete m_pending[i];
00046 }
00047 }
00048 }
00049
00050 bool
00051 QuorumBuilderAct::handler( QuorumBuilderEvent& event )
00052 {
00053 ServerState* serverState = ServerState::instance();
00054 if ( NULL == serverState )
00055 {
00056
00057 return true;
00058 }
00059
00060
00061
00062
00063 for ( unsigned int i = 0 ; i < ServerState::nServers ; ++i )
00064 {
00065
00066
00067
00068 unsigned int hostNum =
00069 ( i + event.lastAttempt() + 1 ) % ServerState::nServers;
00070 if ( ( hostNum > serverState->hostNum() ) &&
00071 ( ! serverState->haveQuorumServer( hostNum ) ) &&
00072 ( NULL == m_pending[ hostNum ] ) )
00073 {
00074
00075 RSType* ars = NULL;
00076 try
00077 {
00078 ars = new RSType( serverState->hostName(hostNum),
00079 serverState->serverPort(hostNum),
00080 serverState->serverOutSocketBuilder() );
00081
00082
00083
00084 m_pending[ hostNum ] = ars;
00085 sendEvent( new QuorumBuilderExpectNonceEvent(this,hostNum),
00086 0 );
00087 }
00088 catch ( ... )
00089 {
00090 if ( NULL != ars ) delete ars;
00091 }
00092 event.setLastAttempt( hostNum );
00093 return false;
00094 }
00095 }
00096
00097 return false;
00098 }
00099
00101 bool
00102 QuorumBuilderAct::handler( QuorumBuilderExpectNonceEvent& event )
00103 {
00104 ServerState* serverState = ServerState::instance();
00105 if ( NULL == serverState )
00106 {
00107
00108 return true;
00109 }
00110
00111
00112 RSType* ars = m_pending[ event.hostNum() ];
00113 if ( NULL == ars )
00114 {
00115 return true;
00116 }
00117 try
00118 {
00119 fd_set read_set;
00120 FD_ZERO(&read_set);
00121 int s = ars->set_fd(&read_set,CODEX_Quorum::SocketBase::kRead);
00122 struct timeval tv;
00123 tv.tv_sec = 0;
00124 tv.tv_usec = 0;
00125 if ( ( 0 <= select( s+1, &read_set, NULL, NULL, &tv ) ) &&
00126 ( ars->isset_fd( &read_set, CODEX_Quorum::SocketBase::kRead ) ) )
00127 {
00128 if ( event.read( ars ) )
00129 {
00130
00131 unsigned char* buffer = (unsigned char*)event.buffer().buffer();
00132 unsigned char* pBuffer = buffer;
00133 int length = event.buffer().length();
00134
00135
00136 CODEX_ASN1::BigNumber bn;
00137 if ( NULL == bn.unmarshal(NULL,&pBuffer,length) )
00138 {
00139 throw 0;
00140 }
00141
00142
00143 CODEX_ASN1::Integer iHost( serverState->hostNum() );
00144 length = iHost.marshal(0);
00145 length += bn.marshal(0);
00146 buffer = new unsigned char[ length ];
00147 pBuffer = buffer;
00148 iHost.marshal(&pBuffer);
00149 bn.marshal(&pBuffer);
00150 CODEX_Quorum::Message msg(buffer,length);
00151
00152
00153 CODEX_ASN1::ustring* str = NULL;
00154 try
00155 {
00156 str =
00157 serverState->hashFunc()(CODEX_ASN1::ustring(buffer,length));
00158 }
00159 catch ( ... )
00160 {
00161 if ( NULL != str ) delete str;
00162 delete [] buffer;
00163 throw;
00164 }
00165 delete [] buffer;
00166 BIGNUM * digest = NULL;
00167 digest = BN_new();
00168 if ( NULL == digest )
00169 {
00170 delete str;
00171 throw CODEX_Exceptions::BignumNullException( __FILE__ ,
00172 __LINE__ );
00173 }
00174 if ( ! BN_bin2bn( str->data(), str->length(), digest ) )
00175 {
00176 delete str;
00177 BN_free( digest );
00178 throw CODEX_Exceptions::BignumBin2BNException( __FILE__ ,
00179 __LINE__ );
00180 }
00181 delete str;
00182
00183
00184 const CODEX_Ciphers::RSAPrivateKey& key =
00185 serverState->privateKey();
00186 if ( ! key.initialized() )
00187 {
00188 BN_free( digest );
00189 throw PublicKeyNotFoundException( __FILE__ , __LINE__ );
00190 }
00191 CODEX_Ciphers::RSASignature* signature = NULL;
00192 try
00193 {
00194 signature = key.sign(digest);
00195 }
00196 catch ( ... )
00197 {
00198 BN_free( digest );
00199 throw;
00200 }
00201 BN_free( digest );
00202
00203
00204 length = signature->marshal(0);
00205 buffer = new unsigned char[ length ];
00206 pBuffer = buffer;
00207 signature->marshal(&pBuffer);
00208 msg.fill(buffer,length);
00209 delete [] buffer;
00210 delete signature;
00211
00212
00213 CODEX_Quorum::RemoteServerReturn r;
00214 ars->sendTo(msg,r);
00215 m_pending[ event.hostNum() ] = NULL;
00216 serverState->addQuorumServer( event.hostNum(), ars );
00217 cout << "Connected to server " << event.hostNum() << endl;
00218 return true;
00219 }
00220 }
00221 }
00222 catch ( ... )
00223 {
00224 if ( NULL != ars ) delete ars;
00225 m_pending[ event.hostNum() ] = NULL;
00226 return true;
00227 }
00228 return false;
00229 }