Mixe for Privacy and Anonymity in the Internet
Public Member Functions | Protected Member Functions | Protected Attributes | Friends
CALastMix Class Reference

#include <CALastMix.hpp>

Inheritance diagram for CALastMix:
[legend]
Collaboration diagram for CALastMix:
[legend]

List of all members.

Public Member Functions

 CALastMix ()
virtual ~CALastMix ()
SINT32 reconfigure ()
tMixType getType () const

Protected Member Functions

virtual SINT32 loop ()=0
SINT32 init ()
virtual SINT32 initOnce ()
SINT32 clean ()
SINT32 initMixCascadeInfo (DOMElement *)
 This will initialize the XML Cascade Info struct XMLFirstMixToInfoService that is sent to the InfoService in CAInfoService::sendCascadeHelo()
virtual SINT32 processKeyExchange ()
 Processes the startup communication with the preceeding mix.
SINT32 setTargets ()
 Reads the configured proxies from options.

Protected Attributes

volatile bool m_bRestart
CAMuxSocketm_pMuxIn
CAQueuem_pQueueSendToMix
CAQueuem_pQueueReadFromMix
CACacheLoadBalancingm_pCacheLB
CACacheLoadBalancingm_pSocksLB
CAASymCipherm_pRSA
CAThreadm_pthreadSendToMix
CAThreadm_pthreadReadFromMix
CALastMixChannelListm_pChannelList
volatile bool m_bRunLog
volatile UINT32 m_logUploadedPackets
volatile UINT64 m_logUploadedBytes
volatile UINT32 m_logDownloadedPackets
volatile UINT64 m_logDownloadedBytes

Friends

THREAD_RETURN lm_loopSendToMix (void *param)
 How to end this thread: 0.
THREAD_RETURN lm_loopReadFromMix (void *pParam)
THREAD_RETURN lm_loopLog (void *)

Detailed Description

Definition at line 57 of file CALastMix.hpp.


Constructor & Destructor Documentation

CALastMix::CALastMix ( ) [inline]

Definition at line 65 of file CALastMix.hpp.

References m_pCacheLB, m_pChannelList, CAMix::m_pInfoService, CAMix::m_pMultiSignature, m_pMuxIn, m_pQueueReadFromMix, m_pQueueSendToMix, m_pRSA, m_pSocksLB, m_pthreadReadFromMix, and m_pthreadSendToMix.

        {
          m_pMuxIn=NULL;
          //m_pSignature=NULL;
          m_pMultiSignature=NULL;
          m_pRSA=NULL;
          m_pInfoService=NULL;
          #ifndef NEW_MIX_TYPE // not TypeB mixes
            /* TypeB mixes are using an own implementation */
          m_pChannelList=NULL;
          #endif
          m_pthreadSendToMix=m_pthreadReadFromMix=NULL;
          m_pQueueSendToMix=m_pQueueReadFromMix=NULL;
          m_pCacheLB=new CACacheLoadBalancing();
          m_pSocksLB=new CACacheLoadBalancing();

          #ifdef LOG_PACKET_STATS
            m_pLogPacketStats=NULL;
          #endif
          #ifdef LOG_CRIME
          //OK lets try to use a regular expression for the task instead of a hand crafted parser...
            const char* request_line_regexp="[\n\r]*([^ ]+)[ ]+([^ ]+)"; //
            m_pregexpRequestLine=new regex_t;
            regcomp(m_pregexpRequestLine,request_line_regexp,REG_EXTENDED );  
            // Regexp for Domain of URI
            const char* uri_regexp="[^:]+[:][/][/]([^:/]+)"; //
            m_pregexpDomainOfURI=new regex_t;
            regcomp(m_pregexpDomainOfURI,uri_regexp,REG_EXTENDED );
          #endif
        }
virtual CALastMix::~CALastMix ( ) [inline, virtual]

Definition at line 96 of file CALastMix.hpp.

References clean(), m_pCacheLB, and m_pSocksLB.

        {
          clean();
          delete m_pCacheLB;
          m_pCacheLB = NULL;
          delete m_pSocksLB;
          m_pSocksLB = NULL;
#ifdef LOG_CRIME
          regfree(m_pregexpRequestLine);
          delete m_pregexpRequestLine;
          regfree(m_pregexpDomainOfURI);
          delete m_pregexpDomainOfURI;
#endif
        }

Here is the call graph for this function:


Member Function Documentation

SINT32 CALastMix::clean ( ) [protected, virtual]

Implements CAMix.

Definition at line 980 of file CALastMix.cpp.

References CAQueue::add(), CASocket::close(), CAMuxSocket::close(), E_SUCCESS, ev_net_prevConnectionClosed, CALastMixChannelList::getFirstSocket(), CALastMixChannelList::getNextSocket(), CAThread::join(), m_bRestart, m_bRunLog, m_pChannelList, m_pMuxIn, CAMix::m_pMuxInControlChannelDispatcher, m_pQueueReadFromMix, m_pQueueSendToMix, CAMixWithReplayDB::m_pReplayMsgProc, m_pRSA, m_pthreadReadFromMix, m_pthreadSendToMix, MONITORING_FIRE_NET_EVENT, t_lastmixchannellist::pCipher, t_lastmixchannellist::pQueueSend, CAMsg::printMsg(), and t_lastmixchannellist::pSocket.

Referenced by ~CALastMix().

{
    m_bRestart=true;
    MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed);
    m_bRunLog=false;
#ifdef REPLAY_DETECTION
    if(m_pReplayMsgProc!=NULL)
      {
        delete m_pReplayMsgProc;
        m_pReplayMsgProc = NULL;
      }
    m_pReplayMsgProc=NULL;
#endif

    if(m_pMuxInControlChannelDispatcher!=NULL)
      {
        delete m_pMuxInControlChannelDispatcher;
        m_pMuxInControlChannelDispatcher = NULL;
      }
    m_pMuxInControlChannelDispatcher=NULL;

    if(m_pMuxIn!=NULL)
      {
        m_pMuxIn->close();
      }
    //writng some bytes to the queue...
    if(m_pQueueSendToMix!=NULL)
      {
        UINT8 b[sizeof(tQueueEntry)+1];
        m_pQueueSendToMix->add(b,sizeof(tQueueEntry)+1);
      }

    if(m_pthreadSendToMix!=NULL)
      {
        CAMsg::printMsg(LOG_CRIT,"Wait for LoopSendToMix!\n");
        m_pthreadSendToMix->join();
        delete m_pthreadSendToMix;
        m_pthreadSendToMix = NULL;
      }
    m_pthreadSendToMix=NULL;
    if(m_pthreadReadFromMix!=NULL)
      {
        CAMsg::printMsg(LOG_CRIT,"Wait for LoopReadFromMix!\n");
        m_pthreadReadFromMix->join();
        delete m_pthreadReadFromMix;
        m_pthreadReadFromMix = NULL;
      }
    m_pthreadReadFromMix=NULL;

#ifdef LOG_PACKET_TIMES
      CAMsg::printMsg(LOG_CRIT,"Wait for LoopLogPacketStats to terminate!\n");
      if(m_pLogPacketStats!=NULL)
        {
          m_pLogPacketStats->stop();
          delete m_pLogPacketStats;
          m_pLogPacketStats = NULL;
        }
      m_pLogPacketStats=NULL;
#endif
    if(m_pChannelList!=NULL)
      {
        lmChannelListEntry* pChannelListEntry=m_pChannelList->getFirstSocket();
        while(pChannelListEntry!=NULL)
          {
            delete pChannelListEntry->pCipher;
            pChannelListEntry->pCipher = NULL;
            delete pChannelListEntry->pQueueSend;
            pChannelListEntry->pQueueSend = NULL;
            if (pChannelListEntry->pSocket != NULL)
            {
              pChannelListEntry->pSocket->close();
              delete pChannelListEntry->pSocket;
              pChannelListEntry->pSocket = NULL;
            }
            pChannelListEntry=m_pChannelList->getNextSocket();
          }
      }
    delete m_pQueueReadFromMix;
    m_pQueueReadFromMix = NULL;
    delete m_pQueueSendToMix;
    m_pQueueSendToMix = NULL;
    #ifndef NEW_MIX_TYPE // not TypeB mixes
      /* TypeB mixes are using an own implementation */
    delete m_pChannelList;
    m_pChannelList = NULL;
    if(m_pMuxIn != NULL)
    {
      m_pMuxIn->close();
      delete m_pMuxIn;
      m_pMuxIn=NULL;
    }

    delete m_pRSA;
    m_pRSA = NULL;
    #endif
    return E_SUCCESS;
  }

Here is the call graph for this function:

tMixType CALastMix::getType ( ) const [inline, virtual]

Implements CAMix.

Definition at line 112 of file CALastMix.hpp.

References CAMix::LAST_MIX.

        {
          return CAMix::LAST_MIX;
        }
SINT32 CALastMix::init ( ) [protected, virtual]

Implements CAMix.

Definition at line 80 of file CALastMix.cpp.

References CAMuxSocket::accept(), E_SUCCESS, E_UNKNOWN, ev_net_keyExchangePrevFailed, ev_net_keyExchangePrevSuccessful, ev_net_prevConnected, CAASymCipher::generateKeyPair(), GET_NET_ERROR, GET_NET_ERROR_STR, CAListenerInterface::getAddr(), CAMuxSocket::getCASocket(), CACmdLnOptions::getListenerInterface(), CACmdLnOptions::getListenerInterfaceCount(), CALibProxytest::getOptions(), CAListenerInterface::isVirtual(), lm_loopReadFromMix, lm_loopSendToMix, LM_PACKET_STATS_LOG_INTERVALL, m_bRestart, m_pChannelList, m_pMuxIn, CAMix::m_pMuxInControlChannelDispatcher, m_pQueueReadFromMix, m_pQueueSendToMix, CAMixWithReplayDB::m_pReplayDB, CAMixWithReplayDB::m_pReplayMsgProc, m_pRSA, m_pthreadReadFromMix, m_pthreadSendToMix, CAMixWithReplayDB::m_u64ReferenceTime, MIXPACKET_SIZE, MONITORING_FIRE_NET_EVENT, CAMsg::printMsg(), processKeyExchange(), readFile(), REPLAY_TIMESTAMP_PROPAGATION_INTERVALL, saveFile(), CASocket::setKeepAlive(), CAThread::setMainLoop(), CASocket::setRecvBuff(), CASocket::setSendBuff(), CADatabase::start(), CAThread::start(), CAReplayCtrlChannelMsgProc::startTimeStampPorpagation(), and CASocketAddr::toString().

  {
    m_pRSA=new CAASymCipher();
#ifdef EXPORT_ASYM_PRIVATE_KEY
    if(CALibProxytest::getOptions()->isImportKey())
      {
        UINT32 keyFileBuffLen=8096;
        UINT8* keyFileBuff=new UINT8[keyFileBuffLen];
        CALibProxytest::getOptions()->getEncryptionKeyImportFile(keyFileBuff,keyFileBuffLen);
        UINT8* keyBuff=readFile(keyFileBuff,&keyFileBuffLen);
        m_pRSA->setPrivateKeyAsXML(keyBuff,keyFileBuffLen);
        delete[] keyFileBuff;
        delete[] keyBuff;
      }
    else
#endif
      {
        if(m_pRSA->generateKeyPair(1024)!=E_SUCCESS)
          {
            CAMsg::printMsg(LOG_CRIT,"Could not generate a valid key pair\n");
            return E_UNKNOWN;
          }
      }
#ifdef EXPORT_ASYM_PRIVATE_KEY
    if(CALibProxytest::getOptions()->isExportKey())
      {
        UINT32 keyFileBuffLen=8096;
        UINT8* keyFileBuff=new UINT8[keyFileBuffLen];
        UINT8* keyBuff=new UINT8[keyFileBuffLen];
        CALibProxytest::getOptions()->getEncryptionKeyExportFile(keyFileBuff,keyFileBuffLen);
        m_pRSA->getPrivateKeyAsXML(keyBuff,&keyFileBuffLen);
        saveFile(keyFileBuff,keyBuff,keyFileBuffLen);
        delete[] keyFileBuff;
        delete[] keyBuff;
      }
#endif

    CAListenerInterface*  pListener=NULL;
    UINT32 interfaces=CALibProxytest::getOptions()->getListenerInterfaceCount();
    for(UINT32 i=1;i<=interfaces;i++)
      {
        pListener=CALibProxytest::getOptions()->getListenerInterface(i);
        if(!pListener->isVirtual())
          break;
        delete pListener;
        pListener=NULL;
      }
    if(pListener==NULL)
      {
        CAMsg::printMsg(LOG_CRIT,"Initialization failed! Reason: No usable (non virtual) interface was found! Hint: Virtual interfaces only needed if you are behind a NAT/network address translation, and therefore have to publish other external IP addresses to the InfoServices than your internal/hidden IP addresses.\n");
        return E_UNKNOWN;
      }

    const CASocketAddr* pAddr=NULL;
    pAddr=pListener->getAddr();
    delete pListener;
    pListener = NULL;
    UINT8 buff[255];
    pAddr->toString(buff,255);

    CAMsg::printMsg(LOG_INFO,"Waiting for connection from previous Mix on %s...\n", buff);

    m_pMuxIn=new CAMuxSocket();
    SINT32 ret=m_pMuxIn->accept(*pAddr);
    delete pAddr;
    pAddr = NULL;
    if(ret!=E_SUCCESS)
        {
        CAMsg::printMsg(LOG_CRIT,"Initialization failed! Reason: Call to accept() failed with error '%s' (%i)\n", 
          GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
        return ret;
        }
    // connected to previous mix
    m_pMuxIn->getCASocket()->setRecvBuff(500*MIXPACKET_SIZE);
    m_pMuxIn->getCASocket()->setSendBuff(500*MIXPACKET_SIZE);
    m_pMuxIn->getCASocket()->setKeepAlive((UINT32)1800);

    MONITORING_FIRE_NET_EVENT(ev_net_prevConnected);
    CAMsg::printMsg(LOG_INFO,"connected!\n");

#ifdef LOG_CRIME
    m_nCrimeRegExpsURL=NULL;
    m_pCrimeRegExpsURL=CALibProxytest::getOptions()->getCrimeRegExpsURL(&m_nCrimeRegExpsURL);
    m_nCrimeRegExpsPayload = NULL;
    m_pCrimeRegExpsPayload = CALibProxytest::getOptions()->getCrimeRegExpsPayload(&m_nCrimeRegExpsPayload);
#endif
    ret=processKeyExchange();
    if(ret!=E_SUCCESS)
    {
      MONITORING_FIRE_NET_EVENT(ev_net_keyExchangePrevFailed);
      return ret;
    }
    MONITORING_FIRE_NET_EVENT(ev_net_keyExchangePrevSuccessful);
    //keyexchange successful
#ifdef REPLAY_DETECTION
    m_pReplayDB=new CADatabase();
    m_pReplayDB->start();
#endif
    m_pQueueSendToMix=new CAQueue(sizeof(tQueueEntry));
    m_pQueueReadFromMix=new CAQueue(sizeof(tQueueEntry));

    m_pMuxInControlChannelDispatcher=new CAControlChannelDispatcher(m_pQueueSendToMix,NULL,0);
#ifdef REPLAY_DETECTION
    m_pReplayMsgProc=new CAReplayCtrlChannelMsgProc(this);
    m_pReplayMsgProc->startTimeStampPorpagation(REPLAY_TIMESTAMP_PROPAGATION_INTERVALL);
    m_u64ReferenceTime=time(NULL);
#endif

    m_bRestart=false;
    //Starting thread for Step 1a
    m_pthreadReadFromMix=new CAThread((UINT8*)"CALastMix - ReadFromMix");
    m_pthreadReadFromMix->setMainLoop(lm_loopReadFromMix);
    m_pthreadReadFromMix->start(this);

    //Starting thread for Step 4
    m_pthreadSendToMix=new CAThread((UINT8*)"CALastMix - SendToMix");
    m_pthreadSendToMix->setMainLoop(lm_loopSendToMix);
    m_pthreadSendToMix->start(this);

    //Starting thread for logging
#ifdef LOG_PACKET_TIMES
    m_pLogPacketStats=new CALogPacketStats();
    m_pLogPacketStats->setLogIntervallInMinutes(LM_PACKET_STATS_LOG_INTERVALL);
    m_pLogPacketStats->start();
#endif
    #ifndef NEW_MIX_TYPE // not TypeB mixes
      /* TypeB mixes are using an own implementation */
    m_pChannelList=new CALastMixChannelList;
    #endif
    return E_SUCCESS;
  }

Here is the call graph for this function:

SINT32 CALastMix::initMixCascadeInfo ( DOMElement *  mixes) [protected, virtual]

This will initialize the XML Cascade Info struct XMLFirstMixToInfoService that is sent to the InfoService in CAInfoService::sendCascadeHelo()

Parameters:
mixesthe <Mixes> element of the XML struct we received from the succeeding mix.
Return values:
E_UNKNOWNif processing produces an error
E_SUCCESSotherwise

Reimplemented from CAMix.

Definition at line 1078 of file CALastMix.cpp.

References CAMix::m_docMixCascadeInfo, and setDOMElementAttribute().

Referenced by initOnce().

{
    SINT32 r = CAMix::initMixCascadeInfo(mixes);
    DOMElement* cascade = m_docMixCascadeInfo->getDocumentElement();
    setDOMElementAttribute(cascade,"create",(UINT8*)"true");
    return r;
}

Here is the call graph for this function:

SINT32 CALastMix::initOnce ( ) [protected, virtual]

Reimplemented from CAMix.

Definition at line 55 of file CALastMix.cpp.

References E_SUCCESS, E_UNKNOWN, CACmdLnOptions::getMultiSigner(), CALibProxytest::getOptions(), initMixCascadeInfo(), CAMix::m_pMultiSignature, CAMsg::printMsg(), and setTargets().

  {
    SINT32 ret=CAMix::initOnce();
    if(ret!=E_SUCCESS)
      return ret;
    if(setTargets()!=E_SUCCESS)
      {
        CAMsg::printMsg(LOG_CRIT,"Could not set Targets (proxies)!\n");
        return E_UNKNOWN;
      }

    //m_pSignature=CALibProxytest::getOptions()->getSignKey();
    m_pMultiSignature=CALibProxytest::getOptions()->getMultiSigner();
    if(m_pMultiSignature==NULL)
      return E_UNKNOWN;
    if(CALibProxytest::getOptions()->getListenerInterfaceCount()<1)
      {
        CAMsg::printMsg(LOG_CRIT,"No ListenerInterfaces specified!\n");
        return E_UNKNOWN;
      }
    if(CALibProxytest::getOptions()->getCascadeXML() != NULL)
      initMixCascadeInfo(CALibProxytest::getOptions()->getCascadeXML());
    return E_SUCCESS;
  }

Here is the call graph for this function:

virtual SINT32 CALastMix::loop ( ) [protected, pure virtual]

Implements CAMix.

Implemented in CALastMixB, and CALastMixA.

SINT32 CALastMix::processKeyExchange ( ) [protected, virtual]

Processes the startup communication with the preceeding mix.

  • Step 1: Mix n-1 open a TCP/IP Connection
  • Step 2: LastMix sends XML struct describing itself, containing PubKey of LastMix, signed by LastMix (see XML structs)
  • Step 3: Mix n-1 sends XML struct containing encrpyted (with PubKey) Symetric Key used for interlink encryption between Mix n-1 <---> LastMix, signed by Mix n-1 (see XML structs)

Getting and calculating the KeepAlive Traffice...

Implements CAMix.

Definition at line 222 of file CALastMix.cpp.

References CAMix::addMixInfo(), CAMix::appendCompatibilityInfo(), CAMix::appendTermsAndConditionsExtension(), CHAIN_TIMEOUT, CHANNEL_DOWNSTREAM_PACKETS, CHANNEL_TIMEOUT, CAMix::checkCompatibility(), createDOMDocument(), createDOMElement(), CABase64::decode(), decodeXMLEncryptedKey(), DOM_Output::dumpToMem(), E_SUCCESS, E_UNKNOWN, CABase64::encode(), FLOW_CONTROL_SENDME_SOFT_LIMIT, GET_NET_ERROR, GET_NET_ERROR_STR, CAMuxSocket::getCASocket(), getDOMChildByName(), getDOMElementValue(), CACmdLnOptions::getKeepAliveRecvInterval(), CACmdLnOptions::getKeepAliveSendInterval(), CALibProxytest::getOptions(), CACmdLnOptions::getPrevMixTestCertificate(), CAASymCipher::getPublicKeyAsDOMElement(), getRandom(), CACmdLnOptions::getTrustedCertificateStore(), len, m_pMuxIn, m_pRSA, CAMix::m_u32KeepAliveRecvInterval, CAMix::m_u32KeepAliveSendInterval, parseDOMDocument(), CAMsg::printMsg(), CAMuxSocket::receiveFully(), CASocket::send(), CAMuxSocket::setCrypt(), setDOMElementAttribute(), setDOMElementValue(), CACmdLnOptions::setPrevMixTestCertificate(), CAMuxSocket::setReceiveKey(), CAMuxSocket::setSendKey(), CAMix::signXML(), CAMix::termsAndConditionsInfoNode(), CAMix::TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT, CACertStore::verifyMixCert(), and CAMultiSignature::verifyXML().

Referenced by init().

  {
    XERCES_CPP_NAMESPACE::DOMDocument* doc=createDOMDocument();
    DOMElement* elemMixes=createDOMElement(doc,"Mixes");
    setDOMElementAttribute(elemMixes,"count",(UINT32)1);
    //UINT8 cName[128];
    //CALibProxytest::getOptions()->getCascadeName(cName,128);
    //setDOMElementAttribute(elemMixes,"cascadeName",cName);
    doc->appendChild(elemMixes);

    addMixInfo(elemMixes, false);
    DOMElement* elemMix=NULL;
    getDOMChildByName(elemMixes, "Mix", elemMix, false);

    //Inserting MixProtocol Version
    // Version 0.3  - "normal", initial mix protocol
    // Version 0.4  - with new flow control [was only used for tests]
    // Version 0.5  - end-to-end 1:n channels (only between client and last mix)
    // Version 0.6  - with new flow control for downstream [productive]
    // Version 0.7  - with new flow control for downstream AND upstream
    DOMElement* elemMixProtocolVersion=createDOMElement(doc,"MixProtocolVersion");
    elemMix->appendChild(elemMixProtocolVersion);
    #ifdef NEW_MIX_TYPE // TypeB mixes
      setDOMElementValue(elemMixProtocolVersion,(UINT8*)"0.5");
      DOM_Element elemDownstreamPackets = doc.createElement("DownstreamPackets");
      setDOMElementValue(elemDownstreamPackets, (UINT32)CHANNEL_DOWNSTREAM_PACKETS);
      elemMixProtocolVersion.appendChild(elemDownstreamPackets);
      DOM_Element elemChannelTimeout = doc.createElement("ChannelTimeout");
      /* let the client use our channel-timeout + 5 seconds */
      setDOMElementValue(elemChannelTimeout, (UINT32)(CHANNEL_TIMEOUT + 5));
      elemMixProtocolVersion.appendChild(elemChannelTimeout);
      DOM_Element elemChainTimeout = doc.createElement("ChainTimeout");
      /* let the client use our chain-timeout - 5 seconds */
      setDOMElementValue(elemChainTimeout, (UINT32)(CHAIN_TIMEOUT - 5));
      elemMixProtocolVersion.appendChild(elemChainTimeout);
    #else
      setDOMElementValue(elemMixProtocolVersion,(UINT8*)"0.6");
      DOMElement* elemFlowControl=createDOMElement(doc,"FlowControl");
      DOMElement* elemUpstreamSendMe=createDOMElement(doc,"UpstreamSendMe");
      DOMElement* elemDownstreamSendMe=createDOMElement(doc,"DownstreamSendMe");
      elemMix->appendChild(elemFlowControl);
      elemFlowControl->appendChild(elemUpstreamSendMe);
      elemFlowControl->appendChild(elemDownstreamSendMe);
      setDOMElementValue(elemUpstreamSendMe,(UINT32)FLOW_CONTROL_SENDME_SOFT_LIMIT);
      setDOMElementValue(elemDownstreamSendMe,(UINT32)FLOW_CONTROL_SENDME_SOFT_LIMIT);
      setDOMElementAttribute(elemFlowControl,"withUpstreamFlowControl",true);
    #endif
    //Inserting RSA-Key
    DOMElement* nodeRsaKey=NULL;
    m_pRSA->getPublicKeyAsDOMElement(nodeRsaKey,doc);
    elemMix->appendChild(nodeRsaKey);

    appendCompatibilityInfo(elemMix);

    //inserting Nonce
    DOMElement* elemNonce=createDOMElement(doc,"Nonce");
    UINT8 arNonce[16];
    getRandom(arNonce,16);
    UINT8 tmpBuff[50];
    UINT32 tmpLen=50;
    CABase64::encode(arNonce,16,tmpBuff,&tmpLen);
    tmpBuff[tmpLen]=0;
    setDOMElementValue(elemNonce,tmpBuff);
    elemMix->appendChild(elemNonce);



// Add Info about KeepAlive traffic
    DOMElement* elemKeepAlive=NULL;
    UINT32 u32KeepAliveSendInterval=CALibProxytest::getOptions()->getKeepAliveSendInterval();
    UINT32 u32KeepAliveRecvInterval=CALibProxytest::getOptions()->getKeepAliveRecvInterval();
    elemKeepAlive=createDOMElement(doc,"KeepAlive");
    DOMElement* elemKeepAliveSendInterval=NULL;
    DOMElement* elemKeepAliveRecvInterval=NULL;
    elemKeepAliveSendInterval=createDOMElement(doc,"SendInterval");
    elemKeepAliveRecvInterval=createDOMElement(doc,"ReceiveInterval");
    elemKeepAlive->appendChild(elemKeepAliveSendInterval);
    elemKeepAlive->appendChild(elemKeepAliveRecvInterval);
    setDOMElementValue(elemKeepAliveSendInterval,u32KeepAliveSendInterval);
    setDOMElementValue(elemKeepAliveRecvInterval,u32KeepAliveRecvInterval);
    elemMix->appendChild(elemKeepAlive);

    CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Offering -- SendInterval %u -- Receive Interval %u\n",u32KeepAliveSendInterval,u32KeepAliveRecvInterval);

    /* append the terms and conditions, if there are any, to the KeyInfo
     * Extensions, (nodes that can be removed from the KeyInfo without
     * destroying the signature of the "Mix"-node).
     */
    if(CALibProxytest::getOptions()->getTermsAndConditions() != NULL)
    {
      appendTermsAndConditionsExtension(doc, elemMixes);
      elemMix->appendChild(termsAndConditionsInfoNode(doc));
    }

    // create signature
    if (signXML(elemMix) != E_SUCCESS)
    {
      CAMsg::printMsg(LOG_DEBUG,"Could not sign KeyInfo sent to users...\n");
    }

    UINT32 len=0;
    UINT8* messageBuff=DOM_Output::dumpToMem(doc,&len);
    if (doc != NULL)
    {
      doc->release();
      doc = NULL;
    }
    UINT32 tmp = htonl(len);
    CAMsg::printMsg(LOG_INFO,"Sending Infos (chain length and RSA-Key, Message-Size %u)\n",len);

    if (len > 100000)
    {
      CAMsg::printMsg(LOG_WARNING,"Unrealistic length for key info: %u We might not be able to get a connection.\n",len);
    }
    
    if( (m_pMuxIn->getCASocket()->send((UINT8*)&tmp, sizeof(tmp)) != sizeof(tmp)) ||
        m_pMuxIn->getCASocket()->send(messageBuff,len)!=(SINT32)len)
    {
      CAMsg::printMsg(LOG_ERR,"Error sending Key-Info!\n");
      delete []messageBuff;
      messageBuff = NULL;
      return E_UNKNOWN;
    }
    delete[] messageBuff;
    messageBuff = NULL;

    SINT32 ret;
    //Now receiving the symmetric key
    CAMsg::printMsg(LOG_INFO,"Waiting for length of symmetric key from previous Mix...\n");
    if((ret = m_pMuxIn->receiveFully((UINT8*) &tmp, sizeof(tmp), TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT)) != E_SUCCESS)
    {
      if (ret != E_UNKNOWN)
      {
        CAMsg::printMsg(LOG_CRIT,"Error receiving symmetric key info length! Reason: '%s' (%i)\n",
          GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
      }
      else
      {
        CAMsg::printMsg(LOG_CRIT,"Error receiving symmetric key info length!\n");
      }
      return ret;
    }
    len = ntohl(tmp);
    
    if (len > 100000)
    {
      CAMsg::printMsg(LOG_WARNING,"Unrealistic length for key info: %u We might not be able to get a connection.\n",len);
    }
    
    messageBuff=new UINT8[len+1]; //+1 for the closing Zero
    CAMsg::printMsg(LOG_INFO,"Waiting for symmetric key from previous Mix with length %i...\n", len);
    if((ret = m_pMuxIn->receiveFully(messageBuff, len, TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT)) != E_SUCCESS)
    {
      if (ret != E_UNKNOWN)
      {
        CAMsg::printMsg(LOG_ERR,"Socket error occurred while receiving the symmetric key from the previous mix! Reason: '%s' (%i) The previous mix might be unable to verify our Mix certificate(s) and therefore closed the connection. Please ask the operator for the log, and exchange your certificates if necessary.\n",
            GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
      }
      else
      {
        CAMsg::printMsg(LOG_ERR,"Socket error occurred while receiving the symmetric key from the previous mix! The previous mix might be unable to verify our Mix certificate(s) and therefore closed the connection. Please ask the operator for the log, and exchange your certificates if necessary.\n");
      }
      delete []messageBuff;
      messageBuff = NULL;
      return ret;
    }
    messageBuff[len]=0;
    CAMsg::printMsg(LOG_INFO,"Symmetric Key Info received from previous mix is:\n");
    CAMsg::printMsg(LOG_INFO,"%s\n",(char*)messageBuff);
    //get document
    doc=parseDOMDocument(messageBuff,len);
    if(doc == NULL)
    {
      CAMsg::printMsg(LOG_CRIT,"Could not parse symmetric key of the previous mix!\n");
      delete []messageBuff;
      messageBuff = NULL;
      return E_UNKNOWN;
    }
    DOMElement* elemRoot=doc->getDocumentElement();
    if(elemRoot == NULL)
    {
      CAMsg::printMsg(LOG_CRIT,"Symmetric key XML structure of previous mix is invalid!\n");
      delete []messageBuff;
      messageBuff = NULL;
      if (doc != NULL)
      {
        doc->release();
        doc = NULL;
      }
      return E_UNKNOWN;
    }
    //verify certificate from previous mix if enabled
    if(CALibProxytest::getOptions()->verifyMixCertificates())
    {
      CACertificate* prevMixCert = CALibProxytest::getOptions()->getTrustedCertificateStore()->verifyMixCert(elemRoot);
      if(prevMixCert != NULL)
      {
        CAMsg::printMsg(LOG_DEBUG, "Previous mix certificate was verified by a trusted root CA.\n");
        CALibProxytest::getOptions()->setPrevMixTestCertificate(prevMixCert);
      }
      else
      {
        CAMsg::printMsg(LOG_ERR, "Could not verify certificate received from previous mix!\n");
        return E_UNKNOWN;
      }
    }
    //verify signature
    //CASignature oSig;
    CACertificate* pCert=CALibProxytest::getOptions()->getPrevMixTestCertificate();
    SINT32 result = CAMultiSignature::verifyXML(messageBuff, len, pCert);
    //oSig.setVerifyKey(pCert);
    delete pCert;
    pCert = NULL;
    //if(oSig.verifyXML(messageBuff,len)!=E_SUCCESS)
    if(result != E_SUCCESS)
    {
      CAMsg::printMsg(LOG_CRIT,"Could not verify the symmetric key!\n");
      delete []messageBuff;
      messageBuff = NULL;
      return E_UNKNOWN;
    }

     if ((result = checkCompatibility(elemRoot, "previous")) != E_SUCCESS)
    {
      delete []messageBuff;
      messageBuff = NULL;
      if (doc != NULL)
      {
        doc->release();
        doc = NULL;
      }
      return result;
    }


    elemNonce=NULL;
    getDOMChildByName(elemRoot,"Nonce",elemNonce,false);
    tmpLen=50;
    memset(tmpBuff,0,tmpLen);
    if(elemNonce==NULL||getDOMElementValue(elemNonce,tmpBuff,&tmpLen)!=E_SUCCESS||
      CABase64::decode(tmpBuff,tmpLen,tmpBuff,&tmpLen)!=E_SUCCESS||
      tmpLen!=SHA_DIGEST_LENGTH ||
      memcmp(SHA1(arNonce,16,NULL),tmpBuff,SHA_DIGEST_LENGTH)!=0
      )
    {
      CAMsg::printMsg(LOG_CRIT,"Could not verify the nonce from previous mix!\n");
      delete []messageBuff;
      messageBuff = NULL;
      if (doc != NULL)
      {
        doc->release();
        doc = NULL;
      }
      return E_UNKNOWN;
    }
    CAMsg::printMsg(LOG_INFO,"Verified the symmetric key from previous mix!\n");

    UINT8 key[150];
    UINT32 keySize=150;
    ret=decodeXMLEncryptedKey(key,&keySize,messageBuff,len,m_pRSA);
    delete []messageBuff;
    messageBuff = NULL;
    if(ret!=E_SUCCESS||keySize!=64)
    {
      CAMsg::printMsg(LOG_CRIT,"Could not decrypt the symmetric key from previous mix!\n");
      if (doc != NULL)
      {
        doc->release();
        doc = NULL;
      }
      return E_UNKNOWN;
    }
    if(m_pMuxIn->setReceiveKey(key,32)!=E_SUCCESS||m_pMuxIn->setSendKey(key+32,32)!=E_SUCCESS)
    {
      CAMsg::printMsg(LOG_CRIT,"Could not set the symmetric key to be used by the MuxSocket!\n");
      if (doc != NULL)
      {
        doc->release();
        doc = NULL;
      }
      return E_UNKNOWN;
    }
    m_pMuxIn->setCrypt(true);
    elemKeepAlive=NULL;
    elemKeepAliveSendInterval=NULL;
    elemKeepAliveRecvInterval=NULL;
    getDOMChildByName(elemRoot,"KeepAlive",elemKeepAlive);
    getDOMChildByName(elemKeepAlive,"SendInterval",elemKeepAliveSendInterval);
    getDOMChildByName(elemKeepAlive,"ReceiveInterval",elemKeepAliveRecvInterval);
    UINT32 tmpSendInterval,tmpRecvInterval;
    getDOMElementValue(elemKeepAliveSendInterval,tmpSendInterval,0xFFFFFFFF); //if now send interval was given set it to "infinite"
    getDOMElementValue(elemKeepAliveRecvInterval,tmpRecvInterval,0xFFFFFFFF); //if no recv interval was given --> set it to "infinite"
    CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Getting offer -- SendInterval %u -- Receive Interval %u\n",tmpSendInterval,tmpRecvInterval);
    m_u32KeepAliveSendInterval = u32KeepAliveSendInterval;
    if (m_u32KeepAliveSendInterval > tmpRecvInterval - 10000)
      m_u32KeepAliveSendInterval-=10000; //make the send interval a little bit smaller than the related receive interval
    m_u32KeepAliveRecvInterval=max(u32KeepAliveRecvInterval,tmpSendInterval);
    if (m_u32KeepAliveRecvInterval - 10000 < tmpSendInterval)
    {
      m_u32KeepAliveRecvInterval += 10000;
    }
    CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Calculated -- SendInterval %u -- Receive Interval %u\n",m_u32KeepAliveSendInterval,m_u32KeepAliveRecvInterval);

    if (doc != NULL)
    {
      doc->release();
      doc = NULL;
    }

    return E_SUCCESS;
  }

Here is the call graph for this function:

Reimplemented from CAMix.

Definition at line 540 of file CALastMix.cpp.

References E_SUCCESS, CALibProxytest::getOptions(), m_pChannelList, CAMsg::printMsg(), and setTargets().

  {
    CAMsg::printMsg(LOG_DEBUG,"Reconfiguring Last Mix\n");
    CAMsg::printMsg(LOG_DEBUG,"Re-read cache proxies\n");
    if(setTargets()!=E_SUCCESS)
      CAMsg::printMsg(LOG_DEBUG,"Could not set new cache proxies\n");
    #ifndef NEW_MIX_TYPE // not TypeB mixes
      #if defined (DELAY_CHANNELS)||defined (DELAY_CHANNELS_LATENCY)
    CAMsg::printMsg(LOG_DEBUG,"Set new resources limitation parameters\n");
        if(m_pChannelList!=NULL) {
    #if defined (DELAY_CHANNELS)
      m_pChannelList->setDelayParameters( CALibProxytest::getOptions()->getDelayChannelUnlimitTraffic(),
                                          CALibProxytest::getOptions()->getDelayChannelBucketGrow(),
                                          CALibProxytest::getOptions()->getDelayChannelBucketGrowIntervall());
    #endif
    #if defined (DELAY_CHANNELS_LATENCY)
      UINT32 utemp=CALibProxytest::getOptions()->getDelayChannelLatency();
      m_pChannelList->setDelayLatencyParameters(  utemp);
    #endif
    }
      #endif
    #else // TypeB mixes
      reconfigureMix();
    #endif
    return E_SUCCESS;
  }

Here is the call graph for this function:

SINT32 CALastMix::setTargets ( ) [protected]

Reads the configured proxies from options.

Return values:
E_UNKNOWNif no proxies are specified
E_SUCCESSif successfully configured the proxies

Definition at line 933 of file CALastMix.cpp.

References CACacheLoadBalancing::add(), CACacheLoadBalancing::clean(), CATargetInterface::cleanAddr(), E_SUCCESS, E_UNKNOWN, CACacheLoadBalancing::get(), CATargetInterface::getAddr(), CACacheLoadBalancing::getElementCount(), CASocketAddrINet::getIP(), CALibProxytest::getOptions(), CASocketAddrINet::getPort(), CACmdLnOptions::getTargetInterface(), CACmdLnOptions::getTargetInterfaceCount(), CATargetInterface::getTargetType(), m_pCacheLB, m_pSocksLB, CAMsg::printMsg(), TARGET_HTTP_PROXY, and TARGET_SOCKS_PROXY.

Referenced by initOnce(), and reconfigure().

  {
    UINT32 cntTargets=CALibProxytest::getOptions()->getTargetInterfaceCount();
    if(cntTargets==0)
      {
        CAMsg::printMsg(LOG_CRIT,"No Targets (proxies) specified!\n");
        return E_UNKNOWN;
      }
    m_pCacheLB->clean();
    m_pSocksLB->clean();
    UINT32 i;
    for(i=1;i<=cntTargets;i++)
      {
        CATargetInterface oTargetInterface;
        CALibProxytest::getOptions()->getTargetInterface(oTargetInterface,i);
        if(oTargetInterface.getTargetType()==TARGET_HTTP_PROXY)
        {
          m_pCacheLB->add(oTargetInterface.getAddr());
        }
        else if(oTargetInterface.getTargetType()==TARGET_SOCKS_PROXY)
        {
          m_pSocksLB->add(oTargetInterface.getAddr());
        }
        oTargetInterface.cleanAddr();
      }
    CAMsg::printMsg(LOG_DEBUG,"This mix will use the following proxies:\n");
    for(i=0;i<m_pCacheLB->getElementCount();i++)
    {
      CASocketAddrINet* pAddr=m_pCacheLB->get();
      UINT8 ip[4];
      pAddr->getIP(ip);
      UINT32 port=pAddr->getPort();
      CAMsg::printMsg(LOG_DEBUG,"%u. HTTP Proxy's Address: %u.%u.%u.%u:%u\n",i+1,ip[0],ip[1],ip[2],ip[3],port);
    }
    for(i=0;i<m_pSocksLB->getElementCount();i++)
      {
        CASocketAddrINet* pAddr=m_pSocksLB->get();
        UINT8 ip[4];
        pAddr->getIP(ip);
        UINT32 port=pAddr->getPort();
        CAMsg::printMsg(LOG_DEBUG,"%u. SOCKS Proxy's Address: %u.%u.%u.%u:%u\n",i+1,ip[0],ip[1],ip[2],ip[3],port);
      }


    return E_SUCCESS;
  }

Here is the call graph for this function:


Friends And Related Function Documentation

THREAD_RETURN lm_loopLog ( void *  ) [friend]

Definition at line 567 of file CALastMix.cpp.

Referenced by CALastMixA::loop(), and CALastMixB::loop().

  {
    CALastMix* pLastMix=(CALastMix*)param;
    pLastMix->m_bRunLog=true;
    UINT32 countLog=0;
    UINT8 buff[256];
    while(pLastMix->m_bRunLog)
      {
        if((countLog%10)==0)
          {
            logMemoryUsage();
          }
        if(countLog==0)
          {
            CAMsg::printMsg(LOG_DEBUG,"Uploaded  Packets: %u\n",pLastMix->m_logUploadedPackets);
            CAMsg::printMsg(LOG_DEBUG,"Downloaded Packets: %u\n",pLastMix->m_logDownloadedPackets);
            print64(buff,(UINT64&)pLastMix->m_logUploadedBytes);
            CAMsg::printMsg(LOG_DEBUG,"Uploaded  Bytes  : %s\n",buff);
            print64(buff,(UINT64&)pLastMix->m_logDownloadedBytes);
            CAMsg::printMsg(LOG_DEBUG,"Downloaded Bytes  : %s\n",buff);
            countLog=30;
          }
        sSleep(30);
        countLog--;
      }
    THREAD_RETURN_SUCCESS;
  }
THREAD_RETURN lm_loopReadFromMix ( void *  pParam) [friend]

Definition at line 696 of file CALastMix.cpp.

Referenced by init().

  {
    CALastMix* pLastMix=(CALastMix*)pParam;
    CAMuxSocket* pMuxSocket=pLastMix->m_pMuxIn;
    CAQueue* pQueue=pLastMix->m_pQueueReadFromMix;
    tQueueEntry* pQueueEntry=new tQueueEntry;
    MIXPACKET* pMixPacket=&pQueueEntry->packet;
    CASingleSocketGroup* pSocketGroup=new CASingleSocketGroup(false);
    pSocketGroup->add(*pMuxSocket);
    #ifdef USE_POOL
      CAPool* pPool=new CAPool(MIX_POOL_SIZE);
    #endif
    UINT64 keepaliveNow,keepaliveLast;
    UINT32 u32KeepAliveRecvInterval=pLastMix->m_u32KeepAliveRecvInterval;
    getcurrentTimeMillis(keepaliveLast);
    while(!pLastMix->m_bRestart)
      {
        if(pQueue->getSize()>MAX_READ_FROM_PREV_MIX_QUEUE_SIZE)
          {
#ifdef DEBUG
            CAMsg::printMsg(LOG_DEBUG,"CAFirstMix::Queue is full!\n");
#endif
            msSleep(200);
            getcurrentTimeMillis(keepaliveLast);
            continue;
          }
        //check if the connection is broken because we did not receive a Keep_alive-Message
        getcurrentTimeMillis(keepaliveNow);
        UINT32 keepaliveDiff=diff64(keepaliveNow,keepaliveLast);
        if(keepaliveDiff>u32KeepAliveRecvInterval)
          {
            CAMsg::printMsg(LOG_ERR,"CALastMix::loopReadFromMix() -- restart because of KeepAlive-Traffic Timeout!\n");
            pLastMix->m_bRestart=true;
            MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed);
            break;
          }
        SINT32 ret=pSocketGroup->select(MIX_POOL_TIMEOUT);
        if(ret < 0)
          {
            if (ret == E_TIMEDOUT)
              {
                #ifdef USE_POOL
                  pMixPacket->flags=CHANNEL_DUMMY;
                  pMixPacket->channel=DUMMY_CHANNEL;
                  getRandom(pMixPacket->data,DATA_SIZE);
                  #ifdef LOG_PACKET_TIMES
                    setZero64(pQueueEntry->timestamp_proccessing_start);
                  #endif
                #else
                  continue;
                #endif
              }
            else
              {
                /* another error occured (happens sometimes while debugging because
                 * of interruption, if a breakpoint is reached -> poll() returns
                 * errorcode EINTR)
                 * Note: Any Error on select() does not mean, that the underliny connections have some error state, because
                 * in this case select() returns the socket and than this socket returns the error
                 */
                continue;
              }
          }
        else if(ret>0)
        {
          ret=pMuxSocket->receive(pMixPacket); //receives a whole MixPacket
          #ifdef LOG_PACKET_TIMES
            getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_start);
          #endif
          #ifdef DATA_RETENTION_LOG
            pQueueEntry->dataRetentionLogEntry.t_in=htonl(time(NULL));
          #endif
          if(ret!=MIXPACKET_SIZE)
          {//something goes wrong...
            CAMsg::printMsg(LOG_ERR,"CALastMix::lm_loopReadFromMix - received returned: %i\n",ret);
            pLastMix->m_bRestart=true;
            MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed);
            break;
          }
        }
    #ifdef USE_POOL
      #ifdef LOG_PACKET_TIMES
        getcurrentTimeMicros(pQueueEntry->pool_timestamp_in);
      #endif
        pPool->pool((tPoolEntry*) pQueueEntry);
      #ifdef LOG_PACKET_TIMES
        getcurrentTimeMicros(pQueueEntry->pool_timestamp_out);
      #endif
    #endif
        pQueue->add(pQueueEntry,sizeof(tQueueEntry));
        getcurrentTimeMillis(keepaliveLast);
      }
    delete pQueueEntry;
    pQueueEntry = NULL;
    delete pSocketGroup;
    pSocketGroup = NULL;
    #ifdef USE_POOL
      delete pPool;
      pPool = NULL;
    #endif
    THREAD_RETURN_SUCCESS;
  }
THREAD_RETURN lm_loopSendToMix ( void *  param) [friend]

How to end this thread: 0.

set m_bRestart=true; 1. Close connection to next mix 2. put a byte in the Mix-Output-Queue

Definition at line 600 of file CALastMix.cpp.

Referenced by init().

  {
    CALastMix* pLastMix=(CALastMix*)param;
    CAQueue* pQueue=pLastMix->m_pQueueSendToMix;
    CAMuxSocket* pMuxSocket=pLastMix->m_pMuxIn;
    SINT32 ret;
    UINT32 len;
    UINT32 u32KeepAliveSendInterval=pLastMix->m_u32KeepAliveSendInterval;
#ifndef USE_POOL
    tQueueEntry* pQueueEntry=new tQueueEntry;
    MIXPACKET* pMixPacket=&pQueueEntry->packet;

    while(!pLastMix->m_bRestart)
      {
        len=sizeof(tQueueEntry);
        ret=pQueue->getOrWait((UINT8*)pQueueEntry,&len,u32KeepAliveSendInterval);
        if(ret==E_TIMEDOUT)
          {
            pMixPacket->flags=CHANNEL_DUMMY;
            pMixPacket->channel=DUMMY_CHANNEL;
            getRandom(pMixPacket->data,DATA_SIZE);
          }
        else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry))
          {
            CAMsg::printMsg(LOG_ERR,"CALastMix::lm_loopSendToMix - Error in dequeueing MixPaket\n");
            CAMsg::printMsg(LOG_ERR,"ret=%i len=%i\n",ret,len);
            MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed);
            break;
          }
        if(pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE)
          {
            CAMsg::printMsg(LOG_ERR,"CALastMix::lm_loopSendToMix - Error in sending MixPaket\n");
            MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed);
            break;
          }
#ifdef LOG_PACKET_TIMES
        if(!isZero64(pQueueEntry->timestamp_proccessing_start))
          {
            getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end);
            pLastMix->m_pLogPacketStats->addToTimeingStats(*pQueueEntry,CHANNEL_DATA,false);
          }
#endif
      }
    delete pQueueEntry;
    pQueueEntry = NULL;
#else
    CAPool* pPool=new CAPool(MIX_POOL_SIZE);
    tPoolEntry* pPoolEntry=new tPoolEntry;
    MIXPACKET* pMixPacket=&pPoolEntry->packet;
    while(!pLastMix->m_bRestart)
      {
        len=sizeof(tQueueEntry);
        SINT32 ret=pQueue->getOrWait((UINT8*)pPoolEntry,&len,MIX_POOL_TIMEOUT);
        if(ret==E_TIMEDOUT)
          {
            pMixPacket->flags=CHANNEL_DUMMY;
            pMixPacket->channel=DUMMY_CHANNEL;
            getRandom(pMixPacket->data,DATA_SIZE);
            #ifdef LOG_PACKET_TIMES
              setZero64(pPoolEntry->timestamp_proccessing_start);
            #endif
          }
        else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry))
          {
            break;
          }
        #ifdef LOG_PACKET_TIMES
          getcurrentTimeMicros(pPoolEntry->pool_timestamp_in);
        #endif
        pPool->pool(pPoolEntry);
        #ifdef LOG_PACKET_TIMES
          getcurrentTimeMicros(pPoolEntry->pool_timestamp_out);
        #endif
        if(pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE)
          break;
#ifdef LOG_PACKET_TIMES
        if(!isZero64(pPoolEntry->timestamp_proccessing_start))
          {
            getcurrentTimeMicros(pPoolEntry->timestamp_proccessing_end);
            pLastMix->m_pLogPacketStats->addToTimeingStats(*pPoolEntry,CHANNEL_DATA,false);
          }
#endif
      }
    delete pPoolEntry;
    pPoolEntry = NULL;
    delete pPool;
    pPool = NULL;
#endif
    CAMsg::printMsg(LOG_DEBUG,"Exiting Thread SendToMix\n");
    THREAD_RETURN_SUCCESS;
  }

Member Data Documentation

volatile bool CALastMix::m_bRestart [protected]
volatile bool CALastMix::m_bRunLog [protected]

Definition at line 176 of file CALastMix.hpp.

Referenced by clean(), lm_loopLog(), CALastMixA::loop(), and CALastMixB::loop().

Definition at line 180 of file CALastMix.hpp.

Referenced by lm_loopLog(), CALastMixA::loop(), and CALastMixB::loop().

Definition at line 179 of file CALastMix.hpp.

Referenced by lm_loopLog(), CALastMixA::loop(), and CALastMixB::loop().

volatile UINT64 CALastMix::m_logUploadedBytes [protected]

Definition at line 178 of file CALastMix.hpp.

Referenced by lm_loopLog(), CALastMixA::loop(), and CALastMixB::loop().

Definition at line 177 of file CALastMix.hpp.

Referenced by lm_loopLog(), CALastMixA::loop(), and CALastMixB::loop().

Definition at line 153 of file CALastMix.hpp.

Referenced by CALastMix(), CALastMixA::loop(), CALastMixB::loop(), setTargets(), and ~CALastMix().

Definition at line 160 of file CALastMix.hpp.

Referenced by CALastMix(), clean(), init(), CALastMixA::loop(), and reconfigure().

Definition at line 154 of file CALastMix.hpp.

Referenced by CALastMix(), CALastMixA::loop(), CALastMixB::loop(), setTargets(), and ~CALastMix().

Definition at line 157 of file CALastMix.hpp.

Referenced by CALastMix(), clean(), init(), and CALastMixB::loop().

Definition at line 156 of file CALastMix.hpp.

Referenced by CALastMix(), clean(), init(), and CALastMixB::loop().


The documentation for this class was generated from the following files: