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