Mixe for Privacy and Anonymity in the Internet
CAMuxSocket.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 #include "CASocketAddr.hpp"
30 #include "CAMuxSocket.hpp"
31 #ifdef _DEBUG
32  #include "CAMsg.hpp"
33 #endif
34 #include "CASingleSocketGroup.hpp"
35 #include "CAUtil.hpp"
37 
41 
43  {
44  m_pSocket = new CASocket();
46  m_aktBuffPos=0;
47  m_bIsCrypted=false;
50  {//generate new hash keys
51  for(UINT i=0;i<512;i++)
52  {
57  }
58  }
62  m_pCipherIn = NULL;
63  m_pCipherOut = NULL;
64  setCipher(algCipher);
65  }
66 
68  {
69  close();
70  delete []m_Buff;
71  m_Buff = NULL;
76  delete m_pCipherIn;
77  delete m_pCipherOut;
78  delete m_pSocket;
79  }
80 
82  {
83  if (m_pSocket == NULL)
84  return E_UNKNOWN;
85  delete m_pSocket;
86  m_pSocket = pSocket;
87  return E_SUCCESS;
88  }
89 
91 {
92  if (algCipher == UNDEFINED_CIPHER)
93  return E_UNKNOWN;
94  if (m_pCipherIn != NULL)
95  {
96  delete m_pCipherIn;
97  }
98  if (m_pCipherOut != NULL)
99  {
100  delete m_pCipherOut;
101  }
102 #ifndef MUXSOCKET_CIPHER_NO_ENCRYPTION
105 #else
106 #ifdef DEUBG
107  CAMsg::printMsg(LOG_WARN, "MuxSocket: Using NULL cipher (no encryption)!\n");
108 #endif
111 #endif
112  return E_SUCCESS;
113 }
114 
116  {
117  m_csSend.lock();
118  m_csReceive.lock();
119  m_bIsCrypted=b;
121  m_csSend.unlock();
122  return E_SUCCESS;
123  }
124 
125 
127  {
128  CASocket oSocket;
129  oSocket.create();
130  oSocket.setReuseAddr(true);
131  if(oSocket.listen(port)!=E_SUCCESS)
132  return E_UNKNOWN;
133  if(oSocket.accept(*m_pSocket)!=E_SUCCESS)
134  return E_UNKNOWN;
135  oSocket.close();
136  //m_Socket.setRecvLowWat(MIXPACKET_SIZE);
137  m_aktBuffPos=0;
138  return E_SUCCESS;
139  }
140 
147  {
148  CASocket oSocket;
149  oSocket.create(oAddr.getType());
150  oSocket.setReuseAddr(true);
151  SINT32 ret=oSocket.listen(oAddr);
152  if(ret!=E_SUCCESS)
153  return ret;
154  ret=oSocket.accept(*m_pSocket);
155  if(ret!=E_SUCCESS)
156  return E_UNKNOWN;
157  oSocket.close();
158  //m_Socket.setRecvLowWat(MIXPACKET_SIZE);
159  m_aktBuffPos=0;
160  return E_SUCCESS;
161  }
162 
164  {
165  return connect(psa,1,0);
166  }
167 
169  {
170  //m_Socket.setRecvLowWat(MIXPACKET_SIZE);
171  m_aktBuffPos=0;
172  return m_pSocket->connect(psa,retry,time);
173  }
176  {
177  m_aktBuffPos=0;
178  return m_pSocket->close();
179  }
187  {
188  m_csSend.lock();
189  int ret;
190  UINT8 tmpBuff[16];
191  memcpy(tmpBuff,pPacket,16);
192  pPacket->channel=htonl(pPacket->channel);
193  pPacket->flags=htons(pPacket->flags);
194  if(m_bIsCrypted)
195  m_pCipherOut->crypt1(((UINT8*)pPacket),((UINT8*)pPacket),16);
196  ret=m_pSocket->sendFully(((UINT8*)pPacket),MIXPACKET_SIZE);
197  if(ret!=E_SUCCESS)
198  {
199  #ifdef _DEBUG
200  CAMsg::printMsg(LOG_DEBUG,"MuxSocket-Send-Error!\n");
201  CAMsg::printMsg(LOG_DEBUG,"SOCKET-ERROR: %i\n",GET_NET_ERROR);
202  #endif
203  ret=E_UNKNOWN;
204  }
205  else
206  {
207  ret=MIXPACKET_SIZE;
208  }
209  memcpy(pPacket,tmpBuff,16);
210  m_csSend.unlock();
211  return ret;
212  }
213 
214 /*** 'Sends' the packet to a buffer*/
216  {
217  m_csSend.lock();
218  int ret;
219  UINT8 tmpBuff[16];
220  memcpy(tmpBuff,pPacket,16);
221  pPacket->channel=htonl(pPacket->channel);
222  pPacket->flags=htons(pPacket->flags);
223  if(m_bIsCrypted)
224  m_pCipherOut->crypt1(((UINT8*)pPacket),((UINT8*)pPacket),16);
225  memcpy(buff,((UINT8*)pPacket),MIXPACKET_SIZE);
226  ret=MIXPACKET_SIZE;
227  memcpy(pPacket,tmpBuff,16);
228  m_csSend.unlock();
229  return ret;
230  }
231 
233  {
234  m_csSend.lock();
235  pinoutPacket->channel=htonl(pinoutPacket->channel);
236  pinoutPacket->flags=htons(pinoutPacket->flags);
237  m_pCipherOut->crypt1(((UINT8*)pinoutPacket),((UINT8*)pinoutPacket),16);
238  m_csSend.unlock();
239  return MIXPACKET_SIZE;
240  }
241 
250  {
251  SINT32 retLock = m_csReceive.lock();
252  if (retLock != E_SUCCESS)
253  {
254  CAMsg::printMsg(LOG_CRIT, "Could not lock MuxSocket receive method! Error code: %d\n", retLock);
255  return E_UNKNOWN;
256  }
257 
259  {
261  return SOCKET_ERROR;
262  }
263  if(m_bIsCrypted)
264  m_pCipherIn->crypt1((UINT8*)pPacket,(UINT8*)pPacket,16);
265  pPacket->channel=ntohl(pPacket->channel);
266  pPacket->flags=ntohs(pPacket->flags);
268  return MIXPACKET_SIZE;
269  }
270 
277 //TODO: Bug if socket is not in non_blocking mode!!
279  {
280  if (m_pSocket->isClosed())
281  {
282  return E_NOT_CONNECTED;
283  }
284 
285  SINT32 retLock = m_csReceive.lock();
286  if (retLock != E_SUCCESS)
287  {
288  CAMsg::printMsg(LOG_CRIT,
289  "Could not lock MuxSocket timed receive method! Error code: %d\n", retLock);
290  return E_UNKNOWN;
291  }
294  if(ret<=0&&ret!=E_AGAIN) //if socket was set in non-blocking mode
295  {
297  return E_UNKNOWN;
298  }
299  if(ret==len) //whole packet recieved
300  {
301  if(m_bIsCrypted)
302  m_pCipherIn->crypt1(m_Buff,m_Buff,16);
303  memcpy(pPacket,m_Buff,MIXPACKET_SIZE);
304  pPacket->channel=ntohl(pPacket->channel);
305  pPacket->flags=ntohs(pPacket->flags);
306  m_aktBuffPos=0;
308  return MIXPACKET_SIZE;
309  }
310  if(ret>0) //some new bytes arrived
311  m_aktBuffPos+=ret;
312  if(msTimeout==0) //we should not wait any more
313  {
315  return E_AGAIN;
316  }
317  UINT64 timeE;
318  UINT64 timeC;
319  getcurrentTimeMillis(timeE);
320  add64(timeE,msTimeout);
321  UINT32 dt=msTimeout;
322  CASingleSocketGroup oSocketGroup(false);
323  oSocketGroup.add(*this);
324  for(;;)
325  {
326  if (m_pSocket->isClosed())
327  {
329  return E_NOT_CONNECTED;
330  }
331  ret=oSocketGroup.select(dt);
332  if(ret!=1)
333  {
335  return E_UNKNOWN;
336  }
338  if (m_pSocket->isClosed())
339  {
341  return E_NOT_CONNECTED;
342  }
344  if(ret<=0&&ret!=E_AGAIN)
345  {
346  if (m_pSocket->isClosed())
347  {
348  CAMsg::printMsg(LOG_ERR, "Error while receiving from socket. Socket is closed! Receive returned: %i Reason: %s (%i)\n", ret, GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
349  }
350  else
351  {
352  CAMsg::printMsg(LOG_ERR, "Error while receiving from socket. Receive returned: %i Reason: %s (%i)\n", ret, GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
353  }
355  return E_UNKNOWN;
356  }
357  if(ret==len)
358  {
359  if(m_bIsCrypted)
360  m_pCipherIn->crypt1(m_Buff,m_Buff,16);
361  memcpy(pPacket,m_Buff,MIXPACKET_SIZE);
362  pPacket->channel=ntohl(pPacket->channel);
363  pPacket->flags=ntohs(pPacket->flags);
364  m_aktBuffPos=0;
366  return MIXPACKET_SIZE;
367  }
368  if(ret>0)
369  m_aktBuffPos+=ret;
370  getcurrentTimeMillis(timeC);
371  if(isGreater64(timeC,timeE)||isEqual64(timeC,timeE))
372  break;
373  dt=diff64(timeE,timeC);
374  }
376  return E_AGAIN;
377  }
378 
379 /*int CAMuxSocket::close(HCHANNEL channel_id)
380  {
381  MIXPACKET oPacket;
382  oPacket.channel=channel_id;
383  oPacket.flags=CHANNEL_CLOSE;
384  return send(&oPacket);
385  }
386 
387 int CAMuxSocket::close(HCHANNEL channel_id,UINT8* buff)
388  {
389  MIXPACKET oPacket;
390  oPacket.channel=channel_id;
391  oPacket.flags=CHANNEL_CLOSE;
392  return send(&oPacket,buff);
393  }*/
394 
395 #ifdef LOG_CRIME
396 void CAMuxSocket::sigCrime(HCHANNEL channel_id,MIXPACKET* sigPacket)
397  {
398  sigPacket->channel=channel_id;
399  UINT16 v;
400  getRandom(&v);
402  sigPacket->flags=(CHANNEL_SIG_CRIME|v);
403  getRandom(sigPacket->data,DATA_SIZE);
404  }
405 #endif
struct __t_hash_key_entry__ t_hashkeylistEntry
Definition: CAMuxSocket.hpp:42
SYMCHANNELCIPHER_ALGORITHM
@ NULL_CIPHER
@ UNDEFINED_CIPHER
SINT32 getcurrentTimeMillis(UINT64 &u64Time)
Gets the current Systemtime in milli seconds.
Definition: CAUtil.cpp:252
SINT32 getRandom(UINT32 *val)
Gets 32 random bits.
Definition: CAUtil.cpp:346
UINT32 diff64(const UINT64 &bigop, const UINT64 &smallop)
Definition: CAUtil.hpp:398
bool isEqual64(UINT64 &op1, UINT64 &op2)
Definition: CAUtil.hpp:455
void add64(UINT64 &op1, UINT32 op2)
Definition: CAUtil.hpp:375
bool isGreater64(UINT64 &op1, UINT64 &op2)
Definition: CAUtil.hpp:416
#define GET_NET_ERROR
Definition: StdAfx.h:469
#define GET_NET_ERROR_STR(x)
Definition: StdAfx.h:471
#define SOCKET_ERROR
Definition: StdAfx.h:464
unsigned short UINT16
Definition: basetypedefs.h:133
unsigned int UINT
Definition: basetypedefs.h:155
signed int SINT32
Definition: basetypedefs.h:132
unsigned char UINT8
Definition: basetypedefs.h:135
unsigned int UINT32
Definition: basetypedefs.h:131
SINT32 receiveFully(UINT8 *buff, UINT32 len)
Receives all len bytes.
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
CAMutex m_csSend
CAMutex m_csReceive
UINT32 m_aktBuffPos
SINT32 close()
Closes the underlying socket.
SINT32 accept(UINT16 port)
SINT32 receive(MIXPACKET *pPacket)
Receives a whole MixPacket.
CASocket * m_pSocket
SINT32 connect(CASocketAddr &psa)
static t_hashkeylistEntry * ms_phashkeylistAvailableHashKeys
CASymCipherMuxSocket * m_pCipherOut
SINT32 setCrypt(bool b)
SINT32 send(MIXPACKET *pPacket)
Sends a MixPacket over the Network.
CASymCipherMuxSocket * m_pCipherIn
SINT32 setCASocket(CASocket *pSocket)
This will set the underlying CASocket.
Definition: CAMuxSocket.cpp:81
UINT8 * m_Buff
static CAMutex * ms_pcsHashKeyList
SINT32 prepareForSend(MIXPACKET *inoutPacket)
SINT32 setCipher(SYMCHANNELCIPHER_ALGORITHM algCipher)
Definition: CAMuxSocket.cpp:90
static SINT32 ms_nMaxHashKeyValue
t_hashkeylistEntry * m_pHashKeyEntry
CAMuxSocket(SYMCHANNELCIPHER_ALGORITHM algCipher)
Definition: CAMuxSocket.cpp:42
This is an abstract class for representing a socket address used in CASocket, CADatagramSocket and CA...
virtual SINT32 getType() const =0
The type (family) of socket for which this address is useful.
SINT32 add(SOCKET &s)
virtual SINT32 receive(UINT8 *buff, UINT32 len)
Will receive some bytes from the socket.
Definition: CASocket.cpp:645
virtual SINT32 listen(const CASocketAddr &psa)
Starts listening on address psa.
Definition: CASocket.cpp:142
virtual bool isClosed()
Definition: CASocket.hpp:132
virtual SINT32 setReuseAddr(bool b)
Definition: CASocket.cpp:839
virtual SINT32 sendFully(const UINT8 *buff, UINT32 len)
Sends all data over the network.
Definition: CASocket.cpp:587
virtual SINT32 accept(CASocket &s)
Accepts a new connection.
Definition: CASocket.cpp:192
virtual SINT32 create()
Definition: CASocket.cpp:73
virtual SINT32 close()
Definition: CASocket.cpp:351
virtual SINT32 connect(const CASocketAddr &psa)
Definition: CASocket.hpp:64
static CASymChannelCipher * createCipher(SYMCHANNELCIPHER_ALGORITHM alg)
const SINT32 E_SUCCESS
Definition: errorcodes.hpp:2
#define E_NOT_CONNECTED
Definition: errorcodes.hpp:22
#define E_AGAIN
Definition: errorcodes.hpp:9
#define E_UNKNOWN
Definition: errorcodes.hpp:3
Definition: CAMuxSocket.hpp:37
struct __t_hash_key_entry__ * next
Definition: CAMuxSocket.hpp:38
SINT32 hashkey
Definition: CAMuxSocket.hpp:39
HCHANNEL channel
Definition: typedefs.hpp:117
UINT8 data[DATA_SIZE]
Definition: typedefs.hpp:121
UINT16 flags
Definition: typedefs.hpp:118
#define MIXPACKET_SIZE
Definition: typedefs.hpp:40
UINT32 HCHANNEL
Definition: typedefs.hpp:34
#define CHANNEL_SIG_CRIME_ID_MASK
Definition: typedefs.hpp:59
UINT16 len
Definition: typedefs.hpp:0
#define CHANNEL_SIG_CRIME
Definition: typedefs.hpp:58
#define DATA_SIZE
Definition: typedefs.hpp:69