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

Data structure that stores all information about the currently open Mix channels. More...

#include <CAFirstMixChannelList.hpp>

Collaboration diagram for CAFirstMixChannelList:

Public Member Functions

 CAFirstMixChannelList ()
 
 ~CAFirstMixChannelList ()
 
fmHashTableEntryadd (CAMuxSocket *pMuxSocket, const UINT8 peerIP[4], CAQueue *pQueueSend, UINT8 *controlChannelKeyRecv, UINT8 *controlChannelKeySent)
 Adds a new TCP/IP connection (a new user) to the channel list. More...
 
SINT32 addChannel (CAMuxSocket *pMuxSocket, HCHANNEL channelIn, CASymChannelCipher *pCipher, HCHANNEL *channelOut)
 Adds a new channel for a given connection to the channel list. More...
 
fmChannelListEntryget (CAMuxSocket *pMuxSocket, HCHANNEL channelIn)
 Returns the information for a given Input-Channel-ID. More...
 
fmHashTableEntrypopTimeoutEntry ()
 
fmHashTableEntrypopTimeoutEntry (bool a_bForce)
 
bool isTimedOut (fmHashTableEntry *pHashTableEntry)
 
bool isKickoutForced (fmHashTableEntry *pHashTableEntry)
 
void setKickoutForced (fmHashTableEntry *pHashTableEntry, bool kickoutForced)
 
bool forceKickout (fmHashTableEntry *pHashTableEntry, const XERCES_CPP_NAMESPACE::DOMDocument *pErrDoc)
 forces a kickout for this entry if the entry is still valid and sends an errorMessage via the control channel belonging to the entry. More...
 
SINT32 pushTimeoutEntry (fmHashTableEntry *pHashTableEntry, bool kickoutForced=!KICKOUT_FORCED)
 adds the entry to the timeout queue with mutex More...
 
SINT32 remove (CAMuxSocket *pMuxSocket)
 Removes all channels, which belongs to the given connection and the connection itself from the list. More...
 
SINT32 removeChannel (CAMuxSocket *pMuxSocket, HCHANNEL channelIn)
 Removes a single channel from the list. More...
 
fmHashTableEntrygetFirst ()
 Gets the first connection of all connections in the list. More...
 
fmHashTableEntrygetNext ()
 Gets the next entry in the connections-list. More...
 
fmHashTableEntryget (CAMuxSocket *pMuxSocket)
 Returns the general data stored for a given Socket (user) More...
 
fmChannelListEntrygetFirstChannelForSocket (CAMuxSocket *pMuxSocket)
 Gets the first channel for a given connection. More...
 
fmChannelListEntrygetNextChannel (fmChannelListEntry *pEntry)
 Gets the next channel for a given connection. More...
 
fmChannelListEntryget (HCHANNEL channelOut)
 Gets the in-channel and all associated information for the given out-channel. More...
 
void setDelayParameters (UINT32 unlimitTraffic, UINT32 bucketGrow, UINT32 intervall)
 
void decDelayBuckets (UINT32 delayBucketID)
 
bool hasDelayBuckets (UINT32 delayBucketID)
 

Static Public Member Functions

static SINT32 test ()
 

Private Member Functions

SINT32 removeFromTimeoutList (fmHashTableEntry *pHashTableEntry)
 
SINT32 pushTimeoutEntry_internal (fmHashTableEntry *pHashTableEntry, bool kickoutForced=!KICKOUT_FORCED)
 adds the entry to the timeout queue More...
 
bool isKickoutForced_internal (fmHashTableEntry *pHashTableEntry)
 
void setKickoutForced_internal (fmHashTableEntry *pHashTableEntry, bool kickoutForced)
 
fmHashTableEntrypopTimeoutEntry_internal (bool a_bForce)
 
UINT32 countTimeoutEntries ()
 
fmChannelListEntryget_intern_without_lock (HCHANNEL channelOut)
 Gets the in-channel and all associated information for the given out-channel. More...
 
bool isTimedOut_internal (fmHashTableEntry *pHashTableEntry)
 

Private Attributes

LP_fmHashTableEntrym_HashTable
 The Hash-Table of all connections. More...
 
LP_fmChannelListEntrym_HashTableOutChannels
 The Hash-Table of all out-channels. More...
 
fmHashTableEntrym_listHashTableHead
 Pointer to the head of a list of all connections. More...
 
fmHashTableEntrym_listHashTableNext
 Next Element in the enumeration of all connections. More...
 
fmHashTableEntrym_listTimoutHead
 Pointer to the head of the timout list of all connections. More...
 
fmHashTableEntrym_listTimoutFoot
 
CAMutex m_Mutex
 This mutex is used in all functions and makes them thread safe. More...
 
volatile UINT32 ** m_pDelayBuckets
 
CAThreadm_pThreadDelayBucketsLoop
 
CAMutexm_pMutexDelayChannel
 
bool m_bDelayBucketsLoopRun
 
volatile UINT32 m_u32DelayChannelUnlimitTraffic
 
volatile UINT32 m_u32DelayChannelBucketGrow
 
volatile UINT32 m_u32DelayChannelBucketGrowIntervall
 

Static Private Attributes

static const SINT32 EXPIRATION_TIME_SECS = 300
 

Friends

THREAD_RETURN fml_loopDelayBuckets (void *)
 

Detailed Description

Data structure that stores all information about the currently open Mix channels.

See [FirstMixChannelList] for more information.

Definition at line 225 of file CAFirstMixChannelList.hpp.

Constructor & Destructor Documentation

◆ CAFirstMixChannelList()

CAFirstMixChannelList::CAFirstMixChannelList ( )

Definition at line 43 of file CAFirstMixChannelList.cpp.

44  {
47  for(int i=0;i<MAX_HASH_KEY;i++)
48  {
50  memset(m_HashTable[i],0,sizeof(fmHashTableEntry));
51 #ifdef PAYMENT
53 #endif
54  }
57 #ifdef PAYMENT
58  m_listTimoutHead = NULL;
59  m_listTimoutFoot = NULL;
60 #endif
62  memset(m_HashTableOutChannels,0,sizeof(LP_fmChannelListEntry)*0x10000);
63 #ifdef DO_TRACE
64  m_aktAlloc=m_maxAlloc=0;
65 #endif
66 #ifdef DELAY_USERS
70  m_pDelayBuckets=new volatile UINT32*[MAX_POLLFD];
71  memset(m_pDelayBuckets,0,sizeof(UINT32*)*MAX_POLLFD);
73  m_pThreadDelayBucketsLoop=new CAThread((UINT8*)"Delay Channel Thread");
77 #endif
78  }
#define MAX_HASH_KEY
struct t_fmhashtableentry fmHashTableEntry
#define DELAY_USERS_BUCKET_GROW
Definition: StdAfx.h:160
#define MAX_POLLFD
Definition: StdAfx.h:192
#define DELAY_USERS_BUCKET_GROW_INTERVALL
Definition: StdAfx.h:159
#define DELAY_USERS_TRAFFIC
Definition: StdAfx.h:154
unsigned char UINT8
Definition: basetypedefs.h:135
unsigned int UINT32
Definition: basetypedefs.h:131
LP_fmChannelListEntry * m_HashTableOutChannels
The Hash-Table of all out-channels.
volatile UINT32 ** m_pDelayBuckets
fmHashTableEntry * m_listTimoutHead
Pointer to the head of the timout list of all connections.
fmHashTableEntry * m_listHashTableNext
Next Element in the enumeration of all connections.
fmHashTableEntry * m_listHashTableHead
Pointer to the head of a list of all connections.
friend THREAD_RETURN fml_loopDelayBuckets(void *)
fmHashTableEntry * m_listTimoutFoot
volatile UINT32 m_u32DelayChannelBucketGrowIntervall
volatile UINT32 m_u32DelayChannelBucketGrow
LP_fmHashTableEntry * m_HashTable
The Hash-Table of all connections.
volatile UINT32 m_u32DelayChannelUnlimitTraffic
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
CAConditionVariable * cleanupNotifier

References t_fmhashtableentry::cleanupNotifier, DELAY_USERS_BUCKET_GROW, DELAY_USERS_BUCKET_GROW_INTERVALL, DELAY_USERS_TRAFFIC, fml_loopDelayBuckets, m_bDelayBucketsLoopRun, m_HashTable, m_HashTableOutChannels, m_listHashTableHead, m_listHashTableNext, m_listTimoutFoot, m_listTimoutHead, m_pDelayBuckets, m_pMutexDelayChannel, m_pThreadDelayBucketsLoop, m_u32DelayChannelBucketGrow, m_u32DelayChannelBucketGrowIntervall, m_u32DelayChannelUnlimitTraffic, MAX_HASH_KEY, MAX_POLLFD, CAThread::setMainLoop(), and CAThread::start().

Referenced by test().

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

◆ ~CAFirstMixChannelList()

CAFirstMixChannelList::~CAFirstMixChannelList ( )

Definition at line 80 of file CAFirstMixChannelList.cpp.

81  {
82 #ifdef DELAY_USERS
87  delete m_pMutexDelayChannel;
88  m_pMutexDelayChannel = NULL;
89  delete []m_pDelayBuckets;
90  m_pDelayBuckets = NULL;
91 #endif
92  for(int i=0;i<MAX_HASH_KEY;i++)
93  {
94 
95 #ifdef PAYMENT
96  delete m_HashTable[i]->cleanupNotifier;
97  m_HashTable[i]->cleanupNotifier = NULL;
98 #endif
99  delete m_HashTable[i];
100  m_HashTable[i] = NULL;
101  }
102  delete []m_HashTable;
103  m_HashTable = NULL;
104  delete []m_HashTableOutChannels;
105  m_HashTableOutChannels = NULL;
106  }
SINT32 join()
Waits for the main function to finish execution.
Definition: CAThread.cpp:187

References t_fmhashtableentry::cleanupNotifier, CAThread::join(), m_bDelayBucketsLoopRun, m_HashTable, m_HashTableOutChannels, m_pDelayBuckets, m_pMutexDelayChannel, m_pThreadDelayBucketsLoop, and MAX_HASH_KEY.

Here is the call graph for this function:

Member Function Documentation

◆ add()

fmHashTableEntry * CAFirstMixChannelList::add ( CAMuxSocket pMuxSocket,
const UINT8  peerIP[4],
CAQueue pQueueSend,
UINT8 controlChannelKeySent,
UINT8 controlChannelKeyRecv 
)

Adds a new TCP/IP connection (a new user) to the channel list.

Parameters
pMuxSocketthe new connection (from a user)
peerIPthe IP of the user, so that we can remove it later from the CAIPList
pQueueSendthe send-queue to use for this connection
Return values
thefmHashTableEntry of the newly added connection
NULLif an error occured

Definition at line 116 of file CAFirstMixChannelList.cpp.

120  {
121  INIT_STACK;
122  BEGIN_STACK("CAFirstMixChannelList::add");
123 
124  if(pMuxSocket==NULL)
125  {
126  FINISH_STACK("CAFirstMixChannelList::add (null socket)");
127  return NULL;
128  }
129  SINT32 hashkey=pMuxSocket->getHashKey();
130  if(hashkey>MAX_HASH_KEY-1||hashkey<0)
131  {
132  FINISH_STACK("CAFirstMixChannelList::add (invalid hash key)");
133  return NULL;
134  }
135  m_Mutex.lock();
136  fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
137  if(pHashTableEntry->pMuxSocket!=NULL) //the entry in the hashtable for this socket (hashkey) must be empty
138  {
139  FINISH_STACK("CAFirstMixChannelList::add (socket exists)");
140  m_Mutex.unlock();
141  return NULL;
142  }
143 
144  //SAVE_STACK("CAFirstMixChannelList::add", "initialising table entry");
145 #ifdef CH_LOG_STUDY
146  pHashTableEntry->channelOpenedLastIntervalTS = 0;
147 #endif
148  pHashTableEntry->pMuxSocket=pMuxSocket;
149  pHashTableEntry->pQueueSend=pQueueSend;
150  pHashTableEntry->pControlMessageQueue = new CAQueue();
151  pHashTableEntry->pControlChannelDispatcher = new CAControlChannelDispatcher(pHashTableEntry->pControlMessageQueue,controlChannelKeyRecv,controlChannelKeySent);
152  pHashTableEntry->uAlreadySendPacketSize=-1;
153  pHashTableEntry->cNumberOfChannels=0;
154 #ifdef LOG_TRAFFIC_PER_USER
155  pHashTableEntry->trafficIn=0;
156  pHashTableEntry->trafficOut=0;
157  getcurrentTimeMillis(pHashTableEntry->timeCreated);
158 #endif
159 #ifdef LOG_DIALOG
160  pHashTableEntry->strDialog=new UINT8[strlen((char*)strDialog)+1];
161  strcpy((char*)pHashTableEntry->strDialog,(char*)strDialog);
162 #endif
163  // TODO Collisions? Is the id still used somewhere?
164  //Yes it is --> for logging to match login /logout
165  //collisions in a hard seens are an issue, but are very unlikely; and because it is only for logging it does not really matter...
166  getRandom(&(pHashTableEntry->id));
167 
168 #ifdef PAYMENT
169  pHashTableEntry->pAccountingInfo=NULL;
170 #endif
171  SAVE_STACK("CAFirstMixChannelList::add", "copying peer IP");
172  memcpy(pHashTableEntry->peerIP,peerIP,4);
173 #if defined(DATA_RETENTION_LOG) || defined(LOG_CRIME)
174  pHashTableEntry->peerPort=pMuxSocket->getCASocket()->getPeerPort();
175 #endif
176 #ifdef DELAY_USERS
178  pHashTableEntry->delayBucket=m_u32DelayChannelUnlimitTraffic; //can always send some first packets
179  for(UINT32 i=0;i<MAX_POLLFD;i++)
180  {
181  if(m_pDelayBuckets[i]==NULL)
182  {
183  pHashTableEntry->delayBucketID=i;
184  break;
185  }
186  }
187  m_pDelayBuckets[pHashTableEntry->delayBucketID]=&pHashTableEntry->delayBucket;
189 #endif
190 
191  SAVE_STACK("CAFirstMixChannelList::add", "inserting in connection list");
192  //now insert the new connection in the list of all open connections
193  if(m_listHashTableHead==NULL) //if first one
194  {
195  pHashTableEntry->list_HashEntries.next=NULL;
196  }
197  else
198  {//add to the head of the double linked list
199  pHashTableEntry->list_HashEntries.next=m_listHashTableHead;
200  m_listHashTableHead->list_HashEntries.prev=pHashTableEntry;
201  }
202  pHashTableEntry->list_HashEntries.prev=NULL;
203  m_listHashTableHead=pHashTableEntry;
204 
205  SAVE_STACK("CAFirstMixChannelList::add", "inserting in timout list");
206  // insert in timeout list; entries are added to the foot of the list
207 #ifdef PAYMENT
208  pHashTableEntry->bRecoverTimeout = true;
209  pHashTableEntry->kickoutSendRetries = MAX_KICKOUT_RETRIES;
210  /* Hot fix: push timeout entry explicitly to avoid
211  * confusion, when timeout occurs during AI login
212  */
213  //pushTimeoutEntry_internal(pHashTableEntry);
214 #endif
215  m_Mutex.unlock();
216 
217  FINISH_STACK("CAFirstMixChannelList::add");
218 
219  return pHashTableEntry;
220  }
#define MAX_KICKOUT_RETRIES
#define INIT_STACK
Definition: CAThread.hpp:48
#define BEGIN_STACK(methodName)
Definition: CAThread.hpp:49
#define FINISH_STACK(methodName)
Definition: CAThread.hpp:50
#define SAVE_STACK(methodName, methodPosition)
Definition: CAThread.hpp:51
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
signed int SINT32
Definition: basetypedefs.h:132
This class "dispatches" messages which it receives via proccessMixPacket() to the associated control ...
CAMutex m_Mutex
This mutex is used in all functions and makes them thread safe.
SINT32 unlock()
Definition: CAMutex.hpp:52
SINT32 lock()
Definition: CAMutex.hpp:41
SINT32 getHashKey()
Returns a Hashkey which uniquely identifies this socket.
Definition: CAMuxSocket.hpp:52
CASocket * getCASocket()
Definition: CAMuxSocket.hpp:84
This is a simple FIFO-Queue.
Definition: CAQueue.hpp:50
virtual SINT32 getPeerPort()
Definition: CASocket.cpp:830
volatile UINT32 delayBucketID
struct t_fmhashtableentry * prev
CAControlChannelDispatcher * pControlChannelDispatcher
volatile UINT32 delayBucket
CountryID of this IP Address.
tAiAccountingInfo * pAccountingInfo
struct t_fmhashtableentry * next
struct t_fmhashtableentry::@0 list_HashEntries

References BEGIN_STACK, t_fmhashtableentry::bRecoverTimeout, t_fmhashtableentry::cNumberOfChannels, t_fmhashtableentry::delayBucket, t_fmhashtableentry::delayBucketID, FINISH_STACK, CAMuxSocket::getCASocket(), getcurrentTimeMillis(), CAMuxSocket::getHashKey(), CASocket::getPeerPort(), getRandom(), t_fmhashtableentry::id, INIT_STACK, t_fmhashtableentry::kickoutSendRetries, t_fmhashtableentry::list_HashEntries, MAX_HASH_KEY, MAX_KICKOUT_RETRIES, MAX_POLLFD, t_fmhashtableentry::next, t_fmhashtableentry::pAccountingInfo, t_fmhashtableentry::pControlChannelDispatcher, t_fmhashtableentry::pControlMessageQueue, t_fmhashtableentry::peerIP, t_fmhashtableentry::pMuxSocket, t_fmhashtableentry::pQueueSend, t_fmhashtableentry::prev, SAVE_STACK, and t_fmhashtableentry::uAlreadySendPacketSize.

Referenced by CAFirstMix::doUserLogin_internal(), and test().

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

◆ addChannel()

SINT32 CAFirstMixChannelList::addChannel ( CAMuxSocket pMuxSocket,
HCHANNEL  channelIn,
CASymChannelCipher pCipher,
HCHANNEL channelOut 
)

Adds a new channel for a given connection to the channel list.

Also a new out-channel id is generated and returned.

Parameters
pMuxSocketthe connection from the user
channelInthe channel, which should be added
pCipherthe symmetric cipher associated with this channel
channelOuta pointer to the place, there the new generated out-channel id is stored
Return values
E_SUCCESSif successful
E_UNKNOWNin case of an error

Definition at line 234 of file CAFirstMixChannelList.cpp.

236  {
237  if(pMuxSocket==NULL||channelOut==NULL)
238  return E_UNKNOWN;
239  SINT32 hashkey=pMuxSocket->getHashKey();
240  if(hashkey>MAX_HASH_KEY-1||hashkey<0)
241  return E_UNKNOWN;
242  m_Mutex.lock();
243  fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
244  if(pHashTableEntry->pMuxSocket==NULL||pHashTableEntry->cNumberOfChannels>=MAX_NUMBER_OF_CHANNELS)
245  {
246  #define ERR_MSG_TO_MANY_CHANNELS "More than " STR(MAX_NUMBER_OF_CHANNELS) " channels!\n"
248  m_Mutex.unlock();
249  return E_UNKNOWN;
250  }
251  fmChannelListEntry* pEntry=pHashTableEntry->pChannelList;
252 #ifndef DO_TRACE
253  fmChannelListEntry* pNewEntry=new fmChannelListEntry;
254 #else
255  fmChannelListEntry* pNewEntry=newChannelListEntry();
256 #endif
257  memset(pNewEntry,0,sizeof(fmChannelListEntry));
258  pNewEntry->pCipher=pCipher;
259  pNewEntry->channelIn=channelIn;
260 
261  do
262  {
263  getRandom(channelOut); //get new Random OUT-CHANNEL-ID
264  } while(*channelOut<256||get_intern_without_lock(*channelOut)!=NULL); //until it is unused...
265  pNewEntry->channelOut=*channelOut;
266  pNewEntry->bIsSuspended=false;
267  pNewEntry->pHead=pHashTableEntry;
268 
269 #ifdef LOG_CHANNEL
270  pNewEntry->packetsInFromUser=0;
271  pNewEntry->packetsOutToUser=0;
272 #endif
273 #ifdef SSL_HACK
274  pNewEntry->downStreamBytes = 0;
275 #endif
276 #ifdef ANON_DEBUG_MODE
277  pNewEntry->bDebug = false;
278 #endif
279 
280 
281 
282  //add to the channel list for the given connection
283  if(pEntry==NULL) //First Entry to the channel list
284  {
285  pNewEntry->list_InChannelPerSocket.next=NULL;
286  pNewEntry->list_InChannelPerSocket.prev=NULL;
287  }
288  else
289  {
290  pNewEntry->list_InChannelPerSocket.next=pEntry;
291  pNewEntry->list_InChannelPerSocket.prev=NULL;
292  pEntry->list_InChannelPerSocket.prev=pNewEntry;
293  }
294  pHashTableEntry->pChannelList=pNewEntry;
295 
296  //add to the out-channel list
297  hashkey=(*channelOut)&0x0000FFFF;
298  pEntry=m_HashTableOutChannels[hashkey];
299  if(pEntry!=NULL) //Hash Table Bucket Over run....
300  {
301  pNewEntry->list_OutChannelHashTable.prev=NULL;
302  pNewEntry->list_OutChannelHashTable.next=pEntry;
303  pEntry->list_OutChannelHashTable.prev=pNewEntry;
304  }
305  m_HashTableOutChannels[hashkey]=pNewEntry;
306  pHashTableEntry->cNumberOfChannels++;
307  m_Mutex.unlock();
308  return E_SUCCESS;
309  }
#define MAX_NUMBER_OF_CHANNELS
The maximum number of channels allowed per connection.
#define ERR_MSG_TO_MANY_CHANNELS
struct t_firstmixchannellist fmChannelListEntry
fmChannelListEntry * get_intern_without_lock(HCHANNEL channelOut)
Gets the in-channel and all associated information for the given out-channel.
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
#define E_UNKNOWN
Definition: errorcodes.hpp:3
CASymChannelCipher * pCipher
struct t_firstmixchannellist * prev
struct t_firstmixchannellist * next
struct t_firstmixchannellist::@2 list_OutChannelHashTable
struct t_firstmixchannellist::@3 list_InChannelPerSocket
struct t_firstmixchannellist * pChannelList

References t_firstmixchannellist::bIsSuspended, t_firstmixchannellist::channelIn, t_firstmixchannellist::channelOut, t_fmhashtableentry::cNumberOfChannels, E_SUCCESS, E_UNKNOWN, ERR_MSG_TO_MANY_CHANNELS, get_intern_without_lock(), CAMuxSocket::getHashKey(), getRandom(), t_firstmixchannellist::list_InChannelPerSocket, t_firstmixchannellist::list_OutChannelHashTable, CAMutex::lock(), m_HashTable, m_HashTableOutChannels, m_Mutex, MAX_HASH_KEY, MAX_NUMBER_OF_CHANNELS, t_firstmixchannellist::next, t_fmhashtableentry::pChannelList, t_firstmixchannellist::pCipher, t_firstmixchannellist::pHead, t_fmhashtableentry::pMuxSocket, t_firstmixchannellist::prev, CAMsg::printMsg(), and CAMutex::unlock().

Referenced by CAFirstMixA::loop(), CAFirstMixB::loop(), and test().

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

◆ countTimeoutEntries()

UINT32 CAFirstMixChannelList::countTimeoutEntries ( )
private

Definition at line 495 of file CAFirstMixChannelList.cpp.

496 {
497  fmHashTableEntry* pHashTableEntry;
498  UINT32 count = 0;
499 
500  for (pHashTableEntry = m_listTimoutHead; pHashTableEntry != NULL;
501  count++, pHashTableEntry = pHashTableEntry->list_TimeoutHashEntries.next);
502 
503  return count;
504 }
struct t_fmhashtableentry::@1 list_TimeoutHashEntries

References t_fmhashtableentry::list_TimeoutHashEntries, m_listTimoutHead, and t_fmhashtableentry::next.

◆ decDelayBuckets()

void CAFirstMixChannelList::decDelayBuckets ( UINT32  delayBucketID)

Definition at line 1203 of file CAFirstMixChannelList.cpp.

1204  {
1206  if(delayBucketID < MAX_POLLFD)
1207  {
1208  if(m_pDelayBuckets[delayBucketID] != NULL)
1209  {
1210  *(m_pDelayBuckets[delayBucketID]) -= ( (*(m_pDelayBuckets[delayBucketID])) > 0 ) ? 1 : 0;
1211  }
1212  /*CAMsg::printMsg(LOG_DEBUG,"DelayBuckets decrementing ID %u downto %u\n",
1213  delayBucketID, (*(m_pDelayBuckets[delayBucketID])) );*/
1214  }
1216  }

References CAMutex::lock(), m_pDelayBuckets, m_pMutexDelayChannel, MAX_POLLFD, and CAMutex::unlock().

Referenced by CAFirstMixA::sendToUsers().

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

◆ forceKickout()

bool CAFirstMixChannelList::forceKickout ( fmHashTableEntry pHashTableEntry,
const XERCES_CPP_NAMESPACE::DOMDocument *  pErrDoc 
)

forces a kickout for this entry if the entry is still valid and sends an errorMessage via the control channel belonging to the entry.

returns true if pHashTableEntry is still valid, false otherwise

Definition at line 408 of file CAFirstMixChannelList.cpp.

409 {
410  bool ret = false;
411  m_Mutex.lock();
412  ret = (pHashTableEntry->pMuxSocket != NULL);
413  if(ret)
414  {
415  if(pErrDoc != NULL)
416  {
417  //NOTE: accessing the control channel in this case works without further locking,
418  //because the control channel is only deleted when the Dispatcher deletes all channels.
419  //This happens when the table entry is removed by CAFirstMixChannelList::remove
420  //which locks over m_Mutex.
421  pHashTableEntry->pAccountingInfo->pControlChannel->sendXMLMessage(pErrDoc);
422  }
423  setKickoutForced_internal(pHashTableEntry, KICKOUT_FORCED);
424  }
425  m_Mutex.unlock();
426  return ret;
427 }
#define KICKOUT_FORCED
SINT32 sendXMLMessage(const XERCES_CPP_NAMESPACE::DOMDocument *pDocMsg) const
Call to send a XML message via this control channel.
void setKickoutForced_internal(fmHashTableEntry *pHashTableEntry, bool kickoutForced)
CAAccountingControlChannel * pControlChannel
a pointer to the user-specific control channel object
Definition: typedefs.hpp:330

References KICKOUT_FORCED, CAMutex::lock(), m_Mutex, t_fmhashtableentry::pAccountingInfo, t_accountinginfo::pControlChannel, t_fmhashtableentry::pMuxSocket, CAAbstractControlChannel::sendXMLMessage(), setKickoutForced_internal(), and CAMutex::unlock().

Referenced by CAFirstMix::forceKickout().

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

◆ get() [1/3]

fmHashTableEntry * CAFirstMixChannelList::get ( CAMuxSocket pMuxSocket)

Returns the general data stored for a given Socket (user)

Parameters
pMuxSocketthe connection from the user
Returns
general data for the given user
Return values
NULLif not found

Definition at line 317 of file CAFirstMixChannelList.cpp.

318  {
319  if(pMuxSocket==NULL)
320  return NULL;
321  SINT32 hashkey=pMuxSocket->getHashKey();
322  if(hashkey>MAX_HASH_KEY-1||hashkey<0)
323  return NULL;
324  m_Mutex.lock();
325  fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
326  m_Mutex.unlock();
327  return pHashTableEntry;
328  }

References CAMuxSocket::getHashKey(), CAMutex::lock(), m_HashTable, m_Mutex, MAX_HASH_KEY, and CAMutex::unlock().

Here is the call graph for this function:

◆ get() [2/3]

fmChannelListEntry * CAFirstMixChannelList::get ( CAMuxSocket pMuxSocket,
HCHANNEL  channelIn 
)

Returns the information for a given Input-Channel-ID.

Parameters
pMuxSocketthe connection from the user
channelInthe channel id
Returns
all channel associated information (output-channel id, cipher etc.)
Return values
NULLif not found

Definition at line 336 of file CAFirstMixChannelList.cpp.

337  {
338  if(pMuxSocket==NULL)
339  return NULL;
340  SINT32 hashkey=pMuxSocket->getHashKey();
341  if(hashkey>MAX_HASH_KEY-1||hashkey<0)
342  return NULL;
343  m_Mutex.lock();
344  fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
345  fmChannelListEntry* pEntry=pHashTableEntry->pChannelList;
346  while(pEntry!=NULL)
347  {
348  if(pEntry->channelIn==channelIn)
349  {
350  m_Mutex.unlock();
351  return pEntry;
352  }
353  pEntry=pEntry->list_InChannelPerSocket.next;
354  }
355  m_Mutex.unlock();
356  return NULL;
357  }

References t_firstmixchannellist::channelIn, CAMuxSocket::getHashKey(), t_firstmixchannellist::list_InChannelPerSocket, CAMutex::lock(), m_HashTable, m_Mutex, MAX_HASH_KEY, t_firstmixchannellist::next, t_fmhashtableentry::pChannelList, and CAMutex::unlock().

Referenced by CAFirstMixA::finishPacket(), CAFirstMixA::loop(), and CAFirstMixB::loop().

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

◆ get() [3/3]

fmChannelListEntry* CAFirstMixChannelList::get ( HCHANNEL  channelOut)
inline

Gets the in-channel and all associated information for the given out-channel.

Parameters
channelOutthe out-channel id for which the information is requested
Returns
the in-channel and all associated information
Return values
NULLif not found in list

Definition at line 333 of file CAFirstMixChannelList.hpp.

334  {
335  m_Mutex.lock();
336  fmChannelListEntry* pEntry=get_intern_without_lock(channelOut);
337  m_Mutex.unlock();
338  return pEntry;
339  }

References get_intern_without_lock(), CAMutex::lock(), m_Mutex, and CAMutex::unlock().

Here is the call graph for this function:

◆ get_intern_without_lock()

fmChannelListEntry* CAFirstMixChannelList::get_intern_without_lock ( HCHANNEL  channelOut)
inlineprivate

Gets the in-channel and all associated information for the given out-channel.

This method is NOT thread safe (and so only for internal use)

See also
get()
Parameters
channelOutthe out-channel id for which the information is requested
Returns
the in-channel and all associated information
Return values
NULLif not found in list

Definition at line 310 of file CAFirstMixChannelList.hpp.

311  {
312  fmChannelListEntry* pEntry=m_HashTableOutChannels[channelOut&0x0000FFFF];
313  while(pEntry!=NULL)
314  {
315  if(pEntry->channelOut==channelOut)
316  {
317  return pEntry;
318  }
319  pEntry=pEntry->list_OutChannelHashTable.next;
320  }
321  return NULL;
322  }

References t_firstmixchannellist::channelOut, t_firstmixchannellist::list_OutChannelHashTable, m_HashTableOutChannels, and t_firstmixchannellist::next.

Referenced by addChannel(), and get().

Here is the caller graph for this function:

◆ getFirst()

fmHashTableEntry * CAFirstMixChannelList::getFirst ( )

Gets the first connection of all connections in the list.

See also
getNext()
Returns
first connection in the list
Return values
NULLif no connection is in the list

Definition at line 1084 of file CAFirstMixChannelList.cpp.

1085  {
1086  m_Mutex.lock();
1087  if(m_listHashTableHead!=NULL)
1089  else
1090  m_listHashTableNext=NULL;
1091  m_Mutex.unlock();
1092  return m_listHashTableHead;
1093  }

References t_fmhashtableentry::list_HashEntries, CAMutex::lock(), m_listHashTableHead, m_listHashTableNext, m_Mutex, t_fmhashtableentry::next, and CAMutex::unlock().

Referenced by CAFirstMix::clean(), CAFirstMixA::loop(), CAFirstMixB::loop(), and CAFirstMixA::sendToUsers().

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

◆ getFirstChannelForSocket()

fmChannelListEntry * CAFirstMixChannelList::getFirstChannelForSocket ( CAMuxSocket pMuxSocket)

Gets the first channel for a given connection.

See also
getNextChannel()
Parameters
pMuxSocketthe connection from the user
Returns
the channel and the associated information
Return values
NULLif no channel for this connection exists at the moment

Definition at line 1116 of file CAFirstMixChannelList.cpp.

1117  {
1118  if(pMuxSocket==NULL)
1119  return NULL;
1120  SINT32 hashkey=pMuxSocket->getHashKey();
1121  if(hashkey>MAX_HASH_KEY-1||hashkey<0)
1122  return NULL;
1123  fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
1124  return pHashTableEntry->pChannelList;
1125  }

References CAMuxSocket::getHashKey(), m_HashTable, MAX_HASH_KEY, and t_fmhashtableentry::pChannelList.

Referenced by CAFirstMix::clean(), CAFirstMixA::closeConnection(), CAFirstMixB::loop(), and CAFirstMixA::notifyAllUserChannels().

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

◆ getNext()

fmHashTableEntry * CAFirstMixChannelList::getNext ( )

Gets the next entry in the connections-list.

See also
getFirst()
Returns
next entry in the connection list
Return values
NULLin case of an error

Definition at line 1100 of file CAFirstMixChannelList.cpp.

1101  {
1102  m_Mutex.lock();
1104  if(m_listHashTableNext!=NULL)
1106  m_Mutex.unlock();
1107  return tmpEntry;
1108  }

References t_fmhashtableentry::list_HashEntries, CAMutex::lock(), m_listHashTableNext, m_Mutex, t_fmhashtableentry::next, and CAMutex::unlock().

Referenced by CAFirstMix::clean(), CAFirstMixA::loop(), CAFirstMixB::loop(), and CAFirstMixA::sendToUsers().

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

◆ getNextChannel()

fmChannelListEntry * CAFirstMixChannelList::getNextChannel ( fmChannelListEntry pEntry)

Gets the next channel for a given connection.

See also
getFirstChannelForSocket()
Parameters
pEntrya entry returned by a previos call to getFirstChannelForSocket() or getNextChannel()
Returns
the next channel and all associated information
Return values
NULLif there are no more channels for this connection

Definition at line 1133 of file CAFirstMixChannelList.cpp.

1134  {
1135  if(pEntry==NULL)
1136  return NULL;
1137  return pEntry->list_InChannelPerSocket.next;
1138  }

References t_firstmixchannellist::list_InChannelPerSocket, and t_firstmixchannellist::next.

Referenced by CAFirstMix::clean(), CAFirstMixA::closeConnection(), CAFirstMixB::loop(), and CAFirstMixA::notifyAllUserChannels().

Here is the caller graph for this function:

◆ hasDelayBuckets()

bool CAFirstMixChannelList::hasDelayBuckets ( UINT32  delayBucketID)

Definition at line 1218 of file CAFirstMixChannelList.cpp.

1219  {
1220  bool ret = false;
1222  if(delayBucketID < MAX_POLLFD)
1223  {
1224  if(m_pDelayBuckets[delayBucketID] != NULL)
1225  {
1226  ret = ( (*(m_pDelayBuckets[delayBucketID])) > 0 );
1227  }
1228  }
1230  return ret;
1231  }

References CAMutex::lock(), m_pDelayBuckets, m_pMutexDelayChannel, MAX_POLLFD, and CAMutex::unlock().

Referenced by CAFirstMixA::sendToUsers().

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

◆ isKickoutForced()

bool CAFirstMixChannelList::isKickoutForced ( fmHashTableEntry pHashTableEntry)

Definition at line 387 of file CAFirstMixChannelList.cpp.

388 {
389  bool ret = false;
390  m_Mutex.lock();
391  ret = isKickoutForced_internal(pHashTableEntry);
392  m_Mutex.unlock();
393  return ret;
394 }
bool isKickoutForced_internal(fmHashTableEntry *pHashTableEntry)

References isKickoutForced_internal(), CAMutex::lock(), m_Mutex, and CAMutex::unlock().

Referenced by CAFirstMixA::checkUserConnections().

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

◆ isKickoutForced_internal()

bool CAFirstMixChannelList::isKickoutForced_internal ( fmHashTableEntry pHashTableEntry)
inlineprivate

Definition at line 436 of file CAFirstMixChannelList.cpp.

437 {
438  return !(pHashTableEntry->bRecoverTimeout);
439 }

References t_fmhashtableentry::bRecoverTimeout.

Referenced by isKickoutForced().

Here is the caller graph for this function:

◆ isTimedOut()

bool CAFirstMixChannelList::isTimedOut ( fmHashTableEntry pHashTableEntry)

Definition at line 376 of file CAFirstMixChannelList.cpp.

377 {
378  bool ret = false;
379 
380  m_Mutex.lock();
381  ret = isTimedOut_internal(pHashTableEntry);
382  m_Mutex.unlock();
383 
384  return ret;
385 }
bool isTimedOut_internal(fmHashTableEntry *pHashTableEntry)

References isTimedOut_internal(), CAMutex::lock(), m_Mutex, and CAMutex::unlock().

Referenced by CAFirstMixA::checkUserConnections().

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

◆ isTimedOut_internal()

bool CAFirstMixChannelList::isTimedOut_internal ( fmHashTableEntry pHashTableEntry)
inlineprivate

Definition at line 431 of file CAFirstMixChannelList.cpp.

432 {
433  return (pHashTableEntry->list_TimeoutHashEntries.timoutSecs <= time(NULL));
434 }

References t_fmhashtableentry::list_TimeoutHashEntries, and t_fmhashtableentry::timoutSecs.

Referenced by isTimedOut(), and popTimeoutEntry_internal().

Here is the caller graph for this function:

◆ popTimeoutEntry() [1/2]

fmHashTableEntry * CAFirstMixChannelList::popTimeoutEntry ( )
inline
Returns
pops the next expired entry from the queue or returns NULL if there are no exired entries

Definition at line 360 of file CAFirstMixChannelList.cpp.

361 {
362  return popTimeoutEntry(false);
363 }
fmHashTableEntry * popTimeoutEntry()

Referenced by CAFirstMixA::checkUserConnections(), and CAFirstMixA::shutDown().

Here is the caller graph for this function:

◆ popTimeoutEntry() [2/2]

fmHashTableEntry * CAFirstMixChannelList::popTimeoutEntry ( bool  a_bForce)
Parameters
ifset to true, forces to return the next timeout enty or NULL if none are left in the queue
Returns
if set to true, forces to return the next timeout enty or NULL if none are left in the queue

Definition at line 365 of file CAFirstMixChannelList.cpp.

366 {
367  fmHashTableEntry* ret;
368 
369  m_Mutex.lock();
370  ret = popTimeoutEntry_internal(a_bForce);
371  m_Mutex.unlock();
372 
373  return ret;
374 }
fmHashTableEntry * popTimeoutEntry_internal(bool a_bForce)

◆ popTimeoutEntry_internal()

fmHashTableEntry * CAFirstMixChannelList::popTimeoutEntry_internal ( bool  a_bForce)
private

Definition at line 454 of file CAFirstMixChannelList.cpp.

455 {
456  fmHashTableEntry* pHashTableEntry;
457 
458  if (m_listTimoutHead == NULL)
459  {
460  // there are not entries in the list
461  return NULL;
462  }
463 
464  pHashTableEntry = m_listTimoutHead;
465  if (a_bForce || isTimedOut_internal(pHashTableEntry))
466  {
467  if (removeFromTimeoutList(pHashTableEntry) == E_SUCCESS)
468  {
469  return pHashTableEntry;
470  }
471  else
472  {
473  CAMsg::printMsg(LOG_CRIT,
474  "CAFirstMixChannelList:popTimeoutEntry_internal: Could not remove expired entry from timeout list!\n");
475  }
476  }
477 
478  return NULL;
479 }
SINT32 removeFromTimeoutList(fmHashTableEntry *pHashTableEntry)

References E_SUCCESS, isTimedOut_internal(), m_listTimoutHead, CAMsg::printMsg(), and removeFromTimeoutList().

Here is the call graph for this function:

◆ pushTimeoutEntry()

SINT32 CAFirstMixChannelList::pushTimeoutEntry ( fmHashTableEntry pHashTableEntry,
bool  kickoutForced = !KICKOUT_FORCED 
)

adds the entry to the timeout queue with mutex

Definition at line 483 of file CAFirstMixChannelList.cpp.

484 {
485  SINT32 ret;
486 
487  m_Mutex.lock();
488  ret = pushTimeoutEntry_internal(pHashTableEntry, kickoutForced);
489  m_Mutex.unlock();
490 
491  return ret;
492 }
SINT32 pushTimeoutEntry_internal(fmHashTableEntry *pHashTableEntry, bool kickoutForced=!KICKOUT_FORCED)
adds the entry to the timeout queue

References CAMutex::lock(), m_Mutex, pushTimeoutEntry_internal(), and CAMutex::unlock().

Referenced by CAFirstMixA::accountTrafficDownstream(), CAFirstMixA::accountTrafficUpstream(), CAFirstMixA::checkUserConnections(), and CAFirstMixA::loop().

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

◆ pushTimeoutEntry_internal()

SINT32 CAFirstMixChannelList::pushTimeoutEntry_internal ( fmHashTableEntry pHashTableEntry,
bool  kickoutForced = !KICKOUT_FORCED 
)
private

adds the entry to the timeout queue

renews the timestamp for the timeout list does not affect forced kickouts.

Definition at line 512 of file CAFirstMixChannelList.cpp.

513 {
514  if (pHashTableEntry == NULL)
515  {
516  return E_UNKNOWN;
517  }
518 
519 
520  /*if(isKickoutForced_internal(pHashTableEntry))
521  {
522  return E_SUCCESS;
523  }*/
524 
525  INIT_STACK;
526  BEGIN_STACK("CAFirstMixChannelList::pushTimeoutEntry_internal");
527 
528  //CAMsg::printMsg(LOG_DEBUG,"Entries in timeout list before push: %d\n", countTimeoutEntries());
529 
530  pHashTableEntry->list_TimeoutHashEntries.timoutSecs = time(NULL) + EXPIRATION_TIME_SECS;
531 
532  //SAVE_STACK("CAFirstMixChannelList::pushTimeoutEntry_internal", "removing from timeout list");
533  // remove from timeout list if needed before adding it to the end
534  removeFromTimeoutList(pHashTableEntry);
535  setKickoutForced_internal(pHashTableEntry, kickoutForced);
536  if (m_listTimoutFoot == NULL)
537  {
538  //SAVE_STACK("CAFirstMixChannelList::pushTimeoutEntry_internal", "new first entry");
539 
540  // this is the first entry in the list
541  pHashTableEntry->list_TimeoutHashEntries.prev = NULL;
542  m_listTimoutHead = pHashTableEntry;
543  }
544  else
545  {
546  //SAVE_STACK("CAFirstMixChannelList::pushTimeoutEntry_internal", "new last entry");
547  // this is the new last entry in the list
548  m_listTimoutFoot->list_TimeoutHashEntries.next = pHashTableEntry;
549  pHashTableEntry->list_TimeoutHashEntries.prev = m_listTimoutFoot;
550  }
551  pHashTableEntry->list_TimeoutHashEntries.next = NULL;
552  m_listTimoutFoot = pHashTableEntry;
553 
554  //CAMsg::printMsg(LOG_DEBUG,"Entries in timeout list after push: %d\n", countTimeoutEntries());
555 
556  FINISH_STACK("CAFirstMixChannelList::pushTimeoutEntry_internal");
557  //CAMsg::printMsg(LOG_DEBUG, "CAFirstMixA: pushed entry %x!\n", pHashTableEntry);
558  return E_SUCCESS;
559 
560 }
static const SINT32 EXPIRATION_TIME_SECS

References BEGIN_STACK, E_SUCCESS, E_UNKNOWN, EXPIRATION_TIME_SECS, FINISH_STACK, INIT_STACK, t_fmhashtableentry::list_TimeoutHashEntries, m_listTimoutFoot, m_listTimoutHead, t_fmhashtableentry::next, t_fmhashtableentry::prev, removeFromTimeoutList(), setKickoutForced_internal(), and t_fmhashtableentry::timoutSecs.

Referenced by pushTimeoutEntry().

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

◆ remove()

SINT32 CAFirstMixChannelList::remove ( CAMuxSocket pMuxSocket)

Removes all channels, which belongs to the given connection and the connection itself from the list.

Parameters
pMuxSocketthe connection from the user
Return values
E_SUCCESSif successful
E_UNKNOWNin case of an error

Definition at line 643 of file CAFirstMixChannelList.cpp.

644  {
645  if(pMuxSocket==NULL)
646  return E_UNKNOWN;
647  SINT32 hashkey=pMuxSocket->getHashKey();
648  if(hashkey>MAX_HASH_KEY-1||hashkey<0)
649  return E_UNKNOWN;
650  m_Mutex.lock();
651  fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
652  if(pHashTableEntry->pMuxSocket==NULL) //this connection is not in the list
653  {
654  m_Mutex.unlock();
655  return E_UNKNOWN;
656  }
657  #ifdef DELAY_USERS
659  m_pDelayBuckets[pHashTableEntry->delayBucketID]=NULL;
661  #endif
663  delete pHashTableEntry->pControlChannelDispatcher; //deletes the dispatcher and all associated control channels
664  delete pHashTableEntry->pControlMessageQueue;
665  pHashTableEntry->pControlChannelDispatcher = NULL;
666  pHashTableEntry->pControlMessageQueue = NULL;
667  if(m_listHashTableNext==pHashTableEntry) //adjust the enumeration over all connections (@see getNext())
668  m_listHashTableNext=pHashTableEntry->list_HashEntries.next;
669 
670  if(pHashTableEntry->list_HashEntries.prev==NULL) //if entry is the head of the connection list
671  {
672  if(pHashTableEntry->list_HashEntries.next==NULL) //if entry is also the last (so the only one in the list..)
673  {
674  m_listHashTableHead=NULL; //list is now empty
675  }
676  else
677  {//remove the head of the list
678  m_listHashTableHead=pHashTableEntry->list_HashEntries.next;
680  }
681  }
682  else
683  { //the connection is not the head of the list
684  if(pHashTableEntry->list_HashEntries.next==NULL)
685  {//the connection is the last element in the list
686  pHashTableEntry->list_HashEntries.prev->list_HashEntries.next=NULL;
687  }
688  else
689  {//its a simple middle element
690  pHashTableEntry->list_HashEntries.prev->list_HashEntries.next=pHashTableEntry->list_HashEntries.next;
691  pHashTableEntry->list_HashEntries.next->list_HashEntries.prev=pHashTableEntry->list_HashEntries.prev;
692  }
693  }
694 
695 
696 #ifdef PAYMENT
697  removeFromTimeoutList(pHashTableEntry);
698 #endif
699 
700  fmChannelListEntry* pEntry=pHashTableEntry->pChannelList;
701  fmChannelListEntry* pTmpEntry;
702  while(pEntry!=NULL)//for all channels....
703  {
704  //remove the out channel form the out channel hast table
705  hashkey=pEntry->channelOut&0x0000FFFF;
706  pTmpEntry=m_HashTableOutChannels[hashkey];
707  while(pTmpEntry!=NULL)
708  {
709  if(pTmpEntry->channelOut==pEntry->channelOut)
710  {//we have found the entry
711  if(pTmpEntry->list_OutChannelHashTable.prev==NULL) //it's the head
712  {
713  if(pTmpEntry->list_OutChannelHashTable.next==NULL)
714  {//it's also the last Element
715  m_HashTableOutChannels[hashkey]=NULL; //empty this hash bucket
716  }
717  else
718  {
721  }
722  }
723  else
724  {//not the head
725  if(pTmpEntry->list_OutChannelHashTable.next==NULL)
726  {//but the last
728  }
729  else
730  {//a middle element
733  }
734  }
735  break;
736  }
737  pTmpEntry=pTmpEntry->list_OutChannelHashTable.next;
738  }
739 
740  pTmpEntry=pEntry->list_InChannelPerSocket.next;
741 #ifndef DO_TRACE
742  delete pEntry;
743  pEntry = NULL;
744 #else
745  deleteChannelListEntry(pEntry);
746 #endif
747  pEntry=pTmpEntry;
748  }
749 /* already done by pHashTableEntry->pControlChannelDispatcher->deleteAllControlChannels();
750 #ifdef PAYMENT
751  // cleanup accounting information
752  CAAccountingInstance::cleanupTableEntry(pHashTableEntry);
753 #endif
754 */
755 #ifdef LOG_DIALOG
756  delete[] pHashTableEntry->strDialog;
757  pHashTableEntry->strDialog = NULL;
758 #endif
759 #ifdef PAYMENT
760  CAConditionVariable *rescue = pHashTableEntry->cleanupNotifier;
761 #endif
762  //TODO: a bit more precise reference cleanup
763  memset(pHashTableEntry,0,sizeof(fmHashTableEntry)); //'delete' the connection from the connection hash table
764 
765 #ifdef PAYMENT
766  pHashTableEntry->cleanupNotifier = rescue;
767  pHashTableEntry->cleanupNotifier->lock();
768  pHashTableEntry->cleanupNotifier->signal();
769  pHashTableEntry->cleanupNotifier->unlock();
770 #endif
771  m_Mutex.unlock();
772  return E_SUCCESS;
773  }
SINT32 signal()
Signals this object.
void deleteAllControlChannels(void)
Deregisters all control channels and calls delete on every registered control channel object.

References t_firstmixchannellist::channelOut, t_fmhashtableentry::cleanupNotifier, t_fmhashtableentry::delayBucketID, CAControlChannelDispatcher::deleteAllControlChannels(), E_SUCCESS, E_UNKNOWN, CAMuxSocket::getHashKey(), t_fmhashtableentry::list_HashEntries, t_firstmixchannellist::list_InChannelPerSocket, t_firstmixchannellist::list_OutChannelHashTable, CAMutex::lock(), m_HashTable, m_HashTableOutChannels, m_listHashTableHead, m_listHashTableNext, m_Mutex, m_pDelayBuckets, m_pMutexDelayChannel, MAX_HASH_KEY, t_fmhashtableentry::next, t_firstmixchannellist::next, t_fmhashtableentry::pChannelList, t_fmhashtableentry::pControlChannelDispatcher, t_fmhashtableentry::pControlMessageQueue, t_fmhashtableentry::pMuxSocket, t_fmhashtableentry::prev, t_firstmixchannellist::prev, removeFromTimeoutList(), CAConditionVariable::signal(), and CAMutex::unlock().

Referenced by CAFirstMix::clean(), CAFirstMixA::closeConnection(), CAFirstMix::doUserLogin_internal(), CAFirstMixB::loop(), and test().

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

◆ removeChannel()

SINT32 CAFirstMixChannelList::removeChannel ( CAMuxSocket pMuxSocket,
HCHANNEL  channelIn 
)

Removes a single channel from the list.

Parameters
pMuxSocketthe connection from the user
channelInthe channel, which should be removed
Return values
E_SUCCESSif successful
E_UNKNOWNin case of an error

Definition at line 983 of file CAFirstMixChannelList.cpp.

984  {
985  if(pMuxSocket==NULL)
986  return E_UNKNOWN;
987  SINT32 hashkey=pMuxSocket->getHashKey();
988  if(hashkey>MAX_HASH_KEY-1||hashkey<0)
989  return E_UNKNOWN;
990  m_Mutex.lock();
991  fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
992  if(pHashTableEntry->pMuxSocket==NULL)
993  {
994  m_Mutex.unlock();
995  return E_UNKNOWN;
996  }
997  fmChannelListEntry* pEntry=pHashTableEntry->pChannelList;
998  while(pEntry!=NULL)
999  {
1000  if(pEntry->channelIn==channelIn) //search for the channel
1001  {
1002  hashkey=pEntry->channelOut&0x0000FFFF; //remove the out channel from the out channel hash table
1003  fmChannelListEntry*pTmpEntry=m_HashTableOutChannels[hashkey];
1004  while(pTmpEntry!=NULL)
1005  {
1006  if(pTmpEntry->channelOut==pEntry->channelOut)
1007  {//found it in the out channel hash table
1008  if(pTmpEntry->list_OutChannelHashTable.prev==NULL) //head
1009  {
1010  if(pTmpEntry->list_OutChannelHashTable.next==NULL)
1011  {
1012  m_HashTableOutChannels[hashkey]=NULL;
1013  }
1014  else
1015  {
1016 
1019  }
1020  }
1021  else
1022  {
1023  if(pTmpEntry->list_OutChannelHashTable.next==NULL)
1024  {//last element
1026  }
1027  else
1028  {//middle element
1031  }
1032  }
1033  break;
1034  }
1035  pTmpEntry=pTmpEntry->list_OutChannelHashTable.next;
1036  }
1037 
1038  //remove the channel from the channel hast table
1039  if(pEntry->list_InChannelPerSocket.prev==NULL) //head
1040  {
1041  if(pEntry->list_InChannelPerSocket.next==NULL)
1042  {//the only element
1043  pHashTableEntry->pChannelList=NULL;
1044  }
1045  else
1046  {
1048  pHashTableEntry->pChannelList=pEntry->list_InChannelPerSocket.next;
1049  }
1050  }
1051  else
1052  {
1053  if(pEntry->list_InChannelPerSocket.next==NULL)
1054  {//the last element
1056  }
1057  else
1058  {//a middle element
1061  }
1062  }
1063  #ifndef DO_TRACE
1064  delete pEntry;
1065  pEntry = NULL;
1066  #else
1067  deleteChannelListEntry(pEntry);
1068  #endif
1069  pHashTableEntry->cNumberOfChannels--;
1070  m_Mutex.unlock();
1071  return E_SUCCESS;
1072  }
1073  pEntry=pEntry->list_InChannelPerSocket.next; //try next channel
1074  }
1075  m_Mutex.unlock();
1076  return E_UNKNOWN;//not found
1077  }

References t_firstmixchannellist::channelIn, t_firstmixchannellist::channelOut, t_fmhashtableentry::cNumberOfChannels, E_SUCCESS, E_UNKNOWN, CAMuxSocket::getHashKey(), t_firstmixchannellist::list_InChannelPerSocket, t_firstmixchannellist::list_OutChannelHashTable, CAMutex::lock(), m_HashTable, m_HashTableOutChannels, m_Mutex, MAX_HASH_KEY, t_firstmixchannellist::next, t_fmhashtableentry::pChannelList, t_fmhashtableentry::pMuxSocket, t_firstmixchannellist::prev, and CAMutex::unlock().

Referenced by CAFirstMixA::finishPacket(), CAFirstMixA::loop(), CAFirstMixB::loop(), and test().

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

◆ removeFromTimeoutList()

SINT32 CAFirstMixChannelList::removeFromTimeoutList ( fmHashTableEntry pHashTableEntry)
private

Definition at line 564 of file CAFirstMixChannelList.cpp.

565 {
566  if (pHashTableEntry == NULL)
567  {
568  return E_UNKNOWN;
569  }
570 
571  //CAMsg::printMsg(LOG_DEBUG, "CAFirstMixA: removing entry %x!\n", pHashTableEntry);
572 
573  if (m_listTimoutHead == NULL || m_listTimoutFoot == NULL)
574  {
575  // there is no entry in the list; therefore this entry does not need to be removed
576  return E_SUCCESS;
577  }
578 
579  if (pHashTableEntry->list_TimeoutHashEntries.prev == NULL &&
580  pHashTableEntry->list_TimeoutHashEntries.next == NULL &&
581  m_listTimoutHead != pHashTableEntry)
582  {
583  // this entry is not in the list; it does not need to be removed
584  return E_SUCCESS;
585  }
586 
587  if(m_listTimoutHead == pHashTableEntry) //if entry is the head of the connection list
588  {
589  if(m_listTimoutFoot == pHashTableEntry) //if entry is also the last (so the only one in the list..)
590  {
591  //list is now empty
592  m_listTimoutHead = NULL;
593  m_listTimoutFoot = NULL;
594  }
595  else
596  {
597  //remove the head of the list
598  m_listTimoutHead = pHashTableEntry->list_TimeoutHashEntries.next;
599  }
600  }
601  else
602  { //the connection is not the head of the list
603  if(pHashTableEntry->list_TimeoutHashEntries.next == NULL)
604  {
605  //the connection is the last element in the list
606  m_listTimoutFoot = pHashTableEntry->list_TimeoutHashEntries.prev;
608  }
609  else
610  {
611  //it is a simple middle element
612  if (pHashTableEntry->list_TimeoutHashEntries.prev == NULL)
613  {
614  CAMsg::printMsg(LOG_CRIT, "CAFirstMixChannelList:removeFromTimeoutList: No previous element!!\n");
615  }
616  else
617  {
619  }
620  if (pHashTableEntry->list_TimeoutHashEntries.next == NULL)
621  {
622  CAMsg::printMsg(LOG_CRIT, "CAFirstMixChanelList:removeFromTimeoutList: No next element!!\n");
623  }
624  else
625  {
627  }
628  }
629  }
630  pHashTableEntry->list_TimeoutHashEntries.prev = NULL;
631  pHashTableEntry->list_TimeoutHashEntries.next = NULL;
632 
633  return E_SUCCESS;
634 }

References E_SUCCESS, E_UNKNOWN, t_fmhashtableentry::list_TimeoutHashEntries, m_listTimoutFoot, m_listTimoutHead, t_fmhashtableentry::next, t_fmhashtableentry::prev, and CAMsg::printMsg().

Referenced by popTimeoutEntry_internal(), pushTimeoutEntry_internal(), and remove().

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

◆ setDelayParameters()

void CAFirstMixChannelList::setDelayParameters ( UINT32  unlimitTraffic,
UINT32  bucketGrow,
UINT32  intervall 
)

Definition at line 1233 of file CAFirstMixChannelList.cpp.

1234  {
1236  CAMsg::printMsg(LOG_DEBUG,"CAFirstMixChannelList - Set new traffic limit per user- unlimit: %u bucketgrow: %u intervall %u\n",
1237  unlimitTraffic,bucketGrow,intervall);
1238  m_u32DelayChannelUnlimitTraffic=unlimitTraffic;
1239  m_u32DelayChannelBucketGrow=bucketGrow;
1241  for(UINT32 i=0;i<MAX_POLLFD;i++)
1242  if(m_pDelayBuckets[i]!=NULL)
1245  }

References CAMutex::lock(), m_pDelayBuckets, m_pMutexDelayChannel, m_u32DelayChannelBucketGrow, m_u32DelayChannelBucketGrowIntervall, m_u32DelayChannelUnlimitTraffic, MAX_POLLFD, CAMsg::printMsg(), and CAMutex::unlock().

Referenced by CAFirstMixA::loop(), CAFirstMixB::loop(), and CAFirstMix::reconfigure().

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

◆ setKickoutForced()

void CAFirstMixChannelList::setKickoutForced ( fmHashTableEntry pHashTableEntry,
bool  kickoutForced 
)

Definition at line 395 of file CAFirstMixChannelList.cpp.

396 {
397  m_Mutex.lock();
398  setKickoutForced_internal(pHashTableEntry, kickoutForced);
399  m_Mutex.unlock();
400 }

References CAMutex::lock(), m_Mutex, setKickoutForced_internal(), and CAMutex::unlock().

Referenced by CAFirstMixA::accountTrafficDownstream(), and CAFirstMixA::accountTrafficUpstream().

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

◆ setKickoutForced_internal()

void CAFirstMixChannelList::setKickoutForced_internal ( fmHashTableEntry pHashTableEntry,
bool  kickoutForced 
)
inlineprivate

Definition at line 441 of file CAFirstMixChannelList.cpp.

442 {
443  if(!pHashTableEntry->bRecoverTimeout && !kickoutForced )
444  {
445  CAMsg::printMsg(LOG_WARNING, "Try to switch back from forced kickout. A forced kickout cannot be undone!\n");
446  }
447  else
448  {
449  pHashTableEntry->bRecoverTimeout = !kickoutForced;
450  }
451 
452 }

References t_fmhashtableentry::bRecoverTimeout, and CAMsg::printMsg().

Referenced by forceKickout(), pushTimeoutEntry_internal(), and setKickoutForced().

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

◆ test()

SINT32 CAFirstMixChannelList::test ( )
static

Definition at line 1140 of file CAFirstMixChannelList.cpp.

1141  {
1143  CAMuxSocket *pMuxSocket=new CAMuxSocket(OFB);
1144  pMuxSocket->getCASocket()->create();
1145  UINT8 peerIP[4];
1146 #ifndef LOG_DIALOG
1147  pList->add(pMuxSocket,peerIP,NULL,NULL,NULL);
1148 #else
1149  pList->add(pMuxSocket,peerIP,NULL,(UINT8*)"1");
1150 #endif
1151 #if defined(HAVE_CRTDBG)
1152  _CrtMemState s1, s2, s3;
1153  _CrtMemCheckpoint( &s1 );
1154 #endif
1155  UINT32 /*channelIn,*/i,channelOut;
1156  for(i=0;i<50;i++)
1157  pList->addChannel(pMuxSocket,i,NULL,&channelOut);
1158  for(i=0;i<50;i++)
1159  pList->removeChannel(pMuxSocket,i);
1160 #if defined(HAVE_CRTDBG)
1161  _CrtMemCheckpoint( &s2 );
1162  if ( _CrtMemDifference( &s3, &s1, &s2 ) )
1163  _CrtMemDumpStatistics( &s3 );
1164 #endif
1165 
1166  pList->remove(pMuxSocket);
1167  delete pMuxSocket;
1168  pMuxSocket = NULL;
1169  delete pList;
1170  pList = NULL;
1171  return E_SUCCESS;
1172  }
Data structure that stores all information about the currently open Mix channels.
SINT32 addChannel(CAMuxSocket *pMuxSocket, HCHANNEL channelIn, CASymChannelCipher *pCipher, HCHANNEL *channelOut)
Adds a new channel for a given connection to the channel list.
SINT32 removeChannel(CAMuxSocket *pMuxSocket, HCHANNEL channelIn)
Removes a single channel from the list.
fmHashTableEntry * add(CAMuxSocket *pMuxSocket, const UINT8 peerIP[4], CAQueue *pQueueSend, UINT8 *controlChannelKeyRecv, UINT8 *controlChannelKeySent)
Adds a new TCP/IP connection (a new user) to the channel list.
SINT32 remove(CAMuxSocket *pMuxSocket)
Removes all channels, which belongs to the given connection and the connection itself from the list.
virtual SINT32 create()
Definition: CASocket.cpp:73

References add(), addChannel(), CAFirstMixChannelList(), CASocket::create(), E_SUCCESS, CAMuxSocket::getCASocket(), OFB, remove(), and removeChannel().

Here is the call graph for this function:

Friends And Related Function Documentation

◆ fml_loopDelayBuckets

THREAD_RETURN fml_loopDelayBuckets ( void *  )
friend

Definition at line 1175 of file CAFirstMixChannelList.cpp.

1176  {
1177  INIT_STACK;
1178  BEGIN_STACK("CAFirstMixChannelList::fml_loopDelayBuckets");
1179 
1180  CAFirstMixChannelList* pChannelList=(CAFirstMixChannelList*)param;
1181  volatile UINT32** pDelayBuckets=pChannelList->m_pDelayBuckets;
1182  while(pChannelList->m_bDelayBucketsLoopRun)
1183  {
1184  pChannelList->m_pMutexDelayChannel->lock();
1185  UINT32 u32BucketGrow=pChannelList->m_u32DelayChannelBucketGrow;
1186  UINT32 u32MaxBucket=u32BucketGrow*10;
1187  for(UINT32 i=0;i<MAX_POLLFD;i++)
1188  {
1189  if(pDelayBuckets[i]!=NULL&&*(pDelayBuckets[i])<u32MaxBucket)
1190  {
1191  *(pDelayBuckets[i])+=u32BucketGrow;
1192  }
1193  }
1194  pChannelList->m_pMutexDelayChannel->unlock();
1196  }
1197 
1198  FINISH_STACK("CAFirstMixChannelList::fml_loopDelayBuckets");
1199 
1201  }
SINT32 msSleep(UINT32 ms)
Sleeps ms milliseconds.
Definition: CAUtil.cpp:406
#define THREAD_RETURN_SUCCESS
Definition: StdAfx.h:542

Referenced by CAFirstMixChannelList().

Member Data Documentation

◆ EXPIRATION_TIME_SECS

const SINT32 CAFirstMixChannelList::EXPIRATION_TIME_SECS = 300
staticprivate

Definition at line 341 of file CAFirstMixChannelList.hpp.

Referenced by pushTimeoutEntry_internal().

◆ m_bDelayBucketsLoopRun

bool CAFirstMixChannelList::m_bDelayBucketsLoopRun
private

Definition at line 366 of file CAFirstMixChannelList.hpp.

Referenced by CAFirstMixChannelList(), and ~CAFirstMixChannelList().

◆ m_HashTable

LP_fmHashTableEntry* CAFirstMixChannelList::m_HashTable
private

The Hash-Table of all connections.

Definition at line 344 of file CAFirstMixChannelList.hpp.

Referenced by addChannel(), CAFirstMixChannelList(), get(), getFirstChannelForSocket(), remove(), removeChannel(), and ~CAFirstMixChannelList().

◆ m_HashTableOutChannels

LP_fmChannelListEntry* CAFirstMixChannelList::m_HashTableOutChannels
private

The Hash-Table of all out-channels.

Definition at line 346 of file CAFirstMixChannelList.hpp.

Referenced by addChannel(), CAFirstMixChannelList(), get_intern_without_lock(), remove(), removeChannel(), and ~CAFirstMixChannelList().

◆ m_listHashTableHead

fmHashTableEntry* CAFirstMixChannelList::m_listHashTableHead
private

Pointer to the head of a list of all connections.

Definition at line 349 of file CAFirstMixChannelList.hpp.

Referenced by CAFirstMixChannelList(), getFirst(), and remove().

◆ m_listHashTableNext

fmHashTableEntry* CAFirstMixChannelList::m_listHashTableNext
private

Next Element in the enumeration of all connections.

Definition at line 351 of file CAFirstMixChannelList.hpp.

Referenced by CAFirstMixChannelList(), getFirst(), getNext(), and remove().

◆ m_listTimoutFoot

fmHashTableEntry* CAFirstMixChannelList::m_listTimoutFoot
private

◆ m_listTimoutHead

fmHashTableEntry* CAFirstMixChannelList::m_listTimoutHead
private

Pointer to the head of the timout list of all connections.

Definition at line 354 of file CAFirstMixChannelList.hpp.

Referenced by CAFirstMixChannelList(), countTimeoutEntries(), popTimeoutEntry_internal(), pushTimeoutEntry_internal(), and removeFromTimeoutList().

◆ m_Mutex

CAMutex CAFirstMixChannelList::m_Mutex
private

This mutex is used in all functions and makes them thread safe.

Definition at line 358 of file CAFirstMixChannelList.hpp.

Referenced by addChannel(), forceKickout(), get(), getFirst(), getNext(), isKickoutForced(), isTimedOut(), pushTimeoutEntry(), remove(), removeChannel(), and setKickoutForced().

◆ m_pDelayBuckets

volatile UINT32** CAFirstMixChannelList::m_pDelayBuckets
private

◆ m_pMutexDelayChannel

CAMutex* CAFirstMixChannelList::m_pMutexDelayChannel
private

◆ m_pThreadDelayBucketsLoop

CAThread* CAFirstMixChannelList::m_pThreadDelayBucketsLoop
private

Definition at line 364 of file CAFirstMixChannelList.hpp.

Referenced by CAFirstMixChannelList(), and ~CAFirstMixChannelList().

◆ m_u32DelayChannelBucketGrow

volatile UINT32 CAFirstMixChannelList::m_u32DelayChannelBucketGrow
private

Definition at line 370 of file CAFirstMixChannelList.hpp.

Referenced by CAFirstMixChannelList(), and setDelayParameters().

◆ m_u32DelayChannelBucketGrowIntervall

volatile UINT32 CAFirstMixChannelList::m_u32DelayChannelBucketGrowIntervall
private

Definition at line 371 of file CAFirstMixChannelList.hpp.

Referenced by CAFirstMixChannelList(), and setDelayParameters().

◆ m_u32DelayChannelUnlimitTraffic

volatile UINT32 CAFirstMixChannelList::m_u32DelayChannelUnlimitTraffic
private

Definition at line 369 of file CAFirstMixChannelList.hpp.

Referenced by CAFirstMixChannelList(), and setDelayParameters().


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