Mixe for Privacy and Anonymity in the Internet
CAMuxSocket.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000, The JAP-Team 
00003 All rights reserved.
00004 Redistribution and use in source and binary forms, with or without modification, 
00005 are permitted provided that the following conditions are met:
00006 
00007   - Redistributions of source code must retain the above copyright notice, 
00008     this list of conditions and the following disclaimer.
00009 
00010   - Redistributions in binary form must reproduce the above copyright notice, 
00011     this list of conditions and the following disclaimer in the documentation and/or 
00012     other materials provided with the distribution.
00013 
00014   - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors 
00015     may be used to endorse or promote products derived from this software without specific 
00016     prior written permission. 
00017 
00018   
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS 
00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 
00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00027 */
00028 #include "StdAfx.h"
00029 #include "CASocketAddr.hpp"
00030 #include "CAMuxSocket.hpp"
00031 #ifdef _DEBUG
00032   #include "CAMsg.hpp"
00033 #endif
00034 #include "CASingleSocketGroup.hpp"
00035 #include "CAUtil.hpp"
00036 
00037 t_hashkeylistEntry* CAMuxSocket::ms_phashkeylistAvailableHashKeys=NULL;
00038 SINT32 CAMuxSocket::ms_nMaxHashKeyValue=0;
00039 CAMutex* CAMuxSocket::ms_pcsHashKeyList=new CAMutex();
00040 
00041 CAMuxSocket::CAMuxSocket()
00042   {
00043     m_Buff=new UINT8[MIXPACKET_SIZE];
00044     m_aktBuffPos=0;
00045     m_bIsCrypted=false;
00046     ms_pcsHashKeyList->lock();
00047     if(ms_phashkeylistAvailableHashKeys==NULL)
00048       {//generate new hash keys
00049         for(UINT i=0;i<512;i++)
00050           {
00051             m_pHashKeyEntry=new t_hashkeylistEntry;
00052             m_pHashKeyEntry->next=ms_phashkeylistAvailableHashKeys;
00053             m_pHashKeyEntry->hashkey=ms_nMaxHashKeyValue++;
00054             ms_phashkeylistAvailableHashKeys=m_pHashKeyEntry;
00055           }
00056       }
00057     m_pHashKeyEntry=ms_phashkeylistAvailableHashKeys;
00058     ms_phashkeylistAvailableHashKeys=m_pHashKeyEntry->next;
00059     ms_pcsHashKeyList->unlock();
00060   }
00061   
00062 CAMuxSocket::~CAMuxSocket()
00063   {
00064     close();
00065     delete []m_Buff;
00066     m_Buff = NULL;
00067     ms_pcsHashKeyList->lock();
00068     m_pHashKeyEntry->next=ms_phashkeylistAvailableHashKeys;
00069     ms_phashkeylistAvailableHashKeys=m_pHashKeyEntry;
00070     ms_pcsHashKeyList->unlock();
00071   } 
00072 
00073 SINT32 CAMuxSocket::setCrypt(bool b)
00074   {
00075     m_csSend.lock();
00076     m_csReceive.lock();
00077     m_bIsCrypted=b;
00078     m_csReceive.unlock();
00079     m_csSend.unlock();
00080     return E_SUCCESS;
00081   }
00082 
00083 
00084 SINT32 CAMuxSocket::accept(UINT16 port)
00085   {
00086     CASocket oSocket;
00087     oSocket.create();
00088     oSocket.setReuseAddr(true);
00089     if(oSocket.listen(port)!=E_SUCCESS)
00090       return E_UNKNOWN;
00091     if(oSocket.accept(m_Socket)!=E_SUCCESS)
00092       return E_UNKNOWN;
00093     oSocket.close();
00094     //m_Socket.setRecvLowWat(MIXPACKET_SIZE);
00095     m_aktBuffPos=0;
00096     return E_SUCCESS;
00097   }
00098 
00104 SINT32 CAMuxSocket::accept(const CASocketAddr& oAddr)
00105   {
00106     CASocket oSocket;
00107     oSocket.create(oAddr.getType());
00108     oSocket.setReuseAddr(true);
00109     SINT32 ret=oSocket.listen(oAddr);
00110     if(ret!=E_SUCCESS)
00111       return ret;
00112     ret=oSocket.accept(m_Socket);
00113     if(ret!=E_SUCCESS)
00114       return E_UNKNOWN;
00115     oSocket.close();
00116     //m_Socket.setRecvLowWat(MIXPACKET_SIZE);
00117     m_aktBuffPos=0;
00118     return E_SUCCESS;
00119   }
00120 
00121 SINT32 CAMuxSocket::connect(CASocketAddr & psa)
00122   {
00123     return connect(psa,1,0);
00124   }
00125 
00126 SINT32 CAMuxSocket::connect(CASocketAddr & psa,UINT retry,UINT32 time)
00127   {
00128     //m_Socket.setRecvLowWat(MIXPACKET_SIZE);
00129     m_aktBuffPos=0;
00130     return m_Socket.connect(psa,retry,time);
00131   }
00133 SINT32 CAMuxSocket::close()
00134   {
00135     m_aktBuffPos=0;
00136     return m_Socket.close();
00137   }
00144 SINT32 CAMuxSocket::send(MIXPACKET *pPacket)
00145   {
00146     m_csSend.lock();
00147     int ret;
00148     UINT8 tmpBuff[16];
00149     memcpy(tmpBuff,pPacket,16);
00150     pPacket->channel=htonl(pPacket->channel);
00151     pPacket->flags=htons(pPacket->flags);
00152     if(m_bIsCrypted)
00153       m_oCipherOut.crypt1(((UINT8*)pPacket),((UINT8*)pPacket),16);
00154     ret=m_Socket.sendFully(((UINT8*)pPacket),MIXPACKET_SIZE);
00155     if(ret!=E_SUCCESS)
00156       {
00157         #ifdef _DEBUG
00158           CAMsg::printMsg(LOG_DEBUG,"MuxSocket-Send-Error!\n");
00159           CAMsg::printMsg(LOG_DEBUG,"SOCKET-ERROR: %i\n",GET_NET_ERROR);
00160         #endif
00161         ret=E_UNKNOWN;
00162       }
00163     else
00164     {
00165       ret=MIXPACKET_SIZE;
00166     }
00167     memcpy(pPacket,tmpBuff,16);
00168     m_csSend.unlock();
00169     return ret;
00170   }
00171 
00172 SINT32 CAMuxSocket::send(MIXPACKET *pPacket,UINT8* buff)
00173   {
00174     m_csSend.lock();
00175     int ret;
00176     UINT8 tmpBuff[16];
00177     memcpy(tmpBuff,pPacket,16);
00178     pPacket->channel=htonl(pPacket->channel);
00179     pPacket->flags=htons(pPacket->flags);
00180     if(m_bIsCrypted)
00181       m_oCipherOut.crypt1(((UINT8*)pPacket),((UINT8*)pPacket),16);
00182     memcpy(buff,((UINT8*)pPacket),MIXPACKET_SIZE);
00183     ret=MIXPACKET_SIZE;
00184     memcpy(pPacket,tmpBuff,16);
00185     m_csSend.unlock();
00186     return ret;
00187   }
00188   
00189 SINT32 CAMuxSocket::prepareForSend(MIXPACKET *pinoutPacket)
00190   { 
00191     m_csSend.lock();
00192     pinoutPacket->channel=htonl(pinoutPacket->channel);
00193     pinoutPacket->flags=htons(pinoutPacket->flags);
00194     m_oCipherOut.crypt1(((UINT8*)pinoutPacket),((UINT8*)pinoutPacket),16);
00195     m_csSend.unlock();
00196     return MIXPACKET_SIZE;
00197   }
00198   
00206 SINT32 CAMuxSocket::receive(MIXPACKET* pPacket)
00207   {
00208     SINT32 retLock = m_csReceive.lock();
00209     if (retLock != E_SUCCESS)
00210     {
00211       CAMsg::printMsg(LOG_CRIT,
00212         "Could not lock MuxSocket receive method! Error code: %d\n", retLock);
00213       return E_UNKNOWN;
00214     }
00215     
00216     if(m_Socket.receiveFully((UINT8*)pPacket,MIXPACKET_SIZE)!=E_SUCCESS)
00217     {
00218       m_csReceive.unlock();
00219       return SOCKET_ERROR;
00220     }
00221     if(m_bIsCrypted)
00222       m_oCipherIn.crypt1((UINT8*)pPacket,(UINT8*)pPacket,16);
00223     pPacket->channel=ntohl(pPacket->channel);
00224     pPacket->flags=ntohs(pPacket->flags);
00225     m_csReceive.unlock();
00226     return MIXPACKET_SIZE;
00227   }
00228 
00235 //TODO: Bug if socket is not in non_blocking mode!!
00236 SINT32 CAMuxSocket::receive(MIXPACKET* pPacket,UINT32 msTimeout)
00237   {
00238     if (m_Socket.isClosed())
00239     {
00240       return E_NOT_CONNECTED;
00241     }
00242     
00243     SINT32 retLock = m_csReceive.lock();
00244     if (retLock != E_SUCCESS)
00245     {
00246       CAMsg::printMsg(LOG_CRIT,
00247         "Could not lock MuxSocket timed receive method! Error code: %d\n", retLock);
00248       return E_UNKNOWN;
00249     }
00250     SINT32 len=MIXPACKET_SIZE-m_aktBuffPos;
00251     SINT32 ret=m_Socket.receive(m_Buff+m_aktBuffPos,len);
00252     if(ret<=0&&ret!=E_AGAIN) //if socket was set in non-blocking mode
00253     {
00254       m_csReceive.unlock();
00255       return E_UNKNOWN;
00256     }
00257     if(ret==len) //whole packet recieved
00258     {
00259       if(m_bIsCrypted)
00260         m_oCipherIn.crypt1(m_Buff,m_Buff,16);
00261       memcpy(pPacket,m_Buff,MIXPACKET_SIZE);
00262       pPacket->channel=ntohl(pPacket->channel);
00263       pPacket->flags=ntohs(pPacket->flags);
00264       m_aktBuffPos=0;
00265       m_csReceive.unlock();
00266       return MIXPACKET_SIZE;
00267     }
00268     if(ret>0) //some new bytes arrived
00269       m_aktBuffPos+=ret;
00270     if(msTimeout==0) //we should not wait any more
00271     {
00272       m_csReceive.unlock();
00273       return E_AGAIN;
00274     }
00275     UINT64 timeE;
00276     UINT64 timeC;
00277     getcurrentTimeMillis(timeE);
00278     add64(timeE,msTimeout);
00279     UINT32 dt=msTimeout;
00280     CASingleSocketGroup oSocketGroup(false);
00281     oSocketGroup.add(*this);
00282     for(;;)
00283       {
00284         if (m_Socket.isClosed())
00285         {
00286           m_csReceive.unlock();
00287           return E_NOT_CONNECTED;
00288         }       
00289         ret=oSocketGroup.select(dt);
00290         if(ret!=1)
00291         {
00292           m_csReceive.unlock();
00293           return E_UNKNOWN;
00294         }
00295         len=MIXPACKET_SIZE-m_aktBuffPos;
00296         if (m_Socket.isClosed())
00297         {
00298           m_csReceive.unlock();
00299           return E_NOT_CONNECTED;
00300         }       
00301         ret=m_Socket.receive(m_Buff+m_aktBuffPos,len);
00302         if(ret<=0&&ret!=E_AGAIN)
00303         {
00304           if (m_Socket.isClosed())
00305           {
00306             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);
00307           }
00308           else
00309           {
00310             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);
00311           }
00312           m_csReceive.unlock();
00313           return E_UNKNOWN;
00314         }
00315         if(ret==len)
00316         {
00317           if(m_bIsCrypted)
00318             m_oCipherIn.crypt1(m_Buff,m_Buff,16);
00319           memcpy(pPacket,m_Buff,MIXPACKET_SIZE);
00320           pPacket->channel=ntohl(pPacket->channel);
00321           pPacket->flags=ntohs(pPacket->flags);
00322           m_aktBuffPos=0;
00323           m_csReceive.unlock();
00324           return MIXPACKET_SIZE;
00325         }
00326         if(ret>0)
00327           m_aktBuffPos+=ret;
00328         getcurrentTimeMillis(timeC);
00329         if(isGreater64(timeC,timeE)||isEqual64(timeC,timeE))
00330           break;
00331         dt=diff64(timeE,timeC);
00332       }
00333     m_csReceive.unlock();
00334     return E_AGAIN;
00335   }
00336 
00337 /*int CAMuxSocket::close(HCHANNEL channel_id)
00338   {
00339     MIXPACKET oPacket;
00340     oPacket.channel=channel_id;
00341     oPacket.flags=CHANNEL_CLOSE;
00342     return send(&oPacket);
00343   }
00344 
00345 int CAMuxSocket::close(HCHANNEL channel_id,UINT8* buff)
00346   {
00347     MIXPACKET oPacket;
00348     oPacket.channel=channel_id;
00349     oPacket.flags=CHANNEL_CLOSE;
00350     return send(&oPacket,buff);
00351   }*/
00352 
00353 #ifdef LOG_CRIME
00354 UINT32 CAMuxSocket::sigCrime(HCHANNEL channel_id,MIXPACKET* sigPacket)
00355   {
00356     sigPacket->channel=channel_id;
00357     UINT32 v;
00358     getRandom(&v);
00359     v&=CHANNEL_SIG_CRIME_ID_MASK;
00360     sigPacket->flags=(CHANNEL_SIG_CRIME|v);
00361     getRandom(sigPacket->data,DATA_SIZE);
00362     return (v>>8);
00363   }
00364 #endif