Mixe for Privacy and Anonymity in the Internet
Functions | Variables
proxytest.cpp File Reference
#include "StdAfx.h"
#include "CACmdLnOptions.hpp"
#include "CAMsg.hpp"
#include "CALocalProxy.hpp"
#include "CAQueue.hpp"
#include "CAThreadList.hpp"
#include "CAStatusManager.hpp"
#include "CALibProxytest.hpp"
#include "xml/DOM_Output.hpp"
#include "CAMix.hpp"
#include "TypeA/CAFirstMixA.hpp"
#include "TypeA/CALastMixA.hpp"
#include "CAMiddleMix.hpp"
#include "CALogPacketStats.hpp"
#include "CATLSClientSocket.hpp"
Include dependency graph for proxytest.cpp:

Go to the source code of this file.

Functions

void removePidFile ()
 Removes the stored PID (file)
void init ()
 do necessary initialisations of libraries etc.
void cleanup ()
 do necessary cleanups of libraries etc.
void my_terminate (void)
 Remark: terminate() might be already defined by the c lib -- do not use this name...
void signal_segv (int)
void signal_term (int)
void signal_interrupt (int)
void signal_hup (int)
void checkSizesOfBaseTypes ()
 Check what the sizes of base types are as expected -- if not kill the programm.
int main (int argc, const char *argv[])

Variables

CAMixpMix = NULL
bool bTriedTermination = false

Function Documentation

Check what the sizes of base types are as expected -- if not kill the programm.

Definition at line 215 of file proxytest.cpp.

References CAMsg::printMsg().

Referenced by main().

  {
    #pragma warning( push )
    #pragma warning( disable : 4127 ) //Disable: Bedingter Ausdruck ist konstant
    if(sizeof(SINT8)!=1)
      {
        CAMsg::printMsg(LOG_CRIT,"sizeof(SINT8) != 1 --> maybe a compiler (optimization) problem!\n");
        exit(-1);
      }
    if(sizeof(UINT8)!=1)
      {
        CAMsg::printMsg(LOG_CRIT,"sizeof(UINT8) != 1 --> maybe a compiler (optimization) problem!\n");
        exit(-1);
      }
    if(sizeof(SINT16)!=2)
      {
        CAMsg::printMsg(LOG_CRIT,"sizeof(SINT16) != 2 --> maybe a compiler (optimization) problem!\n");
        exit(-1);
      }
    if(sizeof(UINT16)!=2)
      {
        CAMsg::printMsg(LOG_CRIT,"sizeof(UINT16) != 2 --> maybe a compiler (optimization) problem!\n");
        exit(-1);
      }
    if(sizeof(SINT32)!=4)
      {
        CAMsg::printMsg(LOG_CRIT,"sizeof(SINT32) != 4 --> maybe a compiler (optimization) problem!\n");
        exit(-1);
      }
    if(sizeof(UINT32)!=4)
      {
        CAMsg::printMsg(LOG_CRIT,"sizeof(UINT32) != 4 --> maybe a compiler (optimization) problem!\n");
        exit(-1);
      }
    #ifdef HAVE_NATIVE_UINT64
      if(sizeof(UINT64)!=8)
        {
          CAMsg::printMsg(LOG_CRIT,"sizeof(UINT64) != 8 --> maybe a compiler (optimization) problem!\n");
          exit(-1);
        }
    #endif
    #pragma warning( pop )
  }

Here is the call graph for this function:

void cleanup ( )

do necessary cleanups of libraries etc.

Definition at line 117 of file proxytest.cpp.

References CALibProxytest::cleanup(), pMix, CAMsg::printMsg(), and removePidFile().

Referenced by CAAccountingInstance::__newSettlementTransaction(), CAFirstMix::clean(), main(), and my_terminate().

  {
#ifdef ENABLE_GPERFTOOLS_CPU_PROFILER
    ProfilerFlush();
    ProfilerStop();
#endif
//    delete pRTT;
#ifndef ONLY_LOCAL_PROXY
    if(pMix!=NULL)
      delete pMix;
    pMix=NULL;
#endif
    CAMsg::printMsg(LOG_CRIT,"Terminating Programm!\n");
    removePidFile();
    CALibProxytest::cleanup();
  }

Here is the call graph for this function:

void init ( )

do necessary initialisations of libraries etc.

Definition at line 111 of file proxytest.cpp.

References CALibProxytest::init().

Referenced by CACmdLnOptions::initLogging(), and main().

Here is the call graph for this function:

int main ( int  argc,
const char *  argv[] 
)

Definition at line 435 of file proxytest.cpp.

References t_MixPacket::channel, checkSizesOfBaseTypes(), CAMsg::cleanup(), cleanup(), t_MixPacketPayload::data, t_MixPacket::data, E_SUCCESS, ev_net_firstMixInited, ev_net_lastMixInited, ev_net_middleMixInited, ev_sys_start, t_MixPacket::flags, CASocket::getMaxOpenSockets(), CALibProxytest::getOptions(), CAMsg::init(), init(), t_MixPacketPayload::len, len, CAReplayDatabase::measurePerformance(), MIXPACKET_SIZE, MONITORING_FIRE_NET_EVENT, MONITORING_FIRE_SYS_EVENT, msSleep(), t_MixPacket::payload, pMix, CAMsg::printMsg(), CASocket::setMaxNormalSockets(), signal_hup(), signal_interrupt(), signal_segv(), signal_term(), CALocalProxy::start(), CAMix::start(), CAQueue::test(), and t_MixPacketPayload::type.

  {
#ifndef ONLY_LOCAL_PROXY
    pMix=NULL;
#endif
    UINT32 lLogOpts = 0;
    SINT32 maxFiles,ret;
#if defined(HAVE_CRTDBG)
//      _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
//      _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
//      _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
//      _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
//      _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
//      _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );

    UINT32 tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
    tmpDbgFlag |= _CRTDBG_ALLOC_MEM_DF;
    tmpDbgFlag |=_CRTDBG_LEAK_CHECK_DF;
    _CrtSetDbgFlag(tmpDbgFlag);
    _CrtMemState s1, s2, s3;
    _CrtMemCheckpoint( &s1 );
#endif
//Switch on debug infos
#ifdef CWDEBUG
    Debug(libcw_do.on());
    Debug(dc::malloc.on());
#endif
    init();
      //some test....
    //UINT8 buff1[500];
    //readPasswd(buff1,500);
    //printf("%s\n",buff1);
    //printf("Len: %i\n",strlen((char*)buff1));

    /*UINT32 size=0;
    UINT8* fg=readFile((UINT8*)"test.xml",&size);
    XERCES_CPP_NAMESPACE::DOMDocument* doc=parseDOMDocument(fg,size);
    delete[] fg;
    doc->release();
    cleanup();
    exit(0);
    */

    checkSizesOfBaseTypes();
#ifndef NEW_MIX_TYPE
    if(MIXPACKET_SIZE!=sizeof(MIXPACKET))
      {
        CAMsg::printMsg(LOG_CRIT,"MIXPACKET_SIZE [%u] != sizeof(MUXPACKET) [%u] --> maybe a compiler (optimization) problem!\n",MIXPACKET_SIZE,sizeof(MIXPACKET));
        CAMsg::printMsg(LOG_CRIT,"Offsets:\n");
        MIXPACKET oPacket;
        UINT8 *p=(UINT8 *)&oPacket;
        UINT32 soffsets[7]={0,4,6,6,6,8,9};
        UINT32 hoffsets[7];
        CAMsg::printMsg(LOG_CRIT,".channel %u (should be 0)\n",hoffsets[0]=(UINT8*)&(oPacket.channel)-p);
        CAMsg::printMsg(LOG_CRIT,".flags: %u (should be 4)\n",hoffsets[1]=(UINT8*)&oPacket.flags-p);
        CAMsg::printMsg(LOG_CRIT,".data: %u (should be 6)\n",hoffsets[2]=(UINT8*)&oPacket.data-p);
        CAMsg::printMsg(LOG_CRIT,".payload: %u (should be 6)\n",hoffsets[3]=(UINT8*)&oPacket.payload-p);
        CAMsg::printMsg(LOG_CRIT,".payload.len: %u (should be 6)\n",hoffsets[4]=(UINT8*)&oPacket.payload.len-p);
        CAMsg::printMsg(LOG_CRIT,".payload.type: %u (should be 8)\n",hoffsets[5]=(UINT8*)&oPacket.payload.type-p);
        CAMsg::printMsg(LOG_CRIT,".payload.data: %u (should be 9)\n",hoffsets[6]=(UINT8*)&oPacket.payload.data-p);
        for(int i=0;i<7;i++)
         if(soffsets[i]!=hoffsets[i])
          exit(EXIT_FAILURE);
        CAMsg::printMsg(LOG_CRIT,"Hm, The Offsets seams to be ok - so we try to continue - hope that works...\n");
      }
#endif
#ifdef LOG_CRIME
//      testTre();
#endif

#ifdef REPLAY_DATABASE_PERFORMANCE_TEST
    CAReplayDatabase::measurePerformance((UINT8*)"dbperformace.log",1,10000001,500000,10,100000);
    exit(0);
#endif


#ifdef DATA_RETENTION_LOG
    if(sizeof(t_dataretentionLogEntry)!=18)
    {
        CAMsg::printMsg(LOG_CRIT,"sizeof(tDataRetentionLogEntry) [%u] != 18 --> maybe a compiler (optimization) problem!\n",sizeof(t_dataretentionLogEntry));
        exit(EXIT_FAILURE);
    }
#endif
//    CADataRetentionLogFile::doCheckAndPerformanceTest();
//    getch();
//    exit(0);
#ifdef _DEBUG
      UINT32 start;
#endif
  /*  CATLSClientSocket ssl;
    CASocketAddrINet addr;
    addr.setAddr((const UINT8*)"127.0.0.1",(UINT16)3456);
    UINT32 len1;
    UINT8* pt=readFile((UINT8*)"/Users/sk13/Documents/projects/jap/testkey.der",&len1);
    CACertificate* pCer=CACertificate::decode(pt,len1,CERT_DER);
    ssl.setServerCertificate(pCer);
    printf("try connect\n");
    ssl.connect(addr,1,0);
    ssl.receiveFully(pt,3);

    exit(0);
*/
//#ifdef INTEL_IPP_CRYPTO
//    CAASymCipher::testSpeed();
//    getch();
//    exit(0);
//#endif

    if(CALibProxytest::getOptions()->parse(argc,argv) != E_SUCCESS)
    {
      CAMsg::printMsg(LOG_CRIT,"An error occurred before we could finish parsing the configuration file. Exiting...\n");
      exit(EXIT_FAILURE);
    }
    if(!( CALibProxytest::getOptions()->isFirstMix()||
          CALibProxytest::getOptions()->isMiddleMix()||
          CALibProxytest::getOptions()->isLastMix()||
          CALibProxytest::getOptions()->isLocalProxy()))
      {
        CAMsg::printMsg(LOG_CRIT,"You must specify which kind of Mix you want to run!\n");
        CAMsg::printMsg(LOG_CRIT,"Use -j or -c\n");
        CAMsg::printMsg(LOG_CRIT,"Or try --help for more options.\n");
        CAMsg::printMsg(LOG_CRIT,"Exiting...\n");
        exit(EXIT_FAILURE);
      }

    UINT8 buff[255];

/*#ifdef LOG_CRIME
    initHttpVerbLengths();
#endif
*/


#ifndef _WIN32
    if(CALibProxytest::getOptions()->getDaemon()) 
      {
        CAMsg::printMsg(LOG_DEBUG,"Starting mix process as daemon...\n");
        CAMsg::cleanup();
        CAMsg::init();
        pid_t pid;
        pid=fork();
        if(pid!=0)
          {
            CAMsg::printMsg(LOG_INFO,"Exiting parent shell process...\n");
            exit(EXIT_SUCCESS);
          }
        setsid();
        #ifndef DO_TRACE
          chdir("/");
          umask(0);
        #endif
       // Close out the standard file descriptors
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
      }
#endif


    if (CALibProxytest::getOptions()->initLogging() != E_SUCCESS)
    {
        exit(EXIT_FAILURE);
    }
    


#if defined (_DEBUG) &&!defined(ONLY_LOCAL_PROXY)
    //    CADatabase::test();
    if(CAQueue::test()!=E_SUCCESS)
      CAMsg::printMsg(LOG_CRIT,"CAQueue::test() NOT passed! Exiting\n");
    else
      CAMsg::printMsg(LOG_DEBUG,"CAQueue::test() passed!\n");

    //CALastMixChannelList::test();
    //exit(0);
    //Testing msSleep
    CAMsg::printMsg(LOG_DEBUG,"Should sleep now for aprox 2 seconds....\n");
    start=time(NULL);
    for(SINT32 i=0;i<10;i++)
      msSleep(200);
    start=time(NULL)-start;
    CAMsg::printMsg(LOG_DEBUG,"done! Takes %u seconds\n",start);
    //end Testin msSleep
#endif


//      CAMsg::printMsg(LOG_ENCRYPTED,"Test: Anon proxy started!\n");
//      CAMsg::printMsg(LOG_ENCRYPTED,"Test2: Anon proxy started!\n");
//      CAMsg::printMsg(LOG_ENCRYPTED,"Test3: Anon proxy started!\n");

    CAMsg::printMsg(LOG_INFO,"Anon proxy started!\n");

#ifdef ENABLE_GPERFTOOLS_CPU_PROFILER
    ProfilerStart("gperf.cpuprofiler.data");
#endif

#ifndef _WIN32
  #ifdef _DEBUG
      signal(SIGPIPE,signal_broken_pipe);
  #else
      signal(SIGPIPE,SIG_IGN);
  #endif
  #ifndef ONLY_LOCAL_PROXY
    struct sigaction newAction;
    memset(&newAction,0,sizeof(newAction));
    newAction.sa_handler=signal_hup;
    newAction.sa_flags=0;
    sigaction(SIGHUP,&newAction,NULL);
  #endif
#endif
    signal(SIGINT,signal_interrupt);
    signal(SIGTERM,signal_term);
#if !defined (_DEBUG) && !defined(NO_SIGSEV_CATCH)
    signal(SIGSEGV,signal_segv);
#endif
    //Try to write pidfile....
    UINT8 strPidFile[512];
    if(CALibProxytest::getOptions()->getPidFile(strPidFile,512)==E_SUCCESS)
      {
        #ifndef _WIN32
          int old_uid=geteuid(); //old uid... stored if we have to switch to root
        #endif
        pid_t pid=getpid();
        UINT8 thePid[10];
        sprintf((char*)thePid,"%i",pid);
        int len=strlen((char*)thePid);
        int hFile=open((char*)strPidFile,O_TRUNC|O_CREAT|O_WRONLY,S_IREAD|S_IWRITE);
#ifndef _WIN32
        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..
          {
            hFile=open((char*)strPidFile,O_TRUNC|O_CREAT|O_WRONLY,S_IREAD|S_IWRITE);
          }
#endif
        if(hFile==-1||len!=write(hFile,thePid,len))
          {
            #ifndef _WIN32
                    seteuid(old_uid);
            #endif
            CAMsg::printMsg(LOG_CRIT,"Could not write pidfile - exiting!\n");
            exit(EXIT_FAILURE);
          }
        close(hFile);
#ifndef _WIN32
        seteuid(old_uid);
#endif
      }

//    CARoundTripTime* pRTT=NULL;
    if(CALibProxytest::getOptions()->isLocalProxy())
      {
        #ifndef NEW_MIX_TYPE
          CALocalProxy* pProxy=new CALocalProxy();
          CAMsg::printMsg(LOG_INFO,"Starting LocalProxy...\n");
          if(pProxy->start()!=E_SUCCESS)
            CAMsg::printMsg(LOG_CRIT,"Error during MIX-Startup!\n");
          delete pProxy;
          pProxy = NULL;
        #else
          CAMsg::printMsg(LOG_CRIT,"Compiled without LocalProxy support!\n");
          exit(EXIT_FAILURE);
        #endif
      }
    else
      {
        //pRTT=new CARoundTripTime();
        //CAMsg::printMsg(LOG_INFO,"Starting RoundTripTime...\n");
        //if(pRTT->start()!=E_SUCCESS)
        //  {
        //    CAMsg::printMsg(LOG_CRIT,"RoundTripTime Startup FAILED - Exiting!\n");
        //    goto EXIT;
        //  }
        //else
#ifndef ONLY_LOCAL_PROXY
      SINT32 s32MaxSockets=CASocket::getMaxOpenSockets();
      CAMsg::printMsg(LOG_INFO,"Max Number of sockets we can open: %i\n",s32MaxSockets);
      
#ifdef SERVER_MONITORING
      CAStatusManager::init();
#endif
      
      if(s32MaxSockets>100&&s32MaxSockets<10000)
        {
        CASocket::setMaxNormalSockets(s32MaxSockets-10);
        }
        MONITORING_FIRE_SYS_EVENT(ev_sys_start);
        if(CALibProxytest::getOptions()->isFirstMix())
        {
          CAMsg::printMsg(LOG_INFO,"I am the First MIX...\n");
          #if !defined(NEW_MIX_TYPE)
            pMix=new CAFirstMixA();
          #else
            pMix=new CAFirstMixB();
          #endif
          MONITORING_FIRE_NET_EVENT(ev_net_firstMixInited);
        }
        else if(CALibProxytest::getOptions()->isMiddleMix())
        {
          CAMsg::printMsg(LOG_INFO,"I am a Middle MIX...\n");
          pMix=new CAMiddleMix();
          MONITORING_FIRE_NET_EVENT(ev_net_middleMixInited);
        }
        else
        {
          CAMsg::printMsg(LOG_INFO,"I am the Last MIX...\n");
          #if !defined(NEW_MIX_TYPE)
            pMix=new CALastMixA();
          #else
            pMix=new CALastMixB();
          #endif
          MONITORING_FIRE_NET_EVENT(ev_net_lastMixInited);
        }
#else
        CAMsg::printMsg(LOG_ERR,"this Mix is compiled to work only as local proxy!\n");
        exit(EXIT_FAILURE);
#endif
      }
#ifndef ONLY_LOCAL_PROXY
#ifndef DYNAMIC_MIX
    CAMsg::printMsg(LOG_INFO,"Starting MIX...\n");
    if(pMix->start()!=E_SUCCESS)
    {
      CAMsg::printMsg(LOG_CRIT,"Error during MIX-Startup!\n");
      exit(EXIT_FAILURE);
    }
#else
    /* LERNGRUPPE */
while(true)
{
  CAMsg::printMsg(LOG_INFO,"Starting MIX...\n");
  if(pMix->start()!=E_SUCCESS)
  {
    CAMsg::printMsg(LOG_CRIT,"Error during MIX-Startup!\n");
    exit(EXIT_FAILURE);
  }

  /* If we got here, the mix should already be reconfigured, so we only need a new instance */
  delete pMix;
  pMix = NULL;

  if(CALibProxytest::getOptions()->isFirstMix())
  {
    CAMsg::printMsg(LOG_INFO,"I am now the First MIX..\n");
#if !defined(NEW_MIX_TYPE)
            pMix=new CAFirstMixA();
#else
            pMix=new CAFirstMixB();
#endif
  }
  else if(CALibProxytest::getOptions()->isMiddleMix())
  {
    CAMsg::printMsg(LOG_INFO,"I am now a Middle MIX..\n");
    pMix=new CAMiddleMix();
  }
  else
  {
    /* Reconfiguration of a last mix?! Not really...*/
    CAMsg::printMsg( LOG_ERR, "Tried to reconfigure a former first/middle-Mix to a LastMix -> impossible!\n");
    exit(EXIT_FAILURE);
  }
}
#endif //DYNAMIC_MIX
#endif //ONLY_LOCAL_PROXY
EXIT:
    cleanup();
#if defined(HAVE_CRTDBG)
    _CrtMemCheckpoint( &s2 );
    if ( _CrtMemDifference( &s3, &s1, &s2 ) )
      _CrtMemDumpStatistics( &s3 );
#endif
#ifdef CWDEBUG
    Debug(list_allocations_on(libcw_do));
#endif
    return 0;
  }

Here is the call graph for this function:

void my_terminate ( void  )

Remark: terminate() might be already defined by the c lib -- do not use this name...

Definition at line 135 of file proxytest.cpp.

References bTriedTermination, cleanup(), CAMix::isShutDown(), msSleep(), pMix, and CAMix::shutDown().

Referenced by signal_interrupt(), and signal_term().

{
  if(!bTriedTermination)
  {
    bTriedTermination = true;
#ifndef ONLY_LOCAL_PROXY
    if(pMix!=NULL)
    {
      pMix->shutDown();
      for (UINT32 i = 0; i < 20 && !(pMix->isShutDown()); i++)
      {
        msSleep(100);
      }
      delete pMix;
      pMix=NULL;
    }
#endif
    cleanup();
  }
}

Here is the call graph for this function:

void removePidFile ( )

Removes the stored PID (file)

Definition at line 88 of file proxytest.cpp.

References E_SUCCESS, and CALibProxytest::getOptions().

Referenced by cleanup().

  {
    if(CALibProxytest::getOptions()==NULL)
      {
        return;
      }
    UINT8 strPidFile[512];
    if(CALibProxytest::getOptions()->getPidFile(strPidFile,512)==E_SUCCESS)
      {
        if(::remove((char*)strPidFile)!=0)
          {
#ifndef _WIN32
            int old_uid=geteuid(); //old uid... stored if we have to switch to root
            seteuid(0);
            ::remove((char*)strPidFile);
            seteuid(old_uid);
#endif
          }
      }
  }

Here is the call graph for this function:

void signal_hup ( int  )

Definition at line 207 of file proxytest.cpp.

References CALibProxytest::getOptions(), and CACmdLnOptions::reread().

Referenced by main().

Here is the call graph for this function:

void signal_interrupt ( int  )

Definition at line 194 of file proxytest.cpp.

References ev_sys_sigInt, MONITORING_FIRE_SYS_EVENT, my_terminate(), and CAMsg::printMsg().

Referenced by main().

  {
    MONITORING_FIRE_SYS_EVENT(ev_sys_sigInt);
    CAMsg::printMsg(LOG_INFO,"Hm.. Strg+C pressed... exiting!\n");
#if defined _DEBUG && ! defined (ONLY_LOCAL_PROXY)
    CAMsg::printMsg(LOG_INFO,"%d threads listed.\n",CALibProxytest::getThreadList()->getSize());
    CALibProxytest::getThreadList()->showAll();
#endif
    my_terminate();
    exit(0);
  }

Here is the call graph for this function:

void signal_segv ( int  )

Definition at line 157 of file proxytest.cpp.

References ev_sys_sigSegV, MONITORING_FIRE_SYS_EVENT, CAMsg::printMsg(), and sSleep().

Referenced by main().

{
  signal(SIGSEGV,SIG_DFL); //otherwise we might end up in endless loops...

  MONITORING_FIRE_SYS_EVENT(ev_sys_sigSegV);
  CAMsg::printMsg(LOG_CRIT,"Oops ... caught SIG_SEGV! Exiting...\n");

  // wait 1 second so that log files may still be written
  sSleep(1);

#ifdef PRINT_THREAD_STACK_TRACE
  CAThread::METHOD_STACK* stack = CAThread::getCurrentStack();
  if (stack != NULL)
  {
    CAMsg::printMsg( LOG_CRIT, "Stack trace: %s, \"%s\"\n", stack->strMethodName, stack->strPosition);

  }
  else
  {
    CAMsg::printMsg( LOG_CRIT, "Stack trace: none available\n");
  }
#endif
  // my_terminate();  temporarily disabled
  exit(1);
}

Here is the call graph for this function:

void signal_term ( int  )

Definition at line 186 of file proxytest.cpp.

References ev_sys_sigTerm, MONITORING_FIRE_SYS_EVENT, my_terminate(), and CAMsg::printMsg().

Referenced by main().

  {
    MONITORING_FIRE_SYS_EVENT(ev_sys_sigTerm);
    CAMsg::printMsg(LOG_INFO,"Hm.. Signal SIG_TERM received... exiting!\n");
    my_terminate();
    exit(0);
  }

Here is the call graph for this function:


Variable Documentation

bool bTriedTermination = false

Definition at line 74 of file proxytest.cpp.

Referenced by my_terminate().

CAMix* pMix = NULL