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

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

#include <CAFirstMixChannelList.hpp>

Collaboration diagram for CAFirstMixChannelList:
[legend]

List of all members.

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.
SINT32 addChannel (CAMuxSocket *pMuxSocket, HCHANNEL channelIn, CASymCipher *pCipher, HCHANNEL *channelOut)
 Adds a new channel for a given connection to the channel list.
fmChannelListEntryget (CAMuxSocket *pMuxSocket, HCHANNEL channelIn)
 Returns the information for a given Input-Channel-ID.
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.
SINT32 pushTimeoutEntry (fmHashTableEntry *pHashTableEntry, bool kickoutForced=!KICKOUT_FORCED)
 adds the entry to the timeout queue with mutex
SINT32 remove (CAMuxSocket *pMuxSocket)
 Removes all channels, which belongs to the given connection and the connection itself from the list.
SINT32 removeChannel (CAMuxSocket *pMuxSocket, HCHANNEL channelIn)
 Removes a single channel from the list.
fmHashTableEntrygetFirst ()
 Gets the first connection of all connections in the list.
fmHashTableEntrygetNext ()
 Gets the next entry in the connections-list.
fmHashTableEntryget (CAMuxSocket *pMuxSocket)
 Returns the general data stored for a given Socket (user)
fmChannelListEntrygetFirstChannelForSocket (CAMuxSocket *pMuxSocket)
 Gets the first channel for a given connection.
fmChannelListEntrygetNextChannel (fmChannelListEntry *pEntry)
 Gets the next channel for a given connection.
fmChannelListEntryget (HCHANNEL channelOut)
 Gets the in-channel and all associated information for the given out-channel.
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
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.
bool isTimedOut_internal (fmHashTableEntry *pHashTableEntry)

Private Attributes

LP_fmHashTableEntrym_HashTable
 The Hash-Table of all connections.
LP_fmChannelListEntrym_HashTableOutChannels
 The Hash-Table of all out-channels.
fmHashTableEntrym_listHashTableHead
 Pointer to the head of a list of all connections.
fmHashTableEntrym_listHashTableNext
 Next Element in the enumeration of all connections.
fmHashTableEntrym_listTimoutHead
 Pointer to the head of the timout list of all connections.
fmHashTableEntrym_listTimoutFoot
CAMutex m_Mutex
 This mutex is used in all functions and makes them thread safe.
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 221 of file CAFirstMixChannelList.hpp.


Constructor & Destructor Documentation

Definition at line 43 of file CAFirstMixChannelList.cpp.

References t_fmhashtableentry::cleanupNotifier, DELAY_USERS_BUCKET_GROW, DELAY_USERS_BUCKET_GROW_INTERVALL, 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:

Definition at line 80 of file CAFirstMixChannelList.cpp.

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

  {
#ifdef DELAY_USERS
    m_bDelayBucketsLoopRun=false;
    m_pThreadDelayBucketsLoop->join();
    delete m_pThreadDelayBucketsLoop;
    m_pThreadDelayBucketsLoop = NULL;
    delete m_pMutexDelayChannel;
    m_pMutexDelayChannel = NULL;
    delete []m_pDelayBuckets;
    m_pDelayBuckets = NULL;
#endif
    for(int i=0;i<MAX_HASH_KEY;i++)
        {

#ifdef PAYMENT
          delete m_HashTable[i]->cleanupNotifier;
          m_HashTable[i]->cleanupNotifier = NULL;
#endif
          delete m_HashTable[i];
          m_HashTable[i] = NULL;
        }
    delete []m_HashTable;
    m_HashTable = NULL;
    delete []m_HashTableOutChannels;
    m_HashTableOutChannels = NULL;
  }

Here is the call graph for this function:


Member Function Documentation

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.

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().

  {
    INIT_STACK;
    BEGIN_STACK("CAFirstMixChannelList::add");

    if(pMuxSocket==NULL)
    {
      FINISH_STACK("CAFirstMixChannelList::add (null socket)");
      return NULL;
    }
    SINT32 hashkey=pMuxSocket->getHashKey();
    if(hashkey>MAX_HASH_KEY-1||hashkey<0)
    {
      FINISH_STACK("CAFirstMixChannelList::add (invalid hash key)");
      return NULL;
    }
    m_Mutex.lock();
    fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
    if(pHashTableEntry->pMuxSocket!=NULL) //the entry in the hashtable for this socket (hashkey) must be empty
    {
      FINISH_STACK("CAFirstMixChannelList::add (socket exists)");
      m_Mutex.unlock();
      return NULL;
    }

    //SAVE_STACK("CAFirstMixChannelList::add", "initialising table entry");
#ifdef CH_LOG_STUDY
    pHashTableEntry->channelOpenedLastIntervalTS = 0;
#endif
    pHashTableEntry->pMuxSocket=pMuxSocket;
    pHashTableEntry->pQueueSend=pQueueSend;
    pHashTableEntry->pControlMessageQueue = new CAQueue();
    pHashTableEntry->pControlChannelDispatcher = new CAControlChannelDispatcher(pHashTableEntry->pControlMessageQueue,controlChannelKeyRecv,controlChannelKeySent);
    pHashTableEntry->uAlreadySendPacketSize=-1;
    pHashTableEntry->cNumberOfChannels=0;
#ifdef LOG_TRAFFIC_PER_USER
    pHashTableEntry->trafficIn=0;
    pHashTableEntry->trafficOut=0;
    getcurrentTimeMillis(pHashTableEntry->timeCreated);
#endif
#ifdef LOG_DIALOG
    pHashTableEntry->strDialog=new UINT8[strlen((char*)strDialog)+1];
    strcpy((char*)pHashTableEntry->strDialog,(char*)strDialog);
#endif
    // TODO Collisions? Is the id still used somewhere?
    //Yes it is --> for logging to match login /logout
    //collisions in a hard seens are an issue, but are very unlikely; and because it is only for logging it does not really matter...
    getRandom(&(pHashTableEntry->id));

#ifdef PAYMENT
    pHashTableEntry->pAccountingInfo=NULL;
#endif

    SAVE_STACK("CAFirstMixChannelList::add", "copying peer IP");
    memcpy(pHashTableEntry->peerIP,peerIP,4);
#ifdef DATA_RETENTION_LOG
    pHashTableEntry->peerPort=pMuxSocket->getCASocket()->getPeerPort();
#endif
#ifdef DELAY_USERS
    m_pMutexDelayChannel->lock();
    pHashTableEntry->delayBucket=m_u32DelayChannelUnlimitTraffic; //can always send some first packets
    for(UINT32 i=0;i<MAX_POLLFD;i++)
      {
        if(m_pDelayBuckets[i]==NULL)
          {
            pHashTableEntry->delayBucketID=i;
            break;
          }
      }
    m_pDelayBuckets[pHashTableEntry->delayBucketID]=&pHashTableEntry->delayBucket;
    m_pMutexDelayChannel->unlock();
#endif

    SAVE_STACK("CAFirstMixChannelList::add", "inserting in connection list");
    //now insert the new connection in the list of all open connections
    if(m_listHashTableHead==NULL) //if first one
    {
      pHashTableEntry->list_HashEntries.next=NULL;
    }
    else
    {//add to the head of the double linked list
      pHashTableEntry->list_HashEntries.next=m_listHashTableHead;
      m_listHashTableHead->list_HashEntries.prev=pHashTableEntry;
    }
    pHashTableEntry->list_HashEntries.prev=NULL;
    m_listHashTableHead=pHashTableEntry;

    SAVE_STACK("CAFirstMixChannelList::add", "inserting in timout list");
    // insert in timeout list; entries are added to the foot of the list
#ifdef PAYMENT
    pHashTableEntry->bRecoverTimeout = true;
    pHashTableEntry->kickoutSendRetries = MAX_KICKOUT_RETRIES;
    /* Hot fix: push timeout entry explicitly to avoid
     * confusion, when timeout occurs during AI login
     */
    //pushTimeoutEntry_internal(pHashTableEntry);
#endif
    m_Mutex.unlock();

    FINISH_STACK("CAFirstMixChannelList::add");

    return pHashTableEntry;
  }

Here is the call graph for this function:

SINT32 CAFirstMixChannelList::addChannel ( CAMuxSocket pMuxSocket,
HCHANNEL  channelIn,
CASymCipher 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 235 of file CAFirstMixChannelList.cpp.

References t_firstmixchannellist::bIsSuspended, t_firstmixchannellist::channelIn, t_firstmixchannellist::channelOut, t_fmhashtableentry::cNumberOfChannels, E_SUCCESS, E_UNKNOWN, 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 CAFirstMixB::loop(), CAFirstMixA::loop(), and test().

  {
    if(pMuxSocket==NULL||channelOut==NULL)
      return E_UNKNOWN;
    SINT32 hashkey=pMuxSocket->getHashKey();
    if(hashkey>MAX_HASH_KEY-1||hashkey<0)
      return E_UNKNOWN;
    m_Mutex.lock();
    fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
    if(pHashTableEntry->pMuxSocket==NULL||pHashTableEntry->cNumberOfChannels>=MAX_NUMBER_OF_CHANNELS)
      {
        CAMsg::printMsg(LOG_DEBUG,"More than 50 channels!\n");
        m_Mutex.unlock();
        return E_UNKNOWN;
      }
    fmChannelListEntry* pEntry=pHashTableEntry->pChannelList;
#ifndef DO_TRACE
    fmChannelListEntry* pNewEntry=new fmChannelListEntry;
#else
    fmChannelListEntry* pNewEntry=newChannelListEntry();
#endif
    memset(pNewEntry,0,sizeof(fmChannelListEntry));
    pNewEntry->pCipher=pCipher;
    pNewEntry->channelIn=channelIn;

    do
      {
        getRandom(channelOut); //get new Random OUT-CHANNEL-ID
      } while(*channelOut<256||get_intern_without_lock(*channelOut)!=NULL); //until it is unused...
    pNewEntry->channelOut=*channelOut;
    pNewEntry->bIsSuspended=false;
    pNewEntry->pHead=pHashTableEntry;

#ifdef LOG_CHANNEL
    pNewEntry->packetsInFromUser=0;
    pNewEntry->packetsOutToUser=0;
#endif
#ifdef SSL_HACK
    pNewEntry->downStreamBytes = 0;
#endif



    //add to the channel list for the given connection
    if(pEntry==NULL) //First Entry to the channel list
    {
      pNewEntry->list_InChannelPerSocket.next=NULL;
      pNewEntry->list_InChannelPerSocket.prev=NULL;
    }
    else
    {
      pNewEntry->list_InChannelPerSocket.next=pEntry;
      pNewEntry->list_InChannelPerSocket.prev=NULL;
      pEntry->list_InChannelPerSocket.prev=pNewEntry;
    }
    pHashTableEntry->pChannelList=pNewEntry;

    //add to the out-channel list
    hashkey=(*channelOut)&0x0000FFFF;
    pEntry=m_HashTableOutChannels[hashkey];
    if(pEntry!=NULL) //Hash Table Bucket Over run....
      {
        pNewEntry->list_OutChannelHashTable.prev=NULL;
        pNewEntry->list_OutChannelHashTable.next=pEntry;
        pEntry->list_OutChannelHashTable.prev=pNewEntry;
      }
    m_HashTableOutChannels[hashkey]=pNewEntry;
    pHashTableEntry->cNumberOfChannels++;
    m_Mutex.unlock();
    return E_SUCCESS;
  }

Here is the call graph for this function:

Definition at line 492 of file CAFirstMixChannelList.cpp.

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

{
  fmHashTableEntry* pHashTableEntry;
  UINT32 count = 0;

  for (pHashTableEntry = m_listTimoutHead; pHashTableEntry != NULL;
    count++, pHashTableEntry = pHashTableEntry->list_TimeoutHashEntries.next);

  return count;
}

Definition at line 1200 of file CAFirstMixChannelList.cpp.

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

Referenced by CAFirstMixA::sendToUsers().

  {
    m_pMutexDelayChannel->lock();
    if(delayBucketID < MAX_POLLFD)
    {
      if(m_pDelayBuckets[delayBucketID] != NULL)
      {
        *(m_pDelayBuckets[delayBucketID]) -= ( (*(m_pDelayBuckets[delayBucketID])) > 0 ) ? 1 : 0;
      }
      /*CAMsg::printMsg(LOG_DEBUG,"DelayBuckets decrementing ID %u downto %u\n",
                delayBucketID, (*(m_pDelayBuckets[delayBucketID])) );*/
    }
    m_pMutexDelayChannel->unlock();
  }

Here is the call graph for this function:

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 405 of file CAFirstMixChannelList.cpp.

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().

{
  bool ret = false;
  m_Mutex.lock();
  ret = (pHashTableEntry->pMuxSocket != NULL);
  if(ret)
  {
    if(pErrDoc != NULL)
    {
      //NOTE: accessing the control channel in this case works without further locking,
      //because the control channel is only deleted when the Dispatcher deletes all channels.
      //This happens when the table entry is removed by CAFirstMixChannelList::remove
      //which locks over m_Mutex.
      pHashTableEntry->pAccountingInfo->pControlChannel->sendXMLMessage(pErrDoc);
    }
    setKickoutForced_internal(pHashTableEntry, KICKOUT_FORCED);
  }
  m_Mutex.unlock();
  return ret;
}

Here is the call graph for this function:

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 333 of file CAFirstMixChannelList.cpp.

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 CAFirstMix::doUserLogin_internal(), CAFirstMixA::finishPacket(), CAFirstMixB::loop(), and CAFirstMixA::loop().

  {
    if(pMuxSocket==NULL)
      return NULL;
    SINT32 hashkey=pMuxSocket->getHashKey();
    if(hashkey>MAX_HASH_KEY-1||hashkey<0)
      return NULL;
    m_Mutex.lock();
    fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
    fmChannelListEntry* pEntry=pHashTableEntry->pChannelList;
    while(pEntry!=NULL)
      {
        if(pEntry->channelIn==channelIn)
          {
            m_Mutex.unlock();
            return pEntry;
          }
        pEntry=pEntry->list_InChannelPerSocket.next;
      }
    m_Mutex.unlock();
    return NULL;
  }

Here is the call graph for this function:

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 314 of file CAFirstMixChannelList.cpp.

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

  {
    if(pMuxSocket==NULL)
      return NULL;
    SINT32 hashkey=pMuxSocket->getHashKey();
    if(hashkey>MAX_HASH_KEY-1||hashkey<0)
      return NULL;
    m_Mutex.lock();
    fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
    m_Mutex.unlock();
    return pHashTableEntry;
  }

Here is the call graph for this function:

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 329 of file CAFirstMixChannelList.hpp.

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

        {
          m_Mutex.lock();
          fmChannelListEntry* pEntry=get_intern_without_lock(channelOut);
          m_Mutex.unlock();
          return pEntry;
        }

Here is the call graph for this function:

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 306 of file CAFirstMixChannelList.hpp.

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

Referenced by addChannel(), and get().

        {
          fmChannelListEntry* pEntry=m_HashTableOutChannels[channelOut&0x0000FFFF];
          while(pEntry!=NULL)
            {
              if(pEntry->channelOut==channelOut)
                {
                  return pEntry;
                }
              pEntry=pEntry->list_OutChannelHashTable.next;
            }
          return NULL;
        }

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 1081 of file CAFirstMixChannelList.cpp.

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

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

Here is the call graph for this function:

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 1113 of file CAFirstMixChannelList.cpp.

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

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

  {
    if(pMuxSocket==NULL)
      return NULL;
    SINT32 hashkey=pMuxSocket->getHashKey();
    if(hashkey>MAX_HASH_KEY-1||hashkey<0)
      return NULL;
    fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
    return pHashTableEntry->pChannelList;
  }

Here is the call graph for this function:

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 1097 of file CAFirstMixChannelList.cpp.

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

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

Here is the call graph for this function:

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 1130 of file CAFirstMixChannelList.cpp.

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

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

  {
    if(pEntry==NULL)
      return NULL;
    return pEntry->list_InChannelPerSocket.next;
  }

Definition at line 1215 of file CAFirstMixChannelList.cpp.

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

Referenced by CAFirstMixA::sendToUsers().

  {
    bool ret = false;
    m_pMutexDelayChannel->lock();
    if(delayBucketID < MAX_POLLFD)
    {
      if(m_pDelayBuckets[delayBucketID] != NULL)
      {
        ret = ( (*(m_pDelayBuckets[delayBucketID])) > 0 );
      }
    }
    m_pMutexDelayChannel->unlock();
    return ret;
  }

Here is the call graph for this function:

Definition at line 384 of file CAFirstMixChannelList.cpp.

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

Referenced by CAFirstMixA::checkUserConnections().

{
  bool ret = false;
  m_Mutex.lock();
  ret = isKickoutForced_internal(pHashTableEntry);
  m_Mutex.unlock();
  return ret;
}

Here is the call graph for this function:

bool CAFirstMixChannelList::isKickoutForced_internal ( fmHashTableEntry pHashTableEntry) [inline, private]

Definition at line 433 of file CAFirstMixChannelList.cpp.

References t_fmhashtableentry::bRecoverTimeout.

Referenced by isKickoutForced().

{
  return !(pHashTableEntry->bRecoverTimeout);
}

Definition at line 373 of file CAFirstMixChannelList.cpp.

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

Referenced by CAFirstMixA::checkUserConnections().

{
  bool ret = false;

  m_Mutex.lock();
  ret = isTimedOut_internal(pHashTableEntry);
  m_Mutex.unlock();

  return ret;
}

Here is the call graph for this function:

bool CAFirstMixChannelList::isTimedOut_internal ( fmHashTableEntry pHashTableEntry) [inline, private]

Definition at line 428 of file CAFirstMixChannelList.cpp.

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

Referenced by isTimedOut(), and popTimeoutEntry_internal().

{
  return (pHashTableEntry->list_TimeoutHashEntries.timoutSecs <= time(NULL));
}
Returns:
pops the next expired entry from the queue or returns NULL if there are no exired entries

Definition at line 357 of file CAFirstMixChannelList.cpp.

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

{
  return popTimeoutEntry(false);
}
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 362 of file CAFirstMixChannelList.cpp.

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

{
  fmHashTableEntry* ret;

  m_Mutex.lock();
  ret = popTimeoutEntry_internal(a_bForce);
  m_Mutex.unlock();

  return ret;
}

Here is the call graph for this function:

Definition at line 451 of file CAFirstMixChannelList.cpp.

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

Referenced by popTimeoutEntry().

{
  fmHashTableEntry* pHashTableEntry;

  if (m_listTimoutHead == NULL)
  {
    // there are not entries in the list
    return NULL;
  }

  pHashTableEntry = m_listTimoutHead;
  if (a_bForce || isTimedOut_internal(pHashTableEntry))
  {
    if (removeFromTimeoutList(pHashTableEntry) == E_SUCCESS)
    {
      return pHashTableEntry;
    }
    else
    {
      CAMsg::printMsg(LOG_CRIT,
        "CAFirstMixChannelList:popTimeoutEntry_internal: Could not remove expired entry from timeout list!\n");
    }
  }

  return NULL;
}

Here is the call graph for this function:

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

adds the entry to the timeout queue with mutex

Definition at line 480 of file CAFirstMixChannelList.cpp.

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

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

{
  SINT32 ret;

  m_Mutex.lock();
  ret = pushTimeoutEntry_internal(pHashTableEntry, kickoutForced);
  m_Mutex.unlock();

  return ret;
}

Here is the call graph for this function:

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 509 of file CAFirstMixChannelList.cpp.

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().

{
  if (pHashTableEntry == NULL)
  {
    return E_UNKNOWN;
  }


  /*if(isKickoutForced_internal(pHashTableEntry))
  {
    return E_SUCCESS;
  }*/

  INIT_STACK;
  BEGIN_STACK("CAFirstMixChannelList::pushTimeoutEntry_internal");

  //CAMsg::printMsg(LOG_DEBUG,"Entries in timeout list before push: %d\n", countTimeoutEntries());

  pHashTableEntry->list_TimeoutHashEntries.timoutSecs = time(NULL) + EXPIRATION_TIME_SECS;

  //SAVE_STACK("CAFirstMixChannelList::pushTimeoutEntry_internal", "removing from timeout list");
  // remove from timeout list if needed before adding it to the end
  removeFromTimeoutList(pHashTableEntry);
  setKickoutForced_internal(pHashTableEntry, kickoutForced);
  if (m_listTimoutFoot == NULL)
  {
    //SAVE_STACK("CAFirstMixChannelList::pushTimeoutEntry_internal", "new first entry");

    // this is the first entry in the list
    pHashTableEntry->list_TimeoutHashEntries.prev = NULL;
    m_listTimoutHead = pHashTableEntry;
  }
  else
  {
    //SAVE_STACK("CAFirstMixChannelList::pushTimeoutEntry_internal", "new last entry");
    // this is the new last entry in the list
    m_listTimoutFoot->list_TimeoutHashEntries.next = pHashTableEntry;
    pHashTableEntry->list_TimeoutHashEntries.prev = m_listTimoutFoot;
  }
  pHashTableEntry->list_TimeoutHashEntries.next = NULL;
  m_listTimoutFoot = pHashTableEntry;

  //CAMsg::printMsg(LOG_DEBUG,"Entries in timeout list after push: %d\n", countTimeoutEntries());

  FINISH_STACK("CAFirstMixChannelList::pushTimeoutEntry_internal");
  //CAMsg::printMsg(LOG_DEBUG, "CAFirstMixA: pushed entry %x!\n", pHashTableEntry);
  return E_SUCCESS;

}

Here is the call graph for this function:

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 640 of file CAFirstMixChannelList.cpp.

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().

  {
    if(pMuxSocket==NULL)
      return E_UNKNOWN;
    SINT32 hashkey=pMuxSocket->getHashKey();
    if(hashkey>MAX_HASH_KEY-1||hashkey<0)
      return E_UNKNOWN;
    m_Mutex.lock();
    fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
    if(pHashTableEntry->pMuxSocket==NULL) //this connection is not in the list
      {
        m_Mutex.unlock();
        return E_UNKNOWN;
      }
  #ifdef DELAY_USERS
    m_pMutexDelayChannel->lock();
    m_pDelayBuckets[pHashTableEntry->delayBucketID]=NULL;
    m_pMutexDelayChannel->unlock();
  #endif
    pHashTableEntry->pControlChannelDispatcher->deleteAllControlChannels();
    delete pHashTableEntry->pControlChannelDispatcher; //deletes the dispatcher and all associated control channels
    delete pHashTableEntry->pControlMessageQueue;
    pHashTableEntry->pControlChannelDispatcher = NULL;
    pHashTableEntry->pControlMessageQueue = NULL;
    if(m_listHashTableNext==pHashTableEntry) //adjust the enumeration over all connections (@see getNext())
      m_listHashTableNext=pHashTableEntry->list_HashEntries.next;

    if(pHashTableEntry->list_HashEntries.prev==NULL) //if entry is the head of the connection list
    {
      if(pHashTableEntry->list_HashEntries.next==NULL) //if entry is also the last (so the only one in the list..)
      {
        m_listHashTableHead=NULL; //list is now empty
      }
      else
      {//remove the head of the list
        m_listHashTableHead=pHashTableEntry->list_HashEntries.next;
        m_listHashTableHead->list_HashEntries.prev=NULL;
      }
    }
    else
    { //the connection is not the head of the list
      if(pHashTableEntry->list_HashEntries.next==NULL)
      {//the connection is the last element in the list
        pHashTableEntry->list_HashEntries.prev->list_HashEntries.next=NULL;
      }
      else
      {//its a simple middle element
        pHashTableEntry->list_HashEntries.prev->list_HashEntries.next=pHashTableEntry->list_HashEntries.next;
        pHashTableEntry->list_HashEntries.next->list_HashEntries.prev=pHashTableEntry->list_HashEntries.prev;
      }
    }


#ifdef PAYMENT
    removeFromTimeoutList(pHashTableEntry);
#endif

    fmChannelListEntry* pEntry=pHashTableEntry->pChannelList;
    fmChannelListEntry* pTmpEntry;
    while(pEntry!=NULL)//for all channels....
      {
        //remove the out channel form the out channel hast table
        hashkey=pEntry->channelOut&0x0000FFFF;
        pTmpEntry=m_HashTableOutChannels[hashkey];
        while(pTmpEntry!=NULL)
          {
            if(pTmpEntry->channelOut==pEntry->channelOut)
              {//we have found the entry
                if(pTmpEntry->list_OutChannelHashTable.prev==NULL) //it's the head
                  {
                    if(pTmpEntry->list_OutChannelHashTable.next==NULL)
                      {//it's also the last Element
                        m_HashTableOutChannels[hashkey]=NULL; //empty this hash bucket
                      }
                    else
                      {
                        pTmpEntry->list_OutChannelHashTable.next->list_OutChannelHashTable.prev=NULL;
                        m_HashTableOutChannels[hashkey]=pTmpEntry->list_OutChannelHashTable.next;
                      }
                  }
                else
                  {//not the head
                    if(pTmpEntry->list_OutChannelHashTable.next==NULL)
                      {//but the last
                        pTmpEntry->list_OutChannelHashTable.prev->list_OutChannelHashTable.next=NULL;
                      }
                    else
                      {//a middle element
                        pTmpEntry->list_OutChannelHashTable.prev->list_OutChannelHashTable.next=pTmpEntry->list_OutChannelHashTable.next;
                        pTmpEntry->list_OutChannelHashTable.next->list_OutChannelHashTable.prev=pTmpEntry->list_OutChannelHashTable.prev;
                      }
                  }
                break;
              }
            pTmpEntry=pTmpEntry->list_OutChannelHashTable.next;
        }

        pTmpEntry=pEntry->list_InChannelPerSocket.next;
#ifndef DO_TRACE
        delete pEntry;
        pEntry = NULL;
#else
        deleteChannelListEntry(pEntry);
#endif
        pEntry=pTmpEntry;
      }
/* already done by pHashTableEntry->pControlChannelDispatcher->deleteAllControlChannels();
#ifdef PAYMENT
    // cleanup accounting information
    CAAccountingInstance::cleanupTableEntry(pHashTableEntry);
#endif
*/
#ifdef LOG_DIALOG
    delete[] pHashTableEntry->strDialog;
    pHashTableEntry->strDialog = NULL;
#endif
#ifdef PAYMENT
    CAConditionVariable *rescue = pHashTableEntry->cleanupNotifier;
#endif
    //TODO: a bit more precise reference cleanup
    memset(pHashTableEntry,0,sizeof(fmHashTableEntry)); //'delete' the connection from the connection hash table

#ifdef PAYMENT
    pHashTableEntry->cleanupNotifier = rescue;
    pHashTableEntry->cleanupNotifier->lock();
    pHashTableEntry->cleanupNotifier->signal();
    pHashTableEntry->cleanupNotifier->unlock();
#endif
    m_Mutex.unlock();
    return E_SUCCESS;
  }

Here is the call graph for this function:

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 980 of file CAFirstMixChannelList.cpp.

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(), CAFirstMixB::loop(), CAFirstMixA::loop(), and test().

  {
    if(pMuxSocket==NULL)
      return E_UNKNOWN;
    SINT32 hashkey=pMuxSocket->getHashKey();
    if(hashkey>MAX_HASH_KEY-1||hashkey<0)
      return E_UNKNOWN;
    m_Mutex.lock();
    fmHashTableEntry* pHashTableEntry=m_HashTable[hashkey];
    if(pHashTableEntry->pMuxSocket==NULL)
      {
        m_Mutex.unlock();
        return E_UNKNOWN;
      }
    fmChannelListEntry* pEntry=pHashTableEntry->pChannelList;
    while(pEntry!=NULL)
      {
        if(pEntry->channelIn==channelIn) //search for the channel
          {
            hashkey=pEntry->channelOut&0x0000FFFF; //remove the out channel from the out channel hash table
            fmChannelListEntry*pTmpEntry=m_HashTableOutChannels[hashkey];
            while(pTmpEntry!=NULL)
              {
                if(pTmpEntry->channelOut==pEntry->channelOut)
                  {//found it in the out channel hash table
                    if(pTmpEntry->list_OutChannelHashTable.prev==NULL) //head
                      {
                        if(pTmpEntry->list_OutChannelHashTable.next==NULL)
                          {
                            m_HashTableOutChannels[hashkey]=NULL;
                          }
                        else
                          {

                            pTmpEntry->list_OutChannelHashTable.next->list_OutChannelHashTable.prev=NULL;
                            m_HashTableOutChannels[hashkey]=pTmpEntry->list_OutChannelHashTable.next;
                          }
                      }
                    else
                      {
                        if(pTmpEntry->list_OutChannelHashTable.next==NULL)
                          {//last element
                            pTmpEntry->list_OutChannelHashTable.prev->list_OutChannelHashTable.next=NULL;
                          }
                        else
                          {//middle element
                            pTmpEntry->list_OutChannelHashTable.prev->list_OutChannelHashTable.next=pTmpEntry->list_OutChannelHashTable.next;
                            pTmpEntry->list_OutChannelHashTable.next->list_OutChannelHashTable.prev=pTmpEntry->list_OutChannelHashTable.prev;
                          }
                      }
                    break;
                  }
                pTmpEntry=pTmpEntry->list_OutChannelHashTable.next;
            }

            //remove the channel from the channel hast table
            if(pEntry->list_InChannelPerSocket.prev==NULL) //head
              {
                if(pEntry->list_InChannelPerSocket.next==NULL)
                  {//the only element
                    pHashTableEntry->pChannelList=NULL;
                  }
                else
                  {
                    pEntry->list_InChannelPerSocket.next->list_InChannelPerSocket.prev=NULL;
                    pHashTableEntry->pChannelList=pEntry->list_InChannelPerSocket.next;
                  }
              }
            else
              {
                if(pEntry->list_InChannelPerSocket.next==NULL)
                  {//the last element
                    pEntry->list_InChannelPerSocket.prev->list_InChannelPerSocket.next=NULL;
                  }
                else
                  {//a middle element
                    pEntry->list_InChannelPerSocket.prev->list_InChannelPerSocket.next=pEntry->list_InChannelPerSocket.next;
                    pEntry->list_InChannelPerSocket.next->list_InChannelPerSocket.prev=pEntry->list_InChannelPerSocket.prev;
                  }
              }
            #ifndef DO_TRACE
              delete pEntry;
              pEntry = NULL;
            #else
              deleteChannelListEntry(pEntry);
            #endif
            pHashTableEntry->cNumberOfChannels--;
            m_Mutex.unlock();
            return E_SUCCESS;
          }
        pEntry=pEntry->list_InChannelPerSocket.next; //try next channel
      }
    m_Mutex.unlock();
    return E_UNKNOWN;//not found
  }

Here is the call graph for this function:

Definition at line 561 of file CAFirstMixChannelList.cpp.

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().

{
  if (pHashTableEntry == NULL)
  {
    return E_UNKNOWN;
  }

  //CAMsg::printMsg(LOG_DEBUG, "CAFirstMixA: removing entry %x!\n", pHashTableEntry);

  if (m_listTimoutHead == NULL || m_listTimoutFoot == NULL)
  {
    // there is no entry in the list; therefore this entry does not need to be removed
    return E_SUCCESS;
  }

  if (pHashTableEntry->list_TimeoutHashEntries.prev == NULL &&
    pHashTableEntry->list_TimeoutHashEntries.next == NULL &&
    m_listTimoutHead != pHashTableEntry)
  {
    // this entry is not in the list; it does not need to be removed
    return E_SUCCESS;
  }

  if(m_listTimoutHead == pHashTableEntry) //if entry is the head of the connection list
  {
    if(m_listTimoutFoot == pHashTableEntry) //if entry is also the last (so the only one in the list..)
    {
      //list is now empty
      m_listTimoutHead = NULL;
      m_listTimoutFoot = NULL;
    }
    else
    {
      //remove the head of the list
      m_listTimoutHead = pHashTableEntry->list_TimeoutHashEntries.next;
    }
  }
  else
  { //the connection is not the head of the list
    if(pHashTableEntry->list_TimeoutHashEntries.next == NULL)
    {
      //the connection is the last element in the list
      m_listTimoutFoot = pHashTableEntry->list_TimeoutHashEntries.prev;
      m_listTimoutFoot->list_TimeoutHashEntries.next = NULL;
    }
    else
    {
      //it is a simple middle element
      if (pHashTableEntry->list_TimeoutHashEntries.prev == NULL)
      {
        CAMsg::printMsg(LOG_CRIT, "CAFirstMixChannelList:removeFromTimeoutList: No previous element!!\n");
      }
      else
      {
        pHashTableEntry->list_TimeoutHashEntries.prev->list_TimeoutHashEntries.next = pHashTableEntry->list_TimeoutHashEntries.next;
      }
      if (pHashTableEntry->list_TimeoutHashEntries.next == NULL)
      {
        CAMsg::printMsg(LOG_CRIT, "CAFirstMixChanelList:removeFromTimeoutList: No next element!!\n");
      }
      else
      {
        pHashTableEntry->list_TimeoutHashEntries.next->list_TimeoutHashEntries.prev = pHashTableEntry->list_TimeoutHashEntries.prev;
      }
    }
  }
  pHashTableEntry->list_TimeoutHashEntries.prev = NULL;
  pHashTableEntry->list_TimeoutHashEntries.next = NULL;

  return E_SUCCESS;
}

Here is the call graph for this function:

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

Definition at line 1230 of file CAFirstMixChannelList.cpp.

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

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

    {
      m_pMutexDelayChannel->lock();
      CAMsg::printMsg(LOG_DEBUG,"CAFirstMixChannelList - Set new traffic limit per user- unlimit: %u bucketgrow: %u intervall %u\n",
        unlimitTraffic,bucketGrow,intervall);
      m_u32DelayChannelUnlimitTraffic=unlimitTraffic;
      m_u32DelayChannelBucketGrow=bucketGrow;
      m_u32DelayChannelBucketGrowIntervall=intervall;
      for(UINT32 i=0;i<MAX_POLLFD;i++)
        if(m_pDelayBuckets[i]!=NULL)
          *(m_pDelayBuckets[i])=m_u32DelayChannelUnlimitTraffic;
      m_pMutexDelayChannel->unlock();
    }

Here is the call graph for this function:

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

Definition at line 392 of file CAFirstMixChannelList.cpp.

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

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

{
  m_Mutex.lock();
  setKickoutForced_internal(pHashTableEntry, kickoutForced);
  m_Mutex.unlock();
}

Here is the call graph for this function:

void CAFirstMixChannelList::setKickoutForced_internal ( fmHashTableEntry pHashTableEntry,
bool  kickoutForced 
) [inline, private]

Definition at line 438 of file CAFirstMixChannelList.cpp.

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

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

{
  if(!pHashTableEntry->bRecoverTimeout && !kickoutForced )
  {
    CAMsg::printMsg(LOG_WARNING, "Try to switch back from forced kickout. A forced kickout cannot be undone!\n");
  }
  else
  {
    pHashTableEntry->bRecoverTimeout = !kickoutForced;
  }

}

Here is the call graph for this function:

Definition at line 1137 of file CAFirstMixChannelList.cpp.

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

  {
    CAFirstMixChannelList* pList=new CAFirstMixChannelList();
    CAMuxSocket *pMuxSocket=new CAMuxSocket();
    pMuxSocket->getCASocket()->create();
    UINT8 peerIP[4];
#ifndef LOG_DIALOG
    pList->add(pMuxSocket,peerIP,NULL,NULL,NULL);
#else
    pList->add(pMuxSocket,peerIP,NULL,(UINT8*)"1");
#endif
#if defined(HAVE_CRTDBG)
    _CrtMemState s1, s2, s3;
    _CrtMemCheckpoint( &s1 );
#endif
    UINT32 /*channelIn,*/i,channelOut;
    for(i=0;i<50;i++)
      pList->addChannel(pMuxSocket,i,NULL,&channelOut);
    for(i=0;i<50;i++)
      pList->removeChannel(pMuxSocket,i);
#if defined(HAVE_CRTDBG)
    _CrtMemCheckpoint( &s2 );
    if ( _CrtMemDifference( &s3, &s1, &s2 ) )
      _CrtMemDumpStatistics( &s3 );
#endif

    pList->remove(pMuxSocket);
    delete pMuxSocket;
    pMuxSocket = NULL;
    delete pList;
    pList = NULL;
    return E_SUCCESS;
  }

Here is the call graph for this function:


Friends And Related Function Documentation

THREAD_RETURN fml_loopDelayBuckets ( void *  ) [friend]

Definition at line 1172 of file CAFirstMixChannelList.cpp.

Referenced by CAFirstMixChannelList().

    {
      INIT_STACK;
      BEGIN_STACK("CAFirstMixChannelList::fml_loopDelayBuckets");

      CAFirstMixChannelList* pChannelList=(CAFirstMixChannelList*)param;
      volatile UINT32** pDelayBuckets=pChannelList->m_pDelayBuckets;
      while(pChannelList->m_bDelayBucketsLoopRun)
        {
          pChannelList->m_pMutexDelayChannel->lock();
          UINT32 u32BucketGrow=pChannelList->m_u32DelayChannelBucketGrow;
          UINT32 u32MaxBucket=u32BucketGrow*10;
          for(UINT32 i=0;i<MAX_POLLFD;i++)
            {
              if(pDelayBuckets[i]!=NULL&&*(pDelayBuckets[i])<u32MaxBucket)
              {
                *(pDelayBuckets[i])+=u32BucketGrow;
              }
            }
          pChannelList->m_pMutexDelayChannel->unlock();
          msSleep(pChannelList->m_u32DelayChannelBucketGrowIntervall);
        }

      FINISH_STACK("CAFirstMixChannelList::fml_loopDelayBuckets");

      THREAD_RETURN_SUCCESS;
    }

Member Data Documentation

const SINT32 CAFirstMixChannelList::EXPIRATION_TIME_SECS = 300 [static, private]

Definition at line 337 of file CAFirstMixChannelList.hpp.

Referenced by pushTimeoutEntry_internal().

The Hash-Table of all connections.

Definition at line 340 of file CAFirstMixChannelList.hpp.

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

The Hash-Table of all out-channels.

Definition at line 342 of file CAFirstMixChannelList.hpp.

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

Pointer to the head of a list of all connections.

Definition at line 345 of file CAFirstMixChannelList.hpp.

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

Next Element in the enumeration of all connections.

Definition at line 347 of file CAFirstMixChannelList.hpp.

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

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

Definition at line 350 of file CAFirstMixChannelList.hpp.

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

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

Definition at line 354 of file CAFirstMixChannelList.hpp.

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

Definition at line 360 of file CAFirstMixChannelList.hpp.

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

Definition at line 365 of file CAFirstMixChannelList.hpp.

Referenced by CAFirstMixChannelList(), and setDelayParameters().


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