00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00130 #include <unistd.h>
00131 #include <signal.h>
00132 #include <openssl/ssl.h>
00133 #include <openssl/rand.h>
00134
00135
00136 #include "CODEX_Server/ServerState.h"
00137 #include "CODEX_KeyService/StateInfo.h"
00138 #include "CODEX_APSS/StateInfo.h"
00139 #include "CODEX_Events/DelayedEvent.h"
00140
00141
00142 #include "CODEX_Server/InternalServer.h"
00143 #include "CODEX_Server/QuorumBuilderAct.h"
00144 #include "CODEX_Server/ServerMessageDispatcher.h"
00145 #include "CODEX_Server/ServerQuorumDispatcher.h"
00146 #include "CODEX_Server/SignRequestHandler.h"
00147 #include "CODEX_Server/ServerResponseHandler.h"
00148 #include "CODEX_Server/BroadcastRequestHandler.h"
00149 #include "CODEX_Server/UnicastRequestHandler.h"
00150
00151 #include "CODEX_Server/ShareLabelChallengeHandler.h"
00152 #include "CODEX_Server/ShareLabelChallengeEvent.h"
00153
00154
00155 #include "CODEX_KeyService/ClientServer.h"
00156 #include "CODEX_KeyService/ClientActivity.h"
00157 #include "CODEX_KeyService/ClientMessageEvent.h"
00158 #include "CODEX_KeyService/ClientMessageVerifier.h"
00159
00160
00161 #include "CODEX_KeyService/DelegateRequestDistributor.h"
00162 #include "CODEX_KeyService/ClientMessageParser.h"
00163 #include "CODEX_KeyService/ClientResponseParser.h"
00164 #include "CODEX_KeyService/RoutedClientMessageVerifier.h"
00165 #include "CODEX_KeyService/DelegateResponseVerifier.h"
00166 #include "CODEX_KeyService/ClientMessageSigner.h"
00167 #include "CODEX_KeyService/ClientResponseSigner.h"
00168
00169
00170
00171
00172 #include "CODEX_APSS/MessageDeliverer.h"
00173 #include "CODEX_APSS/MessageProcessor.h"
00174 #include "CODEX_APSS/MessageVerifier.h"
00175 #include "CODEX_APSS/MessageParser.h"
00176 #include "CODEX_APSS/TriggerActivity.h"
00177
00178
00179 #include "CODEX_Ciphers/CipherExceptions.h"
00180 #include "CODEX_Server/ServerExceptions.h"
00181 #include "CODEX_Server/ConfigurationExceptions.h"
00182
00183
00184 bool running;
00185
00186
00187 bool SlowServer = false;
00188 long int ServerDelayS = 0;
00189 long int ServerDelayUS = 0;
00190 long int ServerSlowdown = 0;
00191
00192
00193 bool SlowLink = false;
00194 long int LinkDelayS = 0;
00195 long int LinkDelayUS = 0;
00196 long int CODEX_Events::DelayedEvent::sDelay;
00197 long int CODEX_Events::DelayedEvent::usDelay;
00198
00199 void handle_interrupt(int signal)
00200 {
00201 running = false;
00202 }
00203
00204 void handle_crash(int signal)
00205 {
00206 cerr << "Fatal error, signal " << signal << endl;
00207 ::exit(1);
00208 }
00209
00210 void
00211 configure_server(int argc, char** argv)
00212 {
00213 int arg = 0;
00214 string config_file;
00215 string config_section;
00216 string usage_string = "Usage: codex_server -c <config_file> [-s <section>]";
00217 while ( -1 != arg )
00218 {
00219 arg = getopt(argc,argv,"c:s:");
00220 switch(arg)
00221 {
00222 case 'c' :
00223 config_file = optarg;
00224 break;
00225 case 's' :
00226 config_section = optarg;
00227 break;
00228 case ':' :
00229 case '?' :
00230 cerr << usage_string << endl;
00231 ::exit(1);
00232 }
00233 }
00234 if ( 0 == config_file.size() )
00235 {
00236 cerr << usage_string << endl;
00237 ::exit(1);
00238 }
00239
00240
00241 CONF* conf = 0;
00242 try
00243 {
00244 conf = NCONF_new(NCONF_default());
00245 if ( 0 == NCONF_load(conf,config_file.c_str(),0) )
00246 {
00247 throw CODEX_Exceptions::FileCannotOpenException( __FILE__ ,
00248 __LINE__ ,
00249 config_file );
00250 }
00251 const char* sec = config_section.c_str();
00252 CODEX_Server::ServerState::instance()->configure(
00253 conf, sec, config_file );
00254 CODEX_KeyService::StateInfo::instance()->configure(
00255 conf, sec, config_file );
00256 CODEX_APSS::StateInfo::instance()->configure(
00257 conf, sec, config_file );
00258
00259
00260
00261
00262 long dummy;
00263 if ( NCONF_get_number_e(conf,sec,"slow_server",&dummy) )
00264 {
00265 if ( dummy != 0 )
00266 {
00267 SlowServer = true;
00268
00269
00270 if (NCONF_get_number_e(conf,sec,"server_delay_s",&ServerDelayS))
00271 {
00272 if ( ServerDelayS < 0 )
00273 {
00274 throw CODEX_Server::BCBadValueException(
00275 __FILE__ , __LINE__ , config_file, "server_delay_s" );
00276 }
00277 }
00278 if (NCONF_get_number_e(conf,sec,"server_delay_us",&ServerDelayUS))
00279 {
00280 if ( ServerDelayUS < 0 )
00281 {
00282 throw CODEX_Server::BCBadValueException(
00283 __FILE__ , __LINE__ , config_file, "server_delay_us" );
00284 }
00285 }
00286 if (NCONF_get_number_e(conf,sec,"server_slowdown",&ServerSlowdown))
00287 {
00288 if ( ServerSlowdown < 0 )
00289 {
00290 throw CODEX_Server::BCBadValueException(
00291 __FILE__ , __LINE__ , config_file, "server_slowdown" );
00292 }
00293 }
00294
00295 cout << "Simulating a slow processor with a delay of "
00296 << ServerDelayS << "s, "
00297 << ServerDelayUS << "us "
00298 << " and slowdown of " << ServerSlowdown << "%"
00299 << endl;
00300 }
00301 }
00302 if ( NCONF_get_number_e(conf,sec,"slow_link",&dummy) )
00303 {
00304 if ( dummy != 0 )
00305 {
00306 SlowLink = true;
00307
00308
00309 if (NCONF_get_number_e(conf,sec,"link_delay_s",&LinkDelayS))
00310 {
00311 if ( LinkDelayS < 0 )
00312 {
00313 throw CODEX_Server::BCBadValueException(
00314 __FILE__ , __LINE__ , config_file, "link_delay_s" );
00315 }
00316 }
00317 if (NCONF_get_number_e(conf,sec,"link_delay_us",&LinkDelayUS))
00318 {
00319 if ( LinkDelayUS < 0 )
00320 {
00321 throw CODEX_Server::BCBadValueException(
00322 __FILE__ , __LINE__ , config_file, "link_delay_us" );
00323 }
00324 }
00325
00326 cout << "Simulating a slow link with a delay of "
00327 << LinkDelayS << "s, "
00328 << LinkDelayUS << "us"
00329 << endl;
00330 CODEX_Events::DelayedEvent::sDelay = LinkDelayS;
00331 CODEX_Events::DelayedEvent::usDelay = LinkDelayUS;
00332 }
00333 }
00334
00335
00336 NCONF_free( conf );
00337 }
00338 catch ( CODEX_Exceptions::ExceptionBase& e )
00339 {
00340 if ( 0 != conf ) NCONF_free(conf);
00341 e.report();
00342 throw;
00343 }
00344 }
00345
00349 void
00350 check_client_servers()
00351 {
00352 fd_set read_set;
00353 fd_set write_set;
00354 FD_ZERO( &read_set );
00355 FD_ZERO( &write_set );
00356 int smax=0;
00357 CODEX_Server::ServerState* serverState =
00358 CODEX_Server::ServerState::instance();
00359
00360 CODEX_Server::ServerState::ServerList::const_iterator cServItr =
00361 serverState->serverListBegin();
00362 for ( ; cServItr != serverState->serverListEnd() ; ++cServItr )
00363 {
00364 int s = (*cServItr)->set_fd( &read_set,
00365 CODEX_Quorum::SocketBase::kRead );
00366 (*cServItr)->set_fd( &write_set, CODEX_Quorum::SocketBase::kWrite );
00367 smax = ( s > smax ) ? s : smax;
00368 }
00369
00370 struct timeval async_timeout;
00371 async_timeout.tv_sec = 0;
00372 async_timeout.tv_usec = 0;
00373
00374
00375 if ( 0 < select( smax+1, &read_set, &write_set, 0, &async_timeout ) )
00376 {
00377 for ( cServItr = serverState->serverListBegin() ;
00378 cServItr != serverState->serverListEnd() ;
00379 ++cServItr )
00380 {
00381 CODEX_Quorum::LocalServer* cs = *cServItr;
00382
00383
00384
00385 try
00386 {
00387
00388 if ( cs->isset_fd(&read_set,CODEX_Quorum::SocketBase::kRead) )
00389 {
00390 cs->processRequest(CODEX_Quorum::SocketBase::kRead);
00391 }
00392
00393
00394 if ( cs->isset_fd(&write_set,CODEX_Quorum::SocketBase::kWrite) )
00395 {
00396 cs->processRequest(CODEX_Quorum::SocketBase::kWrite);
00397 }
00398 }
00399 catch ( ... )
00400 {
00401
00402 --cServItr;
00403 serverState->removeServer( cs );
00404 }
00405 }
00406 }
00407 }
00408
00412 void
00413 process_next_event( CODEX_Events::QType& eventQueue )
00414 {
00415 if ( eventQueue.empty() ) return;
00416 CODEX_Events::EventBase* event = eventQueue.front();
00417 eventQueue.pop();
00418
00419 if ( SlowServer )
00420 {
00421 struct timeval tv;
00422 tv.tv_sec = ServerDelayS;
00423 tv.tv_usec = ServerDelayUS;
00424 select(0,0,0,0,&tv);
00425 }
00426 if ( event->handle() )
00427 {
00428 delete event;
00429 }
00430 else
00431 {
00432
00433 eventQueue.push(event);
00434 }
00435 }
00436
00440 void
00441 consume_queue( CODEX_Events::QType& eventQueue )
00442 {
00443 while ( ! eventQueue.empty() )
00444 {
00445 delete eventQueue.front();
00446 eventQueue.pop();
00447 }
00448 }
00449
00450 void
00451 move_delayed_events( CODEX_Events::QType& delayedEventQueue,
00452 CODEX_Events::QType& eventQueue )
00453 {
00454 while ( ! delayedEventQueue.empty() )
00455 {
00456 eventQueue.push(
00457 new CODEX_Events::DelayedEvent( delayedEventQueue.front() ) );
00458 delayedEventQueue.pop();
00459 }
00460 }
00461
00465 void
00466 garbage_collect_activities( CODEX_Events::DeadPileType& deadPile )
00467 {
00468 while ( deadPile.size() > 0 )
00469 {
00470 CODEX_Events::Activity* act = deadPile.back();
00471 deadPile.pop_back();
00472 delete act;
00473 }
00474 }
00475
00479 void
00480 garbage_collect_servers()
00481 {
00482 CODEX_Server::ServerState* serverState =
00483 CODEX_Server::ServerState::instance();
00484 if ( 0 == serverState ) return;
00485 serverState->garbageCollectServers();
00486 }
00487
00488
00489 int main( int argc, char** argv )
00490 {
00491
00492
00493
00494 CODEX_Server::ServerState* serverState =
00495 CODEX_Server::ServerState::instance();
00496 CODEX_KeyService::StateInfo* keyServiceState =
00497 CODEX_KeyService::StateInfo::instance();
00498 CODEX_APSS::StateInfo* apssState = CODEX_APSS::StateInfo::instance();
00499
00500
00501
00502
00503
00504 unsigned char seed[40] =
00505 {0x38,0x4F,0x67,0x4C,0xA6,0x02,0x3D,0x9E,
00506 0x69, 0x2c, 0x3f, 0xfd, 0x98, 0x50, 0xcc,
00507 0x76, 0xfa, 0x78, 0x34, 0x12, 0x23, 0xdf,
00508 0x8a, 0xd4, 0x34, 0xcd, 0x98, 0x59, 0x19,
00509 0x35, 0x4f, 0xda, 0xed, 0x4e, 0x99, 0x0f};
00510 RAND_seed(seed,40);
00511
00512
00513
00514
00515
00516 SSL_load_error_strings();
00517 SSLeay_add_ssl_algorithms();
00518
00519
00520
00521
00522
00523 signal(SIGINT,handle_interrupt);
00524
00525
00526
00527
00528
00529
00530 cout << "Configuring server..." << endl;
00531 configure_server(argc,argv);
00532 cout << "...Server configuration done" << endl;
00533
00534
00535
00536
00537
00538 CODEX_Events::DeadPileType deadPile;
00539 CODEX_Events::QType eventQueue;
00540 CODEX_Events::QType delayedEventQueue;
00541 CODEX_Events::QType* pLinkQueue;
00542 if ( SlowLink )
00543 {
00544 pLinkQueue = &delayedEventQueue;
00545 }
00546 else
00547 {
00548 pLinkQueue = &eventQueue;
00549 }
00550 CODEX_Events::QType& linkQueue = *pLinkQueue;
00551
00552
00553 CODEX_Server::InternalServer is( serverState->serverPort(),
00554 serverState->serverInSocketBuilder() );
00555 serverState->addServer( &is );
00556 try
00557 {
00558 is.enable();
00559 }
00560 catch ( CODEX_Quorum::QSExceptionBase& e )
00561 {
00562 e.report();
00563 return 1;
00564 }
00565
00566
00567
00568
00569
00570 CODEX_Server::BroadcastRequestHandler broadcastHandler( deadPile,
00571 eventQueue );
00572 CODEX_Server::UnicastRequestHandler unicastHandler( deadPile,
00573 eventQueue );
00574 CODEX_Server::ShareLabelChallengeHandler challengeHandler( deadPile,
00575 eventQueue );
00576 CODEX_Server::SignRequestHandler signHandler( deadPile, eventQueue );
00577 CODEX_KeyService::DelegateRequestDistributor delegateDistributor(
00578 deadPile,
00579 eventQueue,
00580 &broadcastHandler,
00581 &signHandler );
00582 CODEX_KeyService::ClientMessageVerifier* clientMsgVerifier =
00583 new CODEX_KeyService::ClientMessageVerifier( deadPile,
00584 eventQueue,
00585 &delegateDistributor );
00586
00587
00588
00589
00590
00591 CODEX_Server::QuorumBuilderAct* quorumBuilder =
00592 new CODEX_Server::QuorumBuilderAct( deadPile, eventQueue );
00593
00594 CODEX_Server::ServerResponseHandler serverResponseHandler( deadPile,
00595 eventQueue );
00596
00597
00598
00599
00600 CODEX_Server::ServerMessageDispatcher messageDispatcher;
00601
00602
00603 const unsigned char clientMessageDomain = 1;
00604
00605 CODEX_KeyService::ClientMessageSigner
00606 delegateMsgSigner( deadPile, eventQueue, &serverResponseHandler );
00607
00608 CODEX_KeyService::RoutedClientMessageVerifier
00609 delegateVerifier( deadPile, eventQueue, &delegateMsgSigner );
00610
00611 CODEX_KeyService::ClientMessageParser
00612 clientMessageParser( deadPile, linkQueue, &delegateVerifier );
00613
00614 keyServiceState->setMessageDomain( clientMessageDomain );
00615 messageDispatcher.addParser( clientMessageDomain, &clientMessageParser );
00616
00617
00618 const unsigned char clientDelegateDomain = 2;
00619
00620 CODEX_KeyService::ClientResponseSigner
00621 delegateRespSigner( deadPile, eventQueue, &serverResponseHandler );
00622
00623 CODEX_KeyService::DelegateResponseVerifier
00624 delegateResponseVerifier( deadPile, eventQueue, &delegateRespSigner );
00625
00626 CODEX_KeyService::ClientResponseParser
00627 clientResponseParser( deadPile, linkQueue, &delegateResponseVerifier );
00628
00629 keyServiceState->setDelegationDomain( clientDelegateDomain );
00630 messageDispatcher.addParser( clientDelegateDomain, &clientResponseParser );
00631
00632
00633 const unsigned char apssDomain = 3;
00634
00635 CODEX_APSS::MessageProcessor
00636 apssProc( deadPile,
00637 eventQueue,
00638 &serverResponseHandler,
00639 &unicastHandler );
00640
00641 CODEX_APSS::MessageVerifier
00642 apssVerifier( deadPile, eventQueue, &apssProc, &serverResponseHandler );
00643
00644 CODEX_APSS::MessageParser
00645 apssParser( deadPile, linkQueue, &apssVerifier );
00646
00647 CODEX_APSS::MessageDeliverer
00648 apssDeliverer( deadPile,
00649 eventQueue,
00650 &serverResponseHandler,
00651 &broadcastHandler );
00652 apssState->setMessageDeliverer( &apssDeliverer );
00653
00654 apssState->setDomain( apssDomain );
00655 messageDispatcher.addParser( apssDomain, &apssParser );
00656
00657 CODEX_APSS::TriggerActivity( deadPile, eventQueue );
00658
00659
00660
00661
00662 CODEX_Server::ServerQuorumDispatcher quorumDispatcher;
00663
00664
00665
00666
00667
00668 CODEX_KeyService::ClientServer clientServer(
00669 keyServiceState->clientPort(),
00670 serverState->clientSocketBuilder(),
00671 deadPile,
00672 eventQueue,
00673 clientMsgVerifier );
00674 serverState->addServer( &clientServer );
00675 try
00676 {
00677 clientServer.enable();
00678 }
00679 catch ( CODEX_Quorum::QSExceptionBase& e )
00680 {
00681 e.report();
00682 return 1;
00683 }
00684
00685
00686
00687
00688
00689 CODEX_Quorum::QuorumSystem* quorumSystem = serverState->quorumSystem();
00690 if ( 0 == quorumSystem )
00691 {
00692 return 1;
00693 }
00694
00695
00696
00697
00698
00699 running = true;
00700 while(running)
00701 {
00702 try
00703 {
00704 struct timeval tv;
00705 if ( SlowServer )
00706 {
00707 gettimeofday(&tv,0);
00708 }
00709
00710
00711 quorumSystem->poll( messageDispatcher, quorumDispatcher );
00712
00713
00714 check_client_servers();
00715
00716
00717 garbage_collect_activities( deadPile );
00718
00719
00720 garbage_collect_servers();
00721
00722
00723 move_delayed_events( delayedEventQueue, eventQueue );
00724
00725
00726 process_next_event( eventQueue );
00727
00728 if ( SlowServer )
00729 {
00730
00731
00732 struct timeval delay;
00733 gettimeofday(&delay,0);
00734 long int t =
00735 ( delay.tv_sec - tv.tv_sec ) * 1000000 +
00736 ( delay.tv_usec - tv.tv_usec );
00737 t *= ServerSlowdown;
00738 t /= 100;
00739 delay.tv_sec = t / 1000000;
00740 delay.tv_usec = t % 1000000;
00741 select(0,0,0,0,&delay);
00742 }
00743 }
00744 catch ( CODEX_Exceptions::ExceptionBase& e )
00745 {
00746 e.report();
00747
00748 running = false;
00749 }
00750 }
00751
00752
00753
00754
00755
00756 garbage_collect_activities( deadPile );
00757 garbage_collect_servers();
00758 consume_queue( eventQueue );
00759 delete clientMsgVerifier;
00760 delete quorumBuilder;
00761 CODEX_KeyService::StateInfo::destroy();
00762 CODEX_APSS::StateInfo::destroy();
00763 CODEX_Server::ServerState::destroy();
00764 ERR_free_strings();
00765 ERR_remove_state(0);
00766 EVP_cleanup();
00767 RAND_cleanup();
00768
00769
00770
00771
00772
00773 return 0;
00774 }