Mixe for Privacy and Anonymity in the Internet
CAChain.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2006, The JAP-Team
3  * All rights reserved.
4  * Redistribution and use in source and binary forms, with or without
5  * modification, 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
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * - Neither the name of the University of Technology Dresden, Germany nor
15  * the names of its contributors may be used to endorse or promote
16  * products derived from this software without specific prior written
17  * permission.
18  *
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE
31  */
32 #include "../StdAfx.h"
33 #ifndef ONLY_LOCAL_PROXY
34 #include "CAChain.hpp"
35 #include "typedefsb.hpp"
37 #include "../CAUtil.hpp"
38 
39 #ifndef DELAY_CHANNELS
40 CAChain::CAChain(UINT8* a_chainId) {
41 #else
42 CAChain::CAChain(UINT8* a_chainId, CAMutex* a_delayBucketMutex, SINT32* a_delayBucket) {
43 #endif
44  m_chainId = a_chainId;
45  m_firstChannel = NULL;
46  m_socket = NULL;
47  m_lastAccessTime = -1;
49  m_upstreamClosed = false;
50  m_downstreamClosed = false;
51  m_firstSocketGroup = NULL;
52  m_connectionError = false;
53  m_unknownChainId = false;
55  #ifdef LOG_CHAIN_STATISTICS
56  m_packetsFromUser = 0;
57  m_bytesFromUser = 0;
58  m_packetsToUser = 0;
59  m_bytesToUser = 0;
60  getcurrentTimeMicros(m_creationTime);
61  #endif
62  #ifdef DELAY_CHANNELS
63  m_pDelayBucketMutex = a_delayBucketMutex;
64  m_pDelayBucket = a_delayBucket;
65  #endif
66 }
67 
69  if (m_socket != NULL) {
71  m_socket->close();
72  delete m_socket;
73  m_socket = NULL;
74  }
76  delete m_upstreamSendQueue;
77  m_upstreamSendQueue = NULL;
78  /* remove all associated channels (normally there shouldn't be any, but in
79  * case of a shutdown, some channels may be still open)
80  */
81  while (m_firstChannel != NULL) {
82  t_channelEntry* channelEntry = m_firstChannel;
83  /* remove the entry from the channel-table */
84  channelEntry->channel->associatedChannelList->removeFromTable(channelEntry->channel);
85  /* remove all deadlines */
86  while (channelEntry->channel->firstResponseDeadline != NULL) {
87  t_deadlineEntry* currentDeadline = channelEntry->channel->firstResponseDeadline;
88  channelEntry->channel->firstResponseDeadline = currentDeadline->nextDeadline;
89  delete currentDeadline;
90  currentDeadline = NULL;
91  }
92  /* remove the channel-cipher */
93  delete channelEntry->channel->channelCipher;
94  channelEntry->channel->channelCipher = NULL;
95  m_firstChannel = channelEntry->nextChannel;
96  delete channelEntry;
97  channelEntry = NULL;
98  }
99  #ifdef LOG_CHAIN_STATISTICS
100  /* log chain-statistics with format:
101  * Chain-ID, Chain duration [micros], Upload (bytes), Download (bytes), Packets from user, Packets to user
102  */
103  UINT64 currentTime;
104  getcurrentTimeMicros(currentTime);
105  UINT32 duration = diff64(currentTime, m_creationTime);
107  CAMsg::printMsg(LOG_DEBUG, "%s,%u,%u,%u,%u,%u\n", chainId, duration, m_bytesFromUser, m_bytesToUser, m_packetsFromUser, m_packetsToUser);
108  delete []chainId;
109  chainId = NULL;
110  #endif
111  delete []m_chainId;
112  m_chainId = NULL;
113  #ifdef DELAY_CHANNELS
114  /* free the delay-bucket (set it to -1), don't delete the mutex because it
115  * is used for all delay-buckets
116  */
117  m_pDelayBucketMutex->lock();
118  *m_pDelayBucket = -1;
119  m_pDelayBucketMutex->unlock();
120  #endif
121  }
122 
124  return m_chainId;
125 }
126 
127 #ifdef LOG_CHAIN_STATISTICS
128  void CAChain::setSocket(CASocket* a_socket, UINT32 a_alreadyProcessedPackets, UINT32 a_alreadyProcessedBytes) {
129  m_socket = a_socket;
130  m_bytesFromUser = a_alreadyProcessedBytes;
131  m_packetsFromUser = a_alreadyProcessedPackets;
132  }
133 #else
134  void CAChain::setSocket(CASocket* a_socket) {
135  m_socket = a_socket;
136  }
137 #endif
138 
145 #ifdef HAVE_EPOLL
146 SINT32 CAChain::processDownstream(CASocketGroupEpoll* a_signalingGroup, MIXPACKET* a_downstreamPacket, UINT32* a_processedBytes) {
147 #else
148 SINT32 CAChain::processDownstream(CASocketGroup* a_signalingGroup, MIXPACKET* a_downstreamPacket, UINT32* a_processedBytes) {
149 #endif
150  *a_processedBytes = 0;
151  /* first: get the time - we will need it */
152  timespec currentTime;
153  getcurrentTime(currentTime);
154  if (m_lastAccessTime != -1) {
155  /* currently we dont't have an associated channel -> check whether the
156  * access-timeout is reached
157  */
158  if (m_lastAccessTime + CHAIN_TIMEOUT < currentTime.tv_sec) {
159  /* timeout is reached */
161  return 3;
162  }
163  /* there is currently no channel associated -> we can't do anything */
164  return 1;
165  }
166  /* we have at least one associated channel */
167  /* check whether we have to drop packages because of outdated deadlines */
169  if (((testedDeadlineEntry->deadline.tv_sec + DEADLINE_TIMEOUT) < currentTime.tv_sec) || (((testedDeadlineEntry->deadline.tv_sec + DEADLINE_TIMEOUT) == currentTime.tv_sec) && (testedDeadlineEntry->deadline.tv_nsec <= currentTime.tv_nsec))) {
170  /* we are too late, it wouldn't make sense to send the packet -> we will
171  * reduce traffic by dropping the packet (and all following packets of the
172  * channel) -> currently we have to send at least a CHANNEL-CLOSE, so keep
173  * one packet in the channel
174  */
176  /* we will really loose packets -> synchronization between client and
177  * server is destroyed -> signal connection error and close the chain
178  */
181  CAMsg::printMsg(LOG_INFO, "Dropped downstream-packets from chain '%s'!\n", chainId);
182  delete []chainId;
183  chainId = NULL;
186  m_firstChannel->channel->firstResponseDeadline = testedDeadlineEntry->nextDeadline;
187  delete testedDeadlineEntry;
188  testedDeadlineEntry = m_firstChannel->channel->firstResponseDeadline;
189  }
190  }
191  }
192  /* now try to send something */
193  t_downstreamChainCell* pChainCell = (t_downstreamChainCell*)(a_downstreamPacket->data);
194  if ((m_socket != NULL) && (!m_downstreamClosed) && (m_firstChannel != NULL)) {
196  /* we are able to send data to the client -> look whether data is
197  * available at the socket
198  */
199  if (isSignaledInSocketGroup(a_signalingGroup)) {
200  /* there is something available -> check how much data we can process
201  */
205  }
206  #ifdef DELAY_CHANNELS
207  payloadData = min(payloadData, (UINT16)getDelayBucketInternal());
208  #endif
209  if (payloadData > 0) {
210  /* we will receive something */
211  /* if the packet isn't filled fully, some randomness for the
212  * remainging space would be great
213  */
214  getRandom(a_downstreamPacket->data, DATA_SIZE);
215  SINT32 bytesReceived;
217  bytesReceived = m_socket->receive(pChainCell->firstCell.data, payloadData);
218  }
219  else {
220  bytesReceived = m_socket->receive(pChainCell->sequelCell.data, payloadData);
221  }
222  if (bytesReceived >= 0) {
223  if (bytesReceived == 0) {
224  /* seems to be the end of the data-stream */
225  closeDownstream();
226  }
227  else {
228  /* we have received some bytes -> create the packet */
229  #ifdef DELAY_CHANNELS
230  removeFromDelayBucketInternal(bytesReceived);
231  #endif
233  /* also we have to send the Chain-ID */
234  memcpy(pChainCell->firstCell.chainId, m_chainId, CHAIN_ID_LENGTH);
235  m_firstDownstreamPacket = false;
236  }
237  pChainCell->lengthAndFlags = htons((UINT16)bytesReceived);
238  a_downstreamPacket->channel = m_firstChannel->channel->channelId;
239  a_downstreamPacket->flags = CHANNEL_DATA;
240  m_firstChannel->channel->channelCipher->crypt2(a_downstreamPacket->data, a_downstreamPacket->data, DATA_SIZE);
244  delete currentDeadline;
245  currentDeadline = NULL;
246  *a_processedBytes = (UINT32)bytesReceived;
247  #ifdef LOG_CHAIN_STATISTICS
248  m_packetsToUser++;
249  m_bytesToUser = m_bytesToUser + (UINT32)bytesReceived;
250  #endif
251  return 0;
252  }
253  }
254  else {
255  /* there was a connection error */
257  }
258  }
259  }
260  }
261  }
262  /* we cannot send any real data, but maybe we have to send some protocol data */
264  /* currently we have to send a CHANNEL-CLOSE */
265  getRandom(a_downstreamPacket->data, DATA_SIZE);
266  a_downstreamPacket->channel = m_firstChannel->channel->channelId;
267  a_downstreamPacket->flags = CHANNEL_CLOSE;
268  /* delete channel-resources */
270  currentChannel->associatedChannelList->removeFromTable(currentChannel);
271  delete currentChannel->firstResponseDeadline;
272  currentChannel->firstResponseDeadline = NULL;
273  delete currentChannel->channelCipher;
274  currentChannel->channelCipher = NULL;
275  delete currentChannel;
276  currentChannel = NULL;
277  t_channelEntry* currentChannelEntry = m_firstChannel;
278  /* change to the next channel */
280  delete currentChannelEntry;
281  currentChannelEntry = NULL;
282  #ifdef LOG_CHAIN_STATISTICS
283  /* a packet (CHANNEL_CLOSE) without payload is sent */
284  m_packetsToUser++;
285  #endif
286  if (m_firstChannel == NULL) {
288  /* it was the last channel and the chain is closed -> it can be
289  * removed from the table
290  */
291  return 2;
292  }
293  else {
294  /* it was the last channel, but the chain isn't closed -> start the
295  * access timeout
296  */
297  timespec currentTime;
298  getcurrentTime(currentTime);
299  m_lastAccessTime = currentTime.tv_sec;
300  return 0;
301  }
302  }
303  /* we've sent a close but it wasn't the last channel */
304  return 0;
305  }
306  /* no data, no channel-close, but maybe we have to send a packet because of
307  * a deadline
308  */
309  if ((m_firstChannel->channel->firstResponseDeadline->deadline.tv_sec < currentTime.tv_sec) || ((m_firstChannel->channel->firstResponseDeadline->deadline.tv_sec == currentTime.tv_sec) && (m_firstChannel->channel->firstResponseDeadline->deadline.tv_nsec <= currentTime.tv_nsec))) {
310  /* deadline reached */
311  getRandom(a_downstreamPacket->data, DATA_SIZE);
312  pChainCell->lengthAndFlags = 0;
314  /* also we have to send the Chain-ID */
315  memcpy(pChainCell->firstCell.chainId, m_chainId, CHAIN_ID_LENGTH);
316  m_firstDownstreamPacket = false;
317  }
318  /* maybe we have to set some flags */
319  if (m_unknownChainId) {
320  pChainCell->lengthAndFlags = pChainCell->lengthAndFlags | CHAINFLAG_UNKNOWN_CHAIN;
321  /* reset the flag */
322  m_unknownChainId = false;
323  }
324  if (m_connectionError) {
325  pChainCell->lengthAndFlags = pChainCell->lengthAndFlags | CHAINFLAG_CONNECTION_ERROR;
326  /* reset the flag */
327  m_connectionError = false;
328  }
329  if (m_downstreamClosed) {
330  pChainCell->lengthAndFlags = pChainCell->lengthAndFlags | CHAINFLAG_STREAM_CLOSED;
331  /* don't reset the flag */
332  }
333  /* ensure correct byte order */
334  pChainCell->lengthAndFlags = htons(pChainCell->lengthAndFlags);
335  /* finalize packet */
336  a_downstreamPacket->channel = m_firstChannel->channel->channelId;
337  a_downstreamPacket->flags = CHANNEL_DATA;
338  m_firstChannel->channel->channelCipher->crypt2(a_downstreamPacket->data, a_downstreamPacket->data, DATA_SIZE);
339  /* clean up */
343  delete currentDeadline;
344  currentDeadline = NULL;
345  #ifdef LOG_CHAIN_STATISTICS
346  /* a packet without payload is sent */
347  m_packetsToUser++;
348  #endif
349  return 0;
350  }
351  /* no deadline reached and nothing else to do */
352  return 1;
353 }
354 
355 #ifdef HAVE_EPOLL
357  if (m_socket != NULL) {
358  return a_socketGroup->isSignaled(this);
359  }
360  return false;
361 }
362 #else
363 bool CAChain::isSignaledInSocketGroup(CASocketGroup* a_socketGroup) {
364  if (m_socket != NULL) {
365  return a_socketGroup->isSignaled(*m_socket);
366  }
367  return false;
368 }
369 #endif
370 
371 #ifdef HAVE_EPOLL
373 #else
374 void CAChain::addToSocketGroup(CASocketGroup* a_socketGroup) {
375 #endif
376  if (m_socket != NULL) {
377  /* check whether our socket isn't already in the specified socket-group
378  */
379  t_socketGroupEntry* currentEntry = m_firstSocketGroup;
380  t_socketGroupEntry** previousNextEntryPointer = &m_firstSocketGroup;
381  bool alreadyIncluded = false;
382  while ((currentEntry != NULL) && (!alreadyIncluded)) {
383  if (currentEntry->socketGroup == a_socketGroup) {
384  alreadyIncluded = true;
385  }
386  else {
387  previousNextEntryPointer = &(currentEntry->nextSocketGroup);
388  currentEntry = currentEntry->nextSocketGroup;
389  }
390  }
391  if (!alreadyIncluded) {
392  #ifdef HAVE_EPOLL
393  a_socketGroup->add(*m_socket, this);
394  #else
395  a_socketGroup->add(*m_socket);
396  #endif
397  currentEntry = new t_socketGroupEntry;
398  currentEntry->nextSocketGroup = NULL;
399  currentEntry->socketGroup = a_socketGroup;
400  *previousNextEntryPointer = currentEntry;
401  }
402  }
403 }
404 
405 #ifdef HAVE_EPOLL
407 #else
408 void CAChain::removeFromSocketGroup(CASocketGroup* a_socketGroup) {
409 #endif
410  if (m_socket != NULL) {
411  /* check whether our socket is in the specified socket-group */
412  t_socketGroupEntry* currentEntry = m_firstSocketGroup;
413  t_socketGroupEntry** previousNextEntryPointer = &m_firstSocketGroup;
414  while (currentEntry != NULL) {
415  if (currentEntry->socketGroup == a_socketGroup) {
416  /* we are in the specified socket group -> remove occurance */
417  a_socketGroup->remove(*m_socket);
418  *previousNextEntryPointer = currentEntry->nextSocketGroup;
419  delete currentEntry;
420  currentEntry = NULL;
421  }
422  else {
423  previousNextEntryPointer = &(currentEntry->nextSocketGroup);
424  currentEntry = currentEntry->nextSocketGroup;
425  }
426  }
427  }
428 }
429 
430 #ifdef HAVE_EPOLL
431 UINT32 CAChain::sendUpstreamData(UINT32 a_maxLength, CASocketGroupEpoll* a_removedSocketGroup) {
432 #else
433 UINT32 CAChain::sendUpstreamData(UINT32 a_maxLength, CASocketGroup* a_removedSocketGroup) {
434 #endif
435  UINT32 processedBytes = sendUpstreamDataInternal(a_maxLength);
436  if (m_upstreamSendQueue->isEmpty()) {
437  /* queue is empty -> we can remove the entry from the socketgroup */
438  removeFromSocketGroup(a_removedSocketGroup);
439  }
440  return processedBytes;
441 }
442 
443 
445  if (!m_upstreamClosed) {
446  /* only add data if upstream isn't closed */
447  m_upstreamSendQueue->add(a_buffer, a_size);
448  #ifdef LOG_CHAIN_STATISTICS
449  m_packetsFromUser++;
450  m_bytesFromUser = m_bytesFromUser + a_size;
451  #endif
452  }
453 }
454 
456  /* currently we will close the whole chain immediately */
458 }
459 
461  /* currently we will close the whole chain immediately */
463 }
464 
466  m_connectionError = true;
467  /* we will also close the chain */
469 }
470 
472  m_unknownChainId = true;
473  /* we will not send any chain-id -> disable m_firstDownstreamPacket */
474  m_firstDownstreamPacket = false;
475  /* we will also close the chain */
477 }
478 
480  UINT8* printableChainId = bytes2hex(m_chainId, CHAIN_ID_LENGTH);
481  strtrim(printableChainId);
482  return printableChainId;
483 }
484 
485 void CAChain::addChannel(t_lastMixBChannelListEntry* a_channel, bool a_fastResponse) {
486  t_channelEntry* lastChannel = NULL;
487  bool invalidChannel = false;
488  if (m_firstChannel != NULL) {
489  if (m_firstChannel->nextChannel != NULL) {
490  /* somebody is trying to add a third channel to the chain but currently
491  * only 2 channels can be associated to a data-chain -> ignore the new
492  * channel (attention: currently we have to send at least a
493  * CHANNEL-CLOSE because there is no channel-timeout at first and middle
494  * mixes), send an IOException and close the chain
495  */
496  invalidChannel = true;
498  /* find the last associated channel */
499  lastChannel = m_firstChannel->nextChannel;
500  while (lastChannel->nextChannel != NULL) {
501  lastChannel = lastChannel->nextChannel;
502  }
503  }
504  else {
505  lastChannel = m_firstChannel;
506  }
507  }
508  t_channelEntry* newChannel = new t_channelEntry;
509  /* initialize the fields */
510  newChannel->nextChannel = NULL;
511  newChannel->channel = a_channel;
512  if (lastChannel != NULL) {
513  /* close all previous channels immediately */
515  /* now add the new channel */
516  lastChannel->nextChannel = newChannel;
517  }
518  else {
519  m_firstChannel = newChannel;
520  }
521  timespec currentTime;
522  getcurrentTime(currentTime);
523  if (!invalidChannel) {
524  if ((!(m_upstreamClosed && m_downstreamClosed)) && (m_lastAccessTime != -1)) {
525  /* if not downstream and upstream is closed and also an access-timeout
526  * is running -> stop that access-timeout
527  */
528  m_lastAccessTime = -1;
529  }
531  /* create deadlines for the new downstream-packets */
532  t_deadlineEntry** lastNextDeadlinePointer = &(a_channel->firstResponseDeadline);
533  for (UINT32 i = 0; i < CHANNEL_DOWNSTREAM_PACKETS; i++) {
534  t_deadlineEntry* currentDeadline = new t_deadlineEntry;
535  currentDeadline->nextDeadline = NULL;
536  if (!m_downstreamClosed) {
537  if (a_fastResponse && (i == 0)) {
538  /* we shall send a fast response -> send back the first packet of
539  * the new channel immediately
540  */
541  currentDeadline->deadline.tv_sec = currentTime.tv_sec;
542  }
543  else {
544  /* use normal channel-timeout */
545  currentDeadline->deadline.tv_sec = currentTime.tv_sec + CHANNEL_TIMEOUT;
546  }
547  }
548  else {
549  /* downstream is already closed -> send packets back immediately */
550  currentDeadline->deadline.tv_sec = currentTime.tv_sec;
551  }
552  currentDeadline->deadline.tv_nsec = currentTime.tv_nsec;
553  *lastNextDeadlinePointer = currentDeadline;
554  lastNextDeadlinePointer = &(currentDeadline->nextDeadline);
555  }
556  }
557  else {
558  /* send only one packet (will be CHANNEL-CLOSE) */
559  a_channel->remainingDownstreamPackets = 1;
560  a_channel->firstResponseDeadline = new t_deadlineEntry;
561  a_channel->firstResponseDeadline->nextDeadline = NULL;
562  a_channel->firstResponseDeadline->deadline.tv_sec = currentTime.tv_sec;
563  a_channel->firstResponseDeadline->deadline.tv_nsec = currentTime.tv_nsec;
564  }
565 }
566 
568  m_upstreamClosed = true;
569  m_downstreamClosed = true;
571  if (m_socket != NULL) {
573  m_socket->close();
574  delete m_socket;
575  m_socket = NULL;
576  }
577  /* send back all response-packets immediately */
579 }
580 
582  /* set all deadlines to the current time (if they don't have a previous
583  * time) */
584  timespec currentTime;
585  getcurrentTime(currentTime);
586  t_channelEntry* currentChannel = m_firstChannel;
587  while (currentChannel != NULL) {
588  t_deadlineEntry* currentDeadline = currentChannel->channel->firstResponseDeadline;
589  while (currentDeadline != NULL) {
590  if (currentDeadline->deadline.tv_sec > currentTime.tv_sec) {
591  currentDeadline->deadline.tv_sec = currentTime.tv_sec;
592  currentDeadline->deadline.tv_nsec = currentTime.tv_nsec;
593  }
594  else {
595  if ((currentDeadline->deadline.tv_sec == currentTime.tv_sec) && (currentDeadline->deadline.tv_nsec > currentTime.tv_nsec)) {
596  currentDeadline->deadline.tv_nsec = currentTime.tv_nsec;
597  }
598  }
599  currentDeadline = currentDeadline->nextDeadline;
600  }
601  currentChannel = currentChannel->nextChannel;
602  }
603 }
604 
606  t_socketGroupEntry* currentEntry = m_firstSocketGroup;
607  m_firstSocketGroup = NULL;
608  while (currentEntry != NULL) {
609  currentEntry->socketGroup->remove(*m_socket);
610  t_socketGroupEntry* nextEntry = currentEntry->nextSocketGroup;
611  delete currentEntry;
612  currentEntry = nextEntry;
613  }
614 }
615 
617  UINT32 bytesSent = 0;
618  if ((!m_upstreamClosed) && (m_socket != NULL)) {
619  UINT32 length = a_maxLength;
620  UINT8* buffer = new UINT8[length];
621  if (m_upstreamSendQueue->peek(buffer, &length) == E_SUCCESS) {
622  /* queue has filled the buffer */
623  SINT32 errorCode = m_socket->send(buffer, length);
624  if (errorCode >= 0) {
625  length = (UINT32)errorCode;
626  bytesSent = length;
627  m_upstreamSendQueue->remove(&length);
628  }
629  else {
630  /* error while sending data */
632  }
633  }
634  }
635  return bytesSent;
636 }
637 
638 #ifdef DELAY_CHANNELS
639  SINT32 CAChain::getDelayBucketInternal() {
640  SINT32 delayBucket;
641  m_pDelayBucketMutex->lock();
642  delayBucket = *m_pDelayBucket;
643  m_pDelayBucketMutex->unlock();
644  return delayBucket;
645  }
646 
647  void CAChain::removeFromDelayBucketInternal(SINT32 a_bytesToRemove) {
648  m_pDelayBucketMutex->lock();
649  *m_pDelayBucket = (*m_pDelayBucket) + a_bytesToRemove;
650  m_pDelayBucketMutex->unlock();
651  }
652 #endif
653 #endif //ONLY_LOCAL_PROXY
UINT8 * bytes2hex(const void *bytes, UINT32 len)
Converts the byte array to a hex string.
Definition: CAUtil.cpp:90
SINT32 getcurrentTimeMicros(UINT64 &u64Time)
Gets the current Systemtime in micros seconds.
Definition: CAUtil.cpp:280
UINT32 strtrim(UINT8 *s)
Removes leading and ending whitespaces (chars<=32) from a zero terminated string.
Definition: CAUtil.cpp:49
SINT32 getRandom(UINT32 *val)
Gets 32 random bits.
Definition: CAUtil.cpp:346
SINT32 getcurrentTime(timespec &t)
Gets the current Systemtime in milli seconds.
Definition: CAUtil.cpp:227
UINT32 diff64(const UINT64 &bigop, const UINT64 &smallop)
Definition: CAUtil.hpp:398
#define min(a, b)
Definition: StdAfx.h:649
unsigned short UINT16
Definition: basetypedefs.h:133
signed int SINT32
Definition: basetypedefs.h:132
unsigned char UINT8
Definition: basetypedefs.h:135
unsigned int UINT32
Definition: basetypedefs.h:131
void removeFromSocketGroup(CASocketGroupEpoll *a_socketGroup)
Definition: CAChain.cpp:406
UINT8 * getChainId()
Definition: CAChain.cpp:123
bool isSignaledInSocketGroup(CASocketGroupEpoll *a_socketGroup)
Definition: CAChain.cpp:356
bool m_connectionError
Definition: CAChain.hpp:106
void forceImmediateResponsesInternal()
Definition: CAChain.cpp:581
bool m_downstreamClosed
Definition: CAChain.hpp:107
void addToSocketGroup(CASocketGroupEpoll *a_socketGroup)
Definition: CAChain.cpp:372
CAChain(UINT8 *a_chainId)
Definition: CAChain.cpp:40
UINT8 * getPrintableChainId()
Definition: CAChain.cpp:479
bool m_upstreamClosed
Definition: CAChain.hpp:108
UINT8 * m_chainId
Definition: CAChain.hpp:100
void signalConnectionError()
Definition: CAChain.cpp:465
void setSocket(CASocket *a_socket)
Definition: CAChain.cpp:134
void addChannel(t_lastMixBChannelListEntry *a_channel, bool a_fastResponse)
Definition: CAChain.cpp:485
t_socketGroupEntry * m_firstSocketGroup
Definition: CAChain.hpp:105
void closeChainInternal()
Definition: CAChain.cpp:567
~CAChain(void)
Definition: CAChain.cpp:68
CASocket * m_socket
Definition: CAChain.hpp:102
bool m_unknownChainId
Definition: CAChain.hpp:110
void addDataToUpstreamQueue(UINT8 *a_buffer, UINT32 a_size)
Definition: CAChain.cpp:444
UINT32 sendUpstreamData(UINT32 a_maxLength, CASocketGroupEpoll *a_removedSocketGroup)
Definition: CAChain.cpp:431
void closeUpstream()
Definition: CAChain.cpp:455
void closeDownstream()
Definition: CAChain.cpp:460
void removeFromAllSocketGroupsInternal()
Definition: CAChain.cpp:605
void signalUnknownChain()
Definition: CAChain.cpp:471
t_channelEntry * m_firstChannel
Definition: CAChain.hpp:104
bool m_firstDownstreamPacket
Definition: CAChain.hpp:109
CAQueue * m_upstreamSendQueue
Definition: CAChain.hpp:103
SINT32 m_lastAccessTime
Definition: CAChain.hpp:101
SINT32 processDownstream(CASocketGroupEpoll *a_signalingGroup, MIXPACKET *a_downstreamPacket, UINT32 *a_processedBytes)
Returns: 0, if a packet was created.
Definition: CAChain.cpp:146
UINT32 sendUpstreamDataInternal(UINT32 a_maxLength)
Definition: CAChain.cpp:616
void removeFromTable(t_lastMixBChannelListEntry *a_channelEntry)
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
SINT32 add(const void *buff, UINT32 size)
Adds data to the Queue.
Definition: CAQueue.cpp:76
SINT32 clean()
Removes any stored data from the Queue.
Definition: CAQueue.cpp:47
SINT32 peek(UINT8 *pbuff, UINT32 *psize)
Peeks data from the Queue.
Definition: CAQueue.cpp:258
SINT32 remove(UINT32 *psize)
Removes data from the Queue.
Definition: CAQueue.cpp:302
bool isEmpty()
Returns true, if the Queue is empty.
Definition: CAQueue.hpp:125
SINT32 remove(CASocket &s)
bool isSignaled(CASocket &s)
bool isSignaled(CASocket &s)
SINT32 add(SOCKET &s)
SINT32 remove(CASocket &s)
virtual SINT32 receive(UINT8 *buff, UINT32 len)
Will receive some bytes from the socket.
Definition: CASocket.cpp:645
virtual SINT32 send(const UINT8 *buff, UINT32 len)
Sends some data over the network.
Definition: CASocket.cpp:400
virtual SINT32 close()
Definition: CASocket.cpp:351
virtual SINT32 crypt2(const UINT8 *in, UINT8 *out, UINT32 len)=0
const SINT32 E_SUCCESS
Definition: errorcodes.hpp:2
HCHANNEL channel
Definition: typedefs.hpp:117
UINT8 data[DATA_SIZE]
Definition: typedefs.hpp:121
UINT16 flags
Definition: typedefs.hpp:118
Definition: CAChain.hpp:49
t_channelEntry * nextChannel
Definition: CAChain.hpp:51
struct t_lastMixBChannelListEntry * channel
Definition: CAChain.hpp:50
timespec deadline
t_deadlineEntry * nextDeadline
t_first_downstream_chain_cell firstCell
Definition: typedefsb.hpp:157
t_sequel_downstream_chain_cell sequelCell
Definition: typedefsb.hpp:158
UINT8 chainId[CHAIN_ID_LENGTH]
Definition: typedefsb.hpp:146
UINT8 data[MAX_FIRST_DOWNSTREAM_CHAINCELL_PAYLOAD]
Definition: typedefsb.hpp:147
t_deadlineEntry * firstResponseDeadline
HCHANNEL channelId
UINT16 remainingDownstreamPackets
class CALastMixBChannelList * associatedChannelList
CASymChannelCipher * channelCipher
UINT8 data[MAX_SEQUEL_DOWNSTREAM_CHAINCELL_PAYLOAD]
Definition: typedefsb.hpp:151
Definition: CAChain.hpp:54
t_socketGroupEntry * nextSocketGroup
Definition: CAChain.hpp:60
CASocketGroupEpoll * socketGroup
Definition: CAChain.hpp:56
#define CHANNEL_DATA
Definition: typedefs.hpp:42
#define CHANNEL_CLOSE
Definition: typedefs.hpp:47
#define DATA_SIZE
Definition: typedefs.hpp:69
UINT8 chainId[CHAIN_ID_LENGTH]
Definition: typedefsb.hpp:0
#define MAX_SEQUEL_DOWNSTREAM_CHAINCELL_PAYLOAD
Definition: typedefsb.hpp:120
#define CHAIN_TIMEOUT
Definition: typedefsb.hpp:37
#define CHAIN_ID_LENGTH
Definition: typedefsb.hpp:40
#define MAX_FIRST_DOWNSTREAM_CHAINCELL_PAYLOAD
Definition: typedefsb.hpp:119
#define CHAINFLAG_UNKNOWN_CHAIN
Definition: typedefsb.hpp:67
#define CHAINFLAG_STREAM_CLOSED
Definition: typedefsb.hpp:59
#define CHAINFLAG_CONNECTION_ERROR
Definition: typedefsb.hpp:66
#define CHANNEL_TIMEOUT
Definition: typedefsb.hpp:36
#define CHANNEL_DOWNSTREAM_PACKETS
Definition: typedefsb.hpp:35
#define DEADLINE_TIMEOUT
Definition: typedefsb.hpp:38