Mixe for Privacy and Anonymity in the Internet
CALastMixChannelList.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2000, The JAP-Team
3 All rights reserved.
4 Redistribution and use in source and binary forms, with or without modification,
5 are permitted provided that the following conditions are met:
6 
7  - Redistributions of source code must retain the above copyright notice,
8  this list of conditions and the following disclaimer.
9 
10  - Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation and/or
12  other materials provided with the distribution.
13 
14  - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors
15  may be used to endorse or promote products derived from this software without specific
16  prior written permission.
17 
18 
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
20 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
22 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
27 */
28 #include "StdAfx.h"
29 #if !defined ONLY_LOCAL_PROXY|| defined INCLUDE_LAST_MIX
30 #include "CALastMixChannelList.hpp"
31 #include "CAUtil.hpp"
32 #include "CALibProxytest.hpp"
33 
35  {
38  m_listSockets=NULL;
39  m_listSocketsNext=NULL;
40  m_nChannels=0;
41 #ifdef DELAY_CHANNELS
42  m_u32DelayChannelUnlimitTraffic=DELAY_CHANNEL_TRAFFIC;
43  m_u32DelayChannelBucketGrow=DELAY_BUCKET_GROW;
44  m_u32DelayChannelBucketGrowIntervall=DELAY_BUCKET_GROW_INTERVALL;
45  m_pDelayBuckets=new UINT32*[MAX_POLLFD];
46  memset(m_pDelayBuckets,0,sizeof(UINT32*)*MAX_POLLFD);
47  m_pMutexDelayChannel=new CAMutex();
48  m_pThreadDelayBucketsLoop=new CAThread((UINT8*)"Delay Buckets Thread");
49  m_bDelayBucketsLoopRun=true;
50  m_pThreadDelayBucketsLoop->setMainLoop(lml_loopDelayBuckets);
51  m_pThreadDelayBucketsLoop->start(this);
52 #endif
53 #ifdef DELAY_CHANNELS_LATENCY
54  m_u32DelayChannelLatency=DELAY_CHANNEL_LATENCY;
55 #endif
56 #ifdef LOG_CRIME
57  m_pMutex=new CAMutex();
58 #endif
59 }
60 
62  {
63 #ifdef DELAY_CHANNELS
64  m_bDelayBucketsLoopRun=false;
65  m_pThreadDelayBucketsLoop->join();
66  delete m_pThreadDelayBucketsLoop;
67  m_pThreadDelayBucketsLoop = NULL;
68  delete m_pMutexDelayChannel;
69  m_pMutexDelayChannel = NULL;
70  delete []m_pDelayBuckets;
71  m_pDelayBuckets = NULL;
72 #endif
73  for(UINT32 i=0;i < HASHTABLE_SIZE; i++)
74  {
76  lmChannelListEntry* tmp;
77  while(akt!=NULL)
78  {
79  tmp=akt;
80  akt=akt->list_Channels.next;
81  delete tmp;
82  tmp = NULL;
83  }
84  }
85  delete[] m_HashTable;
86  m_HashTable = NULL;
87 #ifdef LOG_CRIME
88  delete m_pMutex;
89 #endif
90 
91  }
92 
94 #ifdef WITH_INTEGRITY_CHECK
95  CASymCipherGCM* pCipher
96 #else
97  CASymChannelCipher* pCipher
98 #endif
99 
100  ,CAQueue* pQueue
101 #ifdef LOG_CHANNEL
102  ,UINT64 timecreated,UINT32 trafficInFromUser
103 #endif
104 #if defined(DELAY_CHANNELS_LATENCY)
105  ,UINT64 delaytime
106 #endif
107 #ifdef LOG_CRIME
108  ,bool bIsCrime,bool bLogPayload, time_t timeChannelOpened
109 #endif
110 #ifdef ANON_DEBUG_MODE
111  , bool bDebug
112 #endif
113 
114  )
115  {
116  UINT32 hash=id & HASH_MASK;
117  lmChannelListEntry* pEntry=m_HashTable[hash];
118  lmChannelListEntry* pNewEntry=new lmChannelListEntry;
119  pNewEntry->channelIn=id;
120  pNewEntry->pCipher=pCipher;
121  pNewEntry->pSocket=pSocket;
122  pNewEntry->pQueueSend=pQueue;
123 #if defined (LOG_CHANNEL)
124  pNewEntry->timeCreated=timecreated;
125 #endif
126 #if defined (DELAY_CHANNELS_LATENCY)
127  pNewEntry->timeLatency=delaytime+m_u32DelayChannelLatency;
128 #endif
129 #ifdef LOG_CHANNEL
130  pNewEntry->trafficInFromUser=trafficInFromUser;
131  pNewEntry->packetsDataInFromUser=1;
132  pNewEntry->packetsDataOutToUser=0;
133  pNewEntry->trafficOutToUser=0;
134 #endif
135 #ifdef LOG_CRIME
136  pNewEntry->bIsCrime=bIsCrime;
137  pNewEntry->bLogPayload=bLogPayload;
138  pNewEntry->timeChannelOpened=timeChannelOpened;
139 #endif
140 #ifdef ANON_DEBUG_MODE
141  pNewEntry->bDebug = bDebug;
142 #endif
143  pNewEntry->sendmeCounterDownstream=0;
144  pNewEntry->sendmeCounterUpstream=0;
145 #ifdef DELAY_CHANNELS
146  pNewEntry->delayBucket=m_u32DelayChannelUnlimitTraffic; //can always send some first packets
147  for(UINT32 i=0;i<MAX_POLLFD;i++)
148  {
149  if(m_pDelayBuckets[i]==NULL)
150  {
151  pNewEntry->delayBucketID=i;
152  break;
153  }
154  }
155  m_pDelayBuckets[pNewEntry->delayBucketID]=&pNewEntry->delayBucket;
156 #endif
157  if(pEntry==NULL) //First Entry for Hash in HashTable
158  {
159  pNewEntry->list_Channels.next=NULL;
160  pNewEntry->list_Channels.prev=NULL;
161  }
162  else //insert in Hashlist for Hashtableentry
163  {
164  pNewEntry->list_Channels.prev=NULL;
165  pNewEntry->list_Channels.next=pEntry;
166  pEntry->list_Channels.prev=pNewEntry;
167  }
168  //Insert in SocketList
169 #ifdef LOG_CRIME
170  m_pMutex->lock();
171 #endif
172  if(m_listSockets==NULL)
173  {
174  m_listSockets=pNewEntry;
175  pNewEntry->list_Sockets.next=NULL;
176  pNewEntry->list_Sockets.prev=NULL;
177  }
178  else
179  {
180  pNewEntry->list_Sockets.prev=NULL;
181  pNewEntry->list_Sockets.next=m_listSockets;
182  m_listSockets->list_Sockets.prev=pNewEntry;
183  m_listSockets=pNewEntry;
184  }
185 #ifdef LOG_CRIME
186  m_pMutex->unlock();
187 #endif
188  m_HashTable[hash]=pNewEntry;
189  //if(m_listSocketsNext==NULL)
190  // m_listSocketsNext=m_listSockets;
191  m_nChannels++;
192  return E_SUCCESS;
193  }
194 
196  {
197  UINT32 hash=channel & HASH_MASK;
198  lmChannelListEntry* pEntry=m_HashTable[hash];
199  while(pEntry!=NULL)
200  {
201  if(pEntry->channelIn==channel)
202  {
203  if(m_listSocketsNext==pEntry) //removing next enumeration Element...
205 //remove from HashTable
206  if(pEntry->list_Channels.prev==NULL)
207  m_HashTable[hash]=pEntry->list_Channels.next;
208  else
209  {
211  }
212  if(pEntry->list_Channels.next!=NULL)
213  {
215  }
216  //remove from SocketList
217 #ifdef LOG_CRIME
218  m_pMutex->lock();
219 #endif
220  if(pEntry->list_Sockets.prev==NULL)
222  else
224  if(pEntry->list_Sockets.next!=NULL)
226  #ifdef DELAY_CHANNELS
227  m_pMutexDelayChannel->lock();
228  m_pDelayBuckets[pEntry->delayBucketID]=NULL;
229  m_pMutexDelayChannel->unlock();
230  #endif
231 #ifdef LOG_CRIME
232  if (pEntry->bIsCrime)
233  {
234  int log=LOG_ENCRYPTED;
235  if(!CALibProxytest::getOptions()->isEncryptedLogEnabled())
236  log=LOG_CRIT;
237  char buff[255];
238  strftime(buff, 255, "%Y/%m/%d-%H:%M:%S", localtime(&pEntry->timeChannelOpened));
239  CAMsg::printMsg(log, "Crime channel closed (opened at: %s [unix timestamp: %u]) -- previous mix channel: %u\n", buff,pEntry->timeChannelOpened,pEntry->channelIn);
240  }
241 #endif
242 
243  delete pEntry;
244  pEntry = NULL;
245  m_nChannels--;
246 #ifdef LOG_CRIME
247  m_pMutex->unlock();
248 #endif
249  return E_SUCCESS;
250  }
251  pEntry=pEntry->list_Channels.next;
252  }
253  return E_SUCCESS;
254  }
255 
257  {
258 #if !defined (LOG_CHANNEL)&&!defined(DELAY_CHANNELS_LATENCY)&&!defined(LOG_CRIME)&&!defined(ANON_DEBUG_MODE)
259  CALastMixChannelList oList;
260  UINT32 c;
261  UINT32 rand;
262  int i,j;
263  for(i=0;i<100;i++)
264  {
265  getRandom(&c);
266  oList.add(c,NULL,NULL,NULL);
267 
268  }
269  for(i=0;i < 10000;i++)
270  {
271  lmChannelListEntry* akt=oList.getFirstSocket();
272  while(akt!=NULL)
273  {
274  getRandom(&rand);
275  if(rand<0x7FFFFFFF)
276  {
277  getRandom(&c);
278  oList.add(c,NULL,NULL,NULL);
279  }
280  getRandom(&rand);
281  if(rand<0x7FFFFFFF)
282  oList.removeChannel(akt->channelIn);
283  getRandom(&rand);
284  if(rand<0x0FFFFFFF)
285  for(j=0;j<5;j++)
286  {
287  getRandom(&c);
288  oList.add(c,NULL,NULL,NULL);
289  }
290  getRandom(&rand);
291  if(rand<0x7FFFFFFF)
292  for(j=0;j<10000;j++)
293  {
294  getRandom(&c);
295  oList.removeChannel(c);
296  }
297  akt=oList.getNextSocket();
298  }
299  }
300 #endif
301  return 0;
302  }
303 
304 #ifdef DELAY_CHANNELS
305  THREAD_RETURN lml_loopDelayBuckets(void* param)
306  {
307  CALastMixChannelList* pChannelList=(CALastMixChannelList*)param;
308  UINT32** pDelayBuckets=pChannelList->m_pDelayBuckets;
309  while(pChannelList->m_bDelayBucketsLoopRun)
310  {
311  pChannelList->m_pMutexDelayChannel->lock();
312  UINT32 u32BucketGrow=pChannelList->m_u32DelayChannelBucketGrow;
313  UINT32 u32MaxBucket=u32BucketGrow*10;
314  for(UINT32 i=0;i<MAX_POLLFD;i++)
315  {
316  if(pDelayBuckets[i]!=NULL&&*(pDelayBuckets[i])<u32MaxBucket)
317  *(pDelayBuckets[i])+=u32BucketGrow;
318  }
319  pChannelList->m_pMutexDelayChannel->unlock();
320  msSleep(pChannelList->m_u32DelayChannelBucketGrowIntervall);
321  }
323  }
324 
325  void CALastMixChannelList::reduceDelayBuckets(UINT32 delayBucketID, UINT32 amount)
326  {
327  m_pMutexDelayChannel->lock();
328  if (*(m_pDelayBuckets[delayBucketID]) < amount)
329  {
330  *(m_pDelayBuckets[delayBucketID]) = 0;
331  }
332  else
333  {
334  *(m_pDelayBuckets[delayBucketID]) -= amount;
335  }
336  m_pMutexDelayChannel->unlock();
337  }
338  /*
339  UINT32 CALastMixChannelList::getDelayBuckets(UINT32 delayBucketID)
340  {
341  UINT32 ret = 0;
342  m_pMutexDelayChannel->lock();
343  ret = ( (*(m_pDelayBuckets[delayBucketID])) > 0 ) ? (*(m_pDelayBuckets[delayBucketID])) : 0;
344  m_pMutexDelayChannel->unlock();
345  return ret;
346  }*/
347 
348  /*bool CALastMixChannelList::hasDelayBuckets(UINT32 delayBucketID)
349  {
350  bool ret = false;
351  m_pMutexDelayChannel->lock();
352  //if(delayBucketID < MAX_POLLFD)
353  //{
354  //if(m_pDelayBuckets[delayBucketID] != NULL)
355  //{
356  ret = ( (*(m_pDelayBuckets[delayBucketID])) > 0 );
357  //}
358  //}
359  m_pMutexDelayChannel->unlock();
360  return ret;
361  }*/
362 
363  void CALastMixChannelList::setDelayParameters(UINT32 unlimitTraffic,UINT32 bucketGrow,UINT32 intervall)
364  {
365  m_pMutexDelayChannel->lock();
366  CAMsg::printMsg(LOG_DEBUG,"CALastMixChannelList - Set new traffic limit per channel- unlimit: %u bucketgrow: %u intervall %u\n",
367  unlimitTraffic,bucketGrow,intervall);
368  m_u32DelayChannelUnlimitTraffic=unlimitTraffic;
369  m_u32DelayChannelBucketGrow=bucketGrow;
370  m_u32DelayChannelBucketGrowIntervall=intervall;
371  for(UINT32 i=0;i<MAX_POLLFD;i++)
372  if(m_pDelayBuckets[i]!=NULL)
373  *(m_pDelayBuckets[i])=m_u32DelayChannelUnlimitTraffic;
374  m_pMutexDelayChannel->unlock();
375  }
376 #endif
377 
378 #ifdef DELAY_CHANNELS_LATENCY
379  void CALastMixChannelList::setDelayLatencyParameters(UINT32 latency)
380  {
381  CAMsg::printMsg(LOG_DEBUG,"CALastMixChannelList - Set new latency: %u ms\n",latency);
382  m_u32DelayChannelLatency=latency;
383  }
384 #endif
385 #endif //ONLY_LOCAL_PROXY
#define HASHTABLE_SIZE
#define HASH_MASK
struct t_lastmixchannellist lmChannelListEntry
#define LOG_ENCRYPTED
Definition: CAMsg.hpp:46
SINT32 getRandom(UINT32 *val)
Gets 32 random bits.
Definition: CAUtil.cpp:346
SINT32 msSleep(UINT32 ms)
Sleeps ms milliseconds.
Definition: CAUtil.cpp:406
#define THREAD_RETURN
Definition: StdAfx.h:540
#define DELAY_CHANNEL_LATENCY
Definition: StdAfx.h:169
#define THREAD_RETURN_SUCCESS
Definition: StdAfx.h:542
#define MAX_POLLFD
Definition: StdAfx.h:192
signed int SINT32
Definition: basetypedefs.h:132
unsigned char UINT8
Definition: basetypedefs.h:135
unsigned int UINT32
Definition: basetypedefs.h:131
SINT32 add(HCHANNEL id, CASocket *pSocket, CASymChannelCipher *pCipher, CAQueue *pQueue)
lmChannelList * m_listSockets
Pointer to the head of a list of all sockets.
lmChannelListEntry * getFirstSocket()
lmChannelListEntry * getNextSocket()
lmChannelList * m_listSocketsNext
Next Element in the enumeration of all sockets.
SINT32 removeChannel(HCHANNEL channelIn)
LP_lmChannelListEntry * m_HashTable
The Hash-Table of all channels.
static CACmdLnOptions * getOptions()
static SINT32 printMsg(UINT32 typ, const char *format,...)
Writes a given message to the log.
Definition: CAMsg.cpp:251
This is a simple FIFO-Queue.
Definition: CAQueue.hpp:50
This class could be used for encryption/decryption of data (streams) with AES using 128bit GCM mode.
const SINT32 E_SUCCESS
Definition: errorcodes.hpp:2
struct t_lastmixchannellist::@4 list_Channels
CASymChannelCipher * pCipher
struct t_lastmixchannellist::@5 list_Sockets
struct t_lastmixchannellist * next
struct t_lastmixchannellist * prev
HCHANNEL channel
Definition: typedefs.hpp:0
UINT32 HCHANNEL
Definition: typedefs.hpp:34