Mixe for Privacy and Anonymity in the Internet
CAFirstMixChannelList.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 #ifndef __CAFRISTMIXCHANNELLIST__
00029 #define __CAFRISTMIXCHANNELLIST__
00030 #include "doxygen.h"
00031 #ifndef ONLY_LOCAL_PROXY
00032 #include "CAMuxSocket.hpp"
00033 #include "CAQueue.hpp"
00034 #include "CASymCipher.hpp"
00035 #include "CAMutex.hpp"
00036 #include "CAMsg.hpp"
00037 #include "CAControlChannelDispatcher.hpp"
00038 #ifdef DELAY_USERS
00039   #include "CAThread.hpp"
00040 #endif
00041 #ifdef PAYMENT
00042 
00043 class CAAccountingControlChannel;
00044 
00045 #endif
00046 
00047 #define KICKOUT_FORCED true
00048 #define MAX_KICKOUT_RETRIES 4
00049 
00050 struct t_fmhashtableentry
00051   {
00052     public:
00053       CAMuxSocket*  pMuxSocket;
00054       CAQueue*    pQueueSend;
00055       /* Separate handling of control messages allows to assign control messages a higher priority. */
00056       CAQueue*    pControlMessageQueue;
00057       CAControlChannelDispatcher* pControlChannelDispatcher;
00058       SINT32      uAlreadySendPacketSize;
00059       tQueueEntry   oQueueEntry;
00060       UINT32        cSuspend;
00061 #ifdef CH_LOG_STUDY
00062       time_t channelOpenedLastIntervalTS;
00063 #endif
00064 
00065 #ifdef LOG_TRAFFIC_PER_USER
00066       UINT32        trafficIn;
00067       UINT32        trafficOut;
00068       UINT64        timeCreated;
00069 #endif
00070       UINT64        id;
00071 
00072       CASymCipher*  pSymCipher;
00073       UINT8         peerIP[4]; //needed for flooding control
00074 #ifdef DATA_RETENTION_LOG
00075       UINT32        peerPort;
00076 #endif
00077 #ifdef COUNTRY_STATS
00078       UINT32 countryID; 
00079 #endif
00080 
00081 #ifdef LOG_DIALOG
00082       UINT8*        strDialog;
00083 #endif
00084 
00085 #ifdef DELAY_USERS
00086       volatile UINT32       delayBucket;
00087       volatile UINT32       delayBucketID;
00088 #endif
00089       // if false, the entry should be deleted the next time it is read from the queue
00090       bool bRecoverTimeout;
00091       SINT32 kickoutSendRetries;
00092     private:
00093       UINT32        cNumberOfChannels;
00094       struct t_firstmixchannellist* pChannelList;
00095 
00096       struct
00097         {
00098           struct t_fmhashtableentry* prev;
00099           struct t_fmhashtableentry* next;
00100         } list_HashEntries;
00101 
00102       // the timeout list
00103       // At the moement only enabled for payment Mixes (to be changed iff new mix protcol supports this for all clients)
00104 #ifdef PAYMENT
00105       struct
00106       {
00107         struct t_fmhashtableentry* prev;
00108         struct t_fmhashtableentry* next;
00109         SINT32 timoutSecs;
00110       } list_TimeoutHashEntries;
00111 
00112       CAConditionVariable *cleanupNotifier;
00113 #endif
00114     friend class CAFirstMixChannelList;
00115 
00116     public:
00117       bool bCountPacket;
00118 #ifdef PAYMENT
00119     private:
00120       tAiAccountingInfo* pAccountingInfo;
00121     friend class CAAccountingInstance;
00122     friend class CAAccountingControlChannel;
00123     friend class CAFirstMixA;
00124 #endif
00125   };
00126 
00127 typedef struct t_fmhashtableentry fmHashTableEntry;
00128 typedef fmHashTableEntry* LP_fmHashTableEntry;
00129 
00130 
00131 
00132 struct t_firstmixchannellist
00133   {
00134     public:
00135       fmHashTableEntry* pHead;
00136 
00137       HCHANNEL channelIn;
00138       HCHANNEL channelOut;
00139 
00140       CASymCipher* pCipher;
00141       bool bIsSuspended;
00142 
00143 #ifdef LOG_CHANNEL
00144       UINT32        packetsInFromUser;
00145       UINT64        timeCreated;
00146       UINT32        packetsOutToUser;
00147 #endif
00148 
00149 #ifdef SSL_HACK
00150       UINT32        downStreamBytes; /* a hack to solve the SSL problem */
00151 #endif
00152     private:
00153       struct
00154         {
00155           struct t_firstmixchannellist* prev;
00156           struct t_firstmixchannellist* next;
00157         } list_OutChannelHashTable;
00158 
00159       struct
00160         {
00161           struct t_firstmixchannellist* prev;
00162           struct t_firstmixchannellist* next;
00163         } list_InChannelPerSocket;
00164 
00165     friend class CAFirstMixChannelList;
00166   };
00167 
00168 typedef struct t_firstmixchannellist fmChannelList;
00169 typedef struct t_firstmixchannellist fmChannelListEntry;
00170 typedef fmChannelListEntry* LP_fmChannelListEntry;
00171 
00172 THREAD_RETURN fml_loopDelayBuckets(void* param);
00173 
00221 class CAFirstMixChannelList
00222   {
00223     public:
00224       CAFirstMixChannelList();
00225       ~CAFirstMixChannelList();
00226 
00227 #ifndef LOG_DIALOG
00228       fmHashTableEntry* add(CAMuxSocket* pMuxSocket,const UINT8 peerIP[4],CAQueue* pQueueSend,
00229       UINT8* controlChannelKeyRecv,UINT8* controlChannelKeySent);
00230 #else
00231       fmHashTableEntry* add(CAMuxSocket* pMuxSocket,const UINT8 peerIP[4],CAQueue* pQueueSend,UINT8* strDialog);
00232 #endif
00233       SINT32 addChannel(CAMuxSocket* pMuxSocket,HCHANNEL channelIn,CASymCipher* pCipher,HCHANNEL* channelOut);
00234 
00235       fmChannelListEntry* get(CAMuxSocket* pMuxSocket,HCHANNEL channelIn);
00236 
00237 #ifdef PAYMENT
00238 
00242       fmHashTableEntry* popTimeoutEntry();
00243 
00250       fmHashTableEntry* popTimeoutEntry(bool a_bForce);
00251 
00252 
00253       bool isTimedOut(fmHashTableEntry* pHashTableEntry);
00254       bool isKickoutForced(fmHashTableEntry* pHashTableEntry);
00255       void setKickoutForced(fmHashTableEntry* pHashTableEntry, bool kickoutForced);
00256 
00257       bool forceKickout(fmHashTableEntry* pHashTableEntry, const XERCES_CPP_NAMESPACE::DOMDocument *pErrDoc);
00261       SINT32 pushTimeoutEntry(fmHashTableEntry* pHashTableEntry, bool kickoutForced = !KICKOUT_FORCED);
00262 #endif
00263 
00264       SINT32 remove(CAMuxSocket* pMuxSocket);
00265       SINT32 removeChannel(CAMuxSocket* pMuxSocket,HCHANNEL channelIn);
00266 
00267       fmHashTableEntry* getFirst();
00268       fmHashTableEntry* getNext();
00269       fmHashTableEntry* get(CAMuxSocket* pMuxSocket);
00270 
00271 
00272       fmChannelListEntry* getFirstChannelForSocket(CAMuxSocket* pMuxSocket);
00273       fmChannelListEntry* getNextChannel(fmChannelListEntry* pEntry);
00274 
00275       static SINT32 test();
00276 
00277       #ifdef NEW_MIX_TYPE
00278         /* additional methods for TypeB first mixes */
00279         SINT32 removeClientPart(CAMuxSocket* pMuxSocket);
00280         void removeVacantOutChannel(fmChannelListEntry* pEntry);
00281         void cleanVacantOutChannels();
00282       #endif
00283 
00284     private:
00285 #ifdef PAYMENT
00286       SINT32 removeFromTimeoutList(fmHashTableEntry* pHashTableEntry);
00290       SINT32 pushTimeoutEntry_internal(fmHashTableEntry* pHashTableEntry, bool kickoutForced = !KICKOUT_FORCED);
00291 
00292       inline bool isKickoutForced_internal(fmHashTableEntry* pHashTableEntry);
00293       inline void setKickoutForced_internal(fmHashTableEntry* pHashTableEntry, bool kickoutForced);
00294 
00295       fmHashTableEntry* popTimeoutEntry_internal(bool a_bForce);
00296 
00297       UINT32 countTimeoutEntries();
00298 #endif
00299 
00306       fmChannelListEntry* get_intern_without_lock(HCHANNEL channelOut)
00307         {
00308           fmChannelListEntry* pEntry=m_HashTableOutChannels[channelOut&0x0000FFFF];
00309           while(pEntry!=NULL)
00310             {
00311               if(pEntry->channelOut==channelOut)
00312                 {
00313                   return pEntry;
00314                 }
00315               pEntry=pEntry->list_OutChannelHashTable.next;
00316             }
00317           return NULL;
00318         }
00319 
00320       //not thread-safe check if a ChannelList hash entry is timed out. */
00321       inline bool isTimedOut_internal(fmHashTableEntry* pHashTableEntry);
00322 
00323     public:
00329       fmChannelListEntry* get(HCHANNEL channelOut)
00330         {
00331           m_Mutex.lock();
00332           fmChannelListEntry* pEntry=get_intern_without_lock(channelOut);
00333           m_Mutex.unlock();
00334           return pEntry;
00335         }
00336     private:
00337       static const SINT32 EXPIRATION_TIME_SECS;
00338 
00340       LP_fmHashTableEntry* m_HashTable;
00342       LP_fmChannelListEntry* m_HashTableOutChannels;
00343 
00345       fmHashTableEntry* m_listHashTableHead;
00347       fmHashTableEntry* m_listHashTableNext;
00348 #ifdef PAYMENT
00349 
00350       fmHashTableEntry* m_listTimoutHead;
00351       fmHashTableEntry* m_listTimoutFoot;
00352 #endif
00353 
00354       CAMutex m_Mutex;
00355 //#ifdef PAYMENT
00356 //      CAAccountingInstance *m_pAccountingInstance;
00357 //#endif
00358       #ifdef DELAY_USERS
00359         volatile UINT32** m_pDelayBuckets;
00360         CAThread* m_pThreadDelayBucketsLoop;
00361         CAMutex* m_pMutexDelayChannel;
00362         bool m_bDelayBucketsLoopRun;
00363         friend THREAD_RETURN fml_loopDelayBuckets(void*);
00364         //Parameters
00365         volatile UINT32 m_u32DelayChannelUnlimitTraffic;  //how many packets without any delay?
00366         volatile UINT32 m_u32DelayChannelBucketGrow; //how many packets to put in each bucket per time intervall
00367         volatile UINT32 m_u32DelayChannelBucketGrowIntervall; //duration of one time intervall in ms
00368                                                               //therefore the allowed max bandwith=BucketGrow/Intervall*1000 *PAYLOAD_SIZE[bytes/s]
00369         public:
00370           void setDelayParameters(UINT32 unlimitTraffic,UINT32 bucketGrow,UINT32 intervall);
00371           void decDelayBuckets(UINT32 delayBucketID);
00372           bool hasDelayBuckets(UINT32 delayBucketID);
00373       #endif
00374 #ifdef DO_TRACE
00375       UINT32 m_aktAlloc;
00376       UINT32 m_maxAlloc;
00377       LP_fmChannelListEntry newChannelListEntry()
00378         {
00379           m_aktAlloc+=sizeof(fmChannelListEntry);
00380           if(m_maxAlloc<m_aktAlloc)
00381             {
00382               m_maxAlloc=m_aktAlloc;
00383               CAMsg::printMsg(LOG_DEBUG,"FirstMixChannelList current alloc: %u\n",m_aktAlloc);
00384             }
00385           return (LP_fmChannelListEntry)new fmChannelListEntry;
00386         }
00387       void deleteChannelListEntry(LP_fmChannelListEntry entry)
00388         {
00389           m_aktAlloc-=sizeof(fmChannelListEntry);
00390           delete entry;
00391           entry = NULL;
00392         }
00393 #endif
00394   };
00395 #endif
00396 #endif //ONLY_LOCAL_PROXY