Mixe for Privacy and Anonymity in the Internet
CAFirstMix.hpp
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 
00029 #ifndef __CAFIRSTMIX__
00030 #define __CAFIRSTMIX__
00031 #include "doxygen.h"
00032 #ifndef ONLY_LOCAL_PROXY
00033 #include "CAMix.hpp"
00034 #include "CAMuxSocket.hpp"
00035 #include "CAASymCipher.hpp"
00036 //#include "CASignature.hpp"
00037 #include "CAFirstMixChannelList.hpp"
00038 #include "CAIPList.hpp"
00039 #include "CASocketGroup.hpp"
00040 #include "CAQueue.hpp"
00041 #include "CAUtil.hpp"
00042 #include "CAThread.hpp"
00043 #include "CAThreadPool.hpp"
00044 #include "TermsAndConditions.hpp"
00045 #include "CALogPacketStats.hpp"
00046 #include "CAConditionVariable.hpp"
00047 #include "CATempIPBlockList.hpp"
00048 #ifdef HAVE_EPOLL
00049   #include "CASocketGroupEpoll.hpp"
00050 #endif
00051 
00052 #ifdef REPLAY_DETECTION
00053   #include "CAMixWithReplayDB.hpp"
00054 #endif
00055 #ifdef COUNTRY_STATS
00056   #include "CAMutex.hpp"
00057 #endif
00058 
00059 #define TNC_SREQUEST "TermsAndConditionsRequest"
00060 #define TNC_RESPONSE "TermsAndConditionsResponse"
00061 #define TNC_SINTERRUPT "TermsAndConditionsInterrupt"
00062 #define TNC_REQ_TRANSLATION "Translation"
00063 #define TNC_RESOURCES "Resources"
00064 #define TNC_RESOURCE_TEMPLATE "Template"
00065 #define TNC_TEMPLATE_ROOT_ELEMENT "TermsAndConditionsTemplate"
00066 #define TNC_RESOURCE_CUSTOMIZED_SECT "CustomizedSections"
00067 
00068 #define TNC_RESPONSE_INVALID_REQUEST "InvalidTermsAndConditionsRequest"
00069 #define TNC_CONFIRM_REQ "TermsAndConditionsConfirm"
00070 
00071 class CAInfoService;
00072 
00073 THREAD_RETURN fm_loopSendToMix(void*);
00074 THREAD_RETURN fm_loopReadFromMix(void*);
00075 THREAD_RETURN fm_loopAcceptUsers(void*);
00076 THREAD_RETURN fm_loopReadFromUsers(void*);
00077 THREAD_RETURN fm_loopDoUserLogin(void* param);
00078 #ifdef CH_LOG_STUDY
00079 THREAD_RETURN fm_loopLogChannelsOpened(void* param);
00080 #endif //CH_LOG_STUDY
00081 THREAD_RETURN fm_loopLog(void*);
00082 
00083 #ifdef COUNTRY_STATS
00084 THREAD_RETURN iplist_loopDoLogCountries(void* param);
00085 class tUINT32withLock
00086   {
00087   private:
00088     volatile UINT32 value;
00089     CAMutex lock;
00090   public:
00091     tUINT32withLock()
00092       {
00093         value=0;
00094       }
00095     void inc()
00096       {
00097         lock.lock();
00098         value++;
00099         lock.unlock();
00100       }
00101 
00102     int getAndzero()
00103       {
00104         UINT32 tmp;
00105         lock.lock();
00106         tmp=value;
00107         value=0;
00108         lock.unlock();
00109         return tmp;
00110       }
00111   };
00112 #endif
00113 
00114 class CAFirstMix:public
00115 #ifdef REPLAY_DETECTION
00116   CAMixWithReplayDB
00117 #else
00118   CAMix
00119 #endif
00120 {
00121 public:
00122     CAFirstMix()
00123         {
00124           m_pmutexUser=new CAMutex();
00125           m_pmutexMixedPackets=new CAMutex();
00126           m_pmutexLoginThreads=new CAMutex();
00127           m_pmutexNewConnections=new CAMutex();
00128 #ifdef CH_LOG_STUDY
00129           //log nr of opened channels per minute
00130           nrOfChOpMutex = new CAMutex();
00131           nrOfChThread = NULL;
00132           nrOfOpenedChannels = 0;
00133           currentOpenedChannels = 0;
00134           lastLogTime = 0;
00135 #endif //CH_LOG_STUDY
00136           m_nMixedPackets=0;
00137           m_nUser=0;
00138           m_nSocketsIn=0;
00139           m_pQueueSendToMix=NULL;
00140           m_pQueueReadFromMix=NULL;
00141           m_pIPList=NULL;
00142           m_arrSocketsIn=NULL;
00143           m_pRSA=NULL;
00144           m_pInfoService=NULL;
00145           m_psocketgroupUsersRead=NULL;
00146           m_psocketgroupUsersWrite=NULL;
00147           m_pChannelList=NULL;
00148           m_pMuxOut=NULL;
00149           m_docMixCascadeInfo=NULL;
00150           m_xmlKeyInfoBuff=NULL;
00151           m_pthreadSendToMix=NULL;
00152           m_pthreadReadFromMix=NULL;
00153           m_pthreadAcceptUsers=NULL;
00154           m_pthreadsLogin=NULL;
00155           m_nrOfTermsAndConditionsDefs = 0;
00156           m_tnCDefs = NULL;
00157           m_nrOfTermsAndConditionsTemplates = 0;
00158           m_templatesOwner = NULL;
00159           m_tcTemplates = NULL;
00160           m_bIsShuttingDown=false;
00161           m_pIPBlockList = NULL;
00162 #ifdef LOG_PACKET_TIMES
00163           m_pLogPacketStats=NULL;
00164 #endif
00165 #ifdef COUNTRY_STATS
00166           m_PacketsPerCountryIN=m_PacketsPerCountryOUT=NULL;
00167           m_CountryStats=NULL;
00168           m_mysqlCon=NULL;
00169           m_threadLogLoop=NULL;
00170 #endif
00171           m_arMixParameters=NULL;
00172 #ifdef DYNAMIC_MIX
00173           m_bBreakNeeded = false;
00174 #endif
00175           TNC_REQUEST = XMLString::transcode(TNC_SREQUEST);
00176           TNC_CONFIRM = XMLString::transcode(TNC_CONFIRM_REQ);
00177           TNC_INTERRUPT =  XMLString::transcode(TNC_SINTERRUPT);
00178 #ifdef PAYMENT
00179           m_pmutexLogin=new CAMutex();
00180 #endif
00181         }
00182 
00183       /*virtual ~CAFirstMix()
00184       {
00185         delete m_pmutexNewConnections;
00186         m_pmutexNewConnections = NULL;
00187       }*/
00188       virtual ~CAFirstMix()
00189     {
00190       //clean(); // speeds up shutdown
00191       delete m_pmutexUser;
00192       m_pmutexUser = NULL;
00193       delete m_pmutexMixedPackets;
00194       m_pmutexMixedPackets = NULL;
00195       delete m_pmutexLoginThreads;
00196       m_pmutexLoginThreads = NULL;
00197 #ifdef PAYMENT
00198       delete m_pmutexLogin;
00199 #endif
00200     }
00201 
00202     tMixType getType() const
00203       {
00204         return CAMix::FIRST_MIX;
00205       }
00206 #ifdef PAYMENT
00207     bool forceKickout(fmHashTableEntry* pHashTableEntry, const XERCES_CPP_NAMESPACE::DOMDocument *pErrDoc=NULL);
00208     CAMutex* getLoginMutex()
00209       {
00210         return m_pmutexLogin;
00211       }
00212 #endif
00213 
00214 #ifdef DYNAMIC_MIX
00215 private:
00216       bool m_bBreakNeeded;
00217 #endif
00218       SINT32 connectToNextMix(CASocketAddr* a_pAddrNext);
00219 protected:
00220       virtual SINT32 loop()=0;
00221       bool isShuttingDown();
00222       SINT32 init();
00223       SINT32 clean();
00224       virtual SINT32 initOnce();
00225 #ifdef DYNAMIC_MIX
00226       void stopCascade()
00227       {
00228         m_bRestart = true;
00229       }
00230 #endif
00231     //added by ronin <ronin2@web.de>
00232     virtual SINT32 processKeyExchange();
00233 
00235     SINT32 initMixParameters(DOMElement* elemMixes);
00236 
00237 
00238 public:
00239     SINT32 getMixedPackets(UINT64& ppackets);
00240     UINT32 getNrOfUsers();
00241     SINT32 getLevel(SINT32* puser,SINT32* prisk,SINT32* ptraffic);
00242 
00243     TermsAndConditions *getTermsAndConditions(const UINT8 *opSki);
00244     DOMNode *getTermsAndConditionsTemplate(UINT8 *templateRefID);
00245 
00246     friend THREAD_RETURN fm_loopSendToMix(void*);
00247     friend THREAD_RETURN fm_loopReadFromMix(void*);
00248     friend THREAD_RETURN fm_loopAcceptUsers(void*);
00249     friend THREAD_RETURN fm_loopReadFromUsers(void*);
00250     friend THREAD_RETURN fm_loopDoUserLogin(void* param);
00251 #ifdef CH_LOG_STUDY
00252     friend THREAD_RETURN fm_loopLogChannelsOpened(void* param);
00253 #endif //CH_LOG_STUDY
00254 
00255 
00256     //How many mixes are in the cascade?
00257     SINT32 getMixCount()
00258       {
00259         return m_u32MixCount;
00260       }
00262     tMixParameters *getMixParameters()
00263       {
00264         return m_arMixParameters;
00265       }
00266 
00270     SINT32 setMixParameters(const tMixParameters& params);
00271 
00272     SINT32 handleKeyInfoExtensions(DOMElement *root);
00273     SINT32 handleTermsAndConditionsExtension(DOMElement *extensionRoot);
00274 
00275 #ifdef REPLAY_DETECTION
00276     UINT64 m_u64LastTimestampReceived;
00277 #endif
00278 
00279 protected:
00280 #ifndef COUNTRY_STATS
00281       SINT32 incUsers()
00282 #else
00283       SINT32 incUsers(LP_fmHashTableEntry pHashEntry)
00284 #endif
00285         {
00286           m_pmutexUser->lock();
00287           m_nUser++;
00288           #ifdef COUNTRY_STATS
00289             pHashEntry->countryID=updateCountryStats(pHashEntry->peerIP,0,false);
00290           #endif
00291           m_pmutexUser->unlock();
00292           return E_SUCCESS;
00293         }
00294 
00295 #ifndef COUNTRY_STATS
00296       SINT32 decUsers()
00297 #else
00298       SINT32 decUsers(LP_fmHashTableEntry pHashEntry)
00299 #endif
00300         {
00301           m_pmutexUser->lock();
00302           m_nUser--;
00303           #ifdef COUNTRY_STATS
00304             updateCountryStats(NULL,pHashEntry->countryID,true);
00305           #endif
00306           m_pmutexUser->unlock();
00307           return E_SUCCESS;
00308         }
00309 
00310       SINT32 incMixedPackets()
00311         {
00312           m_pmutexMixedPackets->lock();
00313           inc64(m_nMixedPackets);
00314           m_pmutexMixedPackets->unlock();
00315           return E_SUCCESS;
00316         }
00317 
00318       /*bool getRestart() const
00319         {
00320           return m_bRestart;
00321         }*/
00322       SINT32 doUserLogin(CAMuxSocket* pNewUSer,UINT8 perrIP[4]);
00323 
00324 #ifdef DELAY_USERS
00325       SINT32 reconfigure();
00326 #endif
00327 
00328 protected:
00329       CAIPList* m_pIPList;
00330       CATempIPBlockList* m_pIPBlockList;
00331       CAQueue* m_pQueueSendToMix;
00332       CAQueue* m_pQueueReadFromMix;
00333 #ifdef LOG_PACKET_TIMES
00334 
00335         CALogPacketStats* m_pLogPacketStats;
00336 #endif
00337 
00338       CAFirstMixChannelList* m_pChannelList;
00339       volatile UINT32 m_nUser;
00340       UINT32 m_nSocketsIn; //number of usable ListenerInterface (non 'virtual')
00341       volatile bool m_bRestart;
00342       CASocket** m_arrSocketsIn;
00343       //how many mixes are in the cascade?
00344       UINT32  m_u32MixCount;
00345       //stores the mix parameters for each mix
00346       tMixParameters* m_arMixParameters;
00347 
00348 #ifdef HAVE_EPOLL
00349 
00350       CASocketGroupEpoll* m_psocketgroupUsersRead;
00351       CASocketGroupEpoll* m_psocketgroupUsersWrite;
00352 #else
00353 
00354       CASocketGroup* m_psocketgroupUsersRead;
00355       CASocketGroup* m_psocketgroupUsersWrite;
00356 #endif
00357     // moved to CAMix
00358     //CAInfoService* m_pInfoService;
00359       CAMuxSocket* m_pMuxOut;
00360 
00361       UINT8* m_xmlKeyInfoBuff;
00362       UINT16 m_xmlKeyInfoSize;
00363 
00364       XERCES_CPP_NAMESPACE::DOMDocument* m_docMixCascadeInfo;
00365       UINT64 m_nMixedPackets;
00366       CAASymCipher* m_pRSA;
00367     // moved to CAMix
00368     //CASignature* m_pSignature;
00369       CAMutex* m_pmutexUser;
00370       CAMutex* m_pmutexMixedPackets;
00371       CAMutex* m_pmutexLoginThreads;
00372 
00373       CAThread* m_pthreadAcceptUsers;
00374       CAThreadPool* m_pthreadsLogin;
00375       CAThread* m_pthreadSendToMix;
00376       CAThread* m_pthreadReadFromMix;
00377 
00378       UINT32 m_nrOfTermsAndConditionsDefs;
00379       TermsAndConditions **m_tnCDefs;
00380       UINT32 m_nrOfTermsAndConditionsTemplates;
00381       DOMNode **m_tcTemplates;
00382       XERCES_CPP_NAMESPACE::DOMDocument *m_templatesOwner; //owner for the TC templates stored in tcTemplates
00383 
00384       /* constants for the XML root tags received from the client */
00385       const XMLCh *TNC_REQUEST;
00386       const XMLCh *TNC_CONFIRM;
00387       const XMLCh *TNC_INTERRUPT;
00388 #ifdef CH_LOG_STUDY
00389 protected:
00390       CAMutex *nrOfChOpMutex;
00391       UINT32 nrOfOpenedChannels;
00392       UINT32 currentOpenedChannels;
00393       CAThread *nrOfChThread;
00394       time_t lastLogTime;
00395 #endif //CH_LOG_STUDY
00396 
00397 #ifdef COUNTRY_STATS
00398     private:
00399       SINT32 initCountryStats(char* db_host,char* db_user,char*db_passwd);
00400       SINT32 updateCountryStats(const UINT8 ip[4],UINT32 a_countryID,bool bRemove);
00401       volatile bool m_bRunLogCountries;
00402       volatile UINT32* m_CountryStats;
00403     protected:
00404         SINT32 deleteCountryStats();
00405       tUINT32withLock* m_PacketsPerCountryIN;
00406       tUINT32withLock* m_PacketsPerCountryOUT;
00407     private:
00408       CAThread* m_threadLogLoop;
00409       MYSQL* m_mysqlCon;
00410       friend THREAD_RETURN iplist_loopDoLogCountries(void* param);
00411 #endif
00412 
00413 #ifdef REPLAY_DETECTION
00414     private:
00415       SINT32 sendReplayTimestampRequestsToAllMixes();
00416 #endif
00417 
00418 protected:
00419   bool m_bIsShuttingDown;
00420   friend THREAD_RETURN  fm_loopLog(void*);
00421   volatile bool         m_bRunLog;
00422 
00423 #ifdef PAYMENT
00424   CAMutex* m_pmutexLogin;
00425 #endif
00426 
00427 private:
00428   SINT32 doUserLogin_internal(CAMuxSocket* pNewUSer,UINT8 perrIP[4]);
00429   SINT32 isAllowedToPassRestrictions(CASocket* pNewMuxSocket);
00430 
00431 
00432   /* handlerFunction for Terms And Conditions invoked during user Login */
00433   termsAndConditionMixAnswer_t *handleTermsAndConditionsLogin(XERCES_CPP_NAMESPACE::DOMDocument *request);
00434 
00435   static const UINT32 MAX_CONCURRENT_NEW_CONNECTIONS;
00436 
00437   volatile UINT32 m_newConnections;
00438   CAMutex* m_pmutexNewConnections;
00439 
00440   void incNewConnections()
00441     {
00442       m_pmutexNewConnections->lock();
00443       m_newConnections++;
00444       m_pmutexNewConnections->unlock();
00445     }
00446 
00447   void decNewConnections()
00448     {
00449       m_pmutexNewConnections->lock();
00450       m_newConnections--;
00451       m_pmutexNewConnections->unlock();
00452     }
00453 
00454 };
00455 
00456 #endif
00457 #endif //ONLY_LOCAL_PROXY