Mixe for Privacy and Anonymity in the Internet
Defines | Functions
CAMiddleMix.cpp File Reference
#include "StdAfx.h"
#include "CAMiddleMix.hpp"
#include "CASingleSocketGroup.hpp"
#include "CAMsg.hpp"
#include "CACmdLnOptions.hpp"
#include "CASocketAddrINet.hpp"
#include "CASocketAddrUnix.hpp"
#include "CAThread.hpp"
#include "CAInfoService.hpp"
#include "CAUtil.hpp"
#include "CABase64.hpp"
#include "CAPool.hpp"
#include "xml/DOM_Output.hpp"
#include "CAStatusManager.hpp"
#include "CALibProxytest.hpp"
Include dependency graph for CAMiddleMix.cpp:

Go to the source code of this file.

Defines

#define MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS   2*KEY_SIZE
#define MIDDLE_MIX_ASYM_PADDING_SIZE   42
#define RETRIES   100
#define RETRYTIME   10

Functions

THREAD_RETURN mm_loopSendToMixAfter (void *param)
 UPSTREAM (to WEB) Take the packets from the Queue and write them to the Socket.
THREAD_RETURN mm_loopSendToMixBefore (void *param)
 DOWNSTREAM (to Client) Take the packets from the Queue and write them to the Socket.
THREAD_RETURN mm_loopReadFromMixBefore (void *param)
THREAD_RETURN mm_loopReadFromMixAfter (void *param)

Define Documentation

Definition at line 886 of file CAMiddleMix.cpp.

Referenced by mm_loopReadFromMixBefore().

Definition at line 885 of file CAMiddleMix.cpp.

Referenced by mm_loopReadFromMixBefore().

#define RETRIES   100
#define RETRYTIME   10

Function Documentation

Definition at line 1059 of file CAMiddleMix.cpp.

References CASocketGroup::add(), CAQueue::add(), t_MixPacket::channel, CHANNEL_ALLOWED_FLAGS, CHANNEL_CLOSE, CHANNEL_DUMMY, CHANNEL_SIG_CRIME, CASymCipher::crypt2(), t_MixPacket::data, DATA_SIZE, DUMMY_CHANNEL, E_SUCCESS, E_TIMEDOUT, ev_net_nextConnectionClosed, t_MixPacket::flags, GET_NET_ERROR, GET_NET_ERROR_STR, CAMiddleMixChannelList::getOutToIn(), getRandom(), CAQueue::getSize(), CAMiddleMix::m_bRun, CAMiddleMix::m_pMiddleMixChannelList, CAMiddleMix::m_pMuxIn, CAMiddleMix::m_pMuxOut, CAMiddleMix::m_pQueueSendToMixAfter, CAMiddleMix::m_pQueueSendToMixBefore, MAX_READ_FROM_NEXT_MIX_QUEUE_SIZE, MIX_POOL_TIMEOUT, MONITORING_FIRE_NET_EVENT, msSleep(), t_queue_entry::packet, pMix, CAPool::pool(), CAMsg::printMsg(), CAMuxSocket::receive(), CAMiddleMixChannelList::remove(), REPLAY_CONTROL_CHANNEL_ID, CASocketGroup::select(), CAMuxSocket::send(), SOCKET_ERROR, THREAD_RETURN_SUCCESS, and CALockAble::unlock().

  {
    CAMiddleMix* pMix=(CAMiddleMix*)param;
    HCHANNEL channelIn;
    CASymCipher* pCipher;

    tPoolEntry* pPoolEntry=new tPoolEntry;
    MIXPACKET* pMixPacket=&pPoolEntry->packet;

    SINT32 ret;
    CASingleSocketGroup oSocketGroup(false);
    oSocketGroup.add(*(pMix->m_pMuxOut));

    CAQueue* pQueue=pMix->m_pQueueSendToMixBefore;

#ifdef USE_POOL
    CAPool* pPool=new CAPool(MIX_POOL_SIZE);
#endif
    while(pMix->m_bRun)
      {
        if(pQueue->getSize()>MAX_READ_FROM_NEXT_MIX_QUEUE_SIZE)
        {
#ifdef DEBUG
          CAMsg::printMsg(LOG_DEBUG,"CAMiddleMix::Queue next is full!\n");
#endif
          msSleep(200);
          continue;
        }
        #ifndef USE_POOL
          ret=oSocketGroup.select(1000);
        #else
          ret=oSocketGroup.select(MIX_POOL_TIMEOUT);
        #endif
        if(ret!=1)
          {
            if(ret==E_TIMEDOUT)
              {
                #ifndef USE_POOL
                  continue;
                #else
                  pMixPacket->channel=DUMMY_CHANNEL;
                  pMixPacket->flags=CHANNEL_DUMMY;
                  getRandom(pMixPacket->data,DATA_SIZE);
                  pPool->pool(pPoolEntry);
                  if(pMix->m_pMuxIn->send(pMixPacket)==SOCKET_ERROR)
                    pMix->m_bRun=false;
                #endif
              }
            else
            {
              CAMsg::printMsg(LOG_CRIT,"loopReadFromMixAfter -- Error on select() while waiting for data from next mix -- goto ERR!\n");
              pMix->m_bRun=false;
              MONITORING_FIRE_NET_EVENT(ev_net_nextConnectionClosed);
            }
          }
        else
          {

            ret=pMix->m_pMuxOut->receive(pMixPacket);
            if ((ret!=SOCKET_ERROR)&&(pMixPacket->flags & ~CHANNEL_ALLOWED_FLAGS))
              {
                CAMsg::printMsg(LOG_INFO,"loopReadFromMixAfter -- received a packet with invalid flags: %0X .  Removing them.\n",(pMixPacket->flags & ~CHANNEL_ALLOWED_FLAGS));
                pMixPacket->flags&=CHANNEL_ALLOWED_FLAGS;
              }
            if(ret==SOCKET_ERROR)
              {
                CAMsg::printMsg(LOG_CRIT,"loopReadFromMixAfter -- Error while receiving data from next mix. Reason: %s (%i)\n",
                  GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
                pMix->m_bRun=false;
                MONITORING_FIRE_NET_EVENT(ev_net_nextConnectionClosed);
              }
            #ifdef USE_POOL
            else if(pMixPacket->channel==DUMMY_CHANNEL)
              {
                pMixPacket->flags=CHANNEL_DUMMY;
                getRandom(pMixPacket->data,DATA_SIZE);
                pPool->pool(pPoolEntry);
                if(pMix->m_pMuxIn->send(pMixPacket)==SOCKET_ERROR)
                  pMix->m_bRun=false;
              }
            #endif
            #ifdef REPLAY_DETECTION
            else if(pMixPacket->channel==REPLAY_CONTROL_CHANNEL_ID)
              {
                pQueue->add(pPoolEntry,sizeof(tPoolEntry));
              }
            #endif
            else if(pMix->m_pMiddleMixChannelList->getOutToIn(&channelIn,pMixPacket->channel,&pCipher)==E_SUCCESS)
              {//connection found
#ifdef LOG_CRIME
                HCHANNEL channelOut = pMixPacket->channel;
#endif
                pMixPacket->channel=channelIn;
#ifdef LOG_CRIME
                if((pMixPacket->flags&CHANNEL_SIG_CRIME)==CHANNEL_SIG_CRIME)
                  {
                    getRandom(pMixPacket->data,DATA_SIZE);
                    //Log in and out channel number, to allow
                    CAMsg::printMsg(LOG_CRIT,"Detecting crime activity - previous mix channel: %u, "
                        "next mix channel: %u\n", channelIn, channelOut);
                  }
                else
#endif
                pCipher->crypt2(pMixPacket->data,pMixPacket->data,DATA_SIZE);
                pCipher->unlock();
                #ifdef USE_POOL
                  pPool->pool(pPoolEntry);
                #endif
                if((pMixPacket->flags&CHANNEL_CLOSE)!=0)
                  {//Channel close received -->remove channel form channellist
                    pMix->m_pMiddleMixChannelList->remove(channelIn);
                  }
                pQueue->add(pPoolEntry,sizeof(tPoolEntry));
              }
          }
      }

    CAMsg::printMsg(LOG_CRIT,"loopReadFromMixAfter -- Exiting clean ups...\n");
    pMix->m_bRun=false;
    UINT8 b[sizeof(tQueueEntry)+1];
    /* write bytes to the send queues to accelerate loop()-joins for the send threads*/
    if(pMix->m_pQueueSendToMixBefore!=NULL)
    {
      pMix->m_pQueueSendToMixBefore->add(b,sizeof(tQueueEntry)+1);
    }
    if(pMix->m_pQueueSendToMixAfter!=NULL)
    {
      pMix->m_pQueueSendToMixAfter->add(b,sizeof(tQueueEntry)+1);
    }
    delete pPoolEntry;
    pPoolEntry = NULL;
    #ifdef USE_POOL
      delete pPool;
      pPool = NULL;
    #endif
    CAMsg::printMsg(LOG_CRIT,"loopReadFromMixAfter -- Now Exiting!\n");
    THREAD_RETURN_SUCCESS;
  }

Here is the call graph for this function:

Definition at line 888 of file CAMiddleMix.cpp.

References CASocketGroup::add(), CAQueue::add(), CAMiddleMixChannelList::add(), t_MixPacket::channel, CHANNEL_ALLOWED_FLAGS, CHANNEL_CLOSE, CHANNEL_DUMMY, CHANNEL_OPEN, CASymCipher::crypt1(), t_MixPacket::data, DATA_SIZE, CAASymCipher::decryptOAEP(), DUMMY_CHANNEL, E_SUCCESS, E_TIMEDOUT, ev_net_prevConnectionClosed, t_MixPacket::flags, CAMiddleMixChannelList::getInToOut(), getRandom(), CAQueue::getSize(), CADatabase::insert(), CAMiddleMix::m_bRun, CAMiddleMix::m_pMiddleMixChannelList, CAMiddleMix::m_pMuxIn, CAMiddleMix::m_pMuxOut, CAMiddleMix::m_pQueueSendToMixAfter, CAMiddleMix::m_pQueueSendToMixBefore, CAMixWithReplayDB::m_pReplayDB, CAMiddleMix::m_pRSA, CAMixWithReplayDB::m_u64ReferenceTime, MAX_READ_FROM_PREV_MIX_QUEUE_SIZE, MIDDLE_MIX_ASYM_PADDING_SIZE, MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS, MIX_POOL_TIMEOUT, MONITORING_FIRE_NET_EVENT, msSleep(), t_queue_entry::packet, pMix, CAPool::pool(), CAMsg::printMsg(), CAMuxSocket::receive(), CAMiddleMixChannelList::remove(), REPLAY_BASE, RSA_SIZE, CASocketGroup::select(), CAMuxSocket::send(), CASymCipher::setKeys(), SOCKET_ERROR, THREAD_RETURN_SUCCESS, and CALockAble::unlock().

  {
    CAMiddleMix* pMix=(CAMiddleMix*)param;
    HCHANNEL channelOut = 0, channelIn = 0;
    tPoolEntry* pPoolEntry=new tPoolEntry;
    MIXPACKET* pMixPacket=&pPoolEntry->packet;

    CAQueue* pQueue=pMix->m_pQueueSendToMixAfter;

    CASymCipher* pCipher;
    SINT32 ret;
    UINT8* tmpRSABuff=new UINT8[RSA_SIZE];
    UINT32 rsaOutLen=RSA_SIZE;
    CASingleSocketGroup oSocketGroup(false);
    oSocketGroup.add(*(pMix->m_pMuxIn));

    #ifdef USE_POOL
      CAPool* pPool=new CAPool(MIX_POOL_SIZE);
    #endif

    while(pMix->m_bRun)
      {
        if(pQueue->getSize()>MAX_READ_FROM_PREV_MIX_QUEUE_SIZE)
        {
#ifdef DEBUG
          CAMsg::printMsg(LOG_DEBUG,"CAFirstMix::Queue prev is full!\n");
#endif
          msSleep(200);
          continue;
        }
        #ifndef USE_POOL
          ret=oSocketGroup.select(1000);
        #else
          ret=oSocketGroup.select(MIX_POOL_TIMEOUT);
        #endif
        if(ret!=1)
          {
            if(ret==E_TIMEDOUT)
              {
                #ifndef USE_POOL
                  continue;
                #else
                  pMixPacket->channel=DUMMY_CHANNEL;
                  pMixPacket->flags=CHANNEL_DUMMY;
                  getRandom(pMixPacket->data,DATA_SIZE);
                  pPool->pool(pPoolEntry);
                  if(m_pMuxOut->send(pMixPacket)==SOCKET_ERROR)
                    pMix->m_bRun=false;
                #endif
              }
            else
              {
                CAMsg::printMsg(LOG_CRIT,"loopUpStream -- Fehler bei select() -- goto ERR!\n");
                pMix->m_bRun=false;
                MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed);
              }
          }
        else
          {
            ret=pMix->m_pMuxIn->receive(pMixPacket);

            if ((ret!=SOCKET_ERROR)&&(pMixPacket->flags & ~CHANNEL_ALLOWED_FLAGS))
            {
              CAMsg::printMsg(LOG_INFO,"loopUpStream received a packet with invalid flags: %0X .  Removing them.\n",(pMixPacket->flags & ~CHANNEL_ALLOWED_FLAGS));
              pMixPacket->flags&=CHANNEL_ALLOWED_FLAGS;
            }

            if(ret==SOCKET_ERROR)
            {

              CAMsg::printMsg(LOG_CRIT,"Fehler beim Empfangen -- Exiting!\n");
              pMix->m_bRun=false;
              MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed);
            }
            #ifdef USE_POOL
            else if(pMixPacket->channel==DUMMY_CHANNEL)
            {
              pMixPacket->flags=CHANNEL_DUMMY;
              getRandom(pMixPacket->data,DATA_SIZE);
              pPool->pool(pPoolEntry);
              if(pMix->m_pMuxOut->send(pMixPacket)==SOCKET_ERROR)
                pMix->m_bRun=false;
            }
            #endif

            else //receive successful
            {
              channelIn = pMixPacket->channel;
              if(pMix->m_pMiddleMixChannelList->getInToOut(pMixPacket->channel,&channelOut,&pCipher)!=E_SUCCESS)
              {//new connection ?
                if(pMixPacket->flags & CHANNEL_OPEN) //if not channel-open flag set -->drop this packet
                {
                  #ifdef _DEBUG
                    CAMsg::printMsg(LOG_DEBUG,"New Connection from previous Mix!\n");
                  #endif
                  pMix->m_pRSA->decryptOAEP(pMixPacket->data,tmpRSABuff,&rsaOutLen);
                  #ifdef REPLAY_DETECTION
                    // replace time(NULL) with the real timestamp ()
                    // packet-timestamp + m_u64ReferenceTime
                    UINT32 stamp=((UINT32)(tmpRSABuff[13]<<16)+(UINT32)(tmpRSABuff[14]<<8)+(UINT32)(tmpRSABuff[15]))*REPLAY_BASE;
                    if(pMix->m_pReplayDB->insert(tmpRSABuff,stamp+pMix->m_u64ReferenceTime)!=E_SUCCESS)
//                      if(pMix->m_pReplayDB->insert(tmpRSABuff,time(NULL))!=E_SUCCESS)
                      {
                        CAMsg::printMsg(LOG_INFO,"Replay: Duplicate packet ignored.\n");
                        continue;
                      }
                  #endif

                  pCipher=new CASymCipher();
                  pCipher->setKeys(tmpRSABuff,MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS);
                  pCipher->crypt1(pMixPacket->data+RSA_SIZE,
                        pMixPacket->data+rsaOutLen-MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS,
                        DATA_SIZE-RSA_SIZE);
                  memcpy(pMixPacket->data,tmpRSABuff+MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS,rsaOutLen-MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS);
                  getRandom(pMixPacket->data+DATA_SIZE-MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS-MIDDLE_MIX_ASYM_PADDING_SIZE,MIDDLE_MIX_SIZE_OF_SYMMETRIC_KEYS+MIDDLE_MIX_ASYM_PADDING_SIZE);
                  pMix->m_pMiddleMixChannelList->add(pMixPacket->channel,pCipher,&channelOut);
                  pMixPacket->channel=channelOut;
                  #ifdef USE_POOL
                    pPool->pool(pPoolEntry);
                  #endif
                  #ifdef LOG_CRIME
                  crimeSurveillanceUpstream(pMixPacket, channelIn);
                  #endif
                  pQueue->add(pPoolEntry,sizeof(tPoolEntry));
                }
              }
              else
              {//established connection
                pCipher->crypt1(pMixPacket->data,pMixPacket->data,DATA_SIZE);
                pCipher->unlock();
                #ifdef USE_POOL
                  pPool->pool(pPoolEntry);
                #endif
                if((pMixPacket->flags&CHANNEL_CLOSE)!=0)
                {//Channel close received -->remove channel form channellist
                  pMix->m_pMiddleMixChannelList->remove(pMixPacket->channel);
                }
                pMixPacket->channel=channelOut;
                #ifdef LOG_CRIME
                crimeSurveillanceUpstream(pMixPacket, channelIn);
                #endif
                pQueue->add(pPoolEntry,sizeof(tPoolEntry));
              }
            }
          }
      }

    CAMsg::printMsg(LOG_CRIT,"loopReadFromMixBefore -- Exiting clean ups...\n");
    pMix->m_bRun=false;
    UINT8 b[sizeof(tQueueEntry)+1];
    /* write bytes to the send queues to accelerate loop()-joins for the send threads*/
    if(pMix->m_pQueueSendToMixBefore!=NULL)
    {
      pMix->m_pQueueSendToMixBefore->add(b,sizeof(tQueueEntry)+1);
    }
    if(pMix->m_pQueueSendToMixAfter!=NULL)
    {
      pMix->m_pQueueSendToMixAfter->add(b,sizeof(tQueueEntry)+1);
    }
    delete tmpRSABuff;
    tmpRSABuff = NULL;
    delete pPoolEntry;
    pPoolEntry = NULL;
    #ifdef USE_POOL
      delete pPool;
      pPool = NULL;
    #endif
    CAMsg::printMsg(LOG_CRIT,"loopReadFromMixBefore -- Now Exiting!\n");
    THREAD_RETURN_SUCCESS;
  }

Here is the call graph for this function:

UPSTREAM (to WEB) Take the packets from the Queue and write them to the Socket.

Definition at line 765 of file CAMiddleMix.cpp.

References BEGIN_STACK, t_MixPacket::channel, CHANNEL_DUMMY, t_MixPacket::data, DATA_SIZE, DUMMY_CHANNEL, E_SUCCESS, E_TIMEDOUT, ev_net_nextConnectionClosed, FINISH_STACK, t_MixPacket::flags, getcurrentTimeMicros(), CAQueue::getOrWait(), getRandom(), INIT_STACK, isZero64(), len, CAMiddleMix::m_bRun, CAMiddleMix::m_pMuxOut, CAMiddleMix::m_u32KeepAliveSendInterval2, MIXPACKET_SIZE, MONITORING_FIRE_NET_EVENT, t_queue_entry::packet, CAMsg::printMsg(), CAMuxSocket::send(), and THREAD_RETURN_SUCCESS.

  {
    INIT_STACK;
    BEGIN_STACK("CAFirstMix::fm_loopSendToMixAfter");

    CAMiddleMix* pMiddleMix=(CAMiddleMix*)param;
    CAQueue* pQueue=((CAMiddleMix*)param)->m_pQueueSendToMixAfter;
    CAMuxSocket* pMuxSocket=pMiddleMix->m_pMuxOut;

    UINT32 len;
    SINT32 ret;
    tPoolEntry* pPoolEntry=new tPoolEntry;
    MIXPACKET* pMixPacket=&pPoolEntry->packet;
    UINT32 u32KeepAliveSendInterval=pMiddleMix->m_u32KeepAliveSendInterval2;
    while(pMiddleMix->m_bRun)
      {
        len=sizeof(tPoolEntry);
        ret=pQueue->getOrWait((UINT8*)pPoolEntry,&len,u32KeepAliveSendInterval);
        if(!(pMiddleMix->m_bRun))
        {
          CAMsg::printMsg(LOG_INFO,"SendToMixAfter thread: was interrupted.\n");
          MONITORING_FIRE_NET_EVENT(ev_net_nextConnectionClosed);
          break;
        }
        if(ret==E_TIMEDOUT)
          {//send a dummy as keep-alive-traffic
            pMixPacket->flags=CHANNEL_DUMMY;
            pMixPacket->channel=DUMMY_CHANNEL;
            getRandom(pMixPacket->data,DATA_SIZE);
          }
        else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry))
          {
            MONITORING_FIRE_NET_EVENT(ev_net_nextConnectionClosed);
            CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMixAfter - Error in dequeueing MixPaket\n");
            CAMsg::printMsg(LOG_ERR,"ret=%i len=%i\n",ret,len);
            break;
          }
        if((pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE))
          {
            MONITORING_FIRE_NET_EVENT(ev_net_nextConnectionClosed);
            CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMixAfter - Error in sending MixPaket\n");
            break;
          }
#ifdef LOG_PACKET_TIMES
        if(!isZero64(pPoolEntry->timestamp_proccessing_start))
          {
            getcurrentTimeMicros(pPoolEntry->timestamp_proccessing_end);
            pFirstMix->m_pLogPacketStats->addToTimeingStats(*pPoolEntry,pMixPacket->flags,true);
          }
#endif
      }
    pMiddleMix->m_bRun = false;
    delete pPoolEntry;
    pPoolEntry = NULL;
    FINISH_STACK("CAFirstMix::fm_loopSendToMixAfter");

    CAMsg::printMsg(LOG_DEBUG,"Exiting Thread SendToMixAfter\n");
    THREAD_RETURN_SUCCESS;
  }

Here is the call graph for this function:

DOWNSTREAM (to Client) Take the packets from the Queue and write them to the Socket.

Definition at line 826 of file CAMiddleMix.cpp.

References BEGIN_STACK, t_MixPacket::channel, CHANNEL_DUMMY, t_MixPacket::data, DATA_SIZE, DUMMY_CHANNEL, E_SUCCESS, E_TIMEDOUT, ev_net_prevConnectionClosed, FINISH_STACK, t_MixPacket::flags, getcurrentTimeMicros(), CAQueue::getOrWait(), getRandom(), INIT_STACK, isZero64(), len, CAMiddleMix::m_bRun, CAMiddleMix::m_pMuxIn, CAMix::m_u32KeepAliveSendInterval, MIXPACKET_SIZE, MONITORING_FIRE_NET_EVENT, t_queue_entry::packet, CAMsg::printMsg(), CAMuxSocket::send(), and THREAD_RETURN_SUCCESS.

  {
    INIT_STACK;
    BEGIN_STACK("CAFirstMix::fm_loopSendToMixBefore");

    CAMiddleMix* pMiddleMix=(CAMiddleMix*)param;
    CAQueue* pQueue=((CAMiddleMix*)param)->m_pQueueSendToMixBefore;
    CAMuxSocket* pMuxSocket=pMiddleMix->m_pMuxIn;

    UINT32 len;
    SINT32 ret;
    tPoolEntry* pPoolEntry=new tPoolEntry;
    MIXPACKET* pMixPacket=&pPoolEntry->packet;
    UINT32 u32KeepAliveSendInterval=pMiddleMix->m_u32KeepAliveSendInterval;
    while(pMiddleMix->m_bRun)
      {
        len=sizeof(tPoolEntry);
        ret=pQueue->getOrWait((UINT8*)pPoolEntry,&len,u32KeepAliveSendInterval);
        if(!(pMiddleMix->m_bRun))
        {
          CAMsg::printMsg(LOG_INFO,"SendToMixBefore thread: was interrupted.\n");
          break;
        }
        if(ret==E_TIMEDOUT)
          {//send a dummy as keep-alive-traffic
            pMixPacket->flags=CHANNEL_DUMMY;
            pMixPacket->channel=DUMMY_CHANNEL;
            getRandom(pMixPacket->data,DATA_SIZE);
          }
        else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry))
          {
            MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed);
            CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMixBefore - Error in dequeueing MixPaket\n");
            CAMsg::printMsg(LOG_ERR,"ret=%i len=%i\n",ret,len);
            break;
          }
        if((pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE))
          {
            MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed);
            CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMixBefore - Error in sending MixPaket\n");
            break;
          }
#ifdef LOG_PACKET_TIMES
        if(!isZero64(pPoolEntry->timestamp_proccessing_start))
          {
            getcurrentTimeMicros(pPoolEntry->timestamp_proccessing_end);
            pFirstMix->m_pLogPacketStats->addToTimeingStats(*pPoolEntry,pMixPacket->flags,true);
          }
#endif
      }
    pMiddleMix->m_bRun = false;
    delete pPoolEntry;
    pPoolEntry = NULL;
    FINISH_STACK("CAFirstMix::fm_loopSendToMixBefore");

    CAMsg::printMsg(LOG_DEBUG,"Exiting Thread SendToMixBefore\n");
    THREAD_RETURN_SUCCESS;
  }

Here is the call graph for this function: