Mixe for Privacy and Anonymity in the Internet
CALastMixChannelList.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000, The JAP-Team 
00003 All rights reserved.
00004 Redistribution and use in source and binary forms, with or without modification, 
00005 are permitted provided that the following conditions are met:
00006 
00007   - Redistributions of source code must retain the above copyright notice, 
00008     this list of conditions and the following disclaimer.
00009 
00010   - Redistributions in binary form must reproduce the above copyright notice, 
00011     this list of conditions and the following disclaimer in the documentation and/or 
00012     other materials provided with the distribution.
00013 
00014   - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors 
00015     may be used to endorse or promote products derived from this software without specific 
00016     prior written permission. 
00017 
00018   
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS 
00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 
00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00027 */
00028 #include "StdAfx.h"
00029 #ifndef ONLY_LOCAL_PROXY
00030 #include "CALastMixChannelList.hpp"
00031 #include "CAUtil.hpp"
00032 
00033 CALastMixChannelList::CALastMixChannelList()
00034   {
00035     m_HashTable=new LP_lmChannelListEntry[HASHTABLE_SIZE];
00036     memset(m_HashTable,0, HASHTABLE_SIZE*sizeof(LP_lmChannelListEntry));
00037     m_listSockets=NULL;
00038     m_listSocketsNext=NULL;
00039     m_nChannels=0;
00040 #ifdef DELAY_CHANNELS
00041     m_u32DelayChannelUnlimitTraffic=DELAY_CHANNEL_TRAFFIC;
00042     m_u32DelayChannelBucketGrow=DELAY_BUCKET_GROW;
00043     m_u32DelayChannelBucketGrowIntervall=DELAY_BUCKET_GROW_INTERVALL;
00044     m_pDelayBuckets=new UINT32*[MAX_POLLFD];
00045     memset(m_pDelayBuckets,0,sizeof(UINT32*)*MAX_POLLFD);
00046     m_pMutexDelayChannel=new CAMutex();
00047     m_pThreadDelayBucketsLoop=new CAThread((UINT8*)"Delay Buckets Thread");
00048     m_bDelayBucketsLoopRun=true;
00049     m_pThreadDelayBucketsLoop->setMainLoop(lml_loopDelayBuckets);
00050     m_pThreadDelayBucketsLoop->start(this);
00051 #endif
00052 #ifdef DELAY_CHANNELS_LATENCY
00053     m_u32DelayChannelLatency=DELAY_CHANNEL_LATENCY;
00054 #endif
00055   }
00056 
00057 CALastMixChannelList::~CALastMixChannelList()
00058   {
00059 #ifdef DELAY_CHANNELS
00060     m_bDelayBucketsLoopRun=false;
00061     m_pThreadDelayBucketsLoop->join();
00062     delete m_pThreadDelayBucketsLoop;
00063     m_pThreadDelayBucketsLoop = NULL;
00064     delete m_pMutexDelayChannel;
00065     m_pMutexDelayChannel = NULL;
00066     delete []m_pDelayBuckets;
00067     m_pDelayBuckets = NULL;
00068 #endif
00069     for(UINT32 i=0;i < HASHTABLE_SIZE; i++)
00070       {
00071         lmChannelListEntry* akt=m_HashTable[i];
00072         lmChannelListEntry* tmp;
00073         while(akt!=NULL)
00074           {
00075             tmp=akt;
00076             akt=akt->list_Channels.next;
00077             delete tmp;
00078             tmp = NULL;
00079           }
00080       }
00081     delete[] m_HashTable;
00082     m_HashTable = NULL;
00083   }
00084 
00085 SINT32 CALastMixChannelList::add(HCHANNEL id,CASocket* pSocket,CASymCipher* pCipher,CAQueue* pQueue
00086 #ifdef LOG_CHANNEL
00087                                   ,UINT64 timecreated,UINT32 trafficInFromUser
00088 #endif
00089 #if defined(DELAY_CHANNELS_LATENCY)
00090                                   ,UINT64 delaytime
00091 #endif
00092                                 )
00093   {
00094     UINT32 hash=id & HASH_MASK;
00095     lmChannelListEntry* pEntry=m_HashTable[hash];
00096     lmChannelListEntry* pNewEntry=new lmChannelListEntry;
00097     pNewEntry->channelIn=id;
00098     pNewEntry->pCipher=pCipher;
00099     pNewEntry->pSocket=pSocket;
00100     pNewEntry->pQueueSend=pQueue;
00101 #if defined (LOG_CHANNEL)
00102     pNewEntry->timeCreated=timecreated;
00103 #endif
00104 #if defined (DELAY_CHANNELS_LATENCY)
00105     pNewEntry->timeLatency=delaytime+m_u32DelayChannelLatency;
00106 #endif
00107 #ifdef LOG_CHANNEL
00108     pNewEntry->trafficInFromUser=trafficInFromUser;
00109     pNewEntry->packetsDataInFromUser=1;
00110     pNewEntry->packetsDataOutToUser=0;
00111     pNewEntry->trafficOutToUser=0;
00112 #endif
00113     pNewEntry->sendmeCounterDownstream=0;
00114     pNewEntry->sendmeCounterUpstream=0;
00115 #ifdef DELAY_CHANNELS
00116     pNewEntry->delayBucket=m_u32DelayChannelUnlimitTraffic; //can always send some first packets
00117     for(UINT32 i=0;i<MAX_POLLFD;i++)
00118       {
00119         if(m_pDelayBuckets[i]==NULL)
00120           {
00121             pNewEntry->delayBucketID=i;
00122             break;
00123           }
00124       }
00125     m_pDelayBuckets[pNewEntry->delayBucketID]=&pNewEntry->delayBucket;
00126 #endif
00127     if(pEntry==NULL) //First Entry for Hash in HashTable
00128       {
00129         pNewEntry->list_Channels.next=NULL;
00130         pNewEntry->list_Channels.prev=NULL;
00131       }
00132     else //insert in Hashlist for Hashtableentry
00133       {
00134         pNewEntry->list_Channels.prev=NULL;
00135         pNewEntry->list_Channels.next=pEntry;
00136         pEntry->list_Channels.prev=pNewEntry;
00137       }
00138     //Insert in SocketList
00139     if(m_listSockets==NULL)
00140       {
00141         m_listSockets=pNewEntry;
00142         pNewEntry->list_Sockets.next=NULL;
00143         pNewEntry->list_Sockets.prev=NULL;
00144       }
00145     else
00146       {
00147         pNewEntry->list_Sockets.prev=NULL;
00148         pNewEntry->list_Sockets.next=m_listSockets;
00149         m_listSockets->list_Sockets.prev=pNewEntry;
00150         m_listSockets=pNewEntry;        
00151       }
00152     m_HashTable[hash]=pNewEntry;
00153     //if(m_listSocketsNext==NULL)
00154     //  m_listSocketsNext=m_listSockets;
00155     m_nChannels++;
00156     return E_SUCCESS;
00157   }
00158 
00159 SINT32 CALastMixChannelList::removeChannel(HCHANNEL channel)
00160   {
00161     UINT32 hash=channel & HASH_MASK;
00162     lmChannelListEntry* pEntry=m_HashTable[hash];
00163     while(pEntry!=NULL)
00164       {
00165         if(pEntry->channelIn==channel)
00166           {
00167             if(m_listSocketsNext==pEntry) //removing next enumeration Element...
00168               m_listSocketsNext=m_listSocketsNext->list_Sockets.next; //adjusting!
00169 //remove from HashTable
00170             if(pEntry->list_Channels.prev==NULL)
00171               m_HashTable[hash]=pEntry->list_Channels.next;
00172             else
00173               {
00174                 pEntry->list_Channels.prev->list_Channels.next=pEntry->list_Channels.next;
00175               }
00176             if(pEntry->list_Channels.next!=NULL)
00177               {
00178                 pEntry->list_Channels.next->list_Channels.prev=pEntry->list_Channels.prev;
00179               }
00180             //remove from SocketList
00181             if(pEntry->list_Sockets.prev==NULL)
00182               m_listSockets=pEntry->list_Sockets.next;
00183             else
00184               pEntry->list_Sockets.prev->list_Sockets.next=pEntry->list_Sockets.next;
00185             if(pEntry->list_Sockets.next!=NULL)
00186               pEntry->list_Sockets.next->list_Sockets.prev=pEntry->list_Sockets.prev;
00187             #ifdef DELAY_CHANNELS
00188               m_pMutexDelayChannel->lock();
00189               m_pDelayBuckets[pEntry->delayBucketID]=NULL;
00190               m_pMutexDelayChannel->unlock();
00191             #endif
00192             delete pEntry;
00193             pEntry = NULL;
00194             m_nChannels--;          
00195             return E_SUCCESS;
00196           }
00197         pEntry=pEntry->list_Channels.next;
00198       }
00199     return E_SUCCESS;
00200   }
00201 
00202 SINT32 CALastMixChannelList::test()
00203         {
00204 #if !defined (LOG_CHANNEL)&&!defined(DELAY_CHANNELS_LATENCY)
00205           CALastMixChannelList oList;
00206           UINT32 c;
00207           UINT32 rand;
00208           int i,j;
00209           for(i=0;i<100;i++)
00210             {
00211               getRandom(&c);
00212               oList.add(c,NULL,NULL,NULL);
00213 
00214           }
00215           for(i=0;i < 10000;i++)
00216             {
00217               lmChannelListEntry* akt=oList.getFirstSocket();
00218               while(akt!=NULL)
00219                 {
00220                   getRandom(&rand);
00221                   if(rand<0x7FFFFFFF)
00222                     {
00223                       getRandom(&c);
00224                       oList.add(c,NULL,NULL,NULL);
00225                     }
00226                   getRandom(&rand);
00227                   if(rand<0x7FFFFFFF)
00228                     oList.removeChannel(akt->channelIn);
00229                   getRandom(&rand);
00230                   if(rand<0x0FFFFFFF)
00231                     for(j=0;j<5;j++)
00232                       {
00233                         getRandom(&c);
00234                         oList.add(c,NULL,NULL,NULL);
00235                       }
00236                   getRandom(&rand);
00237                   if(rand<0x7FFFFFFF)
00238                     for(j=0;j<10000;j++)
00239                       {
00240                         getRandom(&c);
00241                         oList.removeChannel(c);
00242                       }
00243                   akt=oList.getNextSocket();
00244                 }
00245             }
00246 #endif
00247           return 0;
00248         }
00249 
00250 #ifdef DELAY_CHANNELS
00251   THREAD_RETURN lml_loopDelayBuckets(void* param)
00252   {
00253     CALastMixChannelList* pChannelList=(CALastMixChannelList*)param;
00254     UINT32** pDelayBuckets=pChannelList->m_pDelayBuckets;
00255     while(pChannelList->m_bDelayBucketsLoopRun)
00256       {
00257         pChannelList->m_pMutexDelayChannel->lock();
00258         UINT32 u32BucketGrow=pChannelList->m_u32DelayChannelBucketGrow;
00259         UINT32 u32MaxBucket=u32BucketGrow*10;
00260         for(UINT32 i=0;i<MAX_POLLFD;i++)
00261           {
00262             if(pDelayBuckets[i]!=NULL&&*(pDelayBuckets[i])<u32MaxBucket)
00263               *(pDelayBuckets[i])+=u32BucketGrow;
00264           }
00265         pChannelList->m_pMutexDelayChannel->unlock();   
00266         msSleep(pChannelList->m_u32DelayChannelBucketGrowIntervall);
00267       }
00268     THREAD_RETURN_SUCCESS;
00269   }
00270   
00271   void CALastMixChannelList::reduceDelayBuckets(UINT32 delayBucketID, UINT32 amount)
00272   {
00273     m_pMutexDelayChannel->lock();
00274     //if(delayBucketID < MAX_POLLFD)
00275     //{
00276       //if(m_pDelayBuckets[delayBucketID] != NULL)
00277       //{
00278         *(m_pDelayBuckets[delayBucketID]) -= ( (*(m_pDelayBuckets[delayBucketID])) > amount ) 
00279                               ? amount : (*(m_pDelayBuckets[delayBucketID]));
00280       //}
00281       /*CAMsg::printMsg(LOG_DEBUG,"DelayBuckets decrementing ID %u downto %u\n", 
00282                 delayBucketID, (*(m_pDelayBuckets[delayBucketID])) );*/
00283     //}
00284     m_pMutexDelayChannel->unlock();
00285   }
00286   
00287   UINT32 CALastMixChannelList::getDelayBuckets(UINT32 delayBucketID)
00288   {
00289     UINT32 ret = 0;
00290     m_pMutexDelayChannel->lock();
00291     ret = ( (*(m_pDelayBuckets[delayBucketID])) > 0 ) ? (*(m_pDelayBuckets[delayBucketID])) : 0;
00292     m_pMutexDelayChannel->unlock();
00293     return ret;
00294   }
00295   
00296   bool CALastMixChannelList::hasDelayBuckets(UINT32 delayBucketID)
00297   {
00298     bool ret = false;
00299     m_pMutexDelayChannel->lock();
00300     //if(delayBucketID < MAX_POLLFD)
00301     //{
00302       //if(m_pDelayBuckets[delayBucketID] != NULL)
00303       //{
00304         ret = ( (*(m_pDelayBuckets[delayBucketID])) > 0 );
00305       //}
00306     //}
00307     m_pMutexDelayChannel->unlock();
00308     return ret;
00309   }
00310   
00311   void CALastMixChannelList::setDelayParameters(UINT32 unlimitTraffic,UINT32 bucketGrow,UINT32 intervall)
00312   {
00313     m_pMutexDelayChannel->lock();
00314     CAMsg::printMsg(LOG_DEBUG,"CALastMixChannelList - Set new traffic limit per channel- unlimit: %u bucketgrow: %u intervall %u\n",
00315       unlimitTraffic,bucketGrow,intervall);
00316     m_u32DelayChannelUnlimitTraffic=unlimitTraffic;
00317     m_u32DelayChannelBucketGrow=bucketGrow;
00318     m_u32DelayChannelBucketGrowIntervall=intervall;
00319     for(UINT32 i=0;i<MAX_POLLFD;i++)
00320       if(m_pDelayBuckets[i]!=NULL)
00321         *(m_pDelayBuckets[i])=m_u32DelayChannelUnlimitTraffic;
00322     m_pMutexDelayChannel->unlock();   
00323   }                                                       
00324 #endif
00325 
00326 #ifdef DELAY_CHANNELS_LATENCY
00327   void CALastMixChannelList::setDelayLatencyParameters(UINT32 latency)
00328     {
00329       CAMsg::printMsg(LOG_DEBUG,"CALastMixChannelList - Set new latency: %u ms\n",latency);
00330       m_u32DelayChannelLatency=latency;
00331     }
00332 #endif
00333 #endif //ONLY_LOCAL_PROXY