Mixe for Privacy and Anonymity in the Internet
CASocketList.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000, The JAP-Team 
00003 All rights reserved.
00004 Redistribution and use in source and binary forms, with or without modification, 
00005 are permitted provided that the following conditions are met:
00006 
00007   - Redistributions of source code must retain the above copyright notice, 
00008     this list of conditions and the following disclaimer.
00009 
00010   - Redistributions in binary form must reproduce the above copyright notice, 
00011     this list of conditions and the following disclaimer in the documentation and/or 
00012     other materials provided with the distribution.
00013 
00014   - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors 
00015     may be used to endorse or promote products derived from this software without specific 
00016     prior written permission. 
00017 
00018   
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS 
00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 
00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00027 */
00028 #include "StdAfx.h"
00029 #include "CASocketList.hpp"
00030 #include "CAUtil.hpp"
00031 #define POOL_SIZE 1000
00032 
00033 typedef struct t_MEMBLOCK
00034   {
00035     CONNECTIONLIST* mem;
00036     t_MEMBLOCK* next;
00037   } _MEMBLOCK;
00038 
00039 SINT32 CASocketList::increasePool()
00040   {
00041     CONNECTIONLIST* tmp=new CONNECTIONLIST[POOL_SIZE];
00042     if(tmp==NULL)
00043       return E_UNKNOWN;
00044     _MEMBLOCK* tmpMem=new _MEMBLOCK;
00045     if(tmpMem==NULL)
00046       {
00047         delete[] tmp;
00048         tmp = NULL;
00049         return E_UNKNOWN;
00050       }
00051     memset(tmp,0,sizeof(CONNECTIONLIST)*POOL_SIZE);
00052     for(int i=1;i<POOL_SIZE;i++)
00053       {
00054         tmp[i-1].next=&tmp[i];
00055       }
00056     tmp[POOL_SIZE-1].next=m_Pool;
00057     m_Pool=tmp;
00058     tmpMem->next=m_Memlist;
00059     tmpMem->mem=tmp;
00060     m_Memlist=tmpMem;
00061     return E_SUCCESS;
00062   }
00063 
00064 CASocketList::CASocketList()
00065   {
00066     m_Connections=NULL;
00067     m_Pool=NULL;
00068     m_Memlist=NULL;
00069     m_AktEnumPos=NULL;
00070     m_bThreadSafe=false;
00071     setThreadSafe(false);
00072     increasePool();
00073     m_Size=0;
00074   }
00075 
00076 CASocketList::CASocketList(bool bThreadSafe)
00077   {
00078     m_Connections=NULL;
00079     m_Pool=NULL;
00080     m_Memlist=NULL;
00081     m_AktEnumPos=NULL;
00082     m_bThreadSafe=false;
00083     setThreadSafe(bThreadSafe);
00084     increasePool();
00085   }
00086 
00087 CASocketList::~CASocketList()
00088   {
00089     clear();
00090   }
00091 
00092 SINT32 CASocketList::clear()
00093   {
00094     _MEMBLOCK* tmp;
00095     tmp=m_Memlist;
00096     while(tmp!=NULL)
00097       {
00098         delete []tmp->mem;
00099         tmp->mem = NULL;
00100         m_Memlist=tmp;
00101         tmp=tmp->next;
00102         delete m_Memlist;
00103         m_Memlist = NULL;
00104       }
00105     m_Connections=NULL;
00106     m_Pool=NULL;
00107     m_Memlist=NULL;
00108     m_AktEnumPos=NULL;
00109     return E_SUCCESS;
00110   }
00111 
00112 SINT32 CASocketList::setThreadSafe(bool b)
00113   {
00114     m_bThreadSafe=b;
00115     return E_SUCCESS;
00116   }
00117 
00125 SINT32 CASocketList::add(CASocket* pSocket,CASymCipher* pCiphers)
00126   {
00127     if(m_bThreadSafe)
00128       cs.lock();
00129     CONNECTIONLIST* tmp;
00130     if(m_Pool==NULL)
00131       {
00132         if(increasePool()!=E_SUCCESS)
00133           {
00134             if(m_bThreadSafe)
00135               cs.unlock();
00136             return E_UNKNOWN;
00137           }
00138        }
00139     tmp=m_Pool;
00140     m_Pool=m_Pool->next;
00141     tmp->next=m_Connections;
00142     m_Connections=tmp;
00143     m_Connections->pSocket=pSocket;
00144     m_Connections->pCiphers=pCiphers;
00145     m_Connections->currentSendMeCounter=0;
00146     m_Connections->upstreamBytes=0;
00147     for(;;)
00148       {
00149 SELECT_RANDOM_CHANNEL_ID:
00150         getRandom(&m_Connections->outChannel);        
00151         tmp=m_Connections->next;
00152         while(tmp!=NULL)
00153           {
00154             if(tmp->outChannel==m_Connections->outChannel)
00155               goto SELECT_RANDOM_CHANNEL_ID;
00156             tmp=tmp->next;
00157           }
00158         break;
00159       }
00160     m_Size++;
00161     if(m_bThreadSafe)
00162       cs.unlock();
00163     return E_SUCCESS;
00164   }
00165 
00173 SINT32 CASocketList::get(HCHANNEL in,CONNECTION* out)
00174   {
00175     if(m_bThreadSafe)
00176       cs.lock();
00177     CONNECTIONLIST* tmp;
00178     tmp=m_Connections;
00179     while(tmp!=NULL)
00180       {
00181         if(tmp->outChannel==in)
00182           {
00183             memcpy(out,tmp,sizeof(CONNECTION));
00184             if(m_bThreadSafe)
00185               cs.unlock();
00186             return E_SUCCESS;
00187           }
00188         tmp=tmp->next;
00189       }
00190     if(m_bThreadSafe)
00191       cs.unlock();
00192     return E_UNKNOWN;
00193   }
00194 
00195 SINT32 CASocketList::addSendMeCounter(HCHANNEL in,SINT32 value)
00196   {
00197     if(m_bThreadSafe)
00198       cs.lock();
00199     CONNECTIONLIST* tmp;
00200     tmp=m_Connections;
00201     while(tmp!=NULL)
00202       {
00203         if(tmp->outChannel==in)
00204           {
00205             tmp->currentSendMeCounter+=value;
00206             if(m_bThreadSafe)
00207               cs.unlock();
00208             return E_SUCCESS;
00209           }
00210         tmp=tmp->next;
00211       }
00212     if(m_bThreadSafe)
00213       cs.unlock();
00214     return E_UNKNOWN;
00215   }
00216 
00217 CASocket* CASocketList::remove(HCHANNEL id)
00218   {
00219     if(m_bThreadSafe)
00220       cs.lock();
00221     CONNECTIONLIST* tmp,*before;
00222     CASocket* ret;
00223     tmp=m_Connections;
00224     before=NULL;
00225     while(tmp!=NULL)
00226       {
00227         if(tmp->outChannel==id)
00228           {
00229             if(m_AktEnumPos==tmp)
00230               m_AktEnumPos=tmp->next;
00231             if(before!=NULL)
00232               before->next=tmp->next;
00233             else
00234               m_Connections=tmp->next;
00235             tmp->next=m_Pool;
00236             m_Pool=tmp;
00237             ret=tmp->pSocket;
00238             m_Size--;
00239             if(m_bThreadSafe)
00240               cs.unlock();
00241             return ret;
00242           }
00243         before=tmp;
00244         tmp=tmp->next;
00245       }
00246     if(m_bThreadSafe)
00247       cs.unlock();
00248     return NULL;
00249   }
00250