|
Mixe for Privacy and Anonymity in the Internet
|
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 "CALastMix.hpp" 00031 #ifdef NEW_MIX_TYPE // TypeB mixes 00032 #include "TypeB/typedefsb.hpp" 00033 #else // not TypeB mixes 00034 /* TypeB mixes doesn't use the default-implementation */ 00035 #include "CALastMixChannelList.hpp" 00036 #endif 00037 #include "CALibProxytest.hpp" 00038 #include "CASocketGroup.hpp" 00039 #include "CASingleSocketGroup.hpp" 00040 #include "CAMsg.hpp" 00041 #include "CACmdLnOptions.hpp" 00042 #ifdef HAVE_UNIX_DOMAIN_PROTOCOL 00043 #include "CASocketAddrUnix.hpp" 00044 #endif 00045 #include "CACertStore.hpp" 00046 #include "CABase64.hpp" 00047 #include "CAPool.hpp" 00048 #include "xml/DOM_Output.hpp" 00049 #include "CAStatusManager.hpp" 00050 /*******************************************************************************/ 00051 // ----------START NEW VERSION ----------------------- 00052 //--------------------------------------------------------- 00053 /********************************************************************************/ 00054 00055 SINT32 CALastMix::initOnce() 00056 { 00057 SINT32 ret=CAMix::initOnce(); 00058 if(ret!=E_SUCCESS) 00059 return ret; 00060 if(setTargets()!=E_SUCCESS) 00061 { 00062 CAMsg::printMsg(LOG_CRIT,"Could not set Targets (proxies)!\n"); 00063 return E_UNKNOWN; 00064 } 00065 00066 //m_pSignature=CALibProxytest::getOptions()->getSignKey(); 00067 m_pMultiSignature=CALibProxytest::getOptions()->getMultiSigner(); 00068 if(m_pMultiSignature==NULL) 00069 return E_UNKNOWN; 00070 if(CALibProxytest::getOptions()->getListenerInterfaceCount()<1) 00071 { 00072 CAMsg::printMsg(LOG_CRIT,"No ListenerInterfaces specified!\n"); 00073 return E_UNKNOWN; 00074 } 00075 if(CALibProxytest::getOptions()->getCascadeXML() != NULL) 00076 initMixCascadeInfo(CALibProxytest::getOptions()->getCascadeXML()); 00077 return E_SUCCESS; 00078 } 00079 00080 SINT32 CALastMix::init() 00081 { 00082 m_pRSA=new CAASymCipher(); 00083 #ifdef EXPORT_ASYM_PRIVATE_KEY 00084 if(CALibProxytest::getOptions()->isImportKey()) 00085 { 00086 UINT32 keyFileBuffLen=8096; 00087 UINT8* keyFileBuff=new UINT8[keyFileBuffLen]; 00088 CALibProxytest::getOptions()->getEncryptionKeyImportFile(keyFileBuff,keyFileBuffLen); 00089 UINT8* keyBuff=readFile(keyFileBuff,&keyFileBuffLen); 00090 m_pRSA->setPrivateKeyAsXML(keyBuff,keyFileBuffLen); 00091 delete[] keyFileBuff; 00092 delete[] keyBuff; 00093 } 00094 else 00095 #endif 00096 { 00097 if(m_pRSA->generateKeyPair(1024)!=E_SUCCESS) 00098 { 00099 CAMsg::printMsg(LOG_CRIT,"Could not generate a valid key pair\n"); 00100 return E_UNKNOWN; 00101 } 00102 } 00103 #ifdef EXPORT_ASYM_PRIVATE_KEY 00104 if(CALibProxytest::getOptions()->isExportKey()) 00105 { 00106 UINT32 keyFileBuffLen=8096; 00107 UINT8* keyFileBuff=new UINT8[keyFileBuffLen]; 00108 UINT8* keyBuff=new UINT8[keyFileBuffLen]; 00109 CALibProxytest::getOptions()->getEncryptionKeyExportFile(keyFileBuff,keyFileBuffLen); 00110 m_pRSA->getPrivateKeyAsXML(keyBuff,&keyFileBuffLen); 00111 saveFile(keyFileBuff,keyBuff,keyFileBuffLen); 00112 delete[] keyFileBuff; 00113 delete[] keyBuff; 00114 } 00115 #endif 00116 00117 CAListenerInterface* pListener=NULL; 00118 UINT32 interfaces=CALibProxytest::getOptions()->getListenerInterfaceCount(); 00119 for(UINT32 i=1;i<=interfaces;i++) 00120 { 00121 pListener=CALibProxytest::getOptions()->getListenerInterface(i); 00122 if(!pListener->isVirtual()) 00123 break; 00124 delete pListener; 00125 pListener=NULL; 00126 } 00127 if(pListener==NULL) 00128 { 00129 CAMsg::printMsg(LOG_CRIT,"Initialization failed! Reason: No usable (non virtual) interface was found! Hint: Virtual interfaces only needed if you are behind a NAT/network address translation, and therefore have to publish other external IP addresses to the InfoServices than your internal/hidden IP addresses.\n"); 00130 return E_UNKNOWN; 00131 } 00132 00133 const CASocketAddr* pAddr=NULL; 00134 pAddr=pListener->getAddr(); 00135 delete pListener; 00136 pListener = NULL; 00137 UINT8 buff[255]; 00138 pAddr->toString(buff,255); 00139 00140 CAMsg::printMsg(LOG_INFO,"Waiting for connection from previous Mix on %s...\n", buff); 00141 00142 m_pMuxIn=new CAMuxSocket(); 00143 SINT32 ret=m_pMuxIn->accept(*pAddr); 00144 delete pAddr; 00145 pAddr = NULL; 00146 if(ret!=E_SUCCESS) 00147 { 00148 CAMsg::printMsg(LOG_CRIT,"Initialization failed! Reason: Call to accept() failed with error '%s' (%i)\n", 00149 GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR); 00150 return ret; 00151 } 00152 // connected to previous mix 00153 m_pMuxIn->getCASocket()->setRecvBuff(500*MIXPACKET_SIZE); 00154 m_pMuxIn->getCASocket()->setSendBuff(500*MIXPACKET_SIZE); 00155 m_pMuxIn->getCASocket()->setKeepAlive((UINT32)1800); 00156 00157 MONITORING_FIRE_NET_EVENT(ev_net_prevConnected); 00158 CAMsg::printMsg(LOG_INFO,"connected!\n"); 00159 00160 #ifdef LOG_CRIME 00161 m_nCrimeRegExpsURL=NULL; 00162 m_pCrimeRegExpsURL=CALibProxytest::getOptions()->getCrimeRegExpsURL(&m_nCrimeRegExpsURL); 00163 m_nCrimeRegExpsPayload = NULL; 00164 m_pCrimeRegExpsPayload = CALibProxytest::getOptions()->getCrimeRegExpsPayload(&m_nCrimeRegExpsPayload); 00165 #endif 00166 ret=processKeyExchange(); 00167 if(ret!=E_SUCCESS) 00168 { 00169 MONITORING_FIRE_NET_EVENT(ev_net_keyExchangePrevFailed); 00170 return ret; 00171 } 00172 MONITORING_FIRE_NET_EVENT(ev_net_keyExchangePrevSuccessful); 00173 //keyexchange successful 00174 #ifdef REPLAY_DETECTION 00175 m_pReplayDB=new CADatabase(); 00176 m_pReplayDB->start(); 00177 #endif 00178 m_pQueueSendToMix=new CAQueue(sizeof(tQueueEntry)); 00179 m_pQueueReadFromMix=new CAQueue(sizeof(tQueueEntry)); 00180 00181 m_pMuxInControlChannelDispatcher=new CAControlChannelDispatcher(m_pQueueSendToMix,NULL,0); 00182 #ifdef REPLAY_DETECTION 00183 m_pReplayMsgProc=new CAReplayCtrlChannelMsgProc(this); 00184 m_pReplayMsgProc->startTimeStampPorpagation(REPLAY_TIMESTAMP_PROPAGATION_INTERVALL); 00185 m_u64ReferenceTime=time(NULL); 00186 #endif 00187 00188 m_bRestart=false; 00189 //Starting thread for Step 1a 00190 m_pthreadReadFromMix=new CAThread((UINT8*)"CALastMix - ReadFromMix"); 00191 m_pthreadReadFromMix->setMainLoop(lm_loopReadFromMix); 00192 m_pthreadReadFromMix->start(this); 00193 00194 //Starting thread for Step 4 00195 m_pthreadSendToMix=new CAThread((UINT8*)"CALastMix - SendToMix"); 00196 m_pthreadSendToMix->setMainLoop(lm_loopSendToMix); 00197 m_pthreadSendToMix->start(this); 00198 00199 //Starting thread for logging 00200 #ifdef LOG_PACKET_TIMES 00201 m_pLogPacketStats=new CALogPacketStats(); 00202 m_pLogPacketStats->setLogIntervallInMinutes(LM_PACKET_STATS_LOG_INTERVALL); 00203 m_pLogPacketStats->start(); 00204 #endif 00205 #ifndef NEW_MIX_TYPE // not TypeB mixes 00206 /* TypeB mixes are using an own implementation */ 00207 m_pChannelList=new CALastMixChannelList; 00208 #endif 00209 return E_SUCCESS; 00210 } 00211 00222 SINT32 CALastMix::processKeyExchange() 00223 { 00224 XERCES_CPP_NAMESPACE::DOMDocument* doc=createDOMDocument(); 00225 DOMElement* elemMixes=createDOMElement(doc,"Mixes"); 00226 setDOMElementAttribute(elemMixes,"count",(UINT32)1); 00227 //UINT8 cName[128]; 00228 //CALibProxytest::getOptions()->getCascadeName(cName,128); 00229 //setDOMElementAttribute(elemMixes,"cascadeName",cName); 00230 doc->appendChild(elemMixes); 00231 00232 addMixInfo(elemMixes, false); 00233 DOMElement* elemMix=NULL; 00234 getDOMChildByName(elemMixes, "Mix", elemMix, false); 00235 00236 //Inserting MixProtocol Version 00237 // Version 0.3 - "normal", initial mix protocol 00238 // Version 0.4 - with new flow control [was only used for tests] 00239 // Version 0.5 - end-to-end 1:n channels (only between client and last mix) 00240 // Version 0.6 - with new flow control for downstream [productive] 00241 // Version 0.7 - with new flow control for downstream AND upstream 00242 DOMElement* elemMixProtocolVersion=createDOMElement(doc,"MixProtocolVersion"); 00243 elemMix->appendChild(elemMixProtocolVersion); 00244 #ifdef NEW_MIX_TYPE // TypeB mixes 00245 setDOMElementValue(elemMixProtocolVersion,(UINT8*)"0.5"); 00246 DOM_Element elemDownstreamPackets = doc.createElement("DownstreamPackets"); 00247 setDOMElementValue(elemDownstreamPackets, (UINT32)CHANNEL_DOWNSTREAM_PACKETS); 00248 elemMixProtocolVersion.appendChild(elemDownstreamPackets); 00249 DOM_Element elemChannelTimeout = doc.createElement("ChannelTimeout"); 00250 /* let the client use our channel-timeout + 5 seconds */ 00251 setDOMElementValue(elemChannelTimeout, (UINT32)(CHANNEL_TIMEOUT + 5)); 00252 elemMixProtocolVersion.appendChild(elemChannelTimeout); 00253 DOM_Element elemChainTimeout = doc.createElement("ChainTimeout"); 00254 /* let the client use our chain-timeout - 5 seconds */ 00255 setDOMElementValue(elemChainTimeout, (UINT32)(CHAIN_TIMEOUT - 5)); 00256 elemMixProtocolVersion.appendChild(elemChainTimeout); 00257 #else 00258 setDOMElementValue(elemMixProtocolVersion,(UINT8*)"0.6"); 00259 DOMElement* elemFlowControl=createDOMElement(doc,"FlowControl"); 00260 DOMElement* elemUpstreamSendMe=createDOMElement(doc,"UpstreamSendMe"); 00261 DOMElement* elemDownstreamSendMe=createDOMElement(doc,"DownstreamSendMe"); 00262 elemMix->appendChild(elemFlowControl); 00263 elemFlowControl->appendChild(elemUpstreamSendMe); 00264 elemFlowControl->appendChild(elemDownstreamSendMe); 00265 setDOMElementValue(elemUpstreamSendMe,(UINT32)FLOW_CONTROL_SENDME_SOFT_LIMIT); 00266 setDOMElementValue(elemDownstreamSendMe,(UINT32)FLOW_CONTROL_SENDME_SOFT_LIMIT); 00267 setDOMElementAttribute(elemFlowControl,"withUpstreamFlowControl",true); 00268 #endif 00269 //Inserting RSA-Key 00270 DOMElement* nodeRsaKey=NULL; 00271 m_pRSA->getPublicKeyAsDOMElement(nodeRsaKey,doc); 00272 elemMix->appendChild(nodeRsaKey); 00273 00274 appendCompatibilityInfo(elemMix); 00275 00276 //inserting Nonce 00277 DOMElement* elemNonce=createDOMElement(doc,"Nonce"); 00278 UINT8 arNonce[16]; 00279 getRandom(arNonce,16); 00280 UINT8 tmpBuff[50]; 00281 UINT32 tmpLen=50; 00282 CABase64::encode(arNonce,16,tmpBuff,&tmpLen); 00283 tmpBuff[tmpLen]=0; 00284 setDOMElementValue(elemNonce,tmpBuff); 00285 elemMix->appendChild(elemNonce); 00286 00287 00288 00289 // Add Info about KeepAlive traffic 00290 DOMElement* elemKeepAlive=NULL; 00291 UINT32 u32KeepAliveSendInterval=CALibProxytest::getOptions()->getKeepAliveSendInterval(); 00292 UINT32 u32KeepAliveRecvInterval=CALibProxytest::getOptions()->getKeepAliveRecvInterval(); 00293 elemKeepAlive=createDOMElement(doc,"KeepAlive"); 00294 DOMElement* elemKeepAliveSendInterval=NULL; 00295 DOMElement* elemKeepAliveRecvInterval=NULL; 00296 elemKeepAliveSendInterval=createDOMElement(doc,"SendInterval"); 00297 elemKeepAliveRecvInterval=createDOMElement(doc,"ReceiveInterval"); 00298 elemKeepAlive->appendChild(elemKeepAliveSendInterval); 00299 elemKeepAlive->appendChild(elemKeepAliveRecvInterval); 00300 setDOMElementValue(elemKeepAliveSendInterval,u32KeepAliveSendInterval); 00301 setDOMElementValue(elemKeepAliveRecvInterval,u32KeepAliveRecvInterval); 00302 elemMix->appendChild(elemKeepAlive); 00303 00304 CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Offering -- SendInterval %u -- Receive Interval %u\n",u32KeepAliveSendInterval,u32KeepAliveRecvInterval); 00305 00306 /* append the terms and conditions, if there are any, to the KeyInfo 00307 * Extensions, (nodes that can be removed from the KeyInfo without 00308 * destroying the signature of the "Mix"-node). 00309 */ 00310 if(CALibProxytest::getOptions()->getTermsAndConditions() != NULL) 00311 { 00312 appendTermsAndConditionsExtension(doc, elemMixes); 00313 elemMix->appendChild(termsAndConditionsInfoNode(doc)); 00314 } 00315 00316 // create signature 00317 if (signXML(elemMix) != E_SUCCESS) 00318 { 00319 CAMsg::printMsg(LOG_DEBUG,"Could not sign KeyInfo sent to users...\n"); 00320 } 00321 00322 UINT32 len=0; 00323 UINT8* messageBuff=DOM_Output::dumpToMem(doc,&len); 00324 if (doc != NULL) 00325 { 00326 doc->release(); 00327 doc = NULL; 00328 } 00329 UINT32 tmp = htonl(len); 00330 CAMsg::printMsg(LOG_INFO,"Sending Infos (chain length and RSA-Key, Message-Size %u)\n",len); 00331 00332 if (len > 100000) 00333 { 00334 CAMsg::printMsg(LOG_WARNING,"Unrealistic length for key info: %u We might not be able to get a connection.\n",len); 00335 } 00336 00337 if( (m_pMuxIn->getCASocket()->send((UINT8*)&tmp, sizeof(tmp)) != sizeof(tmp)) || 00338 m_pMuxIn->getCASocket()->send(messageBuff,len)!=(SINT32)len) 00339 { 00340 CAMsg::printMsg(LOG_ERR,"Error sending Key-Info!\n"); 00341 delete []messageBuff; 00342 messageBuff = NULL; 00343 return E_UNKNOWN; 00344 } 00345 delete[] messageBuff; 00346 messageBuff = NULL; 00347 00348 SINT32 ret; 00349 //Now receiving the symmetric key 00350 CAMsg::printMsg(LOG_INFO,"Waiting for length of symmetric key from previous Mix...\n"); 00351 if((ret = m_pMuxIn->receiveFully((UINT8*) &tmp, sizeof(tmp), TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT)) != E_SUCCESS) 00352 { 00353 if (ret != E_UNKNOWN) 00354 { 00355 CAMsg::printMsg(LOG_CRIT,"Error receiving symmetric key info length! Reason: '%s' (%i)\n", 00356 GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR); 00357 } 00358 else 00359 { 00360 CAMsg::printMsg(LOG_CRIT,"Error receiving symmetric key info length!\n"); 00361 } 00362 return ret; 00363 } 00364 len = ntohl(tmp); 00365 00366 if (len > 100000) 00367 { 00368 CAMsg::printMsg(LOG_WARNING,"Unrealistic length for key info: %u We might not be able to get a connection.\n",len); 00369 } 00370 00371 messageBuff=new UINT8[len+1]; //+1 for the closing Zero 00372 CAMsg::printMsg(LOG_INFO,"Waiting for symmetric key from previous Mix with length %i...\n", len); 00373 if((ret = m_pMuxIn->receiveFully(messageBuff, len, TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT)) != E_SUCCESS) 00374 { 00375 if (ret != E_UNKNOWN) 00376 { 00377 CAMsg::printMsg(LOG_ERR,"Socket error occurred while receiving the symmetric key from the previous mix! Reason: '%s' (%i) The previous mix might be unable to verify our Mix certificate(s) and therefore closed the connection. Please ask the operator for the log, and exchange your certificates if necessary.\n", 00378 GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR); 00379 } 00380 else 00381 { 00382 CAMsg::printMsg(LOG_ERR,"Socket error occurred while receiving the symmetric key from the previous mix! The previous mix might be unable to verify our Mix certificate(s) and therefore closed the connection. Please ask the operator for the log, and exchange your certificates if necessary.\n"); 00383 } 00384 delete []messageBuff; 00385 messageBuff = NULL; 00386 return ret; 00387 } 00388 messageBuff[len]=0; 00389 CAMsg::printMsg(LOG_INFO,"Symmetric Key Info received from previous mix is:\n"); 00390 CAMsg::printMsg(LOG_INFO,"%s\n",(char*)messageBuff); 00391 //get document 00392 doc=parseDOMDocument(messageBuff,len); 00393 if(doc == NULL) 00394 { 00395 CAMsg::printMsg(LOG_CRIT,"Could not parse symmetric key of the previous mix!\n"); 00396 delete []messageBuff; 00397 messageBuff = NULL; 00398 return E_UNKNOWN; 00399 } 00400 DOMElement* elemRoot=doc->getDocumentElement(); 00401 if(elemRoot == NULL) 00402 { 00403 CAMsg::printMsg(LOG_CRIT,"Symmetric key XML structure of previous mix is invalid!\n"); 00404 delete []messageBuff; 00405 messageBuff = NULL; 00406 if (doc != NULL) 00407 { 00408 doc->release(); 00409 doc = NULL; 00410 } 00411 return E_UNKNOWN; 00412 } 00413 //verify certificate from previous mix if enabled 00414 if(CALibProxytest::getOptions()->verifyMixCertificates()) 00415 { 00416 CACertificate* prevMixCert = CALibProxytest::getOptions()->getTrustedCertificateStore()->verifyMixCert(elemRoot); 00417 if(prevMixCert != NULL) 00418 { 00419 CAMsg::printMsg(LOG_DEBUG, "Previous mix certificate was verified by a trusted root CA.\n"); 00420 CALibProxytest::getOptions()->setPrevMixTestCertificate(prevMixCert); 00421 } 00422 else 00423 { 00424 CAMsg::printMsg(LOG_ERR, "Could not verify certificate received from previous mix!\n"); 00425 return E_UNKNOWN; 00426 } 00427 } 00428 //verify signature 00429 //CASignature oSig; 00430 CACertificate* pCert=CALibProxytest::getOptions()->getPrevMixTestCertificate(); 00431 SINT32 result = CAMultiSignature::verifyXML(messageBuff, len, pCert); 00432 //oSig.setVerifyKey(pCert); 00433 delete pCert; 00434 pCert = NULL; 00435 //if(oSig.verifyXML(messageBuff,len)!=E_SUCCESS) 00436 if(result != E_SUCCESS) 00437 { 00438 CAMsg::printMsg(LOG_CRIT,"Could not verify the symmetric key!\n"); 00439 delete []messageBuff; 00440 messageBuff = NULL; 00441 return E_UNKNOWN; 00442 } 00443 00444 if ((result = checkCompatibility(elemRoot, "previous")) != E_SUCCESS) 00445 { 00446 delete []messageBuff; 00447 messageBuff = NULL; 00448 if (doc != NULL) 00449 { 00450 doc->release(); 00451 doc = NULL; 00452 } 00453 return result; 00454 } 00455 00456 00457 elemNonce=NULL; 00458 getDOMChildByName(elemRoot,"Nonce",elemNonce,false); 00459 tmpLen=50; 00460 memset(tmpBuff,0,tmpLen); 00461 if(elemNonce==NULL||getDOMElementValue(elemNonce,tmpBuff,&tmpLen)!=E_SUCCESS|| 00462 CABase64::decode(tmpBuff,tmpLen,tmpBuff,&tmpLen)!=E_SUCCESS|| 00463 tmpLen!=SHA_DIGEST_LENGTH || 00464 memcmp(SHA1(arNonce,16,NULL),tmpBuff,SHA_DIGEST_LENGTH)!=0 00465 ) 00466 { 00467 CAMsg::printMsg(LOG_CRIT,"Could not verify the nonce from previous mix!\n"); 00468 delete []messageBuff; 00469 messageBuff = NULL; 00470 if (doc != NULL) 00471 { 00472 doc->release(); 00473 doc = NULL; 00474 } 00475 return E_UNKNOWN; 00476 } 00477 CAMsg::printMsg(LOG_INFO,"Verified the symmetric key from previous mix!\n"); 00478 00479 UINT8 key[150]; 00480 UINT32 keySize=150; 00481 ret=decodeXMLEncryptedKey(key,&keySize,messageBuff,len,m_pRSA); 00482 delete []messageBuff; 00483 messageBuff = NULL; 00484 if(ret!=E_SUCCESS||keySize!=64) 00485 { 00486 CAMsg::printMsg(LOG_CRIT,"Could not decrypt the symmetric key from previous mix!\n"); 00487 if (doc != NULL) 00488 { 00489 doc->release(); 00490 doc = NULL; 00491 } 00492 return E_UNKNOWN; 00493 } 00494 if(m_pMuxIn->setReceiveKey(key,32)!=E_SUCCESS||m_pMuxIn->setSendKey(key+32,32)!=E_SUCCESS) 00495 { 00496 CAMsg::printMsg(LOG_CRIT,"Could not set the symmetric key to be used by the MuxSocket!\n"); 00497 if (doc != NULL) 00498 { 00499 doc->release(); 00500 doc = NULL; 00501 } 00502 return E_UNKNOWN; 00503 } 00504 m_pMuxIn->setCrypt(true); 00506 elemKeepAlive=NULL; 00507 elemKeepAliveSendInterval=NULL; 00508 elemKeepAliveRecvInterval=NULL; 00509 getDOMChildByName(elemRoot,"KeepAlive",elemKeepAlive); 00510 getDOMChildByName(elemKeepAlive,"SendInterval",elemKeepAliveSendInterval); 00511 getDOMChildByName(elemKeepAlive,"ReceiveInterval",elemKeepAliveRecvInterval); 00512 UINT32 tmpSendInterval,tmpRecvInterval; 00513 getDOMElementValue(elemKeepAliveSendInterval,tmpSendInterval,0xFFFFFFFF); //if now send interval was given set it to "infinite" 00514 getDOMElementValue(elemKeepAliveRecvInterval,tmpRecvInterval,0xFFFFFFFF); //if no recv interval was given --> set it to "infinite" 00515 CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Getting offer -- SendInterval %u -- Receive Interval %u\n",tmpSendInterval,tmpRecvInterval); 00516 m_u32KeepAliveSendInterval = u32KeepAliveSendInterval; 00517 if (m_u32KeepAliveSendInterval > tmpRecvInterval - 10000) 00518 m_u32KeepAliveSendInterval-=10000; //make the send interval a little bit smaller than the related receive interval 00519 m_u32KeepAliveRecvInterval=max(u32KeepAliveRecvInterval,tmpSendInterval); 00520 if (m_u32KeepAliveRecvInterval - 10000 < tmpSendInterval) 00521 { 00522 m_u32KeepAliveRecvInterval += 10000; 00523 } 00524 CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Calculated -- SendInterval %u -- Receive Interval %u\n",m_u32KeepAliveSendInterval,m_u32KeepAliveRecvInterval); 00525 00526 if (doc != NULL) 00527 { 00528 doc->release(); 00529 doc = NULL; 00530 } 00531 00532 return E_SUCCESS; 00533 } 00534 00535 #ifdef NEW_MIX_TYPE // TypeB mixes 00536 void CALastMix::reconfigureMix() { 00537 } 00538 #endif 00539 00540 SINT32 CALastMix::reconfigure() 00541 { 00542 CAMsg::printMsg(LOG_DEBUG,"Reconfiguring Last Mix\n"); 00543 CAMsg::printMsg(LOG_DEBUG,"Re-read cache proxies\n"); 00544 if(setTargets()!=E_SUCCESS) 00545 CAMsg::printMsg(LOG_DEBUG,"Could not set new cache proxies\n"); 00546 #ifndef NEW_MIX_TYPE // not TypeB mixes 00547 #if defined (DELAY_CHANNELS)||defined (DELAY_CHANNELS_LATENCY) 00548 CAMsg::printMsg(LOG_DEBUG,"Set new resources limitation parameters\n"); 00549 if(m_pChannelList!=NULL) { 00550 #if defined (DELAY_CHANNELS) 00551 m_pChannelList->setDelayParameters( CALibProxytest::getOptions()->getDelayChannelUnlimitTraffic(), 00552 CALibProxytest::getOptions()->getDelayChannelBucketGrow(), 00553 CALibProxytest::getOptions()->getDelayChannelBucketGrowIntervall()); 00554 #endif 00555 #if defined (DELAY_CHANNELS_LATENCY) 00556 UINT32 utemp=CALibProxytest::getOptions()->getDelayChannelLatency(); 00557 m_pChannelList->setDelayLatencyParameters( utemp); 00558 #endif 00559 } 00560 #endif 00561 #else // TypeB mixes 00562 reconfigureMix(); 00563 #endif 00564 return E_SUCCESS; 00565 } 00566 00567 THREAD_RETURN lm_loopLog(void* param) 00568 { 00569 CALastMix* pLastMix=(CALastMix*)param; 00570 pLastMix->m_bRunLog=true; 00571 UINT32 countLog=0; 00572 UINT8 buff[256]; 00573 while(pLastMix->m_bRunLog) 00574 { 00575 if((countLog%10)==0) 00576 { 00577 logMemoryUsage(); 00578 } 00579 if(countLog==0) 00580 { 00581 CAMsg::printMsg(LOG_DEBUG,"Uploaded Packets: %u\n",pLastMix->m_logUploadedPackets); 00582 CAMsg::printMsg(LOG_DEBUG,"Downloaded Packets: %u\n",pLastMix->m_logDownloadedPackets); 00583 print64(buff,(UINT64&)pLastMix->m_logUploadedBytes); 00584 CAMsg::printMsg(LOG_DEBUG,"Uploaded Bytes : %s\n",buff); 00585 print64(buff,(UINT64&)pLastMix->m_logDownloadedBytes); 00586 CAMsg::printMsg(LOG_DEBUG,"Downloaded Bytes : %s\n",buff); 00587 countLog=30; 00588 } 00589 sSleep(30); 00590 countLog--; 00591 } 00592 THREAD_RETURN_SUCCESS; 00593 } 00594 00600 THREAD_RETURN lm_loopSendToMix(void* param) 00601 { 00602 CALastMix* pLastMix=(CALastMix*)param; 00603 CAQueue* pQueue=pLastMix->m_pQueueSendToMix; 00604 CAMuxSocket* pMuxSocket=pLastMix->m_pMuxIn; 00605 SINT32 ret; 00606 UINT32 len; 00607 UINT32 u32KeepAliveSendInterval=pLastMix->m_u32KeepAliveSendInterval; 00608 #ifndef USE_POOL 00609 tQueueEntry* pQueueEntry=new tQueueEntry; 00610 MIXPACKET* pMixPacket=&pQueueEntry->packet; 00611 00612 while(!pLastMix->m_bRestart) 00613 { 00614 len=sizeof(tQueueEntry); 00615 ret=pQueue->getOrWait((UINT8*)pQueueEntry,&len,u32KeepAliveSendInterval); 00616 if(ret==E_TIMEDOUT) 00617 { 00618 pMixPacket->flags=CHANNEL_DUMMY; 00619 pMixPacket->channel=DUMMY_CHANNEL; 00620 getRandom(pMixPacket->data,DATA_SIZE); 00621 } 00622 else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry)) 00623 { 00624 CAMsg::printMsg(LOG_ERR,"CALastMix::lm_loopSendToMix - Error in dequeueing MixPaket\n"); 00625 CAMsg::printMsg(LOG_ERR,"ret=%i len=%i\n",ret,len); 00626 MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed); 00627 break; 00628 } 00629 if(pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE) 00630 { 00631 CAMsg::printMsg(LOG_ERR,"CALastMix::lm_loopSendToMix - Error in sending MixPaket\n"); 00632 MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed); 00633 break; 00634 } 00635 #ifdef LOG_PACKET_TIMES 00636 if(!isZero64(pQueueEntry->timestamp_proccessing_start)) 00637 { 00638 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end); 00639 pLastMix->m_pLogPacketStats->addToTimeingStats(*pQueueEntry,CHANNEL_DATA,false); 00640 } 00641 #endif 00642 } 00643 delete pQueueEntry; 00644 pQueueEntry = NULL; 00645 #else 00646 CAPool* pPool=new CAPool(MIX_POOL_SIZE); 00647 tPoolEntry* pPoolEntry=new tPoolEntry; 00648 MIXPACKET* pMixPacket=&pPoolEntry->packet; 00649 while(!pLastMix->m_bRestart) 00650 { 00651 len=sizeof(tQueueEntry); 00652 SINT32 ret=pQueue->getOrWait((UINT8*)pPoolEntry,&len,MIX_POOL_TIMEOUT); 00653 if(ret==E_TIMEDOUT) 00654 { 00655 pMixPacket->flags=CHANNEL_DUMMY; 00656 pMixPacket->channel=DUMMY_CHANNEL; 00657 getRandom(pMixPacket->data,DATA_SIZE); 00658 #ifdef LOG_PACKET_TIMES 00659 setZero64(pPoolEntry->timestamp_proccessing_start); 00660 #endif 00661 } 00662 else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry)) 00663 { 00664 break; 00665 } 00666 #ifdef LOG_PACKET_TIMES 00667 getcurrentTimeMicros(pPoolEntry->pool_timestamp_in); 00668 #endif 00669 pPool->pool(pPoolEntry); 00670 #ifdef LOG_PACKET_TIMES 00671 getcurrentTimeMicros(pPoolEntry->pool_timestamp_out); 00672 #endif 00673 if(pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE) 00674 break; 00675 #ifdef LOG_PACKET_TIMES 00676 if(!isZero64(pPoolEntry->timestamp_proccessing_start)) 00677 { 00678 getcurrentTimeMicros(pPoolEntry->timestamp_proccessing_end); 00679 pLastMix->m_pLogPacketStats->addToTimeingStats(*pPoolEntry,CHANNEL_DATA,false); 00680 } 00681 #endif 00682 } 00683 delete pPoolEntry; 00684 pPoolEntry = NULL; 00685 delete pPool; 00686 pPool = NULL; 00687 #endif 00688 CAMsg::printMsg(LOG_DEBUG,"Exiting Thread SendToMix\n"); 00689 THREAD_RETURN_SUCCESS; 00690 } 00691 00692 00693 /* How to end this thread: 00694 * 1. set m_brestart=true 00695 */ 00696 THREAD_RETURN lm_loopReadFromMix(void *pParam) 00697 { 00698 CALastMix* pLastMix=(CALastMix*)pParam; 00699 CAMuxSocket* pMuxSocket=pLastMix->m_pMuxIn; 00700 CAQueue* pQueue=pLastMix->m_pQueueReadFromMix; 00701 tQueueEntry* pQueueEntry=new tQueueEntry; 00702 MIXPACKET* pMixPacket=&pQueueEntry->packet; 00703 CASingleSocketGroup* pSocketGroup=new CASingleSocketGroup(false); 00704 pSocketGroup->add(*pMuxSocket); 00705 #ifdef USE_POOL 00706 CAPool* pPool=new CAPool(MIX_POOL_SIZE); 00707 #endif 00708 UINT64 keepaliveNow,keepaliveLast; 00709 UINT32 u32KeepAliveRecvInterval=pLastMix->m_u32KeepAliveRecvInterval; 00710 getcurrentTimeMillis(keepaliveLast); 00711 while(!pLastMix->m_bRestart) 00712 { 00713 if(pQueue->getSize()>MAX_READ_FROM_PREV_MIX_QUEUE_SIZE) 00714 { 00715 #ifdef DEBUG 00716 CAMsg::printMsg(LOG_DEBUG,"CAFirstMix::Queue is full!\n"); 00717 #endif 00718 msSleep(200); 00719 getcurrentTimeMillis(keepaliveLast); 00720 continue; 00721 } 00722 //check if the connection is broken because we did not receive a Keep_alive-Message 00723 getcurrentTimeMillis(keepaliveNow); 00724 UINT32 keepaliveDiff=diff64(keepaliveNow,keepaliveLast); 00725 if(keepaliveDiff>u32KeepAliveRecvInterval) 00726 { 00727 CAMsg::printMsg(LOG_ERR,"CALastMix::loopReadFromMix() -- restart because of KeepAlive-Traffic Timeout!\n"); 00728 pLastMix->m_bRestart=true; 00729 MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed); 00730 break; 00731 } 00732 SINT32 ret=pSocketGroup->select(MIX_POOL_TIMEOUT); 00733 if(ret < 0) 00734 { 00735 if (ret == E_TIMEDOUT) 00736 { 00737 #ifdef USE_POOL 00738 pMixPacket->flags=CHANNEL_DUMMY; 00739 pMixPacket->channel=DUMMY_CHANNEL; 00740 getRandom(pMixPacket->data,DATA_SIZE); 00741 #ifdef LOG_PACKET_TIMES 00742 setZero64(pQueueEntry->timestamp_proccessing_start); 00743 #endif 00744 #else 00745 continue; 00746 #endif 00747 } 00748 else 00749 { 00750 /* another error occured (happens sometimes while debugging because 00751 * of interruption, if a breakpoint is reached -> poll() returns 00752 * errorcode EINTR) 00753 * Note: Any Error on select() does not mean, that the underliny connections have some error state, because 00754 * in this case select() returns the socket and than this socket returns the error 00755 */ 00756 continue; 00757 } 00758 } 00759 else if(ret>0) 00760 { 00761 ret=pMuxSocket->receive(pMixPacket); //receives a whole MixPacket 00762 #ifdef LOG_PACKET_TIMES 00763 getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_start); 00764 #endif 00765 #ifdef DATA_RETENTION_LOG 00766 pQueueEntry->dataRetentionLogEntry.t_in=htonl(time(NULL)); 00767 #endif 00768 if(ret!=MIXPACKET_SIZE) 00769 {//something goes wrong... 00770 CAMsg::printMsg(LOG_ERR,"CALastMix::lm_loopReadFromMix - received returned: %i\n",ret); 00771 pLastMix->m_bRestart=true; 00772 MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed); 00773 break; 00774 } 00775 } 00776 #ifdef USE_POOL 00777 #ifdef LOG_PACKET_TIMES 00778 getcurrentTimeMicros(pQueueEntry->pool_timestamp_in); 00779 #endif 00780 pPool->pool((tPoolEntry*) pQueueEntry); 00781 #ifdef LOG_PACKET_TIMES 00782 getcurrentTimeMicros(pQueueEntry->pool_timestamp_out); 00783 #endif 00784 #endif 00785 pQueue->add(pQueueEntry,sizeof(tQueueEntry)); 00786 getcurrentTimeMillis(keepaliveLast); 00787 } 00788 delete pQueueEntry; 00789 pQueueEntry = NULL; 00790 delete pSocketGroup; 00791 pSocketGroup = NULL; 00792 #ifdef USE_POOL 00793 delete pPool; 00794 pPool = NULL; 00795 #endif 00796 THREAD_RETURN_SUCCESS; 00797 } 00798 00799 #ifdef LOG_CRIME 00800 //Assuming we have aligned HTTP or SOCKS protocolData 00801 UINT8* CALastMix::parseDomainFromPayload(const UINT8 *payloadData, UINT32 payloadDataLength) 00802 { 00803 if( (payloadDataLength < 5) || 00804 (payloadDataLength > PAYLOAD_SIZE) ) 00805 { 00806 return NULL; 00807 } 00808 00809 if( (payloadData[0] == 0x05) && (payloadData[1] & 0x03) ) 00810 { 00811 //in this case we have a SOCKS message 00812 UINT32 tempUrlLength = 0, urlStartOffset = 0; 00813 //of which address type is the dst address? 00814 switch(payloadData[3]) 00815 { 00816 case 0x01: //IPv4_Address 00817 { 00818 tempUrlLength = 4; 00819 urlStartOffset = 4; 00820 break; 00821 } 00822 00823 case 0x03: //Domain name 00824 { 00825 tempUrlLength = payloadData[4]; 00826 urlStartOffset = 5; 00827 //CAMsg::printMsg(LOG_ERR,"SOCKS v5 domain name length %u.\n", tempUrlLength); 00828 break; 00829 } 00830 00831 case 0x4: //IPv6 address 00832 { 00833 tempUrlLength = 16; 00834 urlStartOffset = 4; 00835 break; 00836 } 00837 00838 default: 00839 { 00840 return NULL; 00841 } 00842 } 00843 if(payloadDataLength < (urlStartOffset + tempUrlLength) ) 00844 { 00845 return NULL; 00846 } 00847 UINT8 *address = new UINT8[tempUrlLength+1]; 00848 memcpy(address, payloadData+urlStartOffset, tempUrlLength); 00849 address[tempUrlLength] = 0; 00850 //CAMsg::printMsg(LOG_ERR,"SOCKS v5 found with address %s.\n", address); 00851 return address; 00852 } 00853 else 00854 { 00855 //In this case the message is handled as a common HTTP request 00856 //So we lock for the Request-Line 00857 //Note according to [HTTP 1.1] the Request-Line might be preceded by CRLF 00858 //Snip: In the interest of robustness, servers SHOULD ignore any empty 00859 // line(s) received where a Request-Line is expected. In other words, if 00860 // the server is reading the protocol stream at the beginning of a 00861 // message and receives a CRLF first, it should ignore the CRLF. 00862 00863 //OK lets try to use a regular expression for the task instead of a hand crafted parser... 00864 //do the match... 00865 regmatch_t theMatches[3]; 00866 int ret=regnexec(m_pregexpRequestLine,(const char*)payloadData,payloadDataLength,3,theMatches,0); 00867 if(ret!=0) 00868 return NULL; 00869 00870 const UINT8* httpVerb=payloadData+theMatches[1].rm_so; 00871 UINT8* domainName=NULL; 00872 if((payloadData+theMatches[1].rm_eo-payloadData+theMatches[1].rm_so)>6 && memcmp("CONNECT",httpVerb,7)==0) 00873 {//Connect request --> URI is domain [:port] 00874 UINT32 matchLen=theMatches[2].rm_eo-theMatches[2].rm_so; 00875 domainName=new UINT8[matchLen+1]; 00876 memcpy(domainName,payloadData+theMatches[2].rm_so,matchLen); 00877 domainName[matchLen]=0; 00878 strtok((char*)domainName,":"); 00879 } 00880 else 00881 { 00882 //do the match... 00883 regmatch_t theDomainMatches[2]; 00884 ret=regnexec(m_pregexpDomainOfURI,(const char*)payloadData+theMatches[2].rm_so,theMatches[2].rm_eo-theMatches[2].rm_so,2,theDomainMatches,0); 00885 if(ret!=0) 00886 return NULL; 00887 UINT32 matchLen=theDomainMatches[1].rm_eo-theDomainMatches[1].rm_so; 00888 domainName=new UINT8[matchLen+1]; 00889 memcpy(domainName,payloadData+theMatches[2].rm_so+theDomainMatches[1].rm_so,matchLen); 00890 domainName[matchLen]=0; 00891 } 00892 return domainName; 00893 } 00894 } 00895 00896 bool CALastMix::checkCrime(const UINT8* payLoad,UINT32 payLen,bool bURLCheck) 00897 { 00898 //Lots of TODO!!!! 00899 //DNS Lookup may block if Host does not exists!!!!! 00900 //so we use regexp.... 00901 if(bURLCheck) 00902 { 00903 UINT8 *startOfUrl = parseDomainFromPayload(payLoad, payLen); 00904 if(startOfUrl!=NULL) 00905 { 00906 UINT32 strLen = strlen((char *)startOfUrl); 00907 for(UINT32 i = 0; i < m_nCrimeRegExpsURL; i++) 00908 { 00909 if(regnexec(&m_pCrimeRegExpsURL[i],(char*)startOfUrl,strLen,0,NULL,0)==0) 00910 { 00911 delete [] startOfUrl; 00912 return true; 00913 } 00914 } 00915 delete [] startOfUrl; 00916 } 00917 } 00918 for(UINT32 i = 0; i < m_nCrimeRegExpsPayload; i++) 00919 { 00920 if (regnexec(&m_pCrimeRegExpsPayload[i],(const char*)payLoad ,payLen,0,NULL,0)==0) 00921 { 00922 return true; 00923 } 00924 } 00925 return false; 00926 } 00927 #endif 00928 00933 SINT32 CALastMix::setTargets() 00934 { 00935 UINT32 cntTargets=CALibProxytest::getOptions()->getTargetInterfaceCount(); 00936 if(cntTargets==0) 00937 { 00938 CAMsg::printMsg(LOG_CRIT,"No Targets (proxies) specified!\n"); 00939 return E_UNKNOWN; 00940 } 00941 m_pCacheLB->clean(); 00942 m_pSocksLB->clean(); 00943 UINT32 i; 00944 for(i=1;i<=cntTargets;i++) 00945 { 00946 CATargetInterface oTargetInterface; 00947 CALibProxytest::getOptions()->getTargetInterface(oTargetInterface,i); 00948 if(oTargetInterface.getTargetType()==TARGET_HTTP_PROXY) 00949 { 00950 m_pCacheLB->add(oTargetInterface.getAddr()); 00951 } 00952 else if(oTargetInterface.getTargetType()==TARGET_SOCKS_PROXY) 00953 { 00954 m_pSocksLB->add(oTargetInterface.getAddr()); 00955 } 00956 oTargetInterface.cleanAddr(); 00957 } 00958 CAMsg::printMsg(LOG_DEBUG,"This mix will use the following proxies:\n"); 00959 for(i=0;i<m_pCacheLB->getElementCount();i++) 00960 { 00961 CASocketAddrINet* pAddr=m_pCacheLB->get(); 00962 UINT8 ip[4]; 00963 pAddr->getIP(ip); 00964 UINT32 port=pAddr->getPort(); 00965 CAMsg::printMsg(LOG_DEBUG,"%u. HTTP Proxy's Address: %u.%u.%u.%u:%u\n",i+1,ip[0],ip[1],ip[2],ip[3],port); 00966 } 00967 for(i=0;i<m_pSocksLB->getElementCount();i++) 00968 { 00969 CASocketAddrINet* pAddr=m_pSocksLB->get(); 00970 UINT8 ip[4]; 00971 pAddr->getIP(ip); 00972 UINT32 port=pAddr->getPort(); 00973 CAMsg::printMsg(LOG_DEBUG,"%u. SOCKS Proxy's Address: %u.%u.%u.%u:%u\n",i+1,ip[0],ip[1],ip[2],ip[3],port); 00974 } 00975 00976 00977 return E_SUCCESS; 00978 } 00979 00980 SINT32 CALastMix::clean() 00981 { 00982 m_bRestart=true; 00983 MONITORING_FIRE_NET_EVENT(ev_net_prevConnectionClosed); 00984 m_bRunLog=false; 00985 #ifdef REPLAY_DETECTION 00986 if(m_pReplayMsgProc!=NULL) 00987 { 00988 delete m_pReplayMsgProc; 00989 m_pReplayMsgProc = NULL; 00990 } 00991 m_pReplayMsgProc=NULL; 00992 #endif 00993 00994 if(m_pMuxInControlChannelDispatcher!=NULL) 00995 { 00996 delete m_pMuxInControlChannelDispatcher; 00997 m_pMuxInControlChannelDispatcher = NULL; 00998 } 00999 m_pMuxInControlChannelDispatcher=NULL; 01000 01001 if(m_pMuxIn!=NULL) 01002 { 01003 m_pMuxIn->close(); 01004 } 01005 //writng some bytes to the queue... 01006 if(m_pQueueSendToMix!=NULL) 01007 { 01008 UINT8 b[sizeof(tQueueEntry)+1]; 01009 m_pQueueSendToMix->add(b,sizeof(tQueueEntry)+1); 01010 } 01011 01012 if(m_pthreadSendToMix!=NULL) 01013 { 01014 CAMsg::printMsg(LOG_CRIT,"Wait for LoopSendToMix!\n"); 01015 m_pthreadSendToMix->join(); 01016 delete m_pthreadSendToMix; 01017 m_pthreadSendToMix = NULL; 01018 } 01019 m_pthreadSendToMix=NULL; 01020 if(m_pthreadReadFromMix!=NULL) 01021 { 01022 CAMsg::printMsg(LOG_CRIT,"Wait for LoopReadFromMix!\n"); 01023 m_pthreadReadFromMix->join(); 01024 delete m_pthreadReadFromMix; 01025 m_pthreadReadFromMix = NULL; 01026 } 01027 m_pthreadReadFromMix=NULL; 01028 01029 #ifdef LOG_PACKET_TIMES 01030 CAMsg::printMsg(LOG_CRIT,"Wait for LoopLogPacketStats to terminate!\n"); 01031 if(m_pLogPacketStats!=NULL) 01032 { 01033 m_pLogPacketStats->stop(); 01034 delete m_pLogPacketStats; 01035 m_pLogPacketStats = NULL; 01036 } 01037 m_pLogPacketStats=NULL; 01038 #endif 01039 if(m_pChannelList!=NULL) 01040 { 01041 lmChannelListEntry* pChannelListEntry=m_pChannelList->getFirstSocket(); 01042 while(pChannelListEntry!=NULL) 01043 { 01044 delete pChannelListEntry->pCipher; 01045 pChannelListEntry->pCipher = NULL; 01046 delete pChannelListEntry->pQueueSend; 01047 pChannelListEntry->pQueueSend = NULL; 01048 if (pChannelListEntry->pSocket != NULL) 01049 { 01050 pChannelListEntry->pSocket->close(); 01051 delete pChannelListEntry->pSocket; 01052 pChannelListEntry->pSocket = NULL; 01053 } 01054 pChannelListEntry=m_pChannelList->getNextSocket(); 01055 } 01056 } 01057 delete m_pQueueReadFromMix; 01058 m_pQueueReadFromMix = NULL; 01059 delete m_pQueueSendToMix; 01060 m_pQueueSendToMix = NULL; 01061 #ifndef NEW_MIX_TYPE // not TypeB mixes 01062 /* TypeB mixes are using an own implementation */ 01063 delete m_pChannelList; 01064 m_pChannelList = NULL; 01065 if(m_pMuxIn != NULL) 01066 { 01067 m_pMuxIn->close(); 01068 delete m_pMuxIn; 01069 m_pMuxIn=NULL; 01070 } 01071 01072 delete m_pRSA; 01073 m_pRSA = NULL; 01074 #endif 01075 return E_SUCCESS; 01076 } 01077 01078 SINT32 CALastMix::initMixCascadeInfo(DOMElement* mixes) 01079 { 01080 SINT32 r = CAMix::initMixCascadeInfo(mixes); 01081 DOMElement* cascade = m_docMixCascadeInfo->getDocumentElement(); 01082 setDOMElementAttribute(cascade,"create",(UINT8*)"true"); 01083 return r; 01084 } 01085 #endif //ONLY_LOCAL_PROXY
1.7.6.1