Mixe for Privacy and Anonymity in the Internet
proxytest.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000, The JAP-Team
00003 All rights reserved.
00004 Redistribution and use in source and binary forms, with or without modification,
00005 are permitted provided that the following conditions are met:
00006 
00007   - Redistributions of source code must retain the above copyright notice,
00008     this list of conditions and the following disclaimer.
00009 
00010   - Redistributions in binary form must reproduce the above copyright notice,
00011     this list of conditions and the following disclaimer in the documentation and/or
00012     other materials provided with the distribution.
00013 
00014   - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors
00015     may be used to endorse or promote products derived from this software without specific
00016     prior written permission.
00017 
00018 
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00027 */
00028 // proxytest.cpp : Definiert den Einsprungpunkt fuer die Konsolenanwendung.
00029 //
00030 
00031 #include "StdAfx.h"
00032 
00033 #include "CACmdLnOptions.hpp"
00034 #include "CAMsg.hpp"
00035 #include "CALocalProxy.hpp"
00036 #include "CAQueue.hpp"
00037 #include "CAThreadList.hpp"
00038 #include "CAStatusManager.hpp"
00039 #include "CALibProxytest.hpp"
00040 
00041 #ifdef _DEBUG //For FreeBSD memory checking functionality
00042   const char* _malloc_options="AX";
00043 #endif
00044 
00045 #ifdef REPLAY_DATABASE_PERFORMANCE_TEST
00046 #include "CAReplayDatabase.hpp"
00047 #endif
00048 
00049 #ifndef ONLY_LOCAL_PROXY
00050   #include "xml/DOM_Output.hpp"
00051   #include "CAMix.hpp"
00052   #ifdef LOG_CRIME
00053     #include "tre/regex.h"
00054   #endif
00055   #ifdef NEW_MIX_TYPE
00056     /* use TypeB mixes */
00057     #include "TypeB/CAFirstMixB.hpp"
00058     #include "TypeB/CALastMixB.hpp"
00059   #else
00060     #include "TypeA/CAFirstMixA.hpp"
00061     #include "TypeA/CALastMixA.hpp"
00062   #endif
00063   #include "CAMiddleMix.hpp"
00064   #include "CALogPacketStats.hpp"
00065   #include "CATLSClientSocket.hpp"
00066 
00067 #ifdef REPLAY_DATABASE_PERFORMANCE_TEST
00068   #include "CAReplayDatabase.hpp"
00069 #endif
00070 // The Mix....
00071 CAMix* pMix=NULL;
00072 #endif
00073 
00074 bool bTriedTermination = false;
00075 
00076 #ifndef _WIN32
00077   #ifdef _DEBUG
00078     void signal_broken_pipe( int sig)
00079       {
00080         CAMsg::printMsg(LOG_INFO,"Hm.. Broken Pipe.... Who cares!\n");
00081         signal(SIGPIPE,signal_broken_pipe);
00082       }
00083   #endif
00084 #endif
00085 
00086 
00088 void removePidFile()
00089   {
00090     if(CALibProxytest::getOptions()==NULL)
00091       {
00092         return;
00093       }
00094     UINT8 strPidFile[512];
00095     if(CALibProxytest::getOptions()->getPidFile(strPidFile,512)==E_SUCCESS)
00096       {
00097         if(::remove((char*)strPidFile)!=0)
00098           {
00099 #ifndef _WIN32
00100             int old_uid=geteuid(); //old uid... stored if we have to switch to root
00101             seteuid(0);
00102             ::remove((char*)strPidFile);
00103             seteuid(old_uid);
00104 #endif
00105           }
00106       }
00107   }
00108 
00109 
00111 void init()
00112   {
00113     CALibProxytest::init();
00114   }
00115 
00117 void cleanup()
00118   {
00119 #ifdef ENABLE_GPERFTOOLS_CPU_PROFILER
00120     ProfilerFlush();
00121     ProfilerStop();
00122 #endif
00123 //    delete pRTT;
00124 #ifndef ONLY_LOCAL_PROXY
00125     if(pMix!=NULL)
00126       delete pMix;
00127     pMix=NULL;
00128 #endif
00129     CAMsg::printMsg(LOG_CRIT,"Terminating Programm!\n");
00130     removePidFile();
00131     CALibProxytest::cleanup();
00132   }
00133 
00135 void my_terminate(void)
00136 {
00137   if(!bTriedTermination)
00138   {
00139     bTriedTermination = true;
00140 #ifndef ONLY_LOCAL_PROXY
00141     if(pMix!=NULL)
00142     {
00143       pMix->shutDown();
00144       for (UINT32 i = 0; i < 20 && !(pMix->isShutDown()); i++)
00145       {
00146         msSleep(100);
00147       }
00148       delete pMix;
00149       pMix=NULL;
00150     }
00151 #endif
00152     cleanup();
00153   }
00154 }
00155 
00156 
00157 void signal_segv( int )
00158 {
00159   signal(SIGSEGV,SIG_DFL); //otherwise we might end up in endless loops...
00160 
00161   MONITORING_FIRE_SYS_EVENT(ev_sys_sigSegV);
00162   CAMsg::printMsg(LOG_CRIT,"Oops ... caught SIG_SEGV! Exiting...\n");
00163 
00164   // wait 1 second so that log files may still be written
00165   sSleep(1);
00166 
00167 #ifdef PRINT_THREAD_STACK_TRACE
00168   CAThread::METHOD_STACK* stack = CAThread::getCurrentStack();
00169   if (stack != NULL)
00170   {
00171     CAMsg::printMsg( LOG_CRIT, "Stack trace: %s, \"%s\"\n", stack->strMethodName, stack->strPosition);
00172 
00173   }
00174   else
00175   {
00176     CAMsg::printMsg( LOG_CRIT, "Stack trace: none available\n");
00177   }
00178 #endif
00179   // my_terminate();  temporarily disabled
00180   exit(1);
00181 }
00182 
00183 
00184 
00185 
00186 void signal_term( int )
00187   {
00188     MONITORING_FIRE_SYS_EVENT(ev_sys_sigTerm);
00189     CAMsg::printMsg(LOG_INFO,"Hm.. Signal SIG_TERM received... exiting!\n");
00190     my_terminate();
00191     exit(0);
00192   }
00193 
00194 void signal_interrupt( int)
00195   {
00196     MONITORING_FIRE_SYS_EVENT(ev_sys_sigInt);
00197     CAMsg::printMsg(LOG_INFO,"Hm.. Strg+C pressed... exiting!\n");
00198 #if defined _DEBUG && ! defined (ONLY_LOCAL_PROXY)
00199     CAMsg::printMsg(LOG_INFO,"%d threads listed.\n",CALibProxytest::getThreadList()->getSize());
00200     CALibProxytest::getThreadList()->showAll();
00201 #endif
00202     my_terminate();
00203     exit(0);
00204   }
00205 
00206 #ifndef ONLY_LOCAL_PROXY
00207 void signal_hup(int)
00208   {
00209     CALibProxytest::getOptions()->reread(pMix);
00210   }
00211 #endif
00212 
00213 
00215 void checkSizesOfBaseTypes()
00216   {
00217     #pragma warning( push )
00218     #pragma warning( disable : 4127 ) //Disable: Bedingter Ausdruck ist konstant
00219     if(sizeof(SINT8)!=1)
00220       {
00221         CAMsg::printMsg(LOG_CRIT,"sizeof(SINT8) != 1 --> maybe a compiler (optimization) problem!\n");
00222         exit(-1);
00223       }
00224     if(sizeof(UINT8)!=1)
00225       {
00226         CAMsg::printMsg(LOG_CRIT,"sizeof(UINT8) != 1 --> maybe a compiler (optimization) problem!\n");
00227         exit(-1);
00228       }
00229     if(sizeof(SINT16)!=2)
00230       {
00231         CAMsg::printMsg(LOG_CRIT,"sizeof(SINT16) != 2 --> maybe a compiler (optimization) problem!\n");
00232         exit(-1);
00233       }
00234     if(sizeof(UINT16)!=2)
00235       {
00236         CAMsg::printMsg(LOG_CRIT,"sizeof(UINT16) != 2 --> maybe a compiler (optimization) problem!\n");
00237         exit(-1);
00238       }
00239     if(sizeof(SINT32)!=4)
00240       {
00241         CAMsg::printMsg(LOG_CRIT,"sizeof(SINT32) != 4 --> maybe a compiler (optimization) problem!\n");
00242         exit(-1);
00243       }
00244     if(sizeof(UINT32)!=4)
00245       {
00246         CAMsg::printMsg(LOG_CRIT,"sizeof(UINT32) != 4 --> maybe a compiler (optimization) problem!\n");
00247         exit(-1);
00248       }
00249     #ifdef HAVE_NATIVE_UINT64
00250       if(sizeof(UINT64)!=8)
00251         {
00252           CAMsg::printMsg(LOG_CRIT,"sizeof(UINT64) != 8 --> maybe a compiler (optimization) problem!\n");
00253           exit(-1);
00254         }
00255     #endif
00256     #pragma warning( pop )
00257   }
00258 
00259 
00435 int main(int argc, const char* argv[])
00436   {
00437 #ifndef ONLY_LOCAL_PROXY
00438     pMix=NULL;
00439 #endif
00440     UINT32 lLogOpts = 0;
00441     SINT32 maxFiles,ret;
00442 #if defined(HAVE_CRTDBG)
00443 //      _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
00444 //      _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
00445 //      _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
00446 //      _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
00447 //      _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
00448 //      _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
00449 
00450     UINT32 tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
00451     tmpDbgFlag |= _CRTDBG_ALLOC_MEM_DF;
00452     tmpDbgFlag |=_CRTDBG_LEAK_CHECK_DF;
00453     _CrtSetDbgFlag(tmpDbgFlag);
00454     _CrtMemState s1, s2, s3;
00455     _CrtMemCheckpoint( &s1 );
00456 #endif
00457 //Switch on debug infos
00458 #ifdef CWDEBUG
00459     Debug(libcw_do.on());
00460     Debug(dc::malloc.on());
00461 #endif
00462     init();
00463       //some test....
00464     //UINT8 buff1[500];
00465     //readPasswd(buff1,500);
00466     //printf("%s\n",buff1);
00467     //printf("Len: %i\n",strlen((char*)buff1));
00468 
00469     /*UINT32 size=0;
00470     UINT8* fg=readFile((UINT8*)"test.xml",&size);
00471     XERCES_CPP_NAMESPACE::DOMDocument* doc=parseDOMDocument(fg,size);
00472     delete[] fg;
00473     doc->release();
00474     cleanup();
00475     exit(0);
00476     */
00477 
00478     checkSizesOfBaseTypes();
00479 #ifndef NEW_MIX_TYPE
00480     if(MIXPACKET_SIZE!=sizeof(MIXPACKET))
00481       {
00482         CAMsg::printMsg(LOG_CRIT,"MIXPACKET_SIZE [%u] != sizeof(MUXPACKET) [%u] --> maybe a compiler (optimization) problem!\n",MIXPACKET_SIZE,sizeof(MIXPACKET));
00483         CAMsg::printMsg(LOG_CRIT,"Offsets:\n");
00484         MIXPACKET oPacket;
00485         UINT8 *p=(UINT8 *)&oPacket;
00486         UINT32 soffsets[7]={0,4,6,6,6,8,9};
00487         UINT32 hoffsets[7];
00488         CAMsg::printMsg(LOG_CRIT,".channel %u (should be 0)\n",hoffsets[0]=(UINT8*)&(oPacket.channel)-p);
00489         CAMsg::printMsg(LOG_CRIT,".flags: %u (should be 4)\n",hoffsets[1]=(UINT8*)&oPacket.flags-p);
00490         CAMsg::printMsg(LOG_CRIT,".data: %u (should be 6)\n",hoffsets[2]=(UINT8*)&oPacket.data-p);
00491         CAMsg::printMsg(LOG_CRIT,".payload: %u (should be 6)\n",hoffsets[3]=(UINT8*)&oPacket.payload-p);
00492         CAMsg::printMsg(LOG_CRIT,".payload.len: %u (should be 6)\n",hoffsets[4]=(UINT8*)&oPacket.payload.len-p);
00493         CAMsg::printMsg(LOG_CRIT,".payload.type: %u (should be 8)\n",hoffsets[5]=(UINT8*)&oPacket.payload.type-p);
00494         CAMsg::printMsg(LOG_CRIT,".payload.data: %u (should be 9)\n",hoffsets[6]=(UINT8*)&oPacket.payload.data-p);
00495         for(int i=0;i<7;i++)
00496          if(soffsets[i]!=hoffsets[i])
00497           exit(EXIT_FAILURE);
00498         CAMsg::printMsg(LOG_CRIT,"Hm, The Offsets seams to be ok - so we try to continue - hope that works...\n");
00499       }
00500 #endif
00501 #ifdef LOG_CRIME
00502 //      testTre();
00503 #endif
00504 
00505 #ifdef REPLAY_DATABASE_PERFORMANCE_TEST
00506     CAReplayDatabase::measurePerformance((UINT8*)"dbperformace.log",1,10000001,500000,10,100000);
00507     exit(0);
00508 #endif
00509 
00510 
00511 #ifdef DATA_RETENTION_LOG
00512     if(sizeof(t_dataretentionLogEntry)!=18)
00513     {
00514         CAMsg::printMsg(LOG_CRIT,"sizeof(tDataRetentionLogEntry) [%u] != 18 --> maybe a compiler (optimization) problem!\n",sizeof(t_dataretentionLogEntry));
00515         exit(EXIT_FAILURE);
00516     }
00517 #endif
00518 //    CADataRetentionLogFile::doCheckAndPerformanceTest();
00519 //    getch();
00520 //    exit(0);
00521 #ifdef _DEBUG
00522       UINT32 start;
00523 #endif
00524   /*  CATLSClientSocket ssl;
00525     CASocketAddrINet addr;
00526     addr.setAddr((const UINT8*)"127.0.0.1",(UINT16)3456);
00527     UINT32 len1;
00528     UINT8* pt=readFile((UINT8*)"/Users/sk13/Documents/projects/jap/testkey.der",&len1);
00529     CACertificate* pCer=CACertificate::decode(pt,len1,CERT_DER);
00530     ssl.setServerCertificate(pCer);
00531     printf("try connect\n");
00532     ssl.connect(addr,1,0);
00533     ssl.receiveFully(pt,3);
00534 
00535     exit(0);
00536 */
00537 //#ifdef INTEL_IPP_CRYPTO
00538 //    CAASymCipher::testSpeed();
00539 //    getch();
00540 //    exit(0);
00541 //#endif
00542 
00543     if(CALibProxytest::getOptions()->parse(argc,argv) != E_SUCCESS)
00544     {
00545       CAMsg::printMsg(LOG_CRIT,"An error occurred before we could finish parsing the configuration file. Exiting...\n");
00546       exit(EXIT_FAILURE);
00547     }
00548     if(!( CALibProxytest::getOptions()->isFirstMix()||
00549           CALibProxytest::getOptions()->isMiddleMix()||
00550           CALibProxytest::getOptions()->isLastMix()||
00551           CALibProxytest::getOptions()->isLocalProxy()))
00552       {
00553         CAMsg::printMsg(LOG_CRIT,"You must specify which kind of Mix you want to run!\n");
00554         CAMsg::printMsg(LOG_CRIT,"Use -j or -c\n");
00555         CAMsg::printMsg(LOG_CRIT,"Or try --help for more options.\n");
00556         CAMsg::printMsg(LOG_CRIT,"Exiting...\n");
00557         exit(EXIT_FAILURE);
00558       }
00559 
00560     UINT8 buff[255];
00561 
00562 /*#ifdef LOG_CRIME
00563     initHttpVerbLengths();
00564 #endif
00565 */
00566 
00567 
00568 #ifndef _WIN32
00569     if(CALibProxytest::getOptions()->getDaemon()) 
00570       {
00571         CAMsg::printMsg(LOG_DEBUG,"Starting mix process as daemon...\n");
00572         CAMsg::cleanup();
00573         CAMsg::init();
00574         pid_t pid;
00575         pid=fork();
00576         if(pid!=0)
00577           {
00578             CAMsg::printMsg(LOG_INFO,"Exiting parent shell process...\n");
00579             exit(EXIT_SUCCESS);
00580           }
00581         setsid();
00582         #ifndef DO_TRACE
00583           chdir("/");
00584           umask(0);
00585         #endif
00586        // Close out the standard file descriptors
00587         close(STDIN_FILENO);
00588         close(STDOUT_FILENO);
00589         close(STDERR_FILENO);
00590       }
00591 #endif
00592 
00593 
00594     if (CALibProxytest::getOptions()->initLogging() != E_SUCCESS)
00595     {
00596         exit(EXIT_FAILURE);
00597     }
00598     
00599 
00600 
00601 #if defined (_DEBUG) &&!defined(ONLY_LOCAL_PROXY)
00602     //    CADatabase::test();
00603     if(CAQueue::test()!=E_SUCCESS)
00604       CAMsg::printMsg(LOG_CRIT,"CAQueue::test() NOT passed! Exiting\n");
00605     else
00606       CAMsg::printMsg(LOG_DEBUG,"CAQueue::test() passed!\n");
00607 
00608     //CALastMixChannelList::test();
00609     //exit(0);
00610     //Testing msSleep
00611     CAMsg::printMsg(LOG_DEBUG,"Should sleep now for aprox 2 seconds....\n");
00612     start=time(NULL);
00613     for(SINT32 i=0;i<10;i++)
00614       msSleep(200);
00615     start=time(NULL)-start;
00616     CAMsg::printMsg(LOG_DEBUG,"done! Takes %u seconds\n",start);
00617     //end Testin msSleep
00618 #endif
00619 
00620 
00621 //      CAMsg::printMsg(LOG_ENCRYPTED,"Test: Anon proxy started!\n");
00622 //      CAMsg::printMsg(LOG_ENCRYPTED,"Test2: Anon proxy started!\n");
00623 //      CAMsg::printMsg(LOG_ENCRYPTED,"Test3: Anon proxy started!\n");
00624 
00625     CAMsg::printMsg(LOG_INFO,"Anon proxy started!\n");
00626 
00627 #ifdef ENABLE_GPERFTOOLS_CPU_PROFILER
00628     ProfilerStart("gperf.cpuprofiler.data");
00629 #endif
00630 
00631 #ifndef _WIN32
00632   #ifdef _DEBUG
00633       signal(SIGPIPE,signal_broken_pipe);
00634   #else
00635       signal(SIGPIPE,SIG_IGN);
00636   #endif
00637   #ifndef ONLY_LOCAL_PROXY
00638     struct sigaction newAction;
00639     memset(&newAction,0,sizeof(newAction));
00640     newAction.sa_handler=signal_hup;
00641     newAction.sa_flags=0;
00642     sigaction(SIGHUP,&newAction,NULL);
00643   #endif
00644 #endif
00645     signal(SIGINT,signal_interrupt);
00646     signal(SIGTERM,signal_term);
00647 #if !defined (_DEBUG) && !defined(NO_SIGSEV_CATCH)
00648     signal(SIGSEGV,signal_segv);
00649 #endif
00650     //Try to write pidfile....
00651     UINT8 strPidFile[512];
00652     if(CALibProxytest::getOptions()->getPidFile(strPidFile,512)==E_SUCCESS)
00653       {
00654         #ifndef _WIN32
00655           int old_uid=geteuid(); //old uid... stored if we have to switch to root
00656         #endif
00657         pid_t pid=getpid();
00658         UINT8 thePid[10];
00659         sprintf((char*)thePid,"%i",pid);
00660         int len=strlen((char*)thePid);
00661         int hFile=open((char*)strPidFile,O_TRUNC|O_CREAT|O_WRONLY,S_IREAD|S_IWRITE);
00662 #ifndef _WIN32
00663         if(hFile==-1&&seteuid(0)!=-1) //probably we do not have enough rights (because we have already switch to an other uid --> try to go back temporaly..
00664           {
00665             hFile=open((char*)strPidFile,O_TRUNC|O_CREAT|O_WRONLY,S_IREAD|S_IWRITE);
00666           }
00667 #endif
00668         if(hFile==-1||len!=write(hFile,thePid,len))
00669           {
00670             #ifndef _WIN32
00671                     seteuid(old_uid);
00672             #endif
00673             CAMsg::printMsg(LOG_CRIT,"Could not write pidfile - exiting!\n");
00674             exit(EXIT_FAILURE);
00675           }
00676         close(hFile);
00677 #ifndef _WIN32
00678         seteuid(old_uid);
00679 #endif
00680       }
00681 
00682 //    CARoundTripTime* pRTT=NULL;
00683     if(CALibProxytest::getOptions()->isLocalProxy())
00684       {
00685         #ifndef NEW_MIX_TYPE
00686           CALocalProxy* pProxy=new CALocalProxy();
00687           CAMsg::printMsg(LOG_INFO,"Starting LocalProxy...\n");
00688           if(pProxy->start()!=E_SUCCESS)
00689             CAMsg::printMsg(LOG_CRIT,"Error during MIX-Startup!\n");
00690           delete pProxy;
00691           pProxy = NULL;
00692         #else
00693           CAMsg::printMsg(LOG_CRIT,"Compiled without LocalProxy support!\n");
00694           exit(EXIT_FAILURE);
00695         #endif
00696       }
00697     else
00698       {
00699         //pRTT=new CARoundTripTime();
00700         //CAMsg::printMsg(LOG_INFO,"Starting RoundTripTime...\n");
00701         //if(pRTT->start()!=E_SUCCESS)
00702         //  {
00703         //    CAMsg::printMsg(LOG_CRIT,"RoundTripTime Startup FAILED - Exiting!\n");
00704         //    goto EXIT;
00705         //  }
00706         //else
00707 #ifndef ONLY_LOCAL_PROXY
00708       SINT32 s32MaxSockets=CASocket::getMaxOpenSockets();
00709       CAMsg::printMsg(LOG_INFO,"Max Number of sockets we can open: %i\n",s32MaxSockets);
00710       
00711 #ifdef SERVER_MONITORING
00712       CAStatusManager::init();
00713 #endif
00714       
00715       if(s32MaxSockets>100&&s32MaxSockets<10000)
00716         {
00717         CASocket::setMaxNormalSockets(s32MaxSockets-10);
00718         }
00719         MONITORING_FIRE_SYS_EVENT(ev_sys_start);
00720         if(CALibProxytest::getOptions()->isFirstMix())
00721         {
00722           CAMsg::printMsg(LOG_INFO,"I am the First MIX...\n");
00723           #if !defined(NEW_MIX_TYPE)
00724             pMix=new CAFirstMixA();
00725           #else
00726             pMix=new CAFirstMixB();
00727           #endif
00728           MONITORING_FIRE_NET_EVENT(ev_net_firstMixInited);
00729         }
00730         else if(CALibProxytest::getOptions()->isMiddleMix())
00731         {
00732           CAMsg::printMsg(LOG_INFO,"I am a Middle MIX...\n");
00733           pMix=new CAMiddleMix();
00734           MONITORING_FIRE_NET_EVENT(ev_net_middleMixInited);
00735         }
00736         else
00737         {
00738           CAMsg::printMsg(LOG_INFO,"I am the Last MIX...\n");
00739           #if !defined(NEW_MIX_TYPE)
00740             pMix=new CALastMixA();
00741           #else
00742             pMix=new CALastMixB();
00743           #endif
00744           MONITORING_FIRE_NET_EVENT(ev_net_lastMixInited);
00745         }
00746 #else
00747         CAMsg::printMsg(LOG_ERR,"this Mix is compiled to work only as local proxy!\n");
00748         exit(EXIT_FAILURE);
00749 #endif
00750       }
00751 #ifndef ONLY_LOCAL_PROXY
00752 #ifndef DYNAMIC_MIX
00753     CAMsg::printMsg(LOG_INFO,"Starting MIX...\n");
00754     if(pMix->start()!=E_SUCCESS)
00755     {
00756       CAMsg::printMsg(LOG_CRIT,"Error during MIX-Startup!\n");
00757       exit(EXIT_FAILURE);
00758     }
00759 #else
00760     /* LERNGRUPPE */
00761 while(true)
00762 {
00763   CAMsg::printMsg(LOG_INFO,"Starting MIX...\n");
00764   if(pMix->start()!=E_SUCCESS)
00765   {
00767     CAMsg::printMsg(LOG_CRIT,"Error during MIX-Startup!\n");
00768     exit(EXIT_FAILURE);
00769   }
00770 
00771   /* If we got here, the mix should already be reconfigured, so we only need a new instance */
00772   delete pMix;
00773   pMix = NULL;
00774 
00775   if(CALibProxytest::getOptions()->isFirstMix())
00776   {
00777     CAMsg::printMsg(LOG_INFO,"I am now the First MIX..\n");
00778 #if !defined(NEW_MIX_TYPE)
00779             pMix=new CAFirstMixA();
00780 #else
00781             pMix=new CAFirstMixB();
00782 #endif
00783   }
00784   else if(CALibProxytest::getOptions()->isMiddleMix())
00785   {
00786     CAMsg::printMsg(LOG_INFO,"I am now a Middle MIX..\n");
00787     pMix=new CAMiddleMix();
00788   }
00789   else
00790   {
00791     /* Reconfiguration of a last mix?! Not really...*/
00792     CAMsg::printMsg( LOG_ERR, "Tried to reconfigure a former first/middle-Mix to a LastMix -> impossible!\n");
00793     exit(EXIT_FAILURE);
00794   }
00795 }
00796 #endif //DYNAMIC_MIX
00797 #endif //ONLY_LOCAL_PROXY
00798 EXIT:
00799     cleanup();
00800 #if defined(HAVE_CRTDBG)
00801     _CrtMemCheckpoint( &s2 );
00802     if ( _CrtMemDifference( &s3, &s1, &s2 ) )
00803       _CrtMemDumpStatistics( &s3 );
00804 #endif
00805 #ifdef CWDEBUG
00806     Debug(list_allocations_on(libcw_do));
00807 #endif
00808     return 0;
00809   }