Mixe for Privacy and Anonymity in the Internet
CALastMixA.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 #ifndef ONLY_LOCAL_PROXY
00030 #include "CALastMixA.hpp"
00031 #include "../CALibProxytest.hpp"
00032 #include "../CALastMixChannelList.hpp"
00033 #include "../CASingleSocketGroup.hpp"
00034 #include "../CAPool.hpp"
00035 #include "../CACmdLnOptions.hpp"
00036 #ifdef HAVE_EPOLL
00037 #include "../CASocketGroupEpoll.hpp"
00038 #endif
00039 
00040 #ifdef LOG_CHANNEL
00041 //CAMsg::printMsg(LOG_DEBUG,"Channel time log format is as follows: Channel-ID,Channel Start [micros], Channel End [micros], Upload (bytes), Download (bytes), DataAndOpenAndClosePacketsFromUser, DataAndClosePacketsToUser\n");
00042 #define MACRO_DO_LOG_CHANNEL(a)\
00043   CAMsg::printMsg(LOG_DEBUG,#a ":%u,%Lu,%Lu,%u,%u,%u,%u\n",\
00044       pChannelListEntry->channelIn,pChannelListEntry->timeCreated,pQueueEntry->timestamp_proccessing_end,\
00045       pChannelListEntry->trafficInFromUser,pChannelListEntry->trafficOutToUser,\
00046       pChannelListEntry->packetsDataInFromUser,pChannelListEntry->packetsDataOutToUser);
00047 #define MACRO_DO_LOG_CHANNEL_CLOSE_FROM_USER MACRO_DO_LOG_CHANNEL(1)
00048 #define MACRO_DO_LOG_CHANNEL_CLOSE_FROM_MIX MACRO_DO_LOG_CHANNEL(2)
00049 #endif
00050 
00051 #define LAST_MIX_SIZE_OF_SYMMETRIC_KEYS 2*KEY_SIZE
00052 
00053 
00054 SINT32 CALastMixA::loop()
00055   {
00056 #ifndef NEW_MIX_TYPE
00057     //CASocketList  oSocketList;
00058 #ifdef DELAY_CHANNELS
00059     m_pChannelList->setDelayParameters( CALibProxytest::getOptions()->getDelayChannelUnlimitTraffic(),
00060                                       CALibProxytest::getOptions()->getDelayChannelBucketGrow(),
00061                                       CALibProxytest::getOptions()->getDelayChannelBucketGrowIntervall());
00062 #endif
00063 #ifdef DELAY_CHANNELS_LATENCY
00064     m_pChannelList->setDelayLatencyParameters(  CALibProxytest::getOptions()->getDelayChannelLatency());
00065 #endif
00066 #ifdef HAVE_EPOLL
00067     CASocketGroupEpoll* psocketgroupCacheRead=new CASocketGroupEpoll(false);
00068     CASocketGroupEpoll* psocketgroupCacheWrite=new CASocketGroupEpoll(true);
00069 #else
00070     CASocketGroup* psocketgroupCacheRead=new CASocketGroup(false);
00071     CASocketGroup* psocketgroupCacheWrite=new CASocketGroup(true);
00072 #endif
00073     tQueueEntry* pQueueEntry=new tQueueEntry;
00074     MIXPACKET* pMixPacket=&pQueueEntry->packet;
00075     SINT32 ret;
00076     SINT32 retval;
00077     SINT32 countRead;
00078     lmChannelListEntry* pChannelListEntry;
00079     UINT8* rsaBuff=new UINT8[RSA_SIZE];
00080     UINT32 rsaOutLen=RSA_SIZE;
00081     UINT8* tmpBuff=new UINT8[MIXPACKET_SIZE];
00082     UINT8* ciphertextBuff=new UINT8[DATA_SIZE];
00083     UINT8* plaintextBuff=new UINT8[DATA_SIZE - GCM_MAC_SIZE];
00084     UINT16 payloadLen;
00085     bool bAktiv;
00086     m_logUploadedPackets=m_logDownloadedPackets=0;
00087     set64((UINT64&)m_logUploadedBytes,(UINT32)0);
00088     set64((UINT64&)m_logDownloadedBytes,(UINT32)0);
00089     CAThread* pLogThread=new CAThread((UINT8*)"CALastMixA - LogLoop");
00090     pLogThread->setMainLoop(lm_loopLog);
00091     pLogThread->start(this);
00092 
00093     #ifdef LOG_CRIME
00094     bool userSurveillance = false;
00095     #endif
00096 
00097     #ifdef LOG_CHANNEL
00098       CAMsg::printMsg(LOG_DEBUG,"Channel time log format is as follows: Channel-ID,Channel Start [micros], Channel End [micros], Upload (bytes), Download (bytes), DataAndOpenPacketsFromUser, DataPacketsToUser\n");
00099     #endif
00100 
00101     while(!m_bRestart)
00102       {
00103         bAktiv=false;
00104 //Step 1a reading from previous Mix --> now in separate thread
00105 //Step 1b processing MixPackets from previous mix
00106 // processing maximal number of current channels packets
00107         if(m_pQueueReadFromMix->getSize()>=sizeof(tQueueEntry))
00108           {
00109             bAktiv=true;
00110             UINT32 channels=m_pChannelList->getSize()+1;
00111             for(UINT32 k=0;k<channels&&m_pQueueReadFromMix->getSize()>=sizeof(tQueueEntry);k++)
00112               {
00113                 ret=sizeof(tQueueEntry);
00114                 m_pQueueReadFromMix->get((UINT8*)pQueueEntry,(UINT32*)&ret);
00115                 #if defined(LOG_PACKET_TIMES) ||defined(LOG_CHANNEL)
00116                   getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_start);
00117                 #endif
00118                 #ifdef LOG_PACKET_TIMES
00119                   set64(pQueueEntry->timestamp_proccessing_start,pQueueEntry->timestamp_proccessing_start_OP);
00120                 #endif
00121                 if(pMixPacket->channel>0&&pMixPacket->channel<256)
00122                   {
00123                     m_pMuxInControlChannelDispatcher->proccessMixPacket(pMixPacket);
00124                     continue;
00125                   }
00126                 // one packet received
00127                 m_logUploadedPackets++;
00128                 pChannelListEntry=m_pChannelList->get(pMixPacket->channel);
00129 
00130                 //check if this packet was marked by the previous mixes for user surveillance
00131                 #ifdef LOG_CRIME
00132                 userSurveillance = ((pMixPacket->flags & CHANNEL_SIG_CRIME) != 0);
00133                 pMixPacket->flags &= ~CHANNEL_SIG_CRIME;
00134                 #endif
00135 
00136                 if(pChannelListEntry==NULL)
00137                   {
00138                     if(pMixPacket->flags==CHANNEL_OPEN)
00139                     {
00140                       #if defined(_DEBUG)
00141                         CAMsg::printMsg(LOG_DEBUG,"New Connection from previous Mix!\n");
00142                       #endif
00143 
00144                       m_pRSA->decryptOAEP(pMixPacket->data,rsaBuff,&rsaOutLen);
00145                       #ifdef REPLAY_DETECTION
00146                         // replace time(NULL) with the real timestamp ()
00147                         // packet-timestamp + m_u64ReferenceTime
00148                         UINT32 stamp=((UINT32)(rsaBuff[13]<<16)+(UINT32)(rsaBuff[14]<<8)+(UINT32)(rsaBuff[15]))*REPLAY_BASE;
00149                         if(m_pReplayDB->insert(rsaBuff,stamp+m_u64ReferenceTime)!=E_SUCCESS)
00150 //                          if(m_pReplayDB->insert(rsaBuff,time(NULL))!=E_SUCCESS)
00151                           {
00152                             CAMsg::printMsg(LOG_INFO,"Replay: Duplicate packet ignored.\n");
00153                             continue;
00154                           }
00155                       #endif
00156                       CASymCipher* newCipher = new CASymCipher();
00157                       #ifdef WITH_INTEGRITY_CHECK
00158                         newCipher->setGCMKeys(rsaBuff, rsaBuff + KEY_SIZE);
00159 
00160                         //Decrypt only the first two bytes to get the payload length
00161                         UINT16 lengthAndFlagsField=0;
00162                         newCipher->decryptMessage(rsaBuff + LAST_MIX_SIZE_OF_SYMMETRIC_KEYS, 2,(UINT8*) &lengthAndFlagsField, false);
00163                         payloadLen = ntohs(lengthAndFlagsField);
00164                         payloadLen &= PAYLOAD_LEN_MASK;
00165                         if (payloadLen > (PAYLOAD_SIZE-LAST_MIX_SIZE_OF_SYMMETRIC_KEYS-RSA_SIZE-GCM_MAC_SIZE - PAYLOAD_HEADER_SIZE+rsaOutLen))
00166                           retval=E_UNKNOWN;
00167                         else
00168                           {
00169                             //prepend the asym decrypted sym encrypted part of teh Mix packet to the sym only encrypted part of the mix packet
00170                             memcpy(pMixPacket->data+RSA_SIZE-rsaOutLen+LAST_MIX_SIZE_OF_SYMMETRIC_KEYS,rsaBuff + LAST_MIX_SIZE_OF_SYMMETRIC_KEYS,rsaOutLen-LAST_MIX_SIZE_OF_SYMMETRIC_KEYS);
00171                             //now decrpyt the whole sym encrypted part
00172                             retval = newCipher->decryptMessage(pMixPacket->data +RSA_SIZE-rsaOutLen+LAST_MIX_SIZE_OF_SYMMETRIC_KEYS,  payloadLen+ GCM_MAC_SIZE + PAYLOAD_HEADER_SIZE , pMixPacket->data, true);
00173                           }
00174                       #else
00175                         newCipher->setKeys(rsaBuff,LAST_MIX_SIZE_OF_SYMMETRIC_KEYS);
00176                         newCipher->crypt1(
00177                             pMixPacket->data+RSA_SIZE,
00178                             pMixPacket->data+rsaOutLen-LAST_MIX_SIZE_OF_SYMMETRIC_KEYS,
00179                             DATA_SIZE-RSA_SIZE);
00180                         memcpy( pMixPacket->data,rsaBuff+LAST_MIX_SIZE_OF_SYMMETRIC_KEYS,
00181                               rsaOutLen-LAST_MIX_SIZE_OF_SYMMETRIC_KEYS);
00182                       #endif
00183 
00184                       #ifdef LOG_PACKET_TIMES
00185                         getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end_OP);
00186                       #endif
00187                       #ifdef WITH_INTEGRITY_CHECK
00188                         if (retval != E_SUCCESS)
00189                           {
00190                           /* invalid MAC -> send channel close packet with integrity error flag */
00191                           getRandom(pMixPacket->data, DATA_SIZE);
00192                           pMixPacket->flags = CHANNEL_CLOSE;
00193                           pMixPacket->payload.len = htons(INTEGRITY_ERROR_FLAG);
00194                           pMixPacket->payload.type = 0;
00195                           newCipher->encryptMessage(pMixPacket->data, 3, ciphertextBuff);
00196                           memcpy(pMixPacket->data, ciphertextBuff, 3 + GCM_MAC_SIZE);
00197                           delete newCipher;
00198                           newCipher = NULL;
00199                           #ifdef LOG_PACKET_TIMES
00200                             setZero64(pQueueEntry->timestamp_proccessing_start);
00201                           #endif
00202                           m_pQueueSendToMix->add(pQueueEntry,sizeof(tQueueEntry));
00203                           m_logDownloadedPackets++;
00204                           CAMsg::printMsg(LOG_ERR, "Integrity check failed in channel-open packet!\n");
00205                         } else {
00206                       #endif
00207 
00208                       CASocket* tmpSocket=new CASocket;
00209                       CACacheLoadBalancing* ptmpLB=m_pCacheLB;
00210                       ret=E_UNKNOWN;
00211                       if(pMixPacket->payload.type==MIX_PAYLOAD_SOCKS)
00212                         ptmpLB=m_pSocksLB;
00213                       for(UINT32 count=0;count<ptmpLB->getElementCount();count++)
00214                       {
00215                         tmpSocket->create();
00216                         tmpSocket->setRecvBuff(50000);
00217                         tmpSocket->setSendBuff(5000);
00218                         ret=tmpSocket->connect(*ptmpLB->get(),LAST_MIX_TO_PROXY_CONNECT_TIMEOUT);
00219                         if(ret==E_SUCCESS)
00220                           break;
00221                         tmpSocket->close();
00222                       }
00223                       if(ret!=E_SUCCESS)
00224                       {
00225                           #if defined (_DEBUG) || defined (DELAY_CHANNELS_LATENCY)
00226                             CAMsg::printMsg(LOG_DEBUG,"Cannot connect to Squid!\n");
00227                           #endif
00228                           delete tmpSocket;
00229                           tmpSocket = NULL;
00230                           /* send a close packet signaling the connect error */
00231                           getRandom(pMixPacket->data, DATA_SIZE);
00232                           pMixPacket->flags = CHANNEL_CLOSE;
00233                           pMixPacket->payload.len = 0;
00234                           pMixPacket->payload.type = CONNECTION_ERROR_FLAG;
00235                           #ifdef WITH_INTEGRITY_CHECK
00236                             newCipher->encryptMessage(pMixPacket->data, 3, ciphertextBuff);
00237                             memcpy(pMixPacket->data, ciphertextBuff, 3 + GCM_MAC_SIZE);
00238                           #else
00239                             newCipher->crypt2(pMixPacket->data, pMixPacket->data, DATA_SIZE);
00240                           #endif
00241                           #ifdef LOG_PACKET_TIMES
00242                             setZero64(pQueueEntry->timestamp_proccessing_start);
00243                           #endif
00244                           m_pQueueSendToMix->add(pQueueEntry,sizeof(tQueueEntry));
00245                           m_logDownloadedPackets++;
00246                           delete newCipher;
00247                           newCipher = NULL;
00248                         }
00249                         else
00250                           { //connection to proxy successful
00251                             UINT16 payLen=ntohs(pMixPacket->payload.len);
00252 
00253                             //output payload if packet is marked for user surveillance
00254                             #ifdef LOG_CRIME
00255                             if(userSurveillance)
00256                             {
00257                               UINT8 *domain = parseDomainFromPayload(pMixPacket->payload.data, payLen);
00258 
00259                               if(domain != NULL || (CALibProxytest::getOptions()->isPayloadLogged()) )
00260                               {
00261                                 CAMsg::printMsg(LOG_CRIT,"Crime detection: User surveillance, previous mix channel: %u\n", pMixPacket->channel);
00262                                 if(domain != NULL)
00263                                 {
00264                                   CAMsg::printMsg(LOG_CRIT, "Domain: %s\n", domain);
00265                                   delete [] domain;
00266                                 }
00267                                 if(CALibProxytest::getOptions()->isPayloadLogged())
00268                                 {
00270                                   UINT8 tempPayload[PAYLOAD_SIZE+1];
00271                                   memcpy(tempPayload, pMixPacket->payload.data,payLen);
00272                                   tempPayload[payLen]=0;
00273                                   CAMsg::printMsg(LOG_CRIT, "Payload: %s\n",tempPayload);
00274                                 }
00275                               }
00276                             }
00277                             #endif
00278 
00279                             #ifdef _DEBUG
00280                               UINT8 c=pMixPacket->payload.data[30];
00281                               pMixPacket->payload.data[30]=0;
00282                               CAMsg::printMsg(LOG_DEBUG,"Try sending data to Squid: %s\n",pMixPacket->payload.data);
00283                               pMixPacket->payload.data[30]=c;
00284                             #endif
00285                             #ifdef LOG_CRIME
00286                               if(payLen<=PAYLOAD_SIZE&&checkCrime(pMixPacket->payload.data,payLen,true))
00287                                 {
00288                                   UINT8 crimeBuff[PAYLOAD_SIZE+1];
00289                                   tQueueEntry oSigCrimeQueueEntry;
00290                                   memset(&oSigCrimeQueueEntry,0,sizeof(tQueueEntry));
00291                                   memset(crimeBuff,0,PAYLOAD_SIZE+1);
00292                                   memcpy(crimeBuff,pMixPacket->payload.data,payLen);
00293                                   UINT32 id=m_pMuxIn->sigCrime(pMixPacket->channel,&oSigCrimeQueueEntry.packet);
00294                                   m_pQueueSendToMix->add(&oSigCrimeQueueEntry,sizeof(tQueueEntry));
00295                                   int log=LOG_ENCRYPTED;
00296                                   if(!CALibProxytest::getOptions()->isEncryptedLogEnabled())
00297                                     log=LOG_CRIT;
00298                                   CAMsg::printMsg(log,"Crime detected -- previous mix channel: "
00299                                       "%u -- Content: \n%s\n", pMixPacket->channel,
00300                                       (CALibProxytest::getOptions()->isPayloadLogged() ? crimeBuff : (UINT8 *)"<not logged>"));
00301                                 }
00302                             #endif
00303                             if(payLen>PAYLOAD_SIZE||tmpSocket->sendTimeOut(pMixPacket->payload.data,payLen,LAST_MIX_TO_PROXY_SEND_TIMEOUT)==SOCKET_ERROR)
00304                             {
00305                               #ifdef _DEBUG
00306                                 CAMsg::printMsg(LOG_DEBUG,"Error sending Data to Squid!\n");
00307                               #endif
00308                               tmpSocket->close();
00309                               delete tmpSocket;
00310                               tmpSocket = NULL;
00311                               /* send a close packet signaling the connect error */
00312                               getRandom(pMixPacket->data, DATA_SIZE);
00313                               pMixPacket->flags = CHANNEL_CLOSE;
00314                               pMixPacket->payload.len = htons(CONNECTION_ERROR_FLAG);
00315                               pMixPacket->payload.type = 0;
00316                               #ifdef WITH_INTEGRITY_CHECK
00317                                 newCipher->encryptMessage(pMixPacket->data, 3, ciphertextBuff);
00318                                 memcpy(pMixPacket->data, ciphertextBuff, 3 + GCM_MAC_SIZE);
00319                               #else
00320                                 newCipher->crypt2(pMixPacket->data, pMixPacket->data, DATA_SIZE);
00321                               #endif
00322                               #ifdef LOG_PACKET_TIMES
00323                                 setZero64(pQueueEntry->timestamp_proccessing_start);
00324                               #endif
00325                               m_pQueueSendToMix->add(pQueueEntry,sizeof(tQueueEntry));
00326                               m_logDownloadedPackets++;
00327                                 delete newCipher;
00328                                 newCipher = NULL;
00329                             }
00330                             else
00331                             {
00332                               tmpSocket->setNonBlocking(true);
00333                               #if defined (DELAY_CHANNELS_LATENCY)
00334                                 UINT64 u64temp;
00335                                 getcurrentTimeMillis(u64temp);
00336                               #endif
00337                               CAQueue* pQueue=new CAQueue(PAYLOAD_SIZE);
00338                               #ifdef LASTMIX_CHECK_MEMORY
00339                                 pQueue->logIfSizeGreaterThen(100000);
00340                               #endif
00341                               m_pChannelList->add(pMixPacket->channel,tmpSocket,newCipher,pQueue
00342                               #if defined (LOG_CHANNEL)
00343                                                   ,pQueueEntry->timestamp_proccessing_start,payLen
00344                               #endif
00345                               #if defined (DELAY_CHANNELS_LATENCY)
00346                                                   ,u64temp
00347                               #endif
00348                                                   );
00349 #ifdef HAVE_EPOLL
00350                               psocketgroupCacheRead->add(*tmpSocket,m_pChannelList->get(pMixPacket->channel));
00351 #else
00352                               psocketgroupCacheRead->add(*tmpSocket);
00353 #endif
00354                               #ifdef LOG_PACKET_TIMES
00355                                 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end);
00356                                 m_pLogPacketStats->addToTimeingStats(*pQueueEntry,CHANNEL_OPEN,true);
00357                               #endif
00358                               #ifdef DATA_RETENTION_LOG
00359                                 pQueueEntry->dataRetentionLogEntry.t_out=htonl(time(NULL));
00360                                 pQueueEntry->dataRetentionLogEntry.entity.last.channelid=htonl(pMixPacket->channel);
00361                                 pQueueEntry->dataRetentionLogEntry.entity.last.port_out=tmpSocket->getLocalPort();
00362                                 pQueueEntry->dataRetentionLogEntry.entity.last.port_out=htons(pQueueEntry->dataRetentionLogEntry.entity.last.port_out);
00363                                 tmpSocket->getLocalIP(pQueueEntry->dataRetentionLogEntry.entity.last.ip_out);
00364                                 m_pDataRetentionLog->log(&pQueueEntry->dataRetentionLogEntry);
00365                               #endif
00366 
00367                             }
00368                           }
00369 #ifdef WITH_INTEGRITY_CHECK
00370                       }
00371 #endif
00372                     }
00373                   }
00374                 else
00375                   {//channellist entry !=NULL
00376                     if(pMixPacket->flags==CHANNEL_CLOSE)
00377                       {
00380                         /*
00381                         psocketgroupCacheRead->remove(*(pChannelListEntry->pSocket));
00382                         psocketgroupCacheWrite->remove(*(pChannelListEntry->pSocket));
00383                         pChannelListEntry->pSocket->close();
00384                         delete pChannelListEntry->pSocket;
00385                         pChannelListEntry->pSocket = NULL;
00386                         delete pChannelListEntry->pCipher;
00387                         pChannelListEntry->pCipher = NULL;
00388                         delete pChannelListEntry->pQueueSend;
00389                         pChannelListEntry->pQueueSend = NULL;
00390                         */
00391                         pChannelListEntry->pQueueSend->close();
00392 #ifdef HAVE_EPOLL
00393                         psocketgroupCacheWrite->add(*(pChannelListEntry->pSocket),pChannelListEntry);
00394 #else
00395                         psocketgroupCacheWrite->add(*(pChannelListEntry->pSocket));
00396 #endif
00397                         #if defined (LOG_PACKET_TIMES) ||defined (LOG_CHANNEL)
00398                           getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end);
00399                         #endif
00400                         #if defined (LOG_PACKET_TIMES)
00401                           set64(pQueueEntry->timestamp_proccessing_end_OP,pQueueEntry->timestamp_proccessing_end);
00402                           m_pLogPacketStats->addToTimeingStats(*pQueueEntry,CHANNEL_CLOSE,true);
00403                         #endif
00404                         #ifdef LOG_CHANNEL
00405                           pChannelListEntry->packetsDataInFromUser++;
00406                           MACRO_DO_LOG_CHANNEL_CLOSE_FROM_USER
00407                         #endif
00408                         //m_pChannelList->removeChannel(pMixPacket->channel);
00409                       }
00410                     else if(pMixPacket->flags==CHANNEL_DATA)
00411                       {
00412                         #ifdef LOG_CHANNEL
00413                           pChannelListEntry->packetsDataInFromUser++;
00414                         #endif
00415                         #ifdef WITH_INTEGRITY_CHECK
00416                           /* decrypt only the first 2 bytes to get the payload length */
00417                           UINT16 lengthAndFlagsField=0;
00418                           pChannelListEntry->pCipher->decryptMessage(pMixPacket->data, 2,(UINT8*) &lengthAndFlagsField, false);
00419                           payloadLen = ntohs(lengthAndFlagsField);
00420                           payloadLen &= PAYLOAD_LEN_MASK;
00421                           if (payloadLen > PAYLOAD_SIZE)
00422                             retval=E_UNKNOWN;
00423                           else
00424                             {
00425                               retval = pChannelListEntry->pCipher->decryptMessage(pMixPacket->data, payloadLen + 3 + GCM_MAC_SIZE, plaintextBuff, true);
00426                             }
00427                           if (retval != E_SUCCESS) {
00428                             /* invalid MAC -> send channel close packet with integrity error flag */
00429                             psocketgroupCacheRead->remove(*(pChannelListEntry->pSocket));
00430                             psocketgroupCacheWrite->remove(*(pChannelListEntry->pSocket));
00431                             pChannelListEntry->pSocket->close();
00432                             delete pChannelListEntry->pSocket;
00433                             pChannelListEntry->pSocket = NULL;
00434                             delete pChannelListEntry->pQueueSend;
00435                             pChannelListEntry->pQueueSend = NULL;
00436                             getRandom(pMixPacket->data, DATA_SIZE);
00437                             pMixPacket->flags = CHANNEL_CLOSE;
00438                             pMixPacket->payload.len = htons(INTEGRITY_ERROR_FLAG);
00439                             pMixPacket->payload.type = 0;
00440                             pChannelListEntry->pCipher->encryptMessage(pMixPacket->data, 3, ciphertextBuff);
00441                             memcpy(pMixPacket->data, ciphertextBuff, 3 + GCM_MAC_SIZE);
00442                             delete pChannelListEntry->pCipher;
00443                             pChannelListEntry->pCipher = NULL;
00444                             #ifdef LOG_CHANNEL
00445                                           pChannelListEntry->packetsDataOutToUser++;
00446                               getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end);
00447                               MACRO_DO_LOG_CHANNEL_CLOSE_FROM_MIX
00448                             #endif
00449                                         m_pChannelList->removeChannel(pMixPacket->channel);
00450                             #ifdef LOG_PACKET_TIMES
00451                               setZero64(pQueueEntry->timestamp_proccessing_start);
00452                             #endif
00453                             m_pQueueSendToMix->add(pQueueEntry,sizeof(tQueueEntry));
00454                             m_logDownloadedPackets++;
00455                                         CAMsg::printMsg(LOG_ERR, "Integrity check failed in data packet!\n");
00456                           } else {
00457                             memcpy(pMixPacket->data, plaintextBuff, payloadLen + 3);
00458                         #else
00459                           pChannelListEntry->pCipher->crypt1(pMixPacket->data,pMixPacket->data,DATA_SIZE);
00460                         #endif
00461                         ret=ntohs(pMixPacket->payload.len);
00462                         if(ret&NEW_FLOW_CONTROL_FLAG)
00463                           {
00464                             //CAMsg::printMsg(LOG_DEBUG,"got send me\n");
00465                             pChannelListEntry->sendmeCounterDownstream=max(0,pChannelListEntry->sendmeCounterDownstream-FLOW_CONTROL_SENDME_SOFT_LIMIT);
00466                           }
00467                         ret&=PAYLOAD_LEN_MASK;
00468                         if(ret>=0&&ret<=PAYLOAD_SIZE)
00469                           {
00470                             #ifdef LOG_CHANNEL
00471                               pChannelListEntry->trafficInFromUser+=ret;
00472                             #endif
00473                             #ifdef LOG_PACKET_TIMES
00474                               getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end_OP);
00475                             #endif
00476 
00477                             //output payload if packet is marked for user surveillance
00478                             #ifdef LOG_CRIME
00479                             if(userSurveillance)
00480                             {
00481                               UINT8 *domain = parseDomainFromPayload(pMixPacket->payload.data, ret);
00482 
00483                               if(domain != NULL || (CALibProxytest::getOptions()->isPayloadLogged()) )
00484                               {
00485                                 CAMsg::printMsg(LOG_CRIT,"Crime detection: User surveillance, previous mix channel: %u\n", pMixPacket->channel);
00486                                 if(domain != NULL)
00487                                 {
00488                                   CAMsg::printMsg(LOG_CRIT, "Domain: %s\n", domain);
00489                                   delete [] domain;
00490                                 }
00491                                 if(CALibProxytest::getOptions()->isPayloadLogged())
00492                                 {
00494                                   UINT8 tempPayload[PAYLOAD_SIZE+1];
00495                                   memcpy(tempPayload, pMixPacket->payload.data,ret);
00496                                   tempPayload[ret]=0;
00497                                   CAMsg::printMsg(LOG_CRIT, "Payload: %s\n",tempPayload);
00498                                 }
00499                               }
00500                             }
00501                             else if(checkCrime(pMixPacket->payload.data, ret,false)) // Note: false --> it make no sense to check for URL/Domain in DataPackets
00502                             {
00503                               UINT8 crimeBuff[PAYLOAD_SIZE+1];
00504                               tQueueEntry oSigCrimeQueueEntry;
00505                               memset(&oSigCrimeQueueEntry,0,sizeof(tQueueEntry));
00506                               memset(crimeBuff,0,PAYLOAD_SIZE+1);
00507                               memcpy(crimeBuff,pMixPacket->payload.data, ret);
00508                               UINT32 id=m_pMuxIn->sigCrime(pMixPacket->channel,&oSigCrimeQueueEntry.packet);
00509                               m_pQueueSendToMix->add(&oSigCrimeQueueEntry,sizeof(tQueueEntry));
00510                               int log=LOG_ENCRYPTED;
00511                               if(!CALibProxytest::getOptions()->isEncryptedLogEnabled())
00512                                 log=LOG_CRIT;
00513                               CAMsg::printMsg(log,"Crime detected -- previous mix channel: "
00514                                   "%u -- Content: \n%s\n", pMixPacket->channel,
00515                                   (CALibProxytest::getOptions()->isPayloadLogged() ? crimeBuff : (UINT8 *)"<not logged>"));
00516                             }
00517 
00518                             #endif
00519 
00520                             ret=pChannelListEntry->pQueueSend->add(pMixPacket->payload.data,ret);
00521                           }
00522                         else
00523                           ret=SOCKET_ERROR;
00524                         if(ret==SOCKET_ERROR)
00525                           {
00526                             psocketgroupCacheRead->remove(*(pChannelListEntry->pSocket));
00527                             psocketgroupCacheWrite->remove(*(pChannelListEntry->pSocket));
00528                             pChannelListEntry->pSocket->close();
00529                             delete pChannelListEntry->pSocket;
00530                             pChannelListEntry->pSocket = NULL;
00531                             delete pChannelListEntry->pQueueSend;
00532                             pChannelListEntry->pQueueSend = NULL;
00533                             /* send a close packet signaling the connect error */
00534                             getRandom(pMixPacket->data, DATA_SIZE);
00535                             pMixPacket->flags = CHANNEL_CLOSE;
00536                             pMixPacket->payload.len = 0;
00537                             pMixPacket->payload.type = 0;
00538                             #ifdef WITH_INTEGRITY_CHECK
00539                               pChannelListEntry->pCipher->encryptMessage(pMixPacket->data, 3, ciphertextBuff);
00540                               memcpy(pMixPacket->data, ciphertextBuff, 3 + GCM_MAC_SIZE);
00541                             #endif
00542                                           delete pChannelListEntry->pCipher;
00543                                           pChannelListEntry->pCipher = NULL;
00544                             #ifdef LOG_CHANNEL
00545                               pChannelListEntry->packetsDataOutToUser++;
00546                               getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end);
00547                               MACRO_DO_LOG_CHANNEL_CLOSE_FROM_MIX
00548                             #endif
00549                             m_pChannelList->removeChannel(pMixPacket->channel);
00550                             #ifdef LOG_PACKET_TIMES
00551                               setZero64(pQueueEntry->timestamp_proccessing_start);
00552                             #endif
00553                             m_pQueueSendToMix->add(pQueueEntry,sizeof(tQueueEntry));
00554                             m_logDownloadedPackets++;
00555                           }
00556                         else
00557                           {
00558                             //count this packet as Upstream packet...
00559                             pChannelListEntry->sendmeCounterUpstream++;
00560                             if(pChannelListEntry->sendmeCounterUpstream>=FLOW_CONTROL_SENDME_SOFT_LIMIT) //we need to sent the SENDME ack down to the client...
00561                             {
00562                               getRandom(pMixPacket->data, DATA_SIZE);
00563                               pMixPacket->flags = CHANNEL_DATA;
00564                               pMixPacket->payload.len = htons(NEW_FLOW_CONTROL_FLAG); //signal the SENDME
00565                               pMixPacket->payload.type = 0;
00566                               #ifdef WITH_INTEGRITY_CHECK
00567                                 pChannelListEntry->pCipher->encryptMessage(pMixPacket->data, 3, ciphertextBuff);
00568                                 memcpy(pMixPacket->data, ciphertextBuff, 3 + GCM_MAC_SIZE);
00569                               #else
00570                                 pChannelListEntry->pCipher->crypt2(pMixPacket->data,pMixPacket->data,DATA_SIZE);
00571                               #endif
00572                               #ifdef LOG_CHANNEL
00573                                 pChannelListEntry->packetsDataOutToUser++;
00574                                 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end);
00575                                 MACRO_DO_LOG_CHANNEL_CLOSE_FROM_MIX
00576                               #endif
00577                               #ifdef LOG_PACKET_TIMES
00578                                 setZero64(pQueueEntry->timestamp_proccessing_start);
00579                               #endif
00580                               CAMsg::printMsg(LOG_DEBUG,"sent send me\n");
00581                               m_pQueueSendToMix->add(pQueueEntry,sizeof(tQueueEntry));
00582                               m_logDownloadedPackets++;
00583                               pChannelListEntry->sendmeCounterUpstream-=FLOW_CONTROL_SENDME_SOFT_LIMIT;
00584                             }
00585 #ifdef HAVE_EPOLL
00586                             psocketgroupCacheWrite->add(*(pChannelListEntry->pSocket),pChannelListEntry);
00587 #else
00588                             psocketgroupCacheWrite->add(*(pChannelListEntry->pSocket));
00589 #endif
00590                             #ifdef LOG_PACKET_TIMES
00591                               getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end);
00592                               m_pLogPacketStats->addToTimeingStats(*pQueueEntry,CHANNEL_DATA,true);
00593                             #endif
00594                           }
00595 #ifdef WITH_INTEGRITY_CHECK
00596                         }
00597 #endif
00598                       }
00599                   }
00600               }
00601           }
00602 //end Step 1
00603 
00604 //Step 2 Sending to Cache...
00605         countRead=psocketgroupCacheWrite->select(0);
00606         if(countRead>0)
00607           {
00608             bAktiv=true;
00609 #ifdef HAVE_EPOLL
00610             pChannelListEntry=(lmChannelListEntry*)psocketgroupCacheWrite->getFirstSignaledSocketData();
00611             while(pChannelListEntry!=NULL)
00612               {
00613 #else
00614             pChannelListEntry=m_pChannelList->getFirstSocket();
00615             while(pChannelListEntry!=NULL&&countRead>0)
00616               {
00617                 if(psocketgroupCacheWrite->isSignaled(*(pChannelListEntry->pSocket)))
00618                   {
00619                     countRead--;
00620 #endif
00621                     SINT32 len=MIXPACKET_SIZE;
00622                     SINT32 ret=pChannelListEntry->pQueueSend->peek(tmpBuff,(UINT32*)&len);
00623                     len=pChannelListEntry->pSocket->send(tmpBuff,len);
00624                     if(len>=0)
00625                       {
00626                         add64((UINT64&)m_logUploadedBytes,len);
00627                         pChannelListEntry->pQueueSend->remove((UINT32*)&len);
00628                         if(pChannelListEntry->pQueueSend->isEmpty())
00629                           {
00630                             if(pChannelListEntry->pQueueSend->isClosed()) //channel was closed by user // Queue: EMPTY + CLOSED
00631                               {
00632                                 psocketgroupCacheRead->remove(*(pChannelListEntry->pSocket));
00633                                 psocketgroupCacheWrite->remove(*(pChannelListEntry->pSocket));
00634                                 pChannelListEntry->pSocket->close();
00635                                 delete pChannelListEntry->pSocket;
00636                                 pChannelListEntry->pSocket = NULL;
00637                                 delete pChannelListEntry->pCipher;
00638                                 pChannelListEntry->pCipher = NULL;
00639                                 delete pChannelListEntry->pQueueSend;
00640                                 pChannelListEntry->pQueueSend = NULL;
00641                                 m_pChannelList->removeChannel(pChannelListEntry->channelIn);
00642                               }
00643                             else //Queue: EMPTY+!CLOSED
00644                               {//nothing more to write at the moment...
00645                                 psocketgroupCacheWrite->remove(*(pChannelListEntry->pSocket));
00646                               }
00647                           }
00648                       }
00649                     else
00650                       {
00651                         if(len==SOCKET_ERROR)
00652                           { //do something if send error
00653                             psocketgroupCacheRead->remove(*(pChannelListEntry->pSocket));
00654                             psocketgroupCacheWrite->remove(*(pChannelListEntry->pSocket));
00655                             pChannelListEntry->pSocket->close();
00656                             delete pChannelListEntry->pSocket;
00657                             pChannelListEntry->pSocket = NULL;
00658                             /* send a close packet signaling the connect error */
00659                             getRandom(pMixPacket->data, DATA_SIZE);
00660                             pMixPacket->flags = CHANNEL_CLOSE;
00661                             pMixPacket->payload.len = 0;
00662                             pMixPacket->payload.type = 0;
00663                             #ifdef WITH_INTEGRITY_CHECK
00664                               pChannelListEntry->pCipher->encryptMessage(pMixPacket->data, 3, ciphertextBuff);
00665                               memcpy(pMixPacket->data, ciphertextBuff, 3 + GCM_MAC_SIZE);
00666                             #endif
00667                                           delete pChannelListEntry->pCipher;
00668                                           pChannelListEntry->pCipher = NULL;
00669                             delete pChannelListEntry->pQueueSend;
00670                             pChannelListEntry->pQueueSend = NULL;
00671                             pMixPacket->channel=pChannelListEntry->channelIn;
00672                             #ifdef LOG_PACKET_TIMES
00673                               setZero64(pQueueEntry->timestamp_proccessing_start);
00674                             #endif
00675                             m_pQueueSendToMix->add(pQueueEntry,sizeof(tQueueEntry));
00676                             m_logDownloadedPackets++;
00677                             #ifdef LOG_CHANNEL
00678                               pChannelListEntry->packetsDataOutToUser++;
00679                             #endif
00680                             #ifdef LOG_CHANNEL
00681                               getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end);
00682                               MACRO_DO_LOG_CHANNEL_CLOSE_FROM_MIX
00683                             #endif
00684                             m_pChannelList->removeChannel(pChannelListEntry->channelIn);
00685                           }
00686                       }
00687 #ifdef HAVE_EPOLL
00688                 pChannelListEntry=(lmChannelListEntry*)psocketgroupCacheWrite->getNextSignaledSocketData();
00689 #else
00690                   }
00691                 pChannelListEntry=m_pChannelList->getNextSocket();
00692 #endif
00693               }
00694           }
00695 //End Step 2
00696 
00697 //Step 3 Reading from Cache....
00698 
00699         countRead=psocketgroupCacheRead->select(0);
00700 #ifdef DELAY_CHANNELS_LATENCY
00701         UINT64 current_time_millis;
00702         getcurrentTimeMillis(current_time_millis);
00703 #endif
00704         if(countRead>0&&m_pQueueSendToMix->getSize()<MAX_MIXIN_SEND_QUEUE_SIZE)
00705           {
00706 #ifdef HAVE_EPOLL
00707             pChannelListEntry=(lmChannelListEntry*)psocketgroupCacheRead->getFirstSignaledSocketData();
00708             while(pChannelListEntry!=NULL)
00709               {
00710 #else
00711             pChannelListEntry=m_pChannelList->getFirstSocket();
00712             while(pChannelListEntry!=NULL&&countRead>0)
00713               {
00714                 if(psocketgroupCacheRead->isSignaled(*(pChannelListEntry->pSocket)))
00715                   {
00716                     countRead--;
00717 #endif
00718                     UINT32 bucketSize;
00719                     if((pChannelListEntry->sendmeCounterDownstream<FLOW_CONTROL_SENDME_HARD_LIMIT)
00720                         #ifdef DELAY_CHANNELS
00721                           &&((bucketSize=m_pChannelList->getDelayBuckets(pChannelListEntry->delayBucketID))>0 )
00722                         #endif
00723                         #ifdef DELAY_CHANNELS_LATENCY
00724                           &&(isGreater64(current_time_millis,pChannelListEntry->timeLatency))
00725                         #endif
00726                       )
00727                       {
00728                         #ifndef DELAY_CHANNELS
00729                           ret=pChannelListEntry->pSocket->receive(pMixPacket->payload.data,PAYLOAD_SIZE);
00730                         #else
00731                           UINT32 readLen=
00732                                 min(
00733                                   /*m_pChannelList->getDelayBuckets(pChannelListEntry->delayBucketID)*/bucketSize,
00734                                   PAYLOAD_SIZE);
00735                           ret=pChannelListEntry->pSocket->receive(pMixPacket->payload.data,readLen);
00736                         #endif
00737                         #ifdef LOG_PACKET_TIMES
00738                           getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_start);
00739                           set64(pQueueEntry->timestamp_proccessing_start_OP,pQueueEntry->timestamp_proccessing_start);
00740                         #endif
00741                         bAktiv=true;
00742                         if(ret==SOCKET_ERROR||ret==0)
00743                           {
00744                             psocketgroupCacheRead->remove(*(pChannelListEntry->pSocket));
00745                             psocketgroupCacheWrite->remove(*(pChannelListEntry->pSocket));
00746                             pChannelListEntry->pSocket->close();
00747                             delete pChannelListEntry->pSocket;
00748                             pChannelListEntry->pSocket = NULL;
00749                             /* send a close packet signaling the connect error */
00750                             getRandom(pMixPacket->data, DATA_SIZE);
00751                             pMixPacket->flags = CHANNEL_CLOSE;
00752                             pMixPacket->payload.len = 0;
00753                             pMixPacket->payload.type = 0;
00754                             #ifdef WITH_INTEGRITY_CHECK
00755                               pChannelListEntry->pCipher->encryptMessage(pMixPacket->data, 3, ciphertextBuff);
00756                               memcpy(pMixPacket->data, ciphertextBuff, 3 + GCM_MAC_SIZE);
00757                             #endif
00758                             delete pChannelListEntry->pCipher;
00759                             pChannelListEntry->pCipher = NULL;
00760                             delete pChannelListEntry->pQueueSend;
00761                             pChannelListEntry->pQueueSend = NULL;
00762                             pMixPacket->channel=pChannelListEntry->channelIn;
00763                             #ifdef LOG_PACKET_TIMES
00764                               getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end_OP);
00765                             #endif
00766                             m_pQueueSendToMix->add(pQueueEntry,sizeof(tQueueEntry));
00767                             m_logDownloadedPackets++;
00768                             #ifdef LOG_CHANNEL
00769                               pChannelListEntry->packetsDataOutToUser++;
00770                             #endif
00771                             #ifdef LOG_CHANNEL
00772                               getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end);
00773                               MACRO_DO_LOG_CHANNEL_CLOSE_FROM_MIX
00774                             #endif
00775                             m_pChannelList->removeChannel(pChannelListEntry->channelIn);
00776                           }
00777                         else
00778                           {
00779                             add64((UINT64&)m_logDownloadedBytes,ret);
00780                             #if defined(LOG_CHANNEL)
00781                               pChannelListEntry->trafficOutToUser+=ret;
00782                             #endif
00783                             #ifdef DELAY_CHANNELS
00784                               m_pChannelList->reduceDelayBuckets(pChannelListEntry->delayBucketID, ret);
00785                             #endif
00786                             pMixPacket->channel=pChannelListEntry->channelIn;
00787                             pMixPacket->flags=CHANNEL_DATA;
00788                             pMixPacket->payload.type=0;
00789                             pMixPacket->payload.len=htons((UINT16)ret);
00790                             //#endif
00791                             #ifdef WITH_INTEGRITY_CHECK
00792                               pChannelListEntry->pCipher->encryptMessage(pMixPacket->data, ret + 3, ciphertextBuff);
00793                               memcpy(pMixPacket->data, ciphertextBuff, ret + 3 + GCM_MAC_SIZE);
00794                               getRandom(pMixPacket->data + ret + 3 + GCM_MAC_SIZE, DATA_SIZE - ret - 3 - GCM_MAC_SIZE);
00795                             #else
00796                               pChannelListEntry->pCipher->crypt2(pMixPacket->data,pMixPacket->data,DATA_SIZE);
00797                             #endif
00798                             #ifdef LOG_PACKET_TIMES
00799                               getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end_OP);
00800                             #endif
00801                             m_pQueueSendToMix->add(pQueueEntry, sizeof(tQueueEntry));
00802                             m_logDownloadedPackets++;
00803                             #if defined(LOG_CHANNEL)
00804                               pChannelListEntry->packetsDataOutToUser++;
00805                             #endif
00806                             pChannelListEntry->sendmeCounterDownstream++;
00807                           }
00808                       }
00809 #ifdef HAVE_EPOLL
00810                 pChannelListEntry=(lmChannelListEntry*)psocketgroupCacheRead->getNextSignaledSocketData();
00811 #else
00812                   }
00813                 pChannelListEntry=m_pChannelList->getNextSocket();
00814 #endif
00815               }
00816           }
00817 //end Step 3
00818 
00819 //Step 4 Writing to previous Mix
00820 // Now in a separate Thread!
00821 //
00822 //end step 4
00823         if(!bAktiv)
00824           msSleep(100);
00825       }
00826 
00827 
00828 
00829 
00830 //ERR:
00831     CAMsg::printMsg(LOG_CRIT,"Seems that we are restarting now!!\n");
00832     m_bRunLog=false;
00833     //clean();
00834 
00835     delete []tmpBuff;
00836     tmpBuff = NULL;
00837     delete []rsaBuff;
00838     rsaBuff = NULL;
00839     delete []ciphertextBuff;
00840     ciphertextBuff = NULL;
00841     delete []plaintextBuff;
00842     plaintextBuff = NULL;
00843     delete pQueueEntry;
00844     pQueueEntry = NULL;
00845     pLogThread->join();
00846     delete pLogThread;
00847     pLogThread = NULL;
00848     delete psocketgroupCacheWrite;
00849     psocketgroupCacheWrite = NULL;
00850     delete psocketgroupCacheRead;
00851     psocketgroupCacheRead = NULL;
00852 #endif //! NEW_MIX_TYPE
00853     return E_UNKNOWN;
00854   }
00855 #endif //ONLY_LOCAL_PROXY