Mixe for Privacy and Anonymity in the Internet
CAReplayCtrlChannelMsgProc.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 #ifdef REPLAY_DETECTION
00030 #include "CAReplayCtrlChannelMsgProc.hpp"
00031 #include "CAReplayControlChannel.hpp"
00032 #include "CAMixWithReplayDB.hpp"
00033 #include "CAMix.hpp"
00034 #include "CAReplayControlChannel.hpp"
00035 #include "CACmdLnOptions.hpp"
00036 #include "CAFirstMix.hpp"
00037 #include "CADatabase.hpp"
00038 
00039 CAReplayCtrlChannelMsgProc::CAReplayCtrlChannelMsgProc(const CAMixWithReplayDB* pMix)
00040   {
00041     CAMsg::printMsg(LOG_DEBUG,"CAReplayCtrlChannelMsgProc - constructor - this=%p\n",this);
00042     m_pDownstreamReplayControlChannel=NULL;
00043     m_pUpstreamReplayControlChannel=NULL;
00044     m_pThreadTimestampPropagation=NULL;
00045     m_pMix=pMix;
00046     m_docTemplate=NULL;
00047     initTimestampsMessageTemplate();
00048     CAControlChannelDispatcher* pDispatcher=m_pMix->getDownstreamControlChannelDispatcher();
00049 
00050     if(pDispatcher!=NULL)
00051       {
00052         #ifdef DEBUG
00053           CAMsg::printMsg(LOG_DEBUG,"CAReplayCtrlChannelMsgProc - constructor - registering downstream replay control channel\n",this);
00054         #endif
00055         m_pDownstreamReplayControlChannel=new CAReplayControlChannel(this);
00056         CAMsg::printMsg(LOG_DEBUG,"m_pDownstreamReplayControlChannel= %p\n",m_pDownstreamReplayControlChannel);
00057         pDispatcher->registerControlChannel(m_pDownstreamReplayControlChannel);
00058       }
00059     pDispatcher=m_pMix->getUpstreamControlChannelDispatcher();
00060     if(pDispatcher!=NULL)
00061       {
00062         #ifdef DEBUG
00063           CAMsg::printMsg(LOG_DEBUG,"CAReplayCtrlChannelMsgProc - constructor - registering upstream replay control channel\n",this);
00064         #endif
00065         m_pUpstreamReplayControlChannel=new CAReplayControlChannel(this);
00066         pDispatcher->registerControlChannel(m_pUpstreamReplayControlChannel);
00067       }
00068   }
00069 
00070 CAReplayCtrlChannelMsgProc::~CAReplayCtrlChannelMsgProc()
00071   {
00072     #ifdef DEBUG
00073       CAMsg::printMsg(LOG_DEBUG,"CAReplayCtrlChannelMsgProc::~CAReplayCtrlChannelMsgProc()\n");
00074     #endif
00075     stopTimeStampPorpagation();
00076     CAControlChannelDispatcher* pDispatcher=m_pMix->getDownstreamControlChannelDispatcher();
00077     if(pDispatcher!=NULL)
00078       {
00079         pDispatcher->removeControlChannel(m_pDownstreamReplayControlChannel->getID());
00080         delete m_pDownstreamReplayControlChannel;
00081         m_pDownstreamReplayControlChannel = NULL;
00082       }
00083     pDispatcher=m_pMix->getUpstreamControlChannelDispatcher();
00084     if(pDispatcher!=NULL)
00085       {
00086         pDispatcher->removeControlChannel(m_pUpstreamReplayControlChannel->getID());
00087         delete m_pUpstreamReplayControlChannel;
00088         m_pUpstreamReplayControlChannel = NULL;
00089       }
00090   }
00091 
00092 /* not used and not necesary
00093 SINT32 CAReplayCtrlChannelMsgProc::proccessGetTimestamps(const CAReplayControlChannel* pReceiver) const
00094   {
00095     //Only for the first mix get timestamps is supported for the moment!
00096     if(m_pMix->getType()!=CAMix::FIRST_MIX)
00097       {
00098         return E_UNKNOWN;
00099       }
00100 
00101     CAFirstMix* pMix=(CAFirstMix*)m_pMix;
00102     DOM_Document docTemplate=DOM_Document::createDocument();
00103     DOM_Element elemMixes=docTemplate.createElement("Mixes");
00104     docTemplate.appendChild(elemMixes);
00105     tMixParameters* mixParameters=pMix->getMixParameters();
00106     time_t aktTime=time(NULL);
00107     for(SINT32 i=0;i<pMix->getMixCount()-1;i++)
00108       {
00109         DOM_Element elemMix=docTemplate.createElement("Mix");
00110         setDOMElementAttribute(elemMix,"id",mixParameters[i].m_strMixID);
00111         DOM_Element elemReplay=docTemplate.createElement("Replay");
00112         elemMix.appendChild(elemReplay);
00113         DOM_Element elemReplayOffset=docTemplate.createElement("ReplayOffset");
00114         setDOMElementValue(elemReplayOffset,(UINT32) (mixParameters[i].m_u32ReplayOffset+aktTime-pMix->m_u64LastTimestampReceived));
00115         elemReplay.appendChild(elemReplayOffset);
00116         elemMixes.appendChild(elemMix);
00117       }
00118     return pReceiver->sendXMLMessage(docTemplate);
00119   }
00120 */
00121 // possibility for the first mix to request the timestamps
00122 SINT32 CAReplayCtrlChannelMsgProc::proccessGetTimestamp(const CAReplayControlChannel* pReceiver,const UINT8* strMixID) const
00123   {
00124     UINT8 buff[255];
00125     pglobalOptions->getMixId(buff,255);
00126     if(strMixID==NULL||strncmp((char*)strMixID,(char*)buff,255)==0)//our own replay timestamp is requested
00127       {
00128         //First Mixes does not have to send his timestamp!
00129         if(m_pMix->getType()==CAMix::FIRST_MIX)
00130           return E_SUCCESS;
00131 
00132         const CAMixWithReplayDB* pMix=(CAMixWithReplayDB*)m_pMix;
00133 
00134         DOMElement* elemReplayTimestamp=NULL;
00135         if (getDOMChildByName(m_docTemplate->getDocumentElement(),"ReplayOffset",elemReplayTimestamp,true)!=E_SUCCESS){
00136           return E_UNKNOWN;
00137           }
00138         setDOMElementValue(elemReplayTimestamp,(UINT32) (time(NULL)-m_pMix->m_u64ReferenceTime));
00139 
00140         return pReceiver->sendXMLMessage(m_docTemplate);
00141       }
00142     else if(m_pUpstreamReplayControlChannel!=NULL&&strMixID!=NULL)//the replay timestamp of some other mix is requested
00143       {
00144         XERCES_CPP_NAMESPACE::DOMDocument* doc=createDOMDocument();
00145         DOMElement *elemGet=createDOMElement(doc,"GetTimestamp");
00146         setDOMElementAttribute(elemGet,"id",strMixID);
00147         doc->appendChild(elemGet);
00148 
00149         SINT32 return_value=m_pUpstreamReplayControlChannel->sendXMLMessage(doc);
00150         if (doc != NULL)
00151         {
00152           doc->release();
00153           doc = NULL;
00154         }
00155 
00156         return return_value;
00157       }
00158     return E_SUCCESS; 
00159   }
00160 
00161 SINT32 CAReplayCtrlChannelMsgProc::propagateCurrentReplayTimestamp()
00162   {
00163     UINT8 buff[255];
00164     pglobalOptions->getMixId(buff,255);
00165 
00166     #ifdef DEBUG
00167       CAMsg::printMsg(LOG_DEBUG,"Start replay timestamp propagation\n");
00168     #endif
00169 
00170     if(m_pDownstreamReplayControlChannel==NULL)
00171       return E_UNKNOWN;
00172 
00173     DOMElement* elemReplayTimestamp=NULL;
00174     if (getDOMChildByName(m_docTemplate->getDocumentElement(),"ReplayOffset",elemReplayTimestamp,true)!=E_SUCCESS){
00175       return E_UNKNOWN;
00176       }
00177     setDOMElementValue(elemReplayTimestamp,(UINT32) (time(NULL)-m_pMix->m_u64ReferenceTime));
00178 
00179     m_pDownstreamReplayControlChannel->sendXMLMessage(m_docTemplate);
00180 
00181     #ifdef DEBUG
00182       CAMsg::printMsg(LOG_DEBUG,"Replay timestamp propagation finished\n");
00183     #endif
00184 
00185     return E_SUCCESS;
00186   }
00187 
00188 THREAD_RETURN rp_loopPropagateTimestamp(void* param)
00189   {
00190     CAReplayCtrlChannelMsgProc* pReplayMsgProc=(CAReplayCtrlChannelMsgProc*)param;
00191     UINT32 propagationInterval=pReplayMsgProc->m_u32PropagationInterval;
00192     while(pReplayMsgProc->m_bRun)
00193       {
00194         if(propagationInterval==0)
00195           {
00196             pReplayMsgProc->propagateCurrentReplayTimestamp();
00197             propagationInterval=pReplayMsgProc->m_u32PropagationInterval;
00198           }
00199         sSleep(60);
00200         propagationInterval--;
00201       }
00202     THREAD_RETURN_SUCCESS;
00203   }
00204 
00205 SINT32 CAReplayCtrlChannelMsgProc::startTimeStampPorpagation(UINT32 minutesPropagationInterval)
00206   {
00207     m_u32PropagationInterval=minutesPropagationInterval;
00208     m_pThreadTimestampPropagation=new CAThread();
00209     m_pThreadTimestampPropagation->setMainLoop(rp_loopPropagateTimestamp);
00210     m_bRun=true;
00211     return m_pThreadTimestampPropagation->start(this);
00212   }
00213 
00214 SINT32 CAReplayCtrlChannelMsgProc::stopTimeStampPorpagation()
00215   {
00216     m_bRun=false;
00217     if(m_pThreadTimestampPropagation!=NULL)
00218       {
00219         m_pThreadTimestampPropagation->join();
00220         delete m_pThreadTimestampPropagation;
00221         m_pThreadTimestampPropagation = NULL;
00222       }
00223     m_pThreadTimestampPropagation=NULL;
00224     return E_SUCCESS;
00225   }
00226 
00232 SINT32 CAReplayCtrlChannelMsgProc::initTimestampsMessageTemplate()
00233   {
00234     //NOT for the first mix! Only propagateCurrentReplayTimestamps is supported for the moment!
00235     if(m_pMix->getType()==CAMix::FIRST_MIX)
00236       {
00237         return E_SUCCESS;
00238       }
00239 
00240     if(m_docTemplate!=NULL)
00241       {
00242         return E_UNKNOWN;
00243       }
00244 
00245     UINT8 buff[255];
00246     pglobalOptions->getMixId(buff,255);
00247 
00248     m_docTemplate=createDOMDocument();
00249     DOMElement *elemMix=createDOMElement(m_docTemplate,"Mix");
00250     setDOMElementAttribute(elemMix,"id",buff);
00251     DOMElement *elemReplay=createDOMElement(m_docTemplate,"Replay");
00252     elemMix->appendChild(elemReplay);
00253     DOMElement *elemReplayOffset=createDOMElement(m_docTemplate,"ReplayOffset");
00254 //    setDOMElementValue(elemReplayOffset,(UINT32) (time(NULL)-m_pMix->m_u64ReferenceTime));
00255     elemReplay->appendChild(elemReplayOffset);
00256     DOMElement *elemReplayBase=createDOMElement(m_docTemplate,"ReplayBase");
00257     setDOMElementValue(elemReplayBase,(UINT32) (REPLAY_BASE));
00258     elemReplay->appendChild(elemReplayBase);
00259     m_docTemplate->appendChild(elemMix);
00260 
00261     return E_SUCCESS;
00262   }
00263 
00264 
00265 SINT32 CAReplayCtrlChannelMsgProc::proccessGotTimestamp(const CAReplayControlChannel* pReceiver,const UINT8* strMixID,const UINT32 offset) const
00266   {
00267     //if not first mix just forwards them down the drain...
00268     #ifdef DEBUG
00269       CAMsg::printMsg(LOG_DEBUG,"CAReplayCtrlChannelMsgProc::proccessGotTimestamp() \n");
00270     #endif
00271     if(m_pMix->getType()!=CAMix::FIRST_MIX)
00272       {
00273         XERCES_CPP_NAMESPACE::DOMDocument* doc=createDOMDocument();
00274         DOMElement *elemMix=createDOMElement(doc,"Mix");
00275         setDOMElementAttribute(elemMix,"id",strMixID);
00276         DOMElement *elemReplay=createDOMElement(doc,"Replay");
00277         elemMix->appendChild(elemReplay);
00278         DOMElement *elemReplayOffset=createDOMElement(doc,"ReplayOffset");
00279         setDOMElementValue(elemReplayOffset,(UINT32) offset);
00280         elemReplay->appendChild(elemReplayOffset);
00281         doc->appendChild(elemMix);
00282 
00283         SINT32 return_value=m_pDownstreamReplayControlChannel->sendXMLMessage(doc);
00284         if (doc != NULL)
00285         {
00286           doc->release();
00287           doc = NULL;
00288         }
00289 
00290         return return_value;
00291       }
00292 
00293     //First mix --> update mix parameters
00294     CAFirstMix* pMix=(CAFirstMix*)m_pMix;
00295     #ifdef DEBUG
00296       CAMsg::printMsg(LOG_DEBUG,"CAReplayCtrlChannelMsgProc::proccessGotTimestamp() - MixID: %s\n",strMixID);
00297       CAMsg::printMsg(LOG_DEBUG,"CAReplayCtrlChannelMsgProc::proccessGotTimestamp() - LastTimestamp DIFF: %d\n",time(NULL)-pMix->m_u64LastTimestampReceived);
00298     #endif
00299 
00300     tMixParameters params;
00301     UINT32 len=strlen((char*)strMixID);
00302     params.m_strMixID=new UINT8[len+1];
00303     memcpy(params.m_strMixID,strMixID,len+1);
00304     params.m_u32ReplayOffset=offset;
00305     pMix->setMixParameters(params);
00306 
00307     pMix->m_u64LastTimestampReceived=time(NULL);
00308     delete[] params.m_strMixID;
00309     params.m_strMixID = NULL;
00310     return E_SUCCESS;
00311   }
00312 
00313 SINT32 CAReplayCtrlChannelMsgProc::sendGetTimestamp(const UINT8* strMixID)
00314   {
00315     if(strMixID==NULL||strlen((const char*)strMixID)>400)
00316       return E_UNKNOWN;
00317 
00318     XERCES_CPP_NAMESPACE::DOMDocument* doc=createDOMDocument();
00319     DOMElement *elemGet=createDOMElement(doc,"GetTimestamp");
00320     setDOMElementAttribute(elemGet,"id",strMixID);
00321     doc->appendChild(elemGet);
00322 
00323     SINT32 return_value=m_pUpstreamReplayControlChannel->sendXMLMessage(doc);
00324     if (doc != NULL)
00325     {
00326       doc->release();
00327       doc = NULL;
00328     }
00329 
00330     return return_value;
00331   }
00332 
00333 #endif //REPLAY_DETECTION