Mixe for Privacy and Anonymity in the Internet
Public Member Functions | Protected Member Functions | Private Member Functions | Friends | List of all members
CAFirstMixA Class Reference

#include <CAFirstMixA.hpp>

Inheritance diagram for CAFirstMixA:
Collaboration diagram for CAFirstMixA:

Public Member Functions

virtual void shutDown ()
 
- Public Member Functions inherited from CAFirstMix
 CAFirstMix ()
 
virtual ~CAFirstMix ()
 
tMixType getType () const
 
bool forceKickout (fmHashTableEntry *pHashTableEntry, const XERCES_CPP_NAMESPACE::DOMDocument *pErrDoc=NULL)
 
CAMutexgetLoginMutex ()
 
SINT32 connectToNextMix (CASocketAddr *a_pAddrNext)
 
SINT32 getMixedPackets (UINT64 &ppackets)
 
UINT32 getNrOfUsers ()
 
SINT32 getLevel (SINT32 *puser, SINT32 *prisk, SINT32 *ptraffic)
 
TermsAndConditionsgetTermsAndConditions (const UINT8 *opSki)
 
DOMNode * getTermsAndConditionsTemplate (UINT8 *templateRefID)
 
SINT32 getMixCount ()
 
tMixParametersgetMixParameters ()
 Returns the ordered list of the mix parameters from the first mix to the last mix. More...
 
SINT32 setMixParameters (const tMixParameters &params)
 Sets the parameters for the mix specified in the params.m_strMixID field. More...
 
SINT32 handleKeyInfoExtensions (DOMElement *root)
 
SINT32 handleTermsAndConditionsExtension (DOMElement *extensionRoot)
 
- Public Member Functions inherited from CAMixWithReplayDB
 CAMixWithReplayDB ()
 
CADatabasegetReplayDB () const
 
- Public Member Functions inherited from CAMix
 CAMix ()
 
virtual ~CAMix ()
 
SINT32 start ()
 
virtual bool isShutDown ()
 
SINT32 getMixCascadeInfo (XERCES_CPP_NAMESPACE::DOMDocument *&docMixCascadeInfo)
 Returns the Mix-Cascade info which should be send to the InfoService. More...
 
bool acceptsReconfiguration ()
 
CAControlChannelDispatchergetDownstreamControlChannelDispatcher () const
 
CAControlChannelDispatchergetUpstreamControlChannelDispatcher () const
 
UINT32 getLastConnectionTime ()
 
bool isConnected ()
 

Protected Member Functions

SINT32 loop ()
 
SINT32 closeConnection (fmHashTableEntry *pHashEntry)
 
- Protected Member Functions inherited from CAFirstMix
bool isShuttingDown ()
 
SINT32 init ()
 
SINT32 clean ()
 
virtual SINT32 initOnce ()
 
virtual SINT32 processKeyExchange ()
 
SINT32 initMixParameters (DOMElement *elemMixes)
 Initialises the MixParameters info for each mix form the <Mixes> element received from the second mix. More...
 
SINT32 incUsers (LP_fmHashTableEntry pHashEntry)
 
SINT32 decUsers (LP_fmHashTableEntry pHashEntry)
 
SINT32 incMixedPackets ()
 
SINT32 doUserLogin (CAMuxSocket *pNewUSer, UINT8 perrIP[4])
 
SINT32 reconfigure ()
 
SINT32 deleteCountryStats ()
 
- Protected Member Functions inherited from CAMix
SINT32 checkCompatibility (DOMNode *a_parent, const char *a_mixPosition)
 
SINT32 appendCompatibilityInfo (DOMNode *a_parent)
 
SINT32 addMixInfo (DOMNode *a_element, bool a_bForceFirstNode)
 
virtual SINT32 initMixCascadeInfo (DOMElement *elemMixes)
 This will initialize the XML Cascade Info struct XMLFirstMixToInfoService that is sent to the InfoService in CAInfoService::sendCascadeHelo() More...
 
SINT32 signXML (DOMNode *a_element)
 

Private Member Functions

bool sendToUsers ()
 
void notifyAllUserChannels (fmHashTableEntry *pfmHashEntry, UINT16 flags)
 
void finishPacket (fmHashTableEntry *pfmHashEntry)
 
void checkUserConnections ()
 
SINT32 accountTrafficUpstream (fmHashTableEntry *pHashEntry)
 
SINT32 accountTrafficDownstream (fmHashTableEntry *pfmHashEntry)
 

Friends

THREAD_RETURN fm_loopPacketProcessing (void *params)
 

Additional Inherited Members

- Public Types inherited from CAMix
enum  tMixType { FIRST_MIX , MIDDLE_MIX , LAST_MIX , JAP }
 
- Public Attributes inherited from CAFirstMix
UINT64 m_u64LastTimestampReceived
 
- Public Attributes inherited from CAMixWithReplayDB
UINT64 m_u64ReferenceTime
 
- Static Public Attributes inherited from CAMix
static const UINT32 TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT = 60000
 
- Protected Attributes inherited from CAFirstMix
CAIPListm_pIPList
 
CATempIPBlockListm_pIPBlockList
 
CAQueuem_pQueueSendToMix
 
CAQueuem_pQueueReadFromMix
 
volatile UINT32 m_nUser
 
UINT32 m_nSocketsIn
 
volatile bool m_bRestart
 
CASocket ** m_arrSocketsIn
 
UINT32 m_u32MixCount
 
tMixParametersm_arMixParameters
 
CAFirstMixChannelListm_pChannelList
 
CASocketGroupEpollm_psocketgroupUsersRead
 
CASocketGroupEpollm_psocketgroupUsersWrite
 
CAMuxSocketm_pMuxOut
 
UINT8m_xmlKeyInfoBuff
 
UINT16 m_xmlKeyInfoSize
 
XERCES_CPP_NAMESPACE::DOMDocument * m_docMixCascadeInfo
 
UINT64 m_nMixedPackets
 
CAASymCipherm_pRSA
 
CAMutexm_pmutexUser
 
CAMutexm_pmutexMixedPackets
 
CAMutexm_pmutexLoginThreads
 
CAThreadm_pthreadAcceptUsers
 
CAThreadPoolm_pthreadsLogin
 
CAThreadm_pthreadSendToMix
 
CAThreadm_pthreadReadFromMix
 
UINT32 m_nrOfTermsAndConditionsDefs
 
TermsAndConditions ** m_tnCDefs
 
UINT32 m_nrOfTermsAndConditionsTemplates
 
DOMNode ** m_tcTemplates
 
XERCES_CPP_NAMESPACE::DOMDocument * m_templatesOwner
 
const XMLCh * TNC_REQUEST
 
const XMLCh * TNC_CONFIRM
 
const XMLCh * TNC_INTERRUPT
 
tUINT32withLockm_PacketsPerCountryIN
 
tUINT32withLockm_PacketsPerCountryOUT
 
bool m_bIsShuttingDown
 
volatile bool m_bRunLog
 
CAMutexm_pmutexLogin
 
- Protected Attributes inherited from CAMixWithReplayDB
CADatabasem_pReplayDB
 
CAReplayCtrlChannelMsgProcm_pReplayMsgProc
 
- Protected Attributes inherited from CAMix
volatile bool m_bLoop
 
bool m_bReconfiguring
 
volatile bool m_bShutDown
 
CAMultiSignaturem_pMultiSignature
 
CAInfoServicem_pInfoService
 
UINT32 m_u32KeepAliveRecvInterval
 
UINT32 m_u32KeepAliveSendInterval
 
bool m_acceptReconfiguration
 
volatile bool m_bConnected
 
volatile UINT32 m_lLastConnectionTime
 
XERCES_CPP_NAMESPACE::DOMDocument * m_docMixCascadeInfo
 
CAControlChannelDispatcherm_pMuxOutControlChannelDispatcher
 
CAControlChannelDispatcherm_pMuxInControlChannelDispatcher
 

Detailed Description

Definition at line 38 of file CAFirstMixA.hpp.

Member Function Documentation

◆ accountTrafficDownstream()

SINT32 CAFirstMixA::accountTrafficDownstream ( fmHashTableEntry pfmHashEntry)
private

Definition at line 969 of file CAFirstMixA.cpp.

970 {
971  // count packet for payment
972  SINT32 ret = CAAccountingInstance::handleJapPacket(pfmHashEntry, !(pfmHashEntry->bCountPacket), true);
974  {
975  // renew the timeout
976  //pfmHashEntry->bRecoverTimeout = true;
977  m_pChannelList->pushTimeoutEntry(pfmHashEntry);
978  }
980  {
981  // when all control messages are sent the users connection will be closed
982  //pfmHashEntry->bRecoverTimeout = false;
984  //m_pChannelList->pushTimeoutEntry(pfmHashEntry);
985  }
987  {
988  // close users connection immediately
989  CAMsg::printMsg(LOG_DEBUG, "CAFirstMixA: Closing JAP connection due to illegal payment status!\n", ret);
990  closeConnection(pfmHashEntry);
992  }
993  //please remember that these values also may be returned even though they do not require
994  //any further processing
995  /*else if ( (ret == CAAccountingInstance::HANDLE_PACKET_CONNECTION_UNCHECKED) &&
996  (ret == CAAccountingInstance::HANDLE_PACKET_HOLD_CONNECTION) )
997  {
998 
999  }*/
1000  return E_SUCCESS;
1001 }
#define KICKOUT_FORCED
#define ERR_INTERN_SOCKET_CLOSED
Definition: StdAfx.h:477
signed int SINT32
Definition: basetypedefs.h:132
static const SINT32 HANDLE_PACKET_CONNECTION_OK
static const SINT32 HANDLE_PACKET_CLOSE_CONNECTION
static SINT32 handleJapPacket(fmHashTableEntry *pHashEntry, bool a_bControlMessage, bool a_bMessageToJAP)
This should be called by the FirstMix for every incoming Jap packet.
static const SINT32 HANDLE_PACKET_PREPARE_FOR_CLOSING_CONNECTION
SINT32 closeConnection(fmHashTableEntry *pHashEntry)
Definition: CAFirstMixA.cpp:85
void setKickoutForced(fmHashTableEntry *pHashTableEntry, bool kickoutForced)
SINT32 pushTimeoutEntry(fmHashTableEntry *pHashTableEntry, bool kickoutForced=!KICKOUT_FORCED)
adds the entry to the timeout queue with mutex
CAFirstMixChannelList * m_pChannelList
Definition: CAFirstMix.hpp:464
static SINT32 printMsg(UINT32 typ, const char *format,...)
Writes a given message to the log.
Definition: CAMsg.cpp:251
const SINT32 E_SUCCESS
Definition: errorcodes.hpp:2

References t_fmhashtableentry::bCountPacket, closeConnection(), E_SUCCESS, ERR_INTERN_SOCKET_CLOSED, CAAccountingInstance::HANDLE_PACKET_CLOSE_CONNECTION, CAAccountingInstance::HANDLE_PACKET_CONNECTION_OK, CAAccountingInstance::HANDLE_PACKET_PREPARE_FOR_CLOSING_CONNECTION, CAAccountingInstance::handleJapPacket(), KICKOUT_FORCED, CAFirstMix::m_pChannelList, CAMsg::printMsg(), CAFirstMixChannelList::pushTimeoutEntry(), and CAFirstMixChannelList::setKickoutForced().

Referenced by sendToUsers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ accountTrafficUpstream()

SINT32 CAFirstMixA::accountTrafficUpstream ( fmHashTableEntry pHashEntry)
private

Definition at line 928 of file CAFirstMixA.cpp.

929 {
930  SINT32 ret = E_SUCCESS;
931 
932  SINT32 handleResult = CAAccountingInstance::handleJapPacket(pHashEntry, false, false);
933 
935  {
936  // renew the timeout
937  //pHashEntry->bRecoverTimeout = true;
938  m_pChannelList->pushTimeoutEntry(pHashEntry);
939  }
941  {
942  // do not forward this packet
943  pHashEntry->bRecoverTimeout = false;
945  CAMsg::printMsg(LOG_DEBUG, "CAFirstMixA: 1. setting bRecover timout to false for entry %x!\n", pHashEntry);
946  //m_pChannelList->pushTimeoutEntry(pHashEntry);
947  //don't let any upstream data messages pass for this user.
948  ret = E_UNKNOWN;
949  }
951  {
952  // kickout this user - he deserves it...
953  CAMsg::printMsg(LOG_DEBUG, "CAFirstMixA: kickout upstream!\n");
954  closeConnection(pHashEntry);
955  ret = E_UNKNOWN;
956  }
957  //please remember that these values also may be returned even though they do not require
958  //any further processing
959  /*else if ( (ret == CAAccountingInstance::HANDLE_PACKET_CONNECTION_UNCHECKED) &&
960  (ret == CAAccountingInstance::HANDLE_PACKET_HOLD_CONNECTION) )
961  {
962 
963  }*/
964  return ret;
965 }
#define E_UNKNOWN
Definition: errorcodes.hpp:3

References t_fmhashtableentry::bRecoverTimeout, closeConnection(), E_SUCCESS, E_UNKNOWN, CAAccountingInstance::HANDLE_PACKET_CLOSE_CONNECTION, CAAccountingInstance::HANDLE_PACKET_CONNECTION_OK, CAAccountingInstance::HANDLE_PACKET_PREPARE_FOR_CLOSING_CONNECTION, CAAccountingInstance::handleJapPacket(), KICKOUT_FORCED, CAFirstMix::m_pChannelList, CAMsg::printMsg(), CAFirstMixChannelList::pushTimeoutEntry(), and CAFirstMixChannelList::setKickoutForced().

Referenced by loop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ checkUserConnections()

void CAFirstMixA::checkUserConnections ( )
private

Definition at line 1066 of file CAFirstMixA.cpp.

1067 {
1068  // check the timeout for all connections
1069  fmHashTableEntry* timeoutHashEntry;
1070  fmHashTableEntry* firstIteratorEntry = NULL;
1071  bool currentEntryKickoutForced = false;
1072  /* this check also includes forced kickouts which have not bRecoverTimeout set. */
1073  while ( (timeoutHashEntry = m_pChannelList->popTimeoutEntry(true)) != NULL )
1074  {
1075  currentEntryKickoutForced = m_pChannelList->isKickoutForced(timeoutHashEntry);
1076  if(firstIteratorEntry == timeoutHashEntry)
1077  {
1078  m_pChannelList->pushTimeoutEntry(timeoutHashEntry, currentEntryKickoutForced);
1079  break;
1080  }
1081 
1082  if (!currentEntryKickoutForced)
1083  {
1084  //CAMsg::printMsg(LOG_ERR, "%p\n, ", timeoutHashEntry);
1085  if(m_pChannelList->isTimedOut(timeoutHashEntry) )
1086  {
1087  CAMsg::printMsg(LOG_DEBUG,"Client connection closed due to timeout.\n");
1088  closeConnection(timeoutHashEntry);
1089  continue;
1090  }
1091  }
1092  else
1093  {
1094  //A user to be kicked out: empty his downstream data queue.
1095  timeoutHashEntry->pQueueSend->clean();
1096 
1097  if( (timeoutHashEntry->pControlMessageQueue->getSize() == 0) ||
1098  (timeoutHashEntry->kickoutSendRetries <= 0) )
1099  {
1100  CAMsg::printMsg(LOG_WARNING, "Kickout immediately owner %x!\n", timeoutHashEntry);
1101  UINT32 authFlags = CAAccountingInstance::getAuthFlags(timeoutHashEntry);
1102  if (authFlags > 0)
1103  {
1104  CAMsg::printMsg(LOG_WARNING,"Client connection closed due to forced timeout! Payment auth flags: %u\n", authFlags);
1105  }
1106  else
1107  {
1108  CAMsg::printMsg(LOG_WARNING,"Client connection closed due to forced timeout!\n");
1109  }
1110  //CAAccountingInstance::setPrepaidBytesToZero(timeoutHashEntry->pAccountingInfo);
1111  closeConnection(timeoutHashEntry);
1112  continue;
1113  }
1114  else
1115  {
1116  //Note this counter initialized by calling CAFirstMixChannelList::add
1117  //and accessed by this thread, both do never run concurrently.
1118  //So we can avoid locking.
1119  timeoutHashEntry->kickoutSendRetries--;
1120  CAMsg::printMsg(LOG_INFO, "Size of control message queue for user to be kicked out: %u bytes, retries %d.\n",
1121  timeoutHashEntry->pControlMessageQueue->getSize(), timeoutHashEntry->kickoutSendRetries);
1122  }
1123  // Let the client obtain all his remaining control message packets
1124  //(which in most cases contain the error message with the kickout reason.
1125  CAMsg::printMsg(LOG_WARNING,"A kickout is supposed to happen. Let the user get his %u control message bytes before...\n",
1126  timeoutHashEntry->pControlMessageQueue->getSize());
1127  }
1128  if(firstIteratorEntry == NULL)
1129  {
1130  firstIteratorEntry = timeoutHashEntry;
1131  }
1132  m_pChannelList->pushTimeoutEntry(timeoutHashEntry, currentEntryKickoutForced);
1133  }
1134 }
unsigned int UINT32
Definition: basetypedefs.h:131
static UINT32 getAuthFlags(fmHashTableEntry *pHashEntry)
bool isKickoutForced(fmHashTableEntry *pHashTableEntry)
bool isTimedOut(fmHashTableEntry *pHashTableEntry)
fmHashTableEntry * popTimeoutEntry()
SINT32 clean()
Removes any stored data from the Queue.
Definition: CAQueue.cpp:47
UINT32 getSize()
Returns the size of stored data in byte.
Definition: CAQueue.hpp:101

References CAQueue::clean(), closeConnection(), CAAccountingInstance::getAuthFlags(), CAQueue::getSize(), CAFirstMixChannelList::isKickoutForced(), CAFirstMixChannelList::isTimedOut(), t_fmhashtableentry::kickoutSendRetries, CAFirstMix::m_pChannelList, t_fmhashtableentry::pControlMessageQueue, CAFirstMixChannelList::popTimeoutEntry(), t_fmhashtableentry::pQueueSend, CAMsg::printMsg(), and CAFirstMixChannelList::pushTimeoutEntry().

Referenced by loop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ closeConnection()

SINT32 CAFirstMixA::closeConnection ( fmHashTableEntry pHashEntry)
protected

Definition at line 85 of file CAFirstMixA.cpp.

86 {
87  if (pHashEntry == NULL)
88  {
89  return E_UNKNOWN;
90  }
91 
92  INIT_STACK;
93  BEGIN_STACK("CAFirstMixA::closeConnection");
94 
95 
96  fmChannelListEntry* pEntry;
97  tQueueEntry* pQueueEntry = new tQueueEntry;
98  MIXPACKET* pMixPacket=&pQueueEntry->packet;
99 
100  #ifdef LOG_TRAFFIC_PER_USER
101  UINT64 current_time;
102  getcurrentTimeMillis(current_time);
103  CAMsg::printMsg(LOG_DEBUG,"Removing Connection wiht ID: %Lu -- login time [ms] %Lu -- logout time [ms] %Lu -- Traffic was: IN: %u -- OUT: %u\n",pHashEntry->id,pHashEntry->timeCreated,current_time,pHashEntry->trafficIn,pHashEntry->trafficOut);
104  #endif
105  m_pIPList->removeIP(pHashEntry->peerIP);
106 
107  m_psocketgroupUsersRead->remove(*(pHashEntry->pMuxSocket));
108  m_psocketgroupUsersWrite->remove(*(pHashEntry->pMuxSocket));
109  pEntry = m_pChannelList->getFirstChannelForSocket(pHashEntry->pMuxSocket);
110 
111  while(pEntry!=NULL)
112  {
113  getRandom(pMixPacket->data,DATA_SIZE);
114  pMixPacket->flags=CHANNEL_CLOSE;
115  pMixPacket->channel=pEntry->channelOut;
116  #ifdef LOG_PACKET_TIMES
117  setZero64(pQueueEntry->timestamp_proccessing_start);
118  #endif
119  m_pQueueSendToMix->add(pQueueEntry, sizeof(tQueueEntry));
120  delete pEntry->pCipher;
121  pEntry->pCipher = NULL;
122  pEntry=m_pChannelList->getNextChannel(pEntry);
123 #ifdef CH_LOG_STUDY
124  nrOfChOpMutex->lock();
125  currentOpenedChannels--;
126  nrOfChOpMutex->unlock();
127 #endif //CH_LOG_STUDY
128  }
129  ASSERT(pHashEntry->pQueueSend!=NULL,"Send queue is NULL");
130  delete pHashEntry->pQueueSend;
131  pHashEntry->pQueueSend = NULL;
132  delete pHashEntry->pSymCipher;
133  pHashEntry->pSymCipher = NULL;
134 
135  #ifdef COUNTRY_STATS
136  decUsers(pHashEntry);
137  #else
138  decUsers();
139  #endif
140 
141  CAMuxSocket* pMuxSocket = pHashEntry->pMuxSocket;
142  // Save the socket - its pointer will be deleted in this method!!! Crazy mad programming...
143  m_pChannelList->remove(pHashEntry->pMuxSocket);
144  delete pMuxSocket;
145  pMuxSocket = NULL;
146  //pHashEntry->pMuxSocket = NULL; // not needed now, but maybe in the future...
147 
148  delete pQueueEntry;
149  pQueueEntry = NULL;
150 
151  FINISH_STACK("CAFirstMixA::closeConnection");
152 
153  return E_SUCCESS;
154 }
#define INIT_STACK
Definition: CAThread.hpp:48
#define BEGIN_STACK(methodName)
Definition: CAThread.hpp:49
#define FINISH_STACK(methodName)
Definition: CAThread.hpp:50
SINT32 getcurrentTimeMillis(UINT64 &u64Time)
Gets the current Systemtime in milli seconds.
Definition: CAUtil.cpp:252
SINT32 getRandom(UINT32 *val)
Gets 32 random bits.
Definition: CAUtil.cpp:346
void setZero64(UINT64 &op1)
Definition: CAUtil.hpp:355
#define ASSERT(cond, msg)
Definition: StdAfx.h:546
fmChannelListEntry * getFirstChannelForSocket(CAMuxSocket *pMuxSocket)
Gets the first channel for a given connection.
fmChannelListEntry * getNextChannel(fmChannelListEntry *pEntry)
Gets the next channel for a given connection.
SINT32 remove(CAMuxSocket *pMuxSocket)
Removes all channels, which belongs to the given connection and the connection itself from the list.
CAQueue * m_pQueueSendToMix
Definition: CAFirstMix.hpp:448
CAIPList * m_pIPList
Definition: CAFirstMix.hpp:446
CASocketGroupEpoll * m_psocketgroupUsersWrite
Definition: CAFirstMix.hpp:467
CASocketGroupEpoll * m_psocketgroupUsersRead
Definition: CAFirstMix.hpp:466
SINT32 decUsers(LP_fmHashTableEntry pHashEntry)
Definition: CAFirstMix.hpp:415
SINT32 removeIP(const UINT8 ip[4])
Removes the IP-Address from the list.
Definition: CAIPList.cpp:189
SINT32 add(const void *buff, UINT32 size)
Adds data to the Queue.
Definition: CAQueue.cpp:76
SINT32 remove(CASocket &s)
HCHANNEL channel
Definition: typedefs.hpp:117
UINT8 data[DATA_SIZE]
Definition: typedefs.hpp:121
UINT16 flags
Definition: typedefs.hpp:118
CASymChannelCipher * pCipher
CASymChannelCipher * pSymCipher
Definition: typedefs.hpp:169
MIXPACKET packet
Definition: typedefs.hpp:170
#define CHANNEL_CLOSE
Definition: typedefs.hpp:47
struct t_queue_entry tQueueEntry
Definition: typedefs.hpp:188
#define DATA_SIZE
Definition: typedefs.hpp:69

References CAQueue::add(), ASSERT, BEGIN_STACK, t_MixPacket::channel, CHANNEL_CLOSE, t_firstmixchannellist::channelOut, t_MixPacket::data, DATA_SIZE, CAFirstMix::decUsers(), E_SUCCESS, E_UNKNOWN, FINISH_STACK, t_MixPacket::flags, getcurrentTimeMillis(), CAFirstMixChannelList::getFirstChannelForSocket(), CAFirstMixChannelList::getNextChannel(), getRandom(), t_fmhashtableentry::id, INIT_STACK, CAFirstMix::m_pChannelList, CAFirstMix::m_pIPList, CAFirstMix::m_pQueueSendToMix, CAFirstMix::m_psocketgroupUsersRead, CAFirstMix::m_psocketgroupUsersWrite, t_queue_entry::packet, t_firstmixchannellist::pCipher, t_fmhashtableentry::peerIP, t_fmhashtableentry::pMuxSocket, t_fmhashtableentry::pQueueSend, CAMsg::printMsg(), t_fmhashtableentry::pSymCipher, CAFirstMixChannelList::remove(), CASocketGroupEpoll::remove(), CAIPList::removeIP(), and setZero64().

Referenced by accountTrafficDownstream(), accountTrafficUpstream(), checkUserConnections(), loop(), sendToUsers(), and shutDown().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ finishPacket()

void CAFirstMixA::finishPacket ( fmHashTableEntry pfmHashEntry)
private

Definition at line 1036 of file CAFirstMixA.cpp.

1037 {
1038  tQueueEntry *packetToSend = &(pfmHashEntry->oQueueEntry);
1039  fmChannelList* cListEntry=m_pChannelList->get(packetToSend->packet.channel);
1040  if(cListEntry != NULL)
1041  {
1042  packetToSend->packet.channel = cListEntry->channelIn;
1043  cListEntry->downStreamBytes -= sizeof(tQueueEntry);
1044 #ifdef DEBUG
1045  CAMsg::printMsg(LOG_DEBUG, "CAFirstMixA: channels of current packet, in: %u, out: %u, count: %u, flags: 0x%x\n",
1046  cListEntry->channelIn, cListEntry->channelOut, cListEntry->downStreamBytes,
1047  packetToSend->packet.flags);
1048 #endif
1049  if(packetToSend->packet.flags == CHANNEL_CLOSE)
1050  {
1051  delete cListEntry->pCipher;
1052  cListEntry->pCipher = NULL;
1053  m_pChannelList->removeChannel(pfmHashEntry->pMuxSocket, cListEntry->channelIn);
1054 #ifdef CH_LOG_STUDY
1055  nrOfChOpMutex->lock();
1056  currentOpenedChannels--;
1057  nrOfChOpMutex->unlock();
1058 #endif //CH_LOG_STUDY
1059  }
1060  }
1061 }
fmChannelListEntry * get(CAMuxSocket *pMuxSocket, HCHANNEL channelIn)
Returns the information for a given Input-Channel-ID.
SINT32 removeChannel(CAMuxSocket *pMuxSocket, HCHANNEL channelIn)
Removes a single channel from the list.

References t_MixPacket::channel, CHANNEL_CLOSE, t_firstmixchannellist::channelIn, t_firstmixchannellist::channelOut, t_MixPacket::flags, CAFirstMixChannelList::get(), CAFirstMix::m_pChannelList, t_fmhashtableentry::oQueueEntry, t_queue_entry::packet, t_firstmixchannellist::pCipher, t_fmhashtableentry::pMuxSocket, CAMsg::printMsg(), and CAFirstMixChannelList::removeChannel().

Referenced by sendToUsers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ loop()

SINT32 CAFirstMixA::loop ( )
protectedvirtual
Todo:
check if thread is closed

Implements CAFirstMix.

Definition at line 158 of file CAFirstMixA.cpp.

159  {
160 #ifndef NEW_MIX_TYPE
161 #ifdef DELAY_USERS
162  m_pChannelList->setDelayParameters( CALibProxytest::getOptions()->getDelayChannelUnlimitTraffic(),
163  CALibProxytest::getOptions()->getDelayChannelBucketGrow(),
164  CALibProxytest::getOptions()->getDelayChannelBucketGrowIntervall());
165 #endif
166 
167  // CASingleSocketGroup osocketgroupMixOut;
168  SINT32 countRead=0;
169  //#ifdef LOG_PACKET_TIMES
170  // tPoolEntry* pPoolEntry=new tPoolEntry;
171  // MIXPACKET* pMixPacket=&pPoolEntry->mixpacket;
172  //#else
173  tQueueEntry* pQueueEntry = new tQueueEntry;
174  MIXPACKET* pMixPacket=&pQueueEntry->packet;
175  //#endif
176  m_nUser=0;
177  SINT32 ret;
178  //osocketgroupMixOut.add(*m_pMuxOut);
179 
180  UINT8* tmpBuff=new UINT8[sizeof(tQueueEntry)];
181  CAMsg::printMsg(LOG_DEBUG,"Starting Message Loop... \n");
182  bool bAktiv;
183  UINT8 rsaBuff[RSA_SIZE];
184 
185 #ifdef LOG_TRAFFIC_PER_USER
186  UINT64 current_time;
187  UINT32 diff_time;
188  CAMsg::printMsg(LOG_DEBUG,"Channel log formats:\n");
189  CAMsg::printMsg(LOG_DEBUG,"1. Close received from user (times in micros) - 1:Channel-ID,Connection-ID,Channel open timestamp (microseconds),PacketsIn (only data and open),PacketsOut (only data),ChannelDuration (open packet received --> close packet put into send queue to next mix)\n");
190  CAMsg::printMsg(LOG_DEBUG,"2. Channel close from Mix(times in micros)- 2.:Channel-ID,Connection-ID,Channel open timestamp (microseconds),PacketsIn (only data and open), PacketsOut (only data),ChannelDuration (open packet received)--> close packet put into send queue to next user\n");
191 #endif
193 #ifdef _DEBUG
194  CAThread* pLogThread=new CAThread((UINT8*)"CAFirstMixA - LogLoop");
195  pLogThread->setMainLoop(fm_loopLog);
196  pLogThread->start(this);
197 #endif
198 
199 #ifdef LOG_CRIME
200  CAIPAddrWithNetmask* surveillanceIPs = CALibProxytest::getOptions()->getCrimeSurveillanceIPs();
201  UINT32 nrOfSurveillanceIPs = CALibProxytest::getOptions()->getNrOfCrimeSurveillanceIPs();
202 #endif
203 // CAThread threadReadFromUsers;
204 // threadReadFromUsers.setMainLoop(loopReadFromUsers);
205 // threadReadFromUsers.start(this);
206 
207  while(!m_bRestart) /* the main mix loop as long as there are things that are not handled by threads. */
208  {
209 
210  bAktiv=false;
211 
212 //LOOP_START:
213 #ifdef PAYMENT
214  // while checking if there are connections to close: synch with login threads
215  m_pmutexLogin->lock();
218 #endif
219 //First Step
220 //Checking for new connections
221 // Now in a separate Thread....
222 
223 // Second Step
224 // Checking for data from users
225 // Now in a separate Thread (see loopReadFromUsers())
226 //Only proccess user data, if queue to next mix is not to long!!
227 
229  {
230  countRead=m_psocketgroupUsersRead->select(/*false,*/0); // how many JAP<->mix connections have received data from their coresponding JAP
231  if(countRead>0)
232  bAktiv=true;
233 #ifdef HAVE_EPOLL
234  //if we have epoll we do not need to search the whole list
235  //of connected JAPs to find the ones who have sent data
236  //as epoll will return ONLY these connections.
238  while(pHashEntry!=NULL)
239  {
240  CAMuxSocket* pMuxSocket=pHashEntry->pMuxSocket;
241 #else
242  //if we do not have epoll we have to go to the whole
243  //list of open connections to find the ones which
244  //actually have sent some data
246  while(pHashEntry!=NULL&&countRead>0) // iterate through all connections as long as there is at least one active left
247  {
248  CAMuxSocket* pMuxSocket=pHashEntry->pMuxSocket;
249  if(m_psocketgroupUsersRead->isSignaled(*pMuxSocket)) // if this one seems to have data
250  {
251 #endif
252 /*#ifdef DELAY_USERS
253  * Don't delay upstream
254  if( m_pChannelList->hasDelayBuckets(pHashEntry->delayBucketID) )
255  {
256 #endif*/
257  countRead--;
258  ret=pMuxSocket->receive(pMixPacket,0);
259 
260  #if defined LOG_PACKET_TIMES||defined(LOG_CHANNEL)
261  getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_start);
262  set64(pQueueEntry->timestamp_proccessing_start_OP,pQueueEntry->timestamp_proccessing_start);
263  #endif
264  #ifdef DATA_RETENTION_LOG
265  pQueueEntry->dataRetentionLogEntry.t_in=htonl(time(NULL));
266  #endif
267  if(ret<0&&ret!=E_AGAIN/*||pHashEntry->accessUntil<time()*/)
268  {
269  // remove dead connections
270  closeConnection(pHashEntry);
271  }
272  else if(ret==MIXPACKET_SIZE) // we've read enough data for a whole mix packet. nice!
273  {
274 #ifdef PAYMENT
275  if (pHashEntry->bRecoverTimeout)
276  {
277  // renew the timeout only if recovery is allowed
278  m_pChannelList->pushTimeoutEntry(pHashEntry);
279  }
280 #endif
281  #ifdef LOG_TRAFFIC_PER_USER
282  pHashEntry->trafficIn++;
283  #endif
284  #ifdef COUNTRY_STATS
285  m_PacketsPerCountryIN[pHashEntry->countryID].inc();
286  #endif
287  //New control channel code...!
288  if(pMixPacket->channel>0&&pMixPacket->channel<256)
289  {
290  if (pHashEntry->pControlChannelDispatcher->proccessMixPacket(pMixPacket))
291  {
292  goto NEXT_USER;
293  }
294  else
295  {
296  CAMsg::printMsg(LOG_DEBUG, "Control channel packet is invalid and could not be processed!\n");
297  closeConnection(pHashEntry);
298  goto NEXT_USER;
299  }
300  }
301 #ifdef ANON_DEBUG_MODE
302  bool bIsDebugPacket=false;
303  if (pMixPacket->flags&CHANNEL_DEBUG)
304  {
305  bIsDebugPacket=true;
306  UINT8 base64Payload[DATA_SIZE << 1];
307  EVP_EncodeBlock(base64Payload, pMixPacket->data, DATA_SIZE);//base64 encoding (without newline!)
308  pMixPacket->flags &= ~CHANNEL_DEBUG;
309  CAMsg::printMsg(LOG_DEBUG, "AN.ON packet debug: %s\n", base64Payload);
310  }
311 
312 #endif
313 #ifdef PAYMENT
314  if(accountTrafficUpstream(pHashEntry) != E_SUCCESS) goto NEXT_USER;
315 #endif
316  if(pMixPacket->flags==CHANNEL_DUMMY) // just a dummy to keep the connection alife in e.g. NAT gateways
317  {
318  CAMsg::printMsg(LOG_DEBUG,"received dummy traffic\n");
319  getRandom(pMixPacket->data,DATA_SIZE);
320  #ifdef LOG_PACKET_TIMES
321  setZero64(pQueueEntry->timestamp_proccessing_start);
322  #endif
323  #ifdef LOG_TRAFFIC_PER_USER
324  pHashEntry->trafficOut++;
325  #endif
326  #ifdef COUNTRY_STATS
327  m_PacketsPerCountryOUT[pHashEntry->countryID].inc();
328  #endif
329  pHashEntry->pQueueSend->add(pQueueEntry,sizeof(tQueueEntry));
330  #ifdef HAVE_EPOLL
331  //m_psocketgroupUsersWrite->add(*pMuxSocket,pHashEntry);
332  #else
333  m_psocketgroupUsersWrite->add(*pMuxSocket);
334  #endif
335  }
336  else if(pMixPacket->flags==CHANNEL_CLOSE) // closing one mix-channel (not the JAP<->mix connection!)
337  {
338  fmChannelListEntry* pEntry;
339  pEntry=m_pChannelList->get(pMuxSocket,pMixPacket->channel);
340  if(pEntry!=NULL)
341  {
342  pMixPacket->channel=pEntry->channelOut;
343  getRandom(pMixPacket->data,DATA_SIZE);
344  #ifdef LOG_PACKET_TIMES
345  getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end_OP);
346  #endif
347  m_pQueueSendToMix->add(pQueueEntry, sizeof(tQueueEntry));
348  /* Don't delay upstream
349  #ifdef DELAY_USERS
350  m_pChannelList->decDelayBuckets(pHashEntry->delayBucketID);
351  #endif*/
352  #ifdef LOG_CHANNEL
353  //pEntry->packetsInFromUser++;
354  getcurrentTimeMicros(current_time);
355  diff_time=diff64(current_time,pEntry->timeCreated);
356  CAMsg::printMsg(LOG_DEBUG,"1:%u,%Lu,%Lu,%u,%u,%u\n",
357  pEntry->channelIn,pEntry->pHead->id,pEntry->timeCreated,pEntry->packetsInFromUser,pEntry->packetsOutToUser,
358  diff_time);
359  #endif
360  delete pEntry->pCipher; // forget the symetric key of this connection
361  pEntry->pCipher = NULL;
362  m_pChannelList->removeChannel(pMuxSocket,pEntry->channelIn);
363 
364  #ifdef CH_LOG_STUDY
365  nrOfChOpMutex->lock();
366  currentOpenedChannels--;
367  nrOfChOpMutex->unlock();
368  #endif //CH_LOG_STUDY
369  }
370  #ifdef _DEBUG
371  else
372  {
373 // CAMsg::printMsg(LOG_DEBUG,"Invalid ID to close from Browser!\n");
374  }
375  #endif
376  }
377  else // finally! a normal mix packet
378  {
379  CASymChannelCipher* pCipher=NULL;
380  fmChannelListEntry* pEntry;
381  pEntry=m_pChannelList->get(pMuxSocket,pMixPacket->channel);
382  if (pEntry != NULL&&pMixPacket->flags == CHANNEL_DATA)
383  {
384  pMixPacket->channel = pEntry->channelOut;
385  pCipher = pEntry->pCipher;
386  pCipher->crypt1(pMixPacket->data, pMixPacket->data, DATA_SIZE);
387  // queue the packet for sending to the next mix.
388 #ifdef LOG_PACKET_TIMES
389  getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end_OP);
390 #endif
391 
392  //check if this IP must be logged due to crime detection
393 #ifdef LOG_CRIME
394  crimeSurveillance(surveillanceIPs, nrOfSurveillanceIPs, pEntry->pHead->peerIP,pEntry->pHead->peerPort, pMixPacket);
395 #endif
396 #ifdef ANON_DEBUG_MODE
397  if(bIsDebugPacket)
398  {
399  pMixPacket->flags|=CHANNEL_DEBUG;
400  }
401  #endif
402  m_pQueueSendToMix->add(pQueueEntry, sizeof(tQueueEntry));
403  /* Don't delay upstream
404  #ifdef DELAY_USERS
405  m_pChannelList->decDelayBuckets(pHashEntry->delayBucketID);
406  #endif*/
407  incMixedPackets();
408  #ifdef LOG_CHANNEL
409  pEntry->packetsInFromUser++;
410  #endif
411  }
412  else if(pEntry==NULL&&pMixPacket->flags==CHANNEL_OPEN) // open a new mix channel
413  { // stefan: muesste das nicht vor die behandlung von CHANNEL_DATA? oder gilt OPEN => !DATA ?
414  //es gilt: open -> data
415 
416  //log symcrypto
417  //UINT8* tmpstr=bytes2hex(pMixPacket->data, DATA_SIZE);
418  //CAMsg::printMsg(LOG_DEBUG, "Plain Packet recevied form user: %s\n", tmpstr);
419  //delete tmpstr;
420  //tmpstr = NULL;
421  //end log symcrpyto
422 
423 
424  pHashEntry->pSymCipher->crypt1(pMixPacket->data,rsaBuff,FIRST_MIX_SIZE_OF_SYMMETRIC_KEYS);
425  #ifdef REPLAY_DETECTION
426  // replace time(NULL) with the real timestamp ()
427  // packet-timestamp*REPLAY_BASE + m_u64ReferenceTime
428  if(m_pReplayDB->insert(rsaBuff,time(NULL))!=E_SUCCESS)
429  {
430  CAMsg::printMsg(LOG_INFO,"Replay: Duplicate packet ignored.\n");
431  continue;
432  }
433  #endif
434 
435 
436 
437  pCipher= CASymChannelCipherFactory::createCipher(CALibProxytest::getOptions()->getSymChannelCipherAlgorithm());
438  pCipher->setKeys(rsaBuff,FIRST_MIX_SIZE_OF_SYMMETRIC_KEYS);
439  for(int i=0;i<16;i++)
440  rsaBuff[i]=0xFF;
441  pCipher->setIV2(rsaBuff);
444  #if defined (LOG_CHANNEL) ||defined(DATA_RETENTION_LOG)
445  HCHANNEL tmpC=pMixPacket->channel;
446  #endif
447 #if defined LOG_CRIME || defined _DEBUG
448  HCHANNEL inChannel = pMixPacket->channel;
449 #endif
450  if(m_pChannelList->addChannel(pMuxSocket,pMixPacket->channel,pCipher,&pMixPacket->channel)!=E_SUCCESS)
451  { //todo move up ?
452  delete pCipher;
453  pCipher = NULL;
454  }
455  else
456  {
457  #ifdef CH_LOG_STUDY
458  nrOfChOpMutex->lock();
459  if(pHashEntry->channelOpenedLastIntervalTS !=
460  lastLogTime)
461  {
462  pHashEntry->channelOpenedLastIntervalTS =
463  lastLogTime;
464  nrOfOpenedChannels++;
465  }
466  currentOpenedChannels++;
467  nrOfChOpMutex->unlock();
468  #endif //CH_LOG_STUDY
469 
470  #ifdef LOG_PACKET_TIMES
471  getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end_OP);
472  #endif
473  #ifdef LOG_CHANNEL
474  fmChannelListEntry* pTmpEntry=m_pChannelList->get(pMuxSocket,tmpC);
475  pTmpEntry->packetsInFromUser++;
476  set64(pTmpEntry->timeCreated,pQueueEntry->timestamp_proccessing_start);
477  #endif
478  #ifdef DATA_RETENTION_LOG
479  pQueueEntry->dataRetentionLogEntry.entity.first.channelid=htonl(pMixPacket->channel);
480  fmChannelListEntry* pTmpEntry1=m_pChannelList->get(pMuxSocket,tmpC);
481  memcpy(pQueueEntry->dataRetentionLogEntry.entity.first.ip_in,pTmpEntry1->pHead->peerIP,4);
482  pQueueEntry->dataRetentionLogEntry.entity.first.port_in=(UINT16)pTmpEntry1->pHead->peerPort;
483  pQueueEntry->dataRetentionLogEntry.entity.first.port_in=htons(pQueueEntry->dataRetentionLogEntry.entity.first.port_in);
484  #endif
485 
486  //check if this IP must be logged due to crime detection
487  #ifdef LOG_CRIME
488 
489  pEntry=m_pChannelList->get(pMuxSocket, inChannel);
490  if(pEntry != NULL)
491  {
492  crimeSurveillance(surveillanceIPs, nrOfSurveillanceIPs, pEntry->pHead->peerIP,pEntry->pHead->peerPort, pMixPacket);
493  }
494  #endif
495 #ifdef ANON_DEBUG_MODE
496  if (bIsDebugPacket)
497  {
498  pMixPacket->flags |= CHANNEL_DEBUG;
499  pEntry = m_pChannelList->get(pMuxSocket, inChannel);
500  pEntry->bDebug = true;
501  }
502 #endif
503  //log symcrypto
504  //tmpstr=bytes2hex(pMixPacket->data, DATA_SIZE);
505  //CAMsg::printMsg(LOG_DEBUG, "Plain Packet sent to next mix: %s\n", tmpstr);
506  //delete tmpstr;
507  //end log symcrpyto
508 
509  m_pQueueSendToMix->add(pQueueEntry, sizeof(tQueueEntry));
510  /* Don't delay upstream
511  #ifdef DELAY_USERS
512  m_pChannelList->decDelayBuckets(pHashEntry->delayBucketID);
513  #endif*/
514  incMixedPackets();
515  #ifdef _DEBUG
516  CAMsg::printMsg(LOG_DEBUG,"Added out channel: %u for in channel: %u\n",pMixPacket->channel,inChannel);
517  #endif
518  }
519  }
520  }
521  }
522 /*#ifdef DELAY_USERS
523  }
524 #endif*/
525  #ifdef HAVE_EPOLL
526 NEXT_USER:
528  #else
529  }//if is signaled
530 NEXT_USER:
531  pHashEntry=m_pChannelList->getNext();
532  #endif
533  }
534  if(countRead>0)
535  {
536  CAMsg::printMsg(LOG_DEBUG,"CAFirstMixA::loop() - read from user --> countRead >0 after processing all connections!\n");
537  }
538  }
539 //Third step
540 //Sending to next mix
541 
542 // Now in a separate Thread (see loopSendToMix())
543 
544 //Step 4
545 //Step 4a Receiving from mix to queue now in a separate thread
546 //Step 4b Processing MixPackets received from Mix
547 //todo check for error!!!
548  countRead=m_nUser+1;
549  while(countRead>0&&m_pQueueReadFromMix->getSize()>=sizeof(tQueueEntry))
550  {
551  bAktiv=true;
552  countRead--;
553  ret=sizeof(tQueueEntry);
554  m_pQueueReadFromMix->get((UINT8*)pQueueEntry,(UINT32*)&ret);
555 
556  #ifdef LOG_PACKET_TIMES
557  getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_start_OP);
558  #endif
559 #ifdef ANON_DEBUG_MODE
560  if (pMixPacket->flags&CHANNEL_DEBUG)
561  {
562  UINT8 base64Payload[DATA_SIZE << 1];
563  EVP_EncodeBlock(base64Payload, pMixPacket->data, DATA_SIZE);//base64 encoding (without newline!)
564  CAMsg::printMsg(LOG_DEBUG, "Dequeued Downstream AN.ON packet from previous Mix debug: %s\n", base64Payload);
565  pMixPacket->flags &= ~CHANNEL_DEBUG;
566  }
567 
568 #endif
569 
570  if(pMixPacket->flags==CHANNEL_CLOSE) //close event
571  {
572  #if defined(_DEBUG) && !defined(__MIX_TEST)
573 // CAMsg::printMsg(LOG_DEBUG,"Closing Channel: %u ...\n",pMixPacket->channel);
574  #endif
575  fmChannelList* pEntry=m_pChannelList->get(pMixPacket->channel);
576  if(pEntry!=NULL)
577  {
578  /* a hack to solve the SSL problem:
579  * set channel of downstream packet to in channel after they are dequeued
580  * from pEntry->pQueueSend so we can retrieve the channel entry to decrement
581  * the per channel count of enqueued downstream bytes.
582  */
583  #ifndef SSL_HACK
584  pMixPacket->channel=pEntry->channelIn;
585  #endif
586 
587  pEntry->pCipher->crypt2(pMixPacket->data,pMixPacket->data,DATA_SIZE);
588  //getRandom(pMixPacket->data,DATA_SIZE);
589  #ifdef LOG_PACKET_TIMES
590  getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end_OP);
591  #endif
592  pEntry->pHead->pQueueSend->add(pQueueEntry, sizeof(tQueueEntry));
593  #ifdef LOG_TRAFFIC_PER_USER
594  pEntry->pHead->trafficOut++;
595  #endif
596  #ifdef COUNTRY_STATS
598  #endif
599  #ifdef SSL_HACK
600  /* a hack to solve the SSL problem:
601  * per channel count of enqueued downstream bytes
602  */
603  pEntry->downStreamBytes += sizeof(tQueueEntry);
604  #endif
605  #ifdef LOG_CHANNEL
606  pEntry->packetsOutToUser++;
607  getcurrentTimeMicros(current_time);
608  diff_time=diff64(current_time,pEntry->timeCreated);
609  CAMsg::printMsg(LOG_DEBUG,"2:%u,%Lu,%Lu,%u,%u,%u\n",
610  pEntry->channelIn,pEntry->pHead->id,pEntry->timeCreated,pEntry->packetsInFromUser,pEntry->packetsOutToUser,
611  diff_time);
612  #endif
613 
614  #ifdef HAVE_EPOLL
615  //m_psocketgroupUsersWrite->add(*pEntry->pHead->pMuxSocket,pEntry->pHead);
616  #else
618  #endif
619 
620 
621  #ifndef SSL_HACK
622  delete pEntry->pCipher; // forget the symetric key of this connection
623  pEntry->pCipher = NULL;
625  #ifdef CH_LOG_STUDY
626  nrOfChOpMutex->lock();
627  currentOpenedChannels--;
628  nrOfChOpMutex->unlock();
629  #endif
630  /* a hack to solve the SSL problem:
631  * remove channel after the close packet is enqueued
632  * from pEntry->pQueueSend
633  */
634  #endif
635  }
636  else
637  {
638  #ifdef DEBUG
639  CAMsg::printMsg(LOG_DEBUG, "CAFirstMixA: close channel -> client but channel does not exist.\n");
640  #endif
641  }
642 
643  }
644  else
645  {//flag !=close
646  #if defined(_DEBUG) && !defined(__MIX_TEST)
647 // CAMsg::printMsg(LOG_DEBUG,"Sending Data to Browser!\n");
648  #endif
649  fmChannelList* pEntry=m_pChannelList->get(pMixPacket->channel);
650 
651  if(pEntry!=NULL)
652  {
653  #ifdef LOG_CRIME
654  if((pMixPacket->flags&CHANNEL_SIG_CRIME)==CHANNEL_SIG_CRIME)
655  {
656  //UINT32 id=(pMixPacket->flags>>8)&0x000000FF;
657  int log=LOG_ENCRYPTED;
658  if(!CALibProxytest::getOptions()->isEncryptedLogEnabled())
659  log=LOG_CRIT;
660  CAMsg::printMsg(log,"Detecting crime activity - next mix channel: %u -- "
661  "Incoming (User) IP:Port is: %u.%u.%u.%u:%u \n", pMixPacket->channel,
662  pEntry->pHead->peerIP[0],
663  pEntry->pHead->peerIP[1],
664  pEntry->pHead->peerIP[2],
665  pEntry->pHead->peerIP[3],
666  pEntry->pHead->peerPort);
667  continue;
668  }
669  #endif
670 
671  /* a hack to solve the SSL problem:
672  * same as CHANNEL_CLOSE packets
673  */
674  #ifndef SSL_HACK
675  pMixPacket->channel=pEntry->channelIn;
676  #endif
677 
678  pEntry->pCipher->crypt2(pMixPacket->data,pMixPacket->data,DATA_SIZE);
679 
680  #ifdef LOG_PACKET_TIMES
681  getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end_OP);
682  #endif
683 #ifdef ANON_DEBUG_MODE
684  if (pEntry->bDebug)
685  {
686  pMixPacket->flags |= CHANNEL_DEBUG;
687  UINT8 base64Payload[DATA_SIZE << 1];
688  EVP_EncodeBlock(base64Payload, pMixPacket->data, DATA_SIZE);//base64 encoding (without newline!)
689  CAMsg::printMsg(LOG_DEBUG, "Send Dowwstream AN.ON packet debug: %s\n", base64Payload);
690  }
691 
692 #endif
693  pEntry->pHead->pQueueSend->add(pQueueEntry, sizeof(tQueueEntry));
694  /*CAMsg::printMsg(
695  LOG_INFO,"adding data packet to queue: %x, queue size: %u bytes\n",
696  pEntry->pHead->pQueueSend, pEntry->pHead->pQueueSend->getSize());*/
697  #ifdef LOG_TRAFFIC_PER_USER
698  pEntry->pHead->trafficOut++;
699  #endif
700  #ifdef COUNTRY_STATS
702  #endif
703  #ifdef LOG_CHANNEL
704  pEntry->packetsOutToUser++;
705  #endif
706  #ifdef SSL_HACK
707  /* a hack to solve the SSL problem:
708  * per channel count of downstream packets in bytes
709  */
710  pEntry->downStreamBytes += sizeof(tQueueEntry);
711  #endif
712 
713  #ifdef HAVE_EPOLL
714  /*int epret = m_psocketgroupUsersWrite->add(*pEntry->pHead->pMuxSocket,pEntry->pHead);
715  if(epret == E_UNKNOWN)
716  {
717  epret=errno;
718  CAMsg::printMsg(LOG_INFO,"epoll_add returns: %s (return value: %d) \n", strerror(epret), epret);
719  }*/
720  #else
722  #endif
723 
724  incMixedPackets();
725  }
726  else
727  {
728  #ifdef _DEBUG
729  if(pMixPacket->flags!=CHANNEL_DUMMY)
730  {
731 /* CAMsg::printMsg(LOG_DEBUG,"Error Sending Data to Browser -- "
732  "Channel-Id %u not valid!\n",pMixPacket->channel
733  );*/
734  #ifdef LOG_CHANNEL
735  CAMsg::printMsg(LOG_INFO,"Packet late arrive for channel: %u\n",pMixPacket->channel);
736  #endif
737  }
738  #endif
739  }
740  }
741  }
742 
745  bAktiv = sendToUsers();
746 #ifndef FAST_PROCESSING
747  if(!bAktiv)
748  msSleep(1);
749 #endif
750  }
751 //ERR:
752  CAMsg::printMsg(LOG_CRIT,"Seems that we are restarting now!!\n");
753  m_bRunLog=false;
754  clean();
755  delete pQueueEntry;
756  pQueueEntry = NULL;
757  delete []tmpBuff;
758  tmpBuff = NULL;
759 #ifdef _DEBUG
760  pLogThread->join();
761  delete pLogThread;
762  pLogThread = NULL;
763 #endif
764  CAMsg::printMsg(LOG_CRIT,"Main Loop exited!!\n");
765 #endif//NEW_MIX_TYPE
766  return E_UNKNOWN;
767  }
#define RSA_SIZE
#define FIRST_MIX_SIZE_OF_SYMMETRIC_KEYS
#define LOG_ENCRYPTED
Definition: CAMsg.hpp:46
SINT32 getcurrentTimeMicros(UINT64 &u64Time)
Gets the current Systemtime in micros seconds.
Definition: CAUtil.cpp:280
SINT32 msSleep(UINT32 ms)
Sleeps ms milliseconds.
Definition: CAUtil.cpp:406
UINT32 diff64(const UINT64 &bigop, const UINT64 &smallop)
Definition: CAUtil.hpp:398
void set64(UINT64 &op1, UINT32 op2)
Definition: CAUtil.hpp:321
#define MAX_NEXT_MIX_QUEUE_SIZE
Definition: StdAfx.h:229
unsigned short UINT16
Definition: basetypedefs.h:133
unsigned char UINT8
Definition: basetypedefs.h:135
bool proccessMixPacket(const MIXPACKET *pPacket)
SINT32 insert(UINT8 key[16], UINT64 timestamp)
Inserts this key in the replay DB.
Definition: CADatabase.cpp:93
void checkUserConnections()
bool sendToUsers()
SINT32 accountTrafficUpstream(fmHashTableEntry *pHashEntry)
void setDelayParameters(UINT32 unlimitTraffic, UINT32 bucketGrow, UINT32 intervall)
fmHashTableEntry * getFirst()
Gets the first connection of all connections in the list.
SINT32 addChannel(CAMuxSocket *pMuxSocket, HCHANNEL channelIn, CASymChannelCipher *pCipher, HCHANNEL *channelOut)
Adds a new channel for a given connection to the channel list.
fmHashTableEntry * getNext()
Gets the next entry in the connections-list.
SINT32 incMixedPackets()
Definition: CAFirstMix.hpp:427
volatile bool m_bRestart
Definition: CAFirstMix.hpp:456
volatile bool m_bRunLog
Definition: CAFirstMix.hpp:552
friend THREAD_RETURN fm_loopLog(void *)
volatile UINT32 m_nUser
Definition: CAFirstMix.hpp:454
CAMutex * m_pmutexLogin
Definition: CAFirstMix.hpp:555
tUINT32withLock * m_PacketsPerCountryOUT
Definition: CAFirstMix.hpp:537
tUINT32withLock * m_PacketsPerCountryIN
Definition: CAFirstMix.hpp:536
SINT32 clean()
CAQueue * m_pQueueReadFromMix
Definition: CAFirstMix.hpp:449
static CACmdLnOptions * getOptions()
SINT32 lock()
Locks the lockable object by threadsafe incrementing a reference counter.
Definition: CALockAble.hpp:55
CADatabase * m_pReplayDB
SINT32 unlock()
Definition: CAMutex.hpp:52
SINT32 lock()
Definition: CAMutex.hpp:41
SINT32 receive(MIXPACKET *pPacket)
Receives a whole MixPacket.
SINT32 get(UINT8 *pbuff, UINT32 *psize)
Gets up to psize number of bytes from the Queue.
Definition: CAQueue.cpp:148
bool isSignaled(CASocket &s)
SINT32 add(CASocket &s)
Adds the socket s to the socket group.
static CASymChannelCipher * createCipher(SYMCHANNELCIPHER_ALGORITHM alg)
virtual SINT32 setKeys(const UINT8 *key, UINT32 keysize)=0
Sets the keys for crypt1() and crypt2() either to the same key (if keysize==KEY_SIZE) or to different...
virtual SINT32 setIV2(const UINT8 *p_iv)=0
Sets iv2 to p_iv.
virtual SINT32 crypt2(const UINT8 *in, UINT8 *out, UINT32 len)=0
virtual SINT32 crypt1(const UINT8 *in, UINT8 *out, UINT32 len)=0
SINT32 start(void *param, bool bDaemon=false, bool bSilent=false)
Starts the execution of the main function of this thread.
Definition: CAThread.cpp:115
SINT32 setMainLoop(THREAD_MAIN_TYP fnc)
Sets the main function which will be executed within this thread.
Definition: CAThread.hpp:148
SINT32 join()
Waits for the main function to finish execution.
Definition: CAThread.cpp:187
CAControlChannelDispatcher * pControlChannelDispatcher
#define CHANNEL_DATA
Definition: typedefs.hpp:42
#define MIXPACKET_SIZE
Definition: typedefs.hpp:40
#define CHANNEL_DEBUG
Definition: typedefs.hpp:51
#define CHANNEL_DUMMY
Definition: typedefs.hpp:50
UINT32 HCHANNEL
Definition: typedefs.hpp:34
#define CHANNEL_SIG_CRIME
Definition: typedefs.hpp:58
#define CHANNEL_OPEN
Definition: typedefs.hpp:43

References accountTrafficUpstream(), CASocketGroupEpoll::add(), CAQueue::add(), CAFirstMixChannelList::addChannel(), t_fmhashtableentry::bRecoverTimeout, t_MixPacket::channel, CHANNEL_CLOSE, CHANNEL_DATA, CHANNEL_DEBUG, CHANNEL_DUMMY, CHANNEL_OPEN, CHANNEL_SIG_CRIME, t_firstmixchannellist::channelIn, t_firstmixchannellist::channelOut, checkUserConnections(), CAFirstMix::clean(), closeConnection(), t_fmhashtableentry::countryID, CASymChannelCipherFactory::createCipher(), CASymChannelCipher::crypt1(), CASymChannelCipher::crypt2(), t_MixPacket::data, DATA_SIZE, diff64(), E_SUCCESS, E_UNKNOWN, FIRST_MIX_SIZE_OF_SYMMETRIC_KEYS, t_MixPacket::flags, CAFirstMix::fm_loopLog, CAFirstMixChannelList::get(), CAQueue::get(), getcurrentTimeMicros(), CAFirstMixChannelList::getFirst(), CASocketGroupEpoll::getFirstSignaledSocketData(), CAFirstMixChannelList::getNext(), CASocketGroupEpoll::getNextSignaledSocketData(), CALibProxytest::getOptions(), getRandom(), CAQueue::getSize(), t_fmhashtableentry::id, tUINT32withLock::inc(), CAFirstMix::incMixedPackets(), CADatabase::insert(), CASocketGroupEpoll::isSignaled(), CAThread::join(), CALockAble::lock(), CAMutex::lock(), LOG_ENCRYPTED, CAFirstMix::m_bRestart, CAFirstMix::m_bRunLog, CAFirstMix::m_nUser, CAFirstMix::m_PacketsPerCountryIN, CAFirstMix::m_PacketsPerCountryOUT, CAFirstMix::m_pChannelList, CAFirstMix::m_pmutexLogin, CAFirstMix::m_pQueueReadFromMix, CAFirstMix::m_pQueueSendToMix, CAMixWithReplayDB::m_pReplayDB, CAFirstMix::m_psocketgroupUsersRead, CAFirstMix::m_psocketgroupUsersWrite, MAX_NEXT_MIX_QUEUE_SIZE, MIXPACKET_SIZE, msSleep(), t_queue_entry::packet, t_firstmixchannellist::pCipher, t_fmhashtableentry::pControlChannelDispatcher, t_fmhashtableentry::peerIP, t_firstmixchannellist::pHead, t_fmhashtableentry::pMuxSocket, t_fmhashtableentry::pQueueSend, CAMsg::printMsg(), CAControlChannelDispatcher::proccessMixPacket(), t_fmhashtableentry::pSymCipher, CAFirstMixChannelList::pushTimeoutEntry(), CAMuxSocket::receive(), CAFirstMixChannelList::removeChannel(), RSA_SIZE, CASocketGroupEpoll::select(), sendToUsers(), set64(), CAFirstMixChannelList::setDelayParameters(), CASymChannelCipher::setIV2(), CASymChannelCipher::setKeys(), CAThread::setMainLoop(), setZero64(), CAThread::start(), and CAMutex::unlock().

Here is the call graph for this function:

◆ notifyAllUserChannels()

void CAFirstMixA::notifyAllUserChannels ( fmHashTableEntry pfmHashEntry,
UINT16  flags 
)
private

Definition at line 1004 of file CAFirstMixA.cpp.

1005 {
1006  if(pfmHashEntry == NULL)
1007  return;
1009  tQueueEntry* pQueueEntry=new tQueueEntry;
1010  MIXPACKET *notifyPacket = &(pQueueEntry->packet);
1011  memset(notifyPacket, 0, MIXPACKET_SIZE);
1012 
1013  notifyPacket->flags = flags;
1014  while(pEntry != NULL)
1015  {
1016  if(pEntry->bIsSuspended)
1017  {
1018  notifyPacket->channel = pEntry->channelOut;
1019  getRandom(notifyPacket->data,DATA_SIZE);
1020 #ifdef _DEBUG
1021  CAMsg::printMsg(LOG_INFO,"Sent flags %u for channel: %u\n", flags, notifyPacket->channel);
1022 #endif
1023  m_pQueueSendToMix->add(pQueueEntry, sizeof(tQueueEntry));
1024  pEntry->bIsSuspended = false;
1025  }
1026  pEntry=m_pChannelList->getNextChannel(pEntry);
1027  }
1028  pfmHashEntry->cSuspend=0;
1029  delete pQueueEntry;
1030 }
UINT16 flags
Definition: typedefs.hpp:1

References CAQueue::add(), t_firstmixchannellist::bIsSuspended, t_MixPacket::channel, t_firstmixchannellist::channelOut, t_fmhashtableentry::cSuspend, t_MixPacket::data, DATA_SIZE, flags, t_MixPacket::flags, CAFirstMixChannelList::getFirstChannelForSocket(), CAFirstMixChannelList::getNextChannel(), getRandom(), CAFirstMix::m_pChannelList, CAFirstMix::m_pQueueSendToMix, MIXPACKET_SIZE, t_queue_entry::packet, t_fmhashtableentry::pMuxSocket, and CAMsg::printMsg().

Here is the call graph for this function:

◆ sendToUsers()

bool CAFirstMixA::sendToUsers ( )
private

Definition at line 773 of file CAFirstMixA.cpp.

774 {
775 #ifndef HAVE_EPOLL
776  SINT32 countRead =
777 #endif
778  m_psocketgroupUsersWrite->select(/*true,*/0);
779  tQueueEntry *packetToSend = NULL;
780  SINT32 packetSize = sizeof(tQueueEntry);
781  CAQueue *controlMessageUserQueue = NULL;
782  CAQueue *dataMessageUserQueue = NULL;
783 
784  CAQueue *processedQueue = NULL; /* one the above queues that should be used for processing*/
785  UINT32 extractSize = 0;
786  bool bAktiv = false;
787  UINT32 iSocketErrors = 0;
788 
789 /* Cyclic polling: gets all open sockets that will not block when invoking send()
790  * but will only send at most one packet. After that control is returned to loop()
791  */
792 #ifdef HAVE_EPOLL
793  fmHashTableEntry* pfmHashEntry=
795 
796  while(pfmHashEntry != NULL)
797  {
798 
799 #else
800  fmHashTableEntry* pfmHashEntry=m_pChannelList->getFirst();
801  while( (countRead > 0) && (pfmHashEntry != NULL) )
802  {
803  if(m_psocketgroupUsersWrite->isSignaled(*pfmHashEntry->pMuxSocket))
804  {
805  countRead--;
806 #endif
807  /* loop turn init */
808  extractSize = 0;
809  processedQueue = NULL;
810  packetToSend = &(pfmHashEntry->oQueueEntry);
811  controlMessageUserQueue = pfmHashEntry->pControlMessageQueue;
812  dataMessageUserQueue = pfmHashEntry->pQueueSend;
813 
814  //Control messages have a higher priority.
815  if(controlMessageUserQueue->getSize() > 0)
816  {
817  processedQueue = controlMessageUserQueue;
818  pfmHashEntry->bCountPacket = false;
819  }
820  else if( (dataMessageUserQueue->getSize() > 0)
821 #ifdef DELAY_USERS
822  && m_pChannelList->hasDelayBuckets(pfmHashEntry->delayBucketID)
823 #endif
824  )
825  {
826  processedQueue = dataMessageUserQueue;
827  pfmHashEntry->bCountPacket = true;
828  }
829 
830  if(processedQueue != NULL)
831  {
832  extractSize = packetSize;
833  bAktiv=true;
834 
835  if(pfmHashEntry->uAlreadySendPacketSize == -1)
836  {
837  processedQueue->get((UINT8*) packetToSend, &extractSize);
838 
839  /* Hack for SSL BUG */
840 #ifdef SSL_HACK
841  finishPacket(pfmHashEntry);
842 #endif //SSL_HACK
843 #ifdef ANON_DEBUG_MODE
844  if (packetToSend->packet.flags&CHANNEL_DEBUG)
845  {
846  UINT8 base64Payload[DATA_SIZE << 1];
847  EVP_EncodeBlock(base64Payload, packetToSend->packet.data, DATA_SIZE);//base64 encoding (without newline!)
848  CAMsg::printMsg(LOG_DEBUG, "Send Downstream AN.ON packet to user debug: %s\n", base64Payload);
849  packetToSend->packet.flags &= ~CHANNEL_DEBUG;
850  }
851 
852 #endif
853  pfmHashEntry->pMuxSocket->prepareForSend(&(packetToSend->packet));
854  pfmHashEntry->uAlreadySendPacketSize = 0;
855  }
856  }
857 
858  if( (extractSize > 0) || (pfmHashEntry->uAlreadySendPacketSize > 0) )
859  {
861  UINT8* packetToSendOffset = ((UINT8*)&(packetToSend->packet)) + pfmHashEntry->uAlreadySendPacketSize;
862  CASocket* clientSocket = pfmHashEntry->pMuxSocket->getCASocket();
863 
864  SINT32 ret = clientSocket->send(packetToSendOffset, len);
865 
866  if(ret > 0)
867  {
868 #ifdef PAYMENT
869  SINT32 accounting = E_SUCCESS;
870 #endif
871  pfmHashEntry->uAlreadySendPacketSize += ret;
872 
873  if(pfmHashEntry->uAlreadySendPacketSize == MIXPACKET_SIZE)
874  {
875  #ifdef DELAY_USERS
876  if(processedQueue != controlMessageUserQueue)
877  {
879  }
880  #endif
881 
882  #ifdef LOG_PACKET_TIMES
883  if(!isZero64(pfmHashEntry->oQueueEntry.timestamp_proccessing_start))
884  {
885  getcurrentTimeMicros(pfmHashEntry->oQueueEntry.timestamp_proccessing_end);
886  m_pLogPacketStats->addToTimeingStats(pfmHashEntry->oQueueEntry,CHANNEL_DATA,false);
887  }
888  #endif
889  pfmHashEntry->uAlreadySendPacketSize=-1;
890 #ifdef PAYMENT
891  /* count this packet for accounting */
892  accounting = accountTrafficDownstream(pfmHashEntry);
893 #endif
894  }
895 
896  }
897  else if(ret<0&&ret!=E_AGAIN)
898  {
899  iSocketErrors++;
900  // if (iSocketErrors == 1) // show debug message only at the first error; otherwise, the log may get huge
901  {
902  SOCKET sock=clientSocket->getSocket();
903  CAMsg::printMsg(LOG_DEBUG,"CAFirstMixA::sendtoUser() - send error %d on socket %d. Reason: %s (%i)\n", ret, sock, GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
904  }
905  // kick the user out - these only happens in extreme situations...
906  closeConnection(pfmHashEntry);
907  }
908  //TODO error handling
909  }
910 
911 #ifdef HAVE_EPOLL
913  }
914 #else
915  }//if is socket signaled
916  pfmHashEntry=m_pChannelList->getNext();
917  }
918 #endif
919  if (iSocketErrors > 1)
920  {
921  CAMsg::printMsg(LOG_ERR, "CAFirstMixA::sendtoUser() - %d send errors on a socket occured!\n", iSocketErrors);
922  }
923 
924  return bAktiv;
925 }
bool isZero64(UINT64 &op1)
Definition: CAUtil.hpp:464
#define GET_NET_ERROR
Definition: StdAfx.h:469
#define GET_NET_ERROR_STR(x)
Definition: StdAfx.h:471
#define SOCKET
Definition: StdAfx.h:460
void finishPacket(fmHashTableEntry *pfmHashEntry)
SINT32 accountTrafficDownstream(fmHashTableEntry *pfmHashEntry)
void decDelayBuckets(UINT32 delayBucketID)
bool hasDelayBuckets(UINT32 delayBucketID)
CASocket * getCASocket()
Definition: CAMuxSocket.hpp:84
SINT32 prepareForSend(MIXPACKET *inoutPacket)
This is a simple FIFO-Queue.
Definition: CAQueue.hpp:50
virtual SINT32 send(const UINT8 *buff, UINT32 len)
Sends some data over the network.
Definition: CASocket.cpp:400
#define DELAY_USERS
Definition: doxygen.h:6
#define E_AGAIN
Definition: errorcodes.hpp:9
volatile UINT32 delayBucketID
UINT16 len
Definition: typedefs.hpp:0

References accountTrafficDownstream(), t_fmhashtableentry::bCountPacket, CHANNEL_DATA, CHANNEL_DEBUG, closeConnection(), t_MixPacket::data, DATA_SIZE, CAFirstMixChannelList::decDelayBuckets(), DELAY_USERS, t_fmhashtableentry::delayBucketID, E_AGAIN, E_SUCCESS, finishPacket(), t_MixPacket::flags, CAQueue::get(), GET_NET_ERROR, GET_NET_ERROR_STR, CAMuxSocket::getCASocket(), getcurrentTimeMicros(), CAFirstMixChannelList::getFirst(), CASocketGroupEpoll::getFirstSignaledSocketData(), CAFirstMixChannelList::getNext(), CASocketGroupEpoll::getNextSignaledSocketData(), CAQueue::getSize(), CAFirstMixChannelList::hasDelayBuckets(), CASocketGroupEpoll::isSignaled(), isZero64(), len, CAFirstMix::m_pChannelList, CAFirstMix::m_psocketgroupUsersWrite, MIXPACKET_SIZE, t_fmhashtableentry::oQueueEntry, t_queue_entry::packet, t_fmhashtableentry::pControlMessageQueue, t_fmhashtableentry::pMuxSocket, t_fmhashtableentry::pQueueSend, CAMuxSocket::prepareForSend(), CAMsg::printMsg(), CASocketGroupEpoll::select(), CASocket::send(), SOCKET, and t_fmhashtableentry::uAlreadySendPacketSize.

Referenced by loop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ shutDown()

void CAFirstMixA::shutDown ( )
virtual

Reimplemented from CAMix.

Definition at line 44 of file CAFirstMixA.cpp.

45 {
46  m_bIsShuttingDown = true;
47  m_bLoop=false;
48 #ifdef PAYMENT
49  UINT32 connectionsClosed = 0;
50  fmHashTableEntry* timeoutHashEntry;
51 
52 
53  /* make sure no reconnect is possible when shutting down */
54  if(m_pthreadAcceptUsers!=NULL)
55  {
56  CAMsg::printMsg(LOG_CRIT,"Wait for LoopAcceptUsers!\n");
57  m_bRestart=true;
59  delete m_pthreadAcceptUsers;
60  }
62 
63  if(m_pInfoService != NULL)
64  {
65  CAMsg::printMsg(LOG_DEBUG,"Shutting down infoservice.\n");
67  }
68  if(m_pChannelList!=NULL) // may happen if mixes did not yet connect to each other
69  {
70  while ((timeoutHashEntry = m_pChannelList->popTimeoutEntry(true)) != NULL)
71  {
72  CAMsg::printMsg(LOG_DEBUG,"Shutting down, closing client connection.\n");
73  connectionsClosed++;
74  closeConnection(timeoutHashEntry);
75  }
76  CAMsg::printMsg(LOG_DEBUG,"Closed %i client connections.\n", connectionsClosed);
77  }
78 #endif
79  m_bRestart = true;
80  m_bIsShuttingDown = false;
81 }
CAThread * m_pthreadAcceptUsers
Definition: CAFirstMix.hpp:504
bool m_bIsShuttingDown
Definition: CAFirstMix.hpp:550
volatile bool m_bLoop
Definition: CAMix.hpp:135
CAInfoService * m_pInfoService
Definition: CAMix.hpp:184

References closeConnection(), CAThread::join(), CAFirstMix::m_bIsShuttingDown, CAMix::m_bLoop, CAFirstMix::m_bRestart, CAFirstMix::m_pChannelList, CAMix::m_pInfoService, CAFirstMix::m_pthreadAcceptUsers, CAFirstMixChannelList::popTimeoutEntry(), CAMsg::printMsg(), and CAInfoService::stop().

Here is the call graph for this function:

Friends And Related Function Documentation

◆ fm_loopPacketProcessing

THREAD_RETURN fm_loopPacketProcessing ( void *  params)
friend

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