Mixe for Privacy and Anonymity in the Internet
Public Member Functions | Private Member Functions | Private Attributes | List of all members
CAChain Class Reference

#include <CAChain.hpp>

Collaboration diagram for CAChain:

Public Member Functions

 CAChain (UINT8 *a_chainId)
 
 ~CAChain (void)
 
UINT8getChainId ()
 
void setSocket (CASocket *a_socket)
 
void addChannel (t_lastMixBChannelListEntry *a_channel, bool a_fastResponse)
 
void addDataToUpstreamQueue (UINT8 *a_buffer, UINT32 a_size)
 
void signalConnectionError ()
 
void signalUnknownChain ()
 
void closeUpstream ()
 
void closeDownstream ()
 
UINT8getPrintableChainId ()
 
void addToSocketGroup (CASocketGroupEpoll *a_socketGroup)
 
void removeFromSocketGroup (CASocketGroupEpoll *a_socketGroup)
 
bool isSignaledInSocketGroup (CASocketGroupEpoll *a_socketGroup)
 
UINT32 sendUpstreamData (UINT32 a_maxLength, CASocketGroupEpoll *a_removedSocketGroup)
 
SINT32 processDownstream (CASocketGroupEpoll *a_signalingGroup, MIXPACKET *a_downstreamPacket, UINT32 *a_processedBytes)
 Returns: 0, if a packet was created. More...
 

Private Member Functions

void closeChainInternal ()
 
void forceImmediateResponsesInternal ()
 
void removeFromAllSocketGroupsInternal ()
 
UINT32 sendUpstreamDataInternal (UINT32 a_maxLength)
 

Private Attributes

UINT8m_chainId
 
SINT32 m_lastAccessTime
 
CASocketm_socket
 
CAQueuem_upstreamSendQueue
 
t_channelEntrym_firstChannel
 
t_socketGroupEntrym_firstSocketGroup
 
bool m_connectionError
 
bool m_downstreamClosed
 
bool m_upstreamClosed
 
bool m_firstDownstreamPacket
 
bool m_unknownChainId
 

Detailed Description

Definition at line 64 of file CAChain.hpp.

Constructor & Destructor Documentation

◆ CAChain()

CAChain::CAChain ( UINT8 a_chainId)

Definition at line 40 of file CAChain.cpp.

40  {
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 }
SINT32 getcurrentTimeMicros(UINT64 &u64Time)
Gets the current Systemtime in micros seconds.
Definition: CAUtil.cpp:280
signed int SINT32
Definition: basetypedefs.h:132
unsigned char UINT8
Definition: basetypedefs.h:135
bool m_connectionError
Definition: CAChain.hpp:106
bool m_downstreamClosed
Definition: CAChain.hpp:107
CAChain(UINT8 *a_chainId)
Definition: CAChain.cpp:40
bool m_upstreamClosed
Definition: CAChain.hpp:108
UINT8 * m_chainId
Definition: CAChain.hpp:100
t_socketGroupEntry * m_firstSocketGroup
Definition: CAChain.hpp:105
CASocket * m_socket
Definition: CAChain.hpp:102
bool m_unknownChainId
Definition: CAChain.hpp:110
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
This is a simple FIFO-Queue.
Definition: CAQueue.hpp:50
#define DATA_SIZE
Definition: typedefs.hpp:69

References DATA_SIZE, getcurrentTimeMicros(), m_chainId, m_connectionError, m_downstreamClosed, m_firstChannel, m_firstDownstreamPacket, m_firstSocketGroup, m_lastAccessTime, m_socket, m_unknownChainId, m_upstreamClosed, and m_upstreamSendQueue.

Here is the call graph for this function:

◆ ~CAChain()

CAChain::~CAChain ( void  )

Definition at line 68 of file CAChain.cpp.

68  {
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  }
UINT32 diff64(const UINT64 &bigop, const UINT64 &smallop)
Definition: CAUtil.hpp:398
unsigned int UINT32
Definition: basetypedefs.h:131
UINT8 * getPrintableChainId()
Definition: CAChain.cpp:479
void removeFromAllSocketGroupsInternal()
Definition: CAChain.cpp:605
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
SINT32 clean()
Removes any stored data from the Queue.
Definition: CAQueue.cpp:47
virtual SINT32 close()
Definition: CASocket.cpp:351
Definition: CAChain.hpp:49
t_channelEntry * nextChannel
Definition: CAChain.hpp:51
struct t_lastMixBChannelListEntry * channel
Definition: CAChain.hpp:50
t_deadlineEntry * nextDeadline
t_deadlineEntry * firstResponseDeadline
class CALastMixBChannelList * associatedChannelList
CASymChannelCipher * channelCipher
UINT8 chainId[CHAIN_ID_LENGTH]
Definition: typedefsb.hpp:0

References t_lastMixBChannelListEntry::associatedChannelList, chainId, t_channelEntry::channel, t_lastMixBChannelListEntry::channelCipher, CAQueue::clean(), CASocket::close(), diff64(), t_lastMixBChannelListEntry::firstResponseDeadline, getcurrentTimeMicros(), getPrintableChainId(), m_chainId, m_firstChannel, m_socket, m_upstreamSendQueue, t_channelEntry::nextChannel, t_deadlineEntry::nextDeadline, CAMsg::printMsg(), removeFromAllSocketGroupsInternal(), and CALastMixBChannelList::removeFromTable().

Here is the call graph for this function:

Member Function Documentation

◆ addChannel()

void CAChain::addChannel ( t_lastMixBChannelListEntry a_channel,
bool  a_fastResponse 
)

Definition at line 485 of file CAChain.cpp.

485  {
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 }
SINT32 getcurrentTime(timespec &t)
Gets the current Systemtime in milli seconds.
Definition: CAUtil.cpp:227
void forceImmediateResponsesInternal()
Definition: CAChain.cpp:581
void signalConnectionError()
Definition: CAChain.cpp:465
timespec deadline
UINT16 remainingDownstreamPackets
#define CHANNEL_TIMEOUT
Definition: typedefsb.hpp:36
#define CHANNEL_DOWNSTREAM_PACKETS
Definition: typedefsb.hpp:35

References t_channelEntry::channel, CHANNEL_DOWNSTREAM_PACKETS, CHANNEL_TIMEOUT, t_deadlineEntry::deadline, t_lastMixBChannelListEntry::firstResponseDeadline, forceImmediateResponsesInternal(), getcurrentTime(), m_downstreamClosed, m_firstChannel, m_lastAccessTime, m_upstreamClosed, t_channelEntry::nextChannel, t_deadlineEntry::nextDeadline, t_lastMixBChannelListEntry::remainingDownstreamPackets, and signalConnectionError().

Referenced by CALastMixB::loop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ addDataToUpstreamQueue()

void CAChain::addDataToUpstreamQueue ( UINT8 a_buffer,
UINT32  a_size 
)

Definition at line 444 of file CAChain.cpp.

444  {
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 }
SINT32 add(const void *buff, UINT32 size)
Adds data to the Queue.
Definition: CAQueue.cpp:76

References CAQueue::add(), m_upstreamClosed, and m_upstreamSendQueue.

Referenced by CALastMixB::loop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ addToSocketGroup()

void CAChain::addToSocketGroup ( CASocketGroupEpoll a_socketGroup)

Definition at line 372 of file CAChain.cpp.

372  {
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 }
void addToSocketGroup(CASocketGroupEpoll *a_socketGroup)
Definition: CAChain.cpp:372
SINT32 add(SOCKET &s)
Definition: CAChain.hpp:54
t_socketGroupEntry * nextSocketGroup
Definition: CAChain.hpp:60
CASocketGroupEpoll * socketGroup
Definition: CAChain.hpp:56

References CASocketGroup::add(), m_firstSocketGroup, m_socket, t_socketGroupEntry::nextSocketGroup, and t_socketGroupEntry::socketGroup.

Referenced by CALastMixB::loop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ closeChainInternal()

void CAChain::closeChainInternal ( )
private

Definition at line 567 of file CAChain.cpp.

567  {
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 }

References CAQueue::clean(), CASocket::close(), forceImmediateResponsesInternal(), m_downstreamClosed, m_socket, m_upstreamClosed, m_upstreamSendQueue, and removeFromAllSocketGroupsInternal().

Referenced by closeDownstream(), closeUpstream(), processDownstream(), signalConnectionError(), and signalUnknownChain().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ closeDownstream()

void CAChain::closeDownstream ( )

Definition at line 460 of file CAChain.cpp.

460  {
461  /* currently we will close the whole chain immediately */
463 }
void closeChainInternal()
Definition: CAChain.cpp:567

References closeChainInternal().

Referenced by processDownstream().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ closeUpstream()

void CAChain::closeUpstream ( )

Definition at line 455 of file CAChain.cpp.

455  {
456  /* currently we will close the whole chain immediately */
458 }

References closeChainInternal().

Referenced by CALastMixB::loop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ forceImmediateResponsesInternal()

void CAChain::forceImmediateResponsesInternal ( )
private

Definition at line 581 of file CAChain.cpp.

581  {
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 }

References t_channelEntry::channel, t_deadlineEntry::deadline, t_lastMixBChannelListEntry::firstResponseDeadline, getcurrentTime(), m_firstChannel, t_channelEntry::nextChannel, and t_deadlineEntry::nextDeadline.

Referenced by addChannel(), and closeChainInternal().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getChainId()

UINT8 * CAChain::getChainId ( )

Definition at line 123 of file CAChain.cpp.

123  {
124  return m_chainId;
125 }

References m_chainId.

Referenced by CAChainTable::getEntryInternal(), and CALastMixB::loop().

Here is the caller graph for this function:

◆ getPrintableChainId()

UINT8 * CAChain::getPrintableChainId ( )

Definition at line 479 of file CAChain.cpp.

479  {
480  UINT8* printableChainId = bytes2hex(m_chainId, CHAIN_ID_LENGTH);
481  strtrim(printableChainId);
482  return printableChainId;
483 }
UINT8 * bytes2hex(const void *bytes, UINT32 len)
Converts the byte array to a hex string.
Definition: CAUtil.cpp:90
UINT32 strtrim(UINT8 *s)
Removes leading and ending whitespaces (chars<=32) from a zero terminated string.
Definition: CAUtil.cpp:49
#define CHAIN_ID_LENGTH
Definition: typedefsb.hpp:40

References bytes2hex(), CHAIN_ID_LENGTH, m_chainId, and strtrim().

Referenced by processDownstream(), and ~CAChain().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ isSignaledInSocketGroup()

bool CAChain::isSignaledInSocketGroup ( CASocketGroupEpoll a_socketGroup)

Definition at line 356 of file CAChain.cpp.

356  {
357  if (m_socket != NULL) {
358  return a_socketGroup->isSignaled(this);
359  }
360  return false;
361 }
bool isSignaled(CASocket &s)

References CASocketGroupEpoll::isSignaled(), and m_socket.

Referenced by CALastMixB::loop(), and processDownstream().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ processDownstream()

SINT32 CAChain::processDownstream ( CASocketGroupEpoll a_signalingGroup,
MIXPACKET a_downstreamPacket,
UINT32 a_processedBytes 
)

Returns: 0, if a packet was created.

1, if currently nothing can be done. 2, if a packet was created and the chain can be removed from the chaintable. 3, if no packet was created, but the chain can be removed from the chaintable.

Definition at line 146 of file CAChain.cpp.

146  {
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 }
SINT32 getRandom(UINT32 *val)
Gets 32 random bits.
Definition: CAUtil.cpp:346
#define min(a, b)
Definition: StdAfx.h:649
unsigned short UINT16
Definition: basetypedefs.h:133
bool isSignaledInSocketGroup(CASocketGroupEpoll *a_socketGroup)
Definition: CAChain.cpp:356
void closeDownstream()
Definition: CAChain.cpp:460
SINT32 processDownstream(CASocketGroupEpoll *a_signalingGroup, MIXPACKET *a_downstreamPacket, UINT32 *a_processedBytes)
Returns: 0, if a packet was created.
Definition: CAChain.cpp:146
virtual SINT32 receive(UINT8 *buff, UINT32 len)
Will receive some bytes from the socket.
Definition: CASocket.cpp:645
virtual SINT32 crypt2(const UINT8 *in, UINT8 *out, UINT32 len)=0
HCHANNEL channel
Definition: typedefs.hpp:117
UINT8 data[DATA_SIZE]
Definition: typedefs.hpp:121
UINT16 flags
Definition: typedefs.hpp:118
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
HCHANNEL channelId
UINT8 data[MAX_SEQUEL_DOWNSTREAM_CHAINCELL_PAYLOAD]
Definition: typedefsb.hpp:151
#define CHANNEL_DATA
Definition: typedefs.hpp:42
#define CHANNEL_CLOSE
Definition: typedefs.hpp:47
#define MAX_SEQUEL_DOWNSTREAM_CHAINCELL_PAYLOAD
Definition: typedefsb.hpp:120
#define CHAIN_TIMEOUT
Definition: typedefsb.hpp:37
#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 DEADLINE_TIMEOUT
Definition: typedefsb.hpp:38

References t_lastMixBChannelListEntry::associatedChannelList, CHAIN_ID_LENGTH, CHAIN_TIMEOUT, CHAINFLAG_CONNECTION_ERROR, CHAINFLAG_STREAM_CLOSED, CHAINFLAG_UNKNOWN_CHAIN, chainId, t_first_downstream_chain_cell::chainId, t_channelEntry::channel, t_MixPacket::channel, CHANNEL_CLOSE, CHANNEL_DATA, t_lastMixBChannelListEntry::channelCipher, t_lastMixBChannelListEntry::channelId, closeChainInternal(), closeDownstream(), CASymChannelCipher::crypt2(), t_MixPacket::data, t_first_downstream_chain_cell::data, t_sequel_downstream_chain_cell::data, DATA_SIZE, t_deadlineEntry::deadline, DEADLINE_TIMEOUT, t_downstream_chain_cell::firstCell, t_lastMixBChannelListEntry::firstResponseDeadline, t_MixPacket::flags, getcurrentTime(), getPrintableChainId(), getRandom(), isSignaledInSocketGroup(), t_downstream_chain_cell::lengthAndFlags, m_chainId, m_connectionError, m_downstreamClosed, m_firstChannel, m_firstDownstreamPacket, m_lastAccessTime, m_socket, m_unknownChainId, m_upstreamClosed, MAX_FIRST_DOWNSTREAM_CHAINCELL_PAYLOAD, MAX_SEQUEL_DOWNSTREAM_CHAINCELL_PAYLOAD, min, t_channelEntry::nextChannel, t_deadlineEntry::nextDeadline, CAMsg::printMsg(), CASocket::receive(), t_lastMixBChannelListEntry::remainingDownstreamPackets, CALastMixBChannelList::removeFromTable(), t_downstream_chain_cell::sequelCell, and signalConnectionError().

Referenced by CALastMixB::loop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ removeFromAllSocketGroupsInternal()

void CAChain::removeFromAllSocketGroupsInternal ( )
private

Definition at line 605 of file CAChain.cpp.

605  {
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 }
SINT32 remove(CASocket &s)

References m_firstSocketGroup, m_socket, t_socketGroupEntry::nextSocketGroup, CASocketGroupEpoll::remove(), and t_socketGroupEntry::socketGroup.

Referenced by closeChainInternal(), and ~CAChain().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ removeFromSocketGroup()

void CAChain::removeFromSocketGroup ( CASocketGroupEpoll a_socketGroup)

Definition at line 406 of file CAChain.cpp.

406  {
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 }
void removeFromSocketGroup(CASocketGroupEpoll *a_socketGroup)
Definition: CAChain.cpp:406
SINT32 remove(CASocket &s)

References m_firstSocketGroup, m_socket, t_socketGroupEntry::nextSocketGroup, CASocketGroup::remove(), and t_socketGroupEntry::socketGroup.

Referenced by sendUpstreamData().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendUpstreamData()

UINT32 CAChain::sendUpstreamData ( UINT32  a_maxLength,
CASocketGroupEpoll a_removedSocketGroup 
)

Definition at line 431 of file CAChain.cpp.

431  {
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 }
UINT32 sendUpstreamData(UINT32 a_maxLength, CASocketGroupEpoll *a_removedSocketGroup)
Definition: CAChain.cpp:431
UINT32 sendUpstreamDataInternal(UINT32 a_maxLength)
Definition: CAChain.cpp:616
bool isEmpty()
Returns true, if the Queue is empty.
Definition: CAQueue.hpp:125

References CAQueue::isEmpty(), m_upstreamSendQueue, removeFromSocketGroup(), and sendUpstreamDataInternal().

Referenced by CALastMixB::loop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendUpstreamDataInternal()

UINT32 CAChain::sendUpstreamDataInternal ( UINT32  a_maxLength)
private

Definition at line 616 of file CAChain.cpp.

616  {
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 }
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
virtual SINT32 send(const UINT8 *buff, UINT32 len)
Sends some data over the network.
Definition: CASocket.cpp:400
const SINT32 E_SUCCESS
Definition: errorcodes.hpp:2

References E_SUCCESS, m_socket, m_upstreamClosed, m_upstreamSendQueue, CAQueue::peek(), CAQueue::remove(), CASocket::send(), and signalConnectionError().

Referenced by sendUpstreamData().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setSocket()

void CAChain::setSocket ( CASocket a_socket)

Definition at line 134 of file CAChain.cpp.

134  {
135  m_socket = a_socket;
136  }

References m_socket.

Referenced by CALastMixB::loop().

Here is the caller graph for this function:

◆ signalConnectionError()

void CAChain::signalConnectionError ( )

Definition at line 465 of file CAChain.cpp.

465  {
466  m_connectionError = true;
467  /* we will also close the chain */
469 }

References closeChainInternal(), and m_connectionError.

Referenced by addChannel(), CALastMixB::loop(), processDownstream(), and sendUpstreamDataInternal().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ signalUnknownChain()

void CAChain::signalUnknownChain ( )

Definition at line 471 of file CAChain.cpp.

471  {
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 }

References closeChainInternal(), m_firstDownstreamPacket, and m_unknownChainId.

Referenced by CALastMixB::loop().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ m_chainId

UINT8* CAChain::m_chainId
private

Definition at line 100 of file CAChain.hpp.

Referenced by CAChain(), getChainId(), getPrintableChainId(), processDownstream(), and ~CAChain().

◆ m_connectionError

bool CAChain::m_connectionError
private

Definition at line 106 of file CAChain.hpp.

Referenced by CAChain(), processDownstream(), and signalConnectionError().

◆ m_downstreamClosed

bool CAChain::m_downstreamClosed
private

Definition at line 107 of file CAChain.hpp.

Referenced by addChannel(), CAChain(), closeChainInternal(), and processDownstream().

◆ m_firstChannel

t_channelEntry* CAChain::m_firstChannel
private

◆ m_firstDownstreamPacket

bool CAChain::m_firstDownstreamPacket
private

Definition at line 109 of file CAChain.hpp.

Referenced by CAChain(), processDownstream(), and signalUnknownChain().

◆ m_firstSocketGroup

t_socketGroupEntry* CAChain::m_firstSocketGroup
private

◆ m_lastAccessTime

SINT32 CAChain::m_lastAccessTime
private

Definition at line 101 of file CAChain.hpp.

Referenced by addChannel(), CAChain(), and processDownstream().

◆ m_socket

CASocket* CAChain::m_socket
private

◆ m_unknownChainId

bool CAChain::m_unknownChainId
private

Definition at line 110 of file CAChain.hpp.

Referenced by CAChain(), processDownstream(), and signalUnknownChain().

◆ m_upstreamClosed

bool CAChain::m_upstreamClosed
private

◆ m_upstreamSendQueue

CAQueue* CAChain::m_upstreamSendQueue
private

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