Mixe for Privacy and Anonymity in the Internet
CADatabase.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 #ifndef ONLY_LOCAL_PROXY
30 #include "CADatabase.hpp"
31 #include "CAUtil.hpp"
32 #include "CAMsg.hpp"
33 
35  {
39  m_lastSwitch = time(NULL);
40  m_currentClock = 0;
41  m_pThread = NULL;
42  m_pMutex = new CAMutex();
43  }
44 
46  {
47  t_databaseInfo* pInfo = new t_databaseInfo;
48  memset(pInfo, 0, sizeof(t_databaseInfo));
49  return pInfo;
50  }
51 
53  {
54  m_pMutex->lock();
55  stop();
59  m_pMutex->unlock();
60  delete m_pMutex;
61  m_pMutex = NULL;
62  }
63 
65  {
66  UINT16 tmp, tmp2;
67  for (tmp = 0; tmp < 256; tmp++)
68  {
69  for (tmp2 = 0; tmp2 < 256; tmp2++)
70  {
71  while (pDBInfo->m_pHashTable[tmp][tmp2] != NULL)
72  {
73  t_databaseEntry* anker = pDBInfo->m_pHashTable[tmp][tmp2];
74  pDBInfo->m_pHashTable[tmp][tmp2] = anker->next;
75  delete anker;
76  anker = NULL;
77  }
78  }
79  }
80  pDBInfo->m_u32Size = 0;
81  return E_SUCCESS;
82  }
83 
85  {
86  clearDB(pDBInfo);
87  delete pDBInfo;
88  pDBInfo = NULL;
89  return E_SUCCESS;
90  }
91 
94  {
95  // insert hash if timestamp valid in prevDB currDB nextDB
96  m_pMutex->lock();
97 
98  // return E_UNKNOWN if the timestamp is too old or is too far in the future
99  UINT32 currentTime = (UINT32) time(NULL);
100  if ((timestamp < (m_lastSwitch - SECONDS_PER_INTERVALL)) || (timestamp > (currentTime + FUTURE_TOLERANCE)))
101  {
102  // timestamp not valid!!
103  m_pMutex->unlock();
104  return E_UNKNOWN;
105  }
106 
107  t_databaseInfo* aktDB = NULL;
108  t_databaseInfo* prevDB = NULL;
109  t_databaseInfo* nextDB = NULL;
110 
111  if (timestamp < m_lastSwitch)
112  {
113  aktDB = m_prevDatabase;
114  prevDB = NULL;
115  nextDB = m_currDatabase;
116  }
117  else if (timestamp < (m_lastSwitch + SECONDS_PER_INTERVALL))
118  {
119  aktDB = m_currDatabase;
120  prevDB = m_prevDatabase;
121  nextDB = m_nextDatabase;
122  }
123  else
124  {
125  aktDB = m_nextDatabase;
126  prevDB = m_currDatabase;
127  nextDB = NULL;
128  }
129 
130  UINT64 hashkey = (((UINT64) key[2]) << 56) +
131  (((UINT64) key[3]) << 48) +
132  (((UINT64) key[4]) << 40) +
133  (((UINT64) key[5]) << 32) +
134  (((UINT64) key[6]) << 24) +
135  (((UINT64) key[7]) << 16) +
136  (((UINT64) key[8]) << 8) +
137  ((UINT64) key[9]);
138 
139 // insert
140  if (prevDB != NULL)
141  {
142  t_databaseEntry* tmp = prevDB->m_pHashTable[key[0]][key[1]];
143 
144  while (tmp != NULL)
145  {
146  if (tmp->key != hashkey)
147  {
148  tmp = tmp->next;
149  }
150  else
151  {
152  // duplicate found!!
153  m_pMutex->unlock();
154  return E_UNKNOWN;
155  }
156  }
157 
158  // inserting in DB
159  tmp = new t_databaseEntry;
160  tmp->next = prevDB->m_pHashTable[key[0]][key[1]];
161  tmp->key = hashkey;
162  prevDB->m_pHashTable[key[0]][key[1]] = tmp;
163  prevDB->m_u32Size++;
164  }
165 
166  t_databaseEntry* tmp = aktDB->m_pHashTable[key[0]][key[1]];
167 
168  while (tmp != NULL)
169  {
170  if (tmp->key != hashkey)
171  {
172  tmp = tmp->next;
173  }
174  else
175  {
176  // duplicate found!!
177  m_pMutex->unlock();
178  return E_UNKNOWN;
179  }
180  }
181 
182  // inserting in DB
183  tmp = new t_databaseEntry;
184  tmp->next = aktDB->m_pHashTable[key[0]][key[1]];
185  tmp->key = hashkey;
186  aktDB->m_pHashTable[key[0]][key[1]] = tmp;
187  aktDB->m_u32Size++;
188 
189  if (nextDB != NULL)
190  {
191  t_databaseEntry* tmp = nextDB->m_pHashTable[key[0]][key[1]];
192 
193  while (tmp != NULL)
194  {
195  if (tmp->key != hashkey)
196  {
197  tmp = tmp->next;
198  }
199  else
200  {
201  // duplicate found!!
202  m_pMutex->unlock();
203  return E_UNKNOWN;
204  }
205  }
206 
207  // inserting in DB
208  tmp = new t_databaseEntry;
209  tmp->next = nextDB->m_pHashTable[key[0]][key[1]];
210  tmp->key = hashkey;
211  nextDB->m_pHashTable[key[0]][key[1]] = tmp;
212  nextDB->m_u32Size++;
213  }
214 
215  m_pMutex->unlock();
216  return E_SUCCESS;
217 
218  }
219 
221  {
222  m_pThread = new CAThread();
223  m_bRun = true;
225  return m_pThread->start(this);
226  }
227 
229  {
230  m_bRun = false;
231  SINT32 ret = E_SUCCESS;
232  if (m_pThread != NULL)
233  {
234  ret = m_pThread->join();
235  delete m_pThread;
236  m_pThread = NULL;
237  }
238  return ret;
239  }
240 
242  {
243  INIT_STACK;
244  BEGIN_STACK("CADatabase::db_loopMaintenance");
245 
246  CADatabase* pDatabase=(CADatabase*)param;
247  while(pDatabase->m_bRun)
248  {
249  sSleep(10);
250  UINT32 currentTime=(UINT32)time(NULL);
251  if (pDatabase->m_lastSwitch+SECONDS_PER_INTERVALL<=currentTime)
252  {
253  pDatabase->nextClock();
254  }
255  }
256 
257  FINISH_STACK("CADatabase::db_loopMaintenance");
258 
260  }
261 
263  {
264  m_pMutex->lock();
266  CAMsg::printMsg(LOG_DEBUG, "Replay DB Size was: %u\n", m_prevDatabase->m_u32Size);
271  m_nextDatabase = tmpDB;
272  m_pMutex->unlock();
273  return E_SUCCESS;
274  }
275 
276 // ?????????
278  {
279  /* CADatabase oDatabase;
280  oDatabase.start();
281  UINT8 key[16];
282  memset(key,0,16);
283  UINT32 i;
284  for(i=0;i<20;i++)
285  {
286  getRandom(key,4);
287  oDatabase.insert(key,time(NULL));///TODO WRONG - fixme
288  }
289  for(i=0;i<200000;i++)
290  {
291  getRandom(key,16);
292  oDatabase.insert(key,time(NULL));//TODO WRONG - Fixme
293  }
294  oDatabase.stop();
295  */
296  UINT32 entries = 10000;
297  fill(entries);
298  return E_SUCCESS;
299 // return CADatabase::fill(entries);
300  }
301 
302 // i don't know if this still works
304  UINT32 lowerBoundEntries,
305  UINT32 upperBoundEntries,
306  UINT32 stepBy,
307  UINT32 meassuresPerStep,
308  UINT32 insertsPerMeasure)
309  {
310  initRandom();
311  CADatabase* pDatabase = NULL;
312  UINT32 aktNrOfEntries = lowerBoundEntries;
313  UINT8* key = new UINT8[insertsPerMeasure * 16];
314  UINT8* aktKey;
315  SINT32 file = open((char*) strLogFile, O_CREAT | O_WRONLY | O_LARGEFILE | O_TRUNC, S_IREAD | S_IWRITE);
316  char buff[255];
317  const char* atemplate = "%u,%u,%u\n";
318  const char* header =
319  "The format is as follows: Number of Entries in DB, Number of Inserts done, Total time for Inserts (in micro seconds)\n";
320  write(file, header, strlen(header));
321  while (aktNrOfEntries <= upperBoundEntries)
322  {
323  CAMsg::printMsg(LOG_DEBUG, "Starting measurement with %u entries in the replay database\n", aktNrOfEntries);
324  for (UINT32 i = 0; i < meassuresPerStep; i++)
325  {
326  pDatabase = new CADatabase();
327  pDatabase->fill(aktNrOfEntries);
328  UINT64 startTime, endTime;
329  getRandom(key, insertsPerMeasure * 16);
330  aktKey = key;
331  getcurrentTimeMicros(startTime);
332  for (UINT32 j = 0; j < insertsPerMeasure; j++)
333  {
334  pDatabase->simulateInsert(aktKey);
335  aktKey += 16;
336  }
337  getcurrentTimeMicros(endTime);
338  sprintf(buff, atemplate, aktNrOfEntries, insertsPerMeasure, diff64(endTime, startTime));
339  write(file, buff, strlen(buff));
340  printf("Start delete \n");
341  getcurrentTimeMicros(startTime);
342  delete pDatabase;
343  pDatabase = NULL;
344  getcurrentTimeMicros(endTime);
345  printf("delete takes %u microsecs\n", diff64(endTime, startTime));
346  }
347  aktNrOfEntries += stepBy;
348  }
349  delete[] key;
350  key = NULL;
351  return E_SUCCESS;
352  }
353 
355  {
356  UINT32 i = 0;
357  UINT8 key[16];
358  while (i < nrOfEntries)
359  {
360  getRandom(key, 16);
361  if (insert(key, time(NULL)) == E_SUCCESS)
362  i++;
363  }
364  return E_SUCCESS;
365  }
366 
367 // this won't work anymore
369  {
370  m_pMutex->lock();
371  UINT16 timestamp = (key[14] << 8) | key[15];
372  if (timestamp < m_currentClock - 1 || timestamp > m_currentClock + 1)
373  {
374  //m_pMutex->unlock();
375  //return E_UNKNOWN;
376  }
378  if (timestamp > m_currentClock)
379  {
380  //aktDB=m_nextDatabase;
381  }
382  else if (timestamp < m_currentClock)
383  {
384  //aktDB=m_prevDatabase;
385  }
386 // UINT16 hashKey=(key[8]<<8)|key[9];
387 // t_databaseEntry* hashList=aktDB->m_pHashTable[hashKey];
388 // if(hashList==NULL)
389 // {
390 // LP_databaseEntry newEntry=getNewDBEntry(aktDB);
391 // newEntry->left=NULL;
392 // newEntry->right=NULL;
393 // newEntry->key=key[0]<<24|key[1]<<16|key[2]<<8|key[3];
394  //aktDB->m_pHashTable[hashKey]=newEntry;
395  aktDB->m_u32Size++;
396  m_pMutex->unlock();
397  return E_SUCCESS;
398  /* }
399  else
400  {
401  // UINT32 ret=key[0]<<24|key[1]<<16|key[2]<<8|key[3];
402  // LP_databaseEntry before=NULL;
403  do
404  {
405  //newEntry->keymemcmp(key,hashList->key,6);
406  if(ret==hashList->key)
407  {
408  m_pMutex->unlock();
409  return E_UNKNOWN;
410  }
411  before=hashList;
412  if(hashList->key<ret)
413  {
414  hashList=hashList->right;
415  }
416  else
417  {
418  hashList=hashList->left;
419  }
420  } while(hashList!=NULL);
421  // LP_databaseEntry newEntry=getNewDBEntry(aktDB);
422  // newEntry->left=newEntry->right=NULL;
423  //memcpy(newEntry->key,key,6);
424  // newEntry->key=ret;
425  // if(before->key<ret)
426  // {
427  //before->right=newEntry;
428  // }
429  // else
430  // {
431  //before->left=newEntry;
432  // }
433  }
434  aktDB->m_u32Size++;
435  m_pMutex->unlock();
436  return E_SUCCESS; */
437  }
438 #endif //Only_LOCAL_PROXY
THREAD_RETURN db_loopMaintenance(void *param)
Definition: CADatabase.cpp:241
#define FUTURE_TOLERANCE
Definition: CADatabase.hpp:48
struct _t_database_info t_databaseInfo
#define SECONDS_PER_INTERVALL
Definition: CADatabase.hpp:47
struct _t_database_entry t_databaseEntry
#define INIT_STACK
Definition: CAThread.hpp:48
#define BEGIN_STACK(methodName)
Definition: CAThread.hpp:49
#define FINISH_STACK(methodName)
Definition: CAThread.hpp:50
SINT32 getcurrentTimeMicros(UINT64 &u64Time)
Gets the current Systemtime in micros seconds.
Definition: CAUtil.cpp:280
SINT32 initRandom()
Definition: CAUtil.cpp:302
SINT32 sSleep(UINT32 sec)
Sleeps sec Seconds.
Definition: CAUtil.cpp:425
SINT32 getRandom(UINT32 *val)
Gets 32 random bits.
Definition: CAUtil.cpp:346
UINT32 diff64(const UINT64 &bigop, const UINT64 &smallop)
Definition: CAUtil.hpp:398
#define O_LARGEFILE
Definition: StdAfx.h:635
#define S_IWRITE
Definition: StdAfx.h:491
#define THREAD_RETURN
Definition: StdAfx.h:540
#define THREAD_RETURN_SUCCESS
Definition: StdAfx.h:542
#define S_IREAD
Definition: StdAfx.h:488
unsigned short UINT16
Definition: basetypedefs.h:133
signed int SINT32
Definition: basetypedefs.h:132
struct __UINT64__t_ UINT64
unsigned char UINT8
Definition: basetypedefs.h:135
unsigned int UINT32
Definition: basetypedefs.h:131
SINT32 deleteDB(t_databaseInfo *&pDB)
Deletes the whole database pDB.
Definition: CADatabase.cpp:84
t_databaseInfo * m_prevDatabase
Definition: CADatabase.hpp:106
t_databaseInfo * createDBInfo()
Creates and initialises a dbinfo struct.
Definition: CADatabase.cpp:45
friend THREAD_RETURN db_loopMaintenance(void *param)
Definition: CADatabase.cpp:241
UINT64 m_lastSwitch
Definition: CADatabase.hpp:103
t_databaseInfo * m_currDatabase
Definition: CADatabase.hpp:104
SINT32 clearDB(t_databaseInfo *pDB)
clears the whole database pDB - but does not delete the hashtable pDB
Definition: CADatabase.cpp:64
SINT32 stop()
Definition: CADatabase.cpp:228
CAThread * m_pThread
Definition: CADatabase.hpp:111
static SINT32 measurePerformance(UINT8 *strLogFile, UINT32 lowerBoundEntries, UINT32 upperBoundEntries, UINT32 stepBy, UINT32 meassuresPerStep, UINT32 insertsPerMeasure)
This mehtod can be used to measure the performance of the Replay database.
Definition: CADatabase.cpp:303
SINT32 start()
Definition: CADatabase.cpp:220
CAMutex * m_pMutex
Definition: CADatabase.hpp:110
SINT32 simulateInsert(UINT8 key[16])
This is a modified copy of insert() which simulates the insert() function as close as possible withou...
Definition: CADatabase.cpp:368
t_databaseInfo * m_nextDatabase
Definition: CADatabase.hpp:105
SINT32 insert(UINT8 key[16], UINT64 timestamp)
Inserts this key in the replay DB.
Definition: CADatabase.cpp:93
SINT32 test()
Definition: CADatabase.cpp:277
volatile SINT32 m_currentClock
Definition: CADatabase.hpp:109
SINT32 nextClock()
Definition: CADatabase.cpp:262
volatile bool m_bRun
Definition: CADatabase.hpp:107
SINT32 fill(UINT32 nrOfEntries)
Pre fills the database with nrOfEntries random entries.
Definition: CADatabase.cpp:354
static SINT32 printMsg(UINT32 typ, const char *format,...)
Writes a given message to the log.
Definition: CAMsg.cpp:251
SINT32 unlock()
Definition: CAMutex.hpp:52
SINT32 lock()
Definition: CAMutex.hpp:41
SINT32 start(void *param, bool bDaemon=false, bool bSilent=false)
Starts the execution of the main function of this thread.
Definition: CAThread.cpp:115
SINT32 setMainLoop(THREAD_MAIN_TYP fnc)
Sets the main function which will be executed within this thread.
Definition: CAThread.hpp:148
SINT32 join()
Waits for the main function to finish execution.
Definition: CAThread.cpp:187
const SINT32 E_SUCCESS
Definition: errorcodes.hpp:2
#define E_UNKNOWN
Definition: errorcodes.hpp:3
Definition: CADatabase.hpp:35
_t_database_entry * next
Definition: CADatabase.hpp:36
UINT64 key
Definition: CADatabase.hpp:37
t_databaseEntry * m_pHashTable[0x100][0x100]
Definition: CADatabase.hpp:42