Mixe for Privacy and Anonymity in the Internet
Public Member Functions | Protected Member Functions | Protected Attributes | Friends | List of all members
CALastMix Class Referenceabstract

#include <CALastMix.hpp>

Inheritance diagram for CALastMix:
Collaboration diagram for CALastMix:

Public Member Functions

 CALastMix ()
 
virtual ~CALastMix ()
 
SINT32 reconfigure ()
 
tMixType getType () const
 
- Public Member Functions inherited from CAMixWithReplayDB
 CAMixWithReplayDB ()
 
CADatabasegetReplayDB () const
 
- Public Member Functions inherited from CAMix
 CAMix ()
 
virtual ~CAMix ()
 
SINT32 start ()
 
virtual void shutDown ()
 
virtual bool isShutDown ()
 
SINT32 getMixCascadeInfo (XERCES_CPP_NAMESPACE::DOMDocument *&docMixCascadeInfo)
 Returns the Mix-Cascade info which should be send to the InfoService. More...
 
bool acceptsReconfiguration ()
 
CAControlChannelDispatchergetDownstreamControlChannelDispatcher () const
 
CAControlChannelDispatchergetUpstreamControlChannelDispatcher () const
 
UINT32 getLastConnectionTime ()
 
bool isConnected ()
 

Protected Member Functions

virtual SINT32 loop ()=0
 
SINT32 init ()
 
virtual SINT32 initOnce ()
 
SINT32 clean ()
 
SINT32 initMixCascadeInfo (DOMElement *)
 This will initialize the XML Cascade Info struct XMLFirstMixToInfoService that is sent to the InfoService in CAInfoService::sendCascadeHelo() More...
 
virtual SINT32 processKeyExchange ()
 Processes the startup communication with the preceeding mix. More...
 
SINT32 setTargets ()
 Reads the configured proxies from options. More...
 
- Protected Member Functions inherited from CAMix
SINT32 checkCompatibility (DOMNode *a_parent, const char *a_mixPosition)
 
SINT32 appendCompatibilityInfo (DOMNode *a_parent)
 
SINT32 addMixInfo (DOMNode *a_element, bool a_bForceFirstNode)
 
SINT32 signXML (DOMNode *a_element)
 

Protected Attributes

volatile bool m_bRestart
 
CAMuxSocketm_pMuxIn
 
CAQueuem_pQueueSendToMix
 
CAQueuem_pQueueReadFromMix
 
CACacheLoadBalancingm_pCacheLB
 
CACacheLoadBalancingm_pSocksLB
 
CACacheLoadBalancingm_pVPNLB
 
CAASymCipherm_pRSA
 
CAThreadm_pthreadSendToMix
 
CAThreadm_pthreadReadFromMix
 
CALastMixChannelListm_pChannelList
 
volatile bool m_bRunLog
 
volatile UINT32 m_logUploadedPackets
 
volatile UINT64 m_logUploadedBytes
 
volatile UINT32 m_logDownloadedPackets
 
volatile UINT64 m_logDownloadedBytes
 
- Protected Attributes inherited from CAMixWithReplayDB
CADatabasem_pReplayDB
 
CAReplayCtrlChannelMsgProcm_pReplayMsgProc
 
- Protected Attributes inherited from CAMix
volatile bool m_bLoop
 
bool m_bReconfiguring
 
volatile bool m_bShutDown
 
CAMultiSignaturem_pMultiSignature
 
CAInfoServicem_pInfoService
 
UINT32 m_u32KeepAliveRecvInterval
 
UINT32 m_u32KeepAliveSendInterval
 
bool m_acceptReconfiguration
 
volatile bool m_bConnected
 
volatile UINT32 m_lLastConnectionTime
 
XERCES_CPP_NAMESPACE::DOMDocument * m_docMixCascadeInfo
 
CAControlChannelDispatcherm_pMuxOutControlChannelDispatcher
 
CAControlChannelDispatcherm_pMuxInControlChannelDispatcher
 

Friends

THREAD_RETURN lm_loopSendToMix (void *param)
 How to end this thread: 0. More...
 
THREAD_RETURN lm_loopReadFromMix (void *pParam)
 
THREAD_RETURN lm_loopLog (void *)
 

Additional Inherited Members

- Public Types inherited from CAMix
enum  tMixType { FIRST_MIX , MIDDLE_MIX , LAST_MIX , JAP }
 
- Public Attributes inherited from CAMixWithReplayDB
UINT64 m_u64ReferenceTime
 
- Static Public Attributes inherited from CAMix
static const UINT32 TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT = 60000
 

Detailed Description

Definition at line 58 of file CALastMix.hpp.

Constructor & Destructor Documentation

◆ CALastMix()

CALastMix::CALastMix ( )
inline

Definition at line 66 of file CALastMix.hpp.

67  {
68  m_pMuxIn=NULL;
69  //m_pSignature=NULL;
70  m_pMultiSignature=NULL;
71  m_pRSA=NULL;
72  m_pInfoService=NULL;
73  #ifndef NEW_MIX_TYPE // not TypeB mixes
74  /* TypeB mixes are using an own implementation */
75  m_pChannelList=NULL;
76  #endif
82 
83  #ifdef LOG_PACKET_STATS
84  m_pLogPacketStats=NULL;
85  #endif
86  #ifdef LOG_CRIME
87  //OK lets try to use a regular expression for the task instead of a hand crafted parser...
88  const char* request_line_regexp="[\n\r]*([^ ]+)[ ]+([^ ]+)"; //
89  m_pregexpRequestLine=new tre_regex_t;
90  tre_regcomp(m_pregexpRequestLine,request_line_regexp,REG_EXTENDED );
91  // Regexp for Domain of URI
92  const char* uri_regexp="[^:]+[:][/][/]([^:/]+)"; //
93  m_pregexpDomainOfURI=new tre_regex_t;
94  tre_regcomp(m_pregexpDomainOfURI,uri_regexp,REG_EXTENDED );
95  m_pSquidLogHelper = NULL;
96  #endif
97  }
This class stores Addresses off different Cache-Proxies.
CAQueue * m_pQueueSendToMix
Definition: CALastMix.hpp:153
CACacheLoadBalancing * m_pVPNLB
Definition: CALastMix.hpp:160
CAASymCipher * m_pRSA
Definition: CALastMix.hpp:161
CALastMixChannelList * m_pChannelList
Definition: CALastMix.hpp:166
CAQueue * m_pQueueReadFromMix
Definition: CALastMix.hpp:154
CAThread * m_pthreadReadFromMix
Definition: CALastMix.hpp:163
CAThread * m_pthreadSendToMix
Definition: CALastMix.hpp:162
CACacheLoadBalancing * m_pCacheLB
Definition: CALastMix.hpp:158
CAMuxSocket * m_pMuxIn
Definition: CALastMix.hpp:152
CACacheLoadBalancing * m_pSocksLB
Definition: CALastMix.hpp:159
CAInfoService * m_pInfoService
Definition: CAMix.hpp:184
CAMultiSignature * m_pMultiSignature
Definition: CAMix.hpp:183

References m_pCacheLB, m_pChannelList, CAMix::m_pInfoService, CAMix::m_pMultiSignature, m_pMuxIn, m_pQueueReadFromMix, m_pQueueSendToMix, m_pRSA, m_pSocksLB, m_pthreadReadFromMix, m_pthreadSendToMix, and m_pVPNLB.

◆ ~CALastMix()

virtual CALastMix::~CALastMix ( )
inlinevirtual

Definition at line 99 of file CALastMix.hpp.

100  {
101  clean();
102  delete m_pCacheLB;
103  m_pCacheLB = NULL;
104  delete m_pSocksLB;
105  m_pSocksLB = NULL;
106  delete m_pVPNLB;
107  m_pVPNLB = NULL;
108 #ifdef LOG_CRIME
109  tre_regfree(m_pregexpRequestLine);
110  delete m_pregexpRequestLine;
111  tre_regfree(m_pregexpDomainOfURI);
112  delete m_pregexpDomainOfURI;
113 #endif
114  }
SINT32 clean()
Definition: CALastMix.cpp:1031

References clean(), m_pCacheLB, m_pSocksLB, and m_pVPNLB.

Here is the call graph for this function:

Member Function Documentation

◆ clean()

SINT32 CALastMix::clean ( )
protectedvirtual

Implements CAMix.

Definition at line 1031 of file CALastMix.cpp.

1032 {
1033 #ifdef LOG_CRIME
1034  if (m_pSquidLogHelper != NULL)
1035  {
1036  m_pSquidLogHelper->stop();
1037  delete m_pSquidLogHelper;
1038  m_pSquidLogHelper = NULL;
1039  }
1040 #endif
1041 
1042  m_bRestart=true;
1044  m_bRunLog=false;
1045 #ifdef REPLAY_DETECTION
1046  if(m_pReplayMsgProc!=NULL)
1047  {
1048  delete m_pReplayMsgProc;
1049  m_pReplayMsgProc = NULL;
1050  }
1051  m_pReplayMsgProc=NULL;
1052 #endif
1053 
1055  {
1058  }
1060 
1061  if(m_pMuxIn!=NULL)
1062  {
1063  m_pMuxIn->close();
1064  }
1065  //writing some bytes to the queue...
1066  if(m_pQueueSendToMix!=NULL)
1067  {
1068  UINT8 b[sizeof(tQueueEntry)+1];
1069  m_pQueueSendToMix->add(b,sizeof(tQueueEntry)+1);
1070  }
1071 
1072  if(m_pthreadSendToMix!=NULL)
1073  {
1074  CAMsg::printMsg(LOG_CRIT,"Wait for LoopSendToMix!\n");
1076  delete m_pthreadSendToMix;
1077  m_pthreadSendToMix = NULL;
1078  }
1079  m_pthreadSendToMix=NULL;
1080  if(m_pthreadReadFromMix!=NULL)
1081  {
1082  CAMsg::printMsg(LOG_CRIT,"Wait for LoopReadFromMix!\n");
1084  CAMsg::printMsg(LOG_CRIT, "Thread LoopReadFromMix joind successful!\n");
1085  delete m_pthreadReadFromMix;
1086  m_pthreadReadFromMix = NULL;
1087  }
1088  m_pthreadReadFromMix=NULL;
1089 
1090 #ifdef LOG_PACKET_TIMES
1091  CAMsg::printMsg(LOG_CRIT,"Wait for LoopLogPacketStats to terminate!\n");
1092  if(m_pLogPacketStats!=NULL)
1093  {
1094  m_pLogPacketStats->stop();
1095  delete m_pLogPacketStats;
1096  m_pLogPacketStats = NULL;
1097  }
1098  m_pLogPacketStats=NULL;
1099 #endif
1100  if(m_pChannelList!=NULL)
1101  {
1102  lmChannelListEntry* pChannelListEntry=m_pChannelList->getFirstSocket();
1103  while(pChannelListEntry!=NULL)
1104  {
1105  delete pChannelListEntry->pCipher;
1106  pChannelListEntry->pCipher = NULL;
1107  delete pChannelListEntry->pQueueSend;
1108  pChannelListEntry->pQueueSend = NULL;
1109  if (pChannelListEntry->pSocket != NULL)
1110  {
1111  pChannelListEntry->pSocket->close();
1112  delete pChannelListEntry->pSocket;
1113  pChannelListEntry->pSocket = NULL;
1114  }
1115  pChannelListEntry=m_pChannelList->getNextSocket();
1116  }
1117  }
1118  delete m_pQueueReadFromMix;
1119  m_pQueueReadFromMix = NULL;
1120  delete m_pQueueSendToMix;
1121  m_pQueueSendToMix = NULL;
1122  #ifndef NEW_MIX_TYPE // not TypeB mixes
1123  /* TypeB mixes are using an own implementation */
1124  delete m_pChannelList;
1125  m_pChannelList = NULL;
1126  if(m_pMuxIn != NULL)
1127  {
1128  m_pMuxIn->close();
1129  delete m_pMuxIn;
1130  m_pMuxIn=NULL;
1131  }
1132 
1133  delete m_pRSA;
1134  m_pRSA = NULL;
1135  #endif
1136  CAMsg::printMsg(LOG_CRIT, "LastMix:clean() finished!\n");
1137  return E_SUCCESS;
1138  }
#define MONITORING_FIRE_NET_EVENT(e_type)
unsigned char UINT8
Definition: basetypedefs.h:135
lmChannelListEntry * getFirstSocket()
lmChannelListEntry * getNextSocket()
volatile bool m_bRunLog
Definition: CALastMix.hpp:189
volatile bool m_bRestart
Definition: CALastMix.hpp:151
CAControlChannelDispatcher * m_pMuxInControlChannelDispatcher
Definition: CAMix.hpp:196
CAReplayCtrlChannelMsgProc * m_pReplayMsgProc
static SINT32 printMsg(UINT32 typ, const char *format,...)
Writes a given message to the log.
Definition: CAMsg.cpp:251
SINT32 close()
Closes the underlying socket.
SINT32 add(const void *buff, UINT32 size)
Adds data to the Queue.
Definition: CAQueue.cpp:76
virtual SINT32 close()
Definition: CASocket.cpp:351
SINT32 join()
Waits for the main function to finish execution.
Definition: CAThread.cpp:187
const SINT32 E_SUCCESS
Definition: errorcodes.hpp:2
@ ev_net_prevConnectionClosed
CASymChannelCipher * pCipher
Definition: typedefs.hpp:169
struct t_queue_entry tQueueEntry
Definition: typedefs.hpp:188

References CAQueue::add(), CAMuxSocket::close(), CASocket::close(), E_SUCCESS, ev_net_prevConnectionClosed, CALastMixChannelList::getFirstSocket(), CALastMixChannelList::getNextSocket(), CAThread::join(), m_bRestart, m_bRunLog, m_pChannelList, m_pMuxIn, CAMix::m_pMuxInControlChannelDispatcher, m_pQueueReadFromMix, m_pQueueSendToMix, CAMixWithReplayDB::m_pReplayMsgProc, m_pRSA, m_pthreadReadFromMix, m_pthreadSendToMix, MONITORING_FIRE_NET_EVENT, t_lastmixchannellist::pCipher, t_lastmixchannellist::pQueueSend, CAMsg::printMsg(), and t_lastmixchannellist::pSocket.

Referenced by CALastMixA::loop(), and ~CALastMix().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getType()

tMixType CALastMix::getType ( ) const
inlinevirtual

Implements CAMix.

Definition at line 117 of file CALastMix.hpp.

118  {
119  return CAMix::LAST_MIX;
120  }
@ LAST_MIX
Definition: CAMix.hpp:55

References CAMix::LAST_MIX.

◆ init()

SINT32 CALastMix::init ( )
protectedvirtual

Implements CAMix.

Definition at line 84 of file CALastMix.cpp.

85  {
86  m_pRSA=new CAASymCipher();
87 #ifdef EXPORT_ASYM_PRIVATE_KEY
88  if(CALibProxytest::getOptions()->isImportKey())
89  {
90  UINT32 keyFileBuffLen=8096;
91  UINT8* keyFileBuff=new UINT8[keyFileBuffLen];
92  CALibProxytest::getOptions()->getEncryptionKeyImportFile(keyFileBuff,keyFileBuffLen);
93  UINT8* keyBuff=readFile(keyFileBuff,&keyFileBuffLen);
94  m_pRSA->setPrivateKeyAsXML(keyBuff,keyFileBuffLen);
95  delete[] keyFileBuff;
96  delete[] keyBuff;
97  }
98  else
99 #endif
100  {
101  if(m_pRSA->generateKeyPair(1024)!=E_SUCCESS)
102  {
103  CAMsg::printMsg(LOG_CRIT,"Could not generate a valid key pair\n");
104  return E_UNKNOWN;
105  }
106  }
107 #ifdef EXPORT_ASYM_PRIVATE_KEY
108  if(CALibProxytest::getOptions()->isExportKey())
109  {
110  UINT32 keyFileBuffLen=8096;
111  UINT8* keyFileBuff=new UINT8[keyFileBuffLen];
112  UINT8* keyBuff=new UINT8[keyFileBuffLen];
113  CALibProxytest::getOptions()->getEncryptionKeyExportFile(keyFileBuff,keyFileBuffLen);
114  m_pRSA->getPrivateKeyAsXML(keyBuff,&keyFileBuffLen);
115  saveFile(keyFileBuff,keyBuff,keyFileBuffLen);
116  delete[] keyFileBuff;
117  delete[] keyBuff;
118  }
119 #endif
120 
121  CAListenerInterface* pListener=NULL;
123  for(UINT32 i=1;i<=interfaces;i++)
124  {
126  if(!pListener->isVirtual())
127  break;
128  delete pListener;
129  pListener=NULL;
130  }
131  if(pListener==NULL)
132  {
133  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");
134  return E_UNKNOWN;
135  }
136 
137  const CASocketAddr* pAddr=NULL;
138  pAddr=pListener->getAddr();
139  delete pListener;
140  pListener = NULL;
141  UINT8 buff[255];
142  pAddr->toString(buff,255);
143 
144  CAMsg::printMsg(LOG_INFO,"Waiting for connection from previous Mix on %s...\n", buff);
145 
146  m_pMuxIn=new CAMuxSocket(OFB);
147  SINT32 ret=m_pMuxIn->accept(*pAddr);
148 #ifdef __BUILD_AS_SHADOW_PLUGIN__
150 #endif
151  delete pAddr;
152  pAddr = NULL;
153  if(ret!=E_SUCCESS)
154  {
155  CAMsg::printMsg(LOG_CRIT,"Initialization failed! Reason: Call to accept() failed with error '%s' (%i)\n",
157  return ret;
158  }
159  // connected to previous mix
163 
165  CAMsg::printMsg(LOG_INFO,"connected!\n");
166 
167 #ifdef LOG_CRIME
168  m_nCrimeRegExpsURL=0;
169  m_pCrimeRegExpsURL=CALibProxytest::getOptions()->getCrimeRegExpsURL(&m_nCrimeRegExpsURL);
170  m_nCrimeRegExpsPayload = 0;
171  m_pCrimeRegExpsPayload = CALibProxytest::getOptions()->getCrimeRegExpsPayload(&m_nCrimeRegExpsPayload);
172  m_pSquidLogHelper = new CASquidLogHelper(this,1);
173  if (m_pSquidLogHelper->start()!=E_SUCCESS)
174  {
175  CAMsg::printMsg(LOG_ERR, "Could not start SquidLogHelper!\n");
176  return E_UNKNOWN;
177  }
178 
179 #endif
180  ret=processKeyExchange();
181  if(ret!=E_SUCCESS)
182  {
184  return ret;
185  }
187  //keyexchange successful
188 #ifdef REPLAY_DETECTION
189  m_pReplayDB=new CADatabase();
190  m_pReplayDB->start();
191 #endif
194 
196 #ifdef REPLAY_DETECTION
199  m_u64ReferenceTime=time(NULL);
200 #endif
201 
202  m_bRestart=false;
203  //Starting thread for Step 1a
204  m_pthreadReadFromMix=new CAThread((UINT8*)"CALastMix - ReadFromMix");
207 
208  //Starting thread for Step 4
209  m_pthreadSendToMix=new CAThread((UINT8*)"CALastMix - SendToMix");
211  m_pthreadSendToMix->start(this);
212 
213  //Starting thread for logging
214 #ifdef LOG_PACKET_TIMES
215  m_pLogPacketStats=new CALogPacketStats();
216  m_pLogPacketStats->setLogIntervallInMinutes(LM_PACKET_STATS_LOG_INTERVALL);
217  m_pLogPacketStats->start();
218 #endif
219  #ifndef NEW_MIX_TYPE // not TypeB mixes
220  /* TypeB mixes are using an own implementation */
222  #endif
223  return E_SUCCESS;
224  }
UINT8 * readFile(const UINT8 *const name, UINT32 *size)
ONLY_LOCAL_PROXY or first.
Definition: CAUtil.cpp:1330
SINT32 saveFile(const UINT8 *const name, const UINT8 *const buff, UINT32 buffSize)
Definition: CAUtil.cpp:1352
#define LM_PACKET_STATS_LOG_INTERVALL
Definition: StdAfx.h:249
#define GET_NET_ERROR
Definition: StdAfx.h:469
#define GET_NET_ERROR_STR(x)
Definition: StdAfx.h:471
#define REPLAY_TIMESTAMP_PROPAGATION_INTERVALL
Definition: StdAfx.h:176
signed int SINT32
Definition: basetypedefs.h:132
unsigned int UINT32
Definition: basetypedefs.h:131
SINT32 generateKeyPair(UINT32 size)
Generates a new random key-pair of size bits.
UINT32 getListenerInterfaceCount()
CAListenerInterface * getListenerInterface(UINT32 nr)
This class "dispatches" messages which it receives via proccessMixPacket() to the associated control ...
SINT32 start()
Definition: CADatabase.cpp:220
friend THREAD_RETURN lm_loopReadFromMix(void *pParam)
Definition: CALastMix.cpp:731
virtual SINT32 processKeyExchange()
Processes the startup communication with the preceeding mix.
Definition: CALastMix.cpp:236
friend THREAD_RETURN lm_loopSendToMix(void *param)
How to end this thread: 0.
Definition: CALastMix.cpp:623
static CACmdLnOptions * getOptions()
CASocketAddr * getAddr() const
CADatabase * m_pReplayDB
SINT32 accept(UINT16 port)
CASocket * getCASocket()
Definition: CAMuxSocket.hpp:84
This is a simple FIFO-Queue.
Definition: CAQueue.hpp:50
SINT32 startTimeStampPorpagation(UINT32 minutesPropagationIntervall)
Sends the current replay timestamp periodically on the downstream replay control channel.
This is an abstract class for representing a socket address used in CASocket, CADatagramSocket and CA...
virtual SINT32 toString(UINT8 *buff, UINT32 bufflen) const =0
Returns a string which describes this address in a human readable form.
virtual SINT32 setKeepAlive(bool b)
Enables/disables the socket keep-alive option.
Definition: CASocket.cpp:906
virtual SINT32 setRecvBuff(UINT32 r)
Definition: CASocket.cpp:846
virtual SINT32 setNonBlocking(bool b)
Definition: CASocket.cpp:947
virtual SINT32 setSendBuff(SINT32 r)
Returns < 0 on error, otherwise the new sendbuffersize (which may be less than r)
Definition: CASocket.cpp:862
SINT32 start(void *param, bool bDaemon=false, bool bSilent=false)
Starts the execution of the main function of this thread.
Definition: CAThread.cpp:115
SINT32 setMainLoop(THREAD_MAIN_TYP fnc)
Sets the main function which will be executed within this thread.
Definition: CAThread.hpp:148
#define E_UNKNOWN
Definition: errorcodes.hpp:3
@ ev_net_keyExchangePrevSuccessful
@ ev_net_keyExchangePrevFailed
@ ev_net_prevConnected
#define MIXPACKET_SIZE
Definition: typedefs.hpp:40

References CAMuxSocket::accept(), E_SUCCESS, E_UNKNOWN, ev_net_keyExchangePrevFailed, ev_net_prevConnected, CAASymCipher::generateKeyPair(), GET_NET_ERROR, GET_NET_ERROR_STR, CAListenerInterface::getAddr(), CAMuxSocket::getCASocket(), CACmdLnOptions::getListenerInterface(), CACmdLnOptions::getListenerInterfaceCount(), CALibProxytest::getOptions(), CAListenerInterface::isVirtual(), m_pMuxIn, m_pRSA, MIXPACKET_SIZE, MONITORING_FIRE_NET_EVENT, OFB, CAMsg::printMsg(), processKeyExchange(), readFile(), saveFile(), CASocket::setKeepAlive(), CASocket::setNonBlocking(), CASocket::setRecvBuff(), CASocket::setSendBuff(), and CASocketAddr::toString().

Here is the call graph for this function:

◆ initMixCascadeInfo()

SINT32 CALastMix::initMixCascadeInfo ( DOMElement *  mixes)
protectedvirtual

This will initialize the XML Cascade Info struct XMLFirstMixToInfoService that is sent to the InfoService in CAInfoService::sendCascadeHelo()

Parameters
mixesthe <Mixes> element of the XML struct we received from the succeeding mix.
Return values
E_UNKNOWNif processing produces an error
E_SUCCESSotherwise

Reimplemented from CAMix.

Definition at line 1140 of file CALastMix.cpp.

1141 {
1142  SINT32 r = CAMix::initMixCascadeInfo(mixes);
1143  DOMElement* cascade = m_docMixCascadeInfo->getDocumentElement();
1144  setDOMElementAttribute(cascade,"create",(UINT8*)"true");
1145  return r;
1146 }
SINT32 setDOMElementAttribute(DOMNode *pElem, const char *attrName, const char *value)
Definition: CAUtil.cpp:831
virtual SINT32 initMixCascadeInfo(DOMElement *elemMixes)
This will initialize the XML Cascade Info struct XMLFirstMixToInfoService that is sent to the InfoSer...
Definition: CAMix.cpp:299
XERCES_CPP_NAMESPACE::DOMDocument * m_docMixCascadeInfo
Definition: CAMix.hpp:193

References CAMix::initMixCascadeInfo(), CAMix::m_docMixCascadeInfo, and setDOMElementAttribute().

Referenced by initOnce().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ initOnce()

SINT32 CALastMix::initOnce ( )
protectedvirtual

TODO: Check what is done her and if this is important for any last mix or only in case of dynamic mixes...

Reimplemented from CAMix.

Definition at line 56 of file CALastMix.cpp.

57  {
58  SINT32 ret=CAMix::initOnce();
59  if(ret!=E_SUCCESS)
60  return ret;
61  if(setTargets()!=E_SUCCESS)
62  {
63  CAMsg::printMsg(LOG_CRIT,"Could not set Targets (proxies)!\n");
64  return E_UNKNOWN;
65  }
66 
67  //m_pSignature=CALibProxytest::getOptions()->getSignKey();
69  if(m_pMultiSignature==NULL)
70  return E_UNKNOWN;
71  if(CALibProxytest::getOptions()->getListenerInterfaceCount()<1)
72  {
73  CAMsg::printMsg(LOG_CRIT,"No ListenerInterfaces specified!\n");
74  return E_UNKNOWN;
75  }
76 #ifndef INCLUDE_LAST_MIX
78  if(CALibProxytest::getOptions()->getCascadeXML() != NULL)
80 #endif
81  return E_SUCCESS;
82  }
CAMultiSignature * getMultiSigner()
SINT32 initMixCascadeInfo(DOMElement *)
This will initialize the XML Cascade Info struct XMLFirstMixToInfoService that is sent to the InfoSer...
Definition: CALastMix.cpp:1140
SINT32 setTargets()
Reads the configured proxies from options.
Definition: CALastMix.cpp:971
virtual SINT32 initOnce()
Definition: CAMix.cpp:78

References E_SUCCESS, E_UNKNOWN, CACmdLnOptions::getMultiSigner(), CALibProxytest::getOptions(), initMixCascadeInfo(), CAMix::initOnce(), CAMix::m_pMultiSignature, CAMsg::printMsg(), and setTargets().

Here is the call graph for this function:

◆ loop()

virtual SINT32 CALastMix::loop ( )
protectedpure virtual

Implements CAMix.

Implemented in CALastMixB, and CALastMixA.

◆ processKeyExchange()

SINT32 CALastMix::processKeyExchange ( )
protectedvirtual

Processes the startup communication with the preceeding mix.

  • Step 1: Mix n-1 open a TCP/IP Connection
  • Step 2: LastMix sends XML struct describing itself, containing PubKey of LastMix, signed by LastMix (see XML structs)
  • Step 3: Mix n-1 sends XML struct containing encrpyted (with PubKey) Symetric Key used for interlink encryption between Mix n-1 <—> LastMix, signed by Mix n-1 (see XML structs)

Getting and calculating the KeepAlive Traffice...

Implements CAMix.

Definition at line 236 of file CALastMix.cpp.

237  {
238  XERCES_CPP_NAMESPACE::DOMDocument* doc=createDOMDocument();
239  DOMElement* elemMixes=createDOMElement(doc,"Mixes");
240  setDOMElementAttribute(elemMixes,"count",(UINT32)1);
241  //UINT8 cName[128];
242  //CALibProxytest::getOptions()->getCascadeName(cName,128);
243  //setDOMElementAttribute(elemMixes,"cascadeName",cName);
244  doc->appendChild(elemMixes);
245 
246  addMixInfo(elemMixes, false);
247  DOMElement* elemMix=NULL;
248  getDOMChildByName(elemMixes, "Mix", elemMix, false);
249 
250  //Inserting MixProtocol Version
251  // Version 0.3 - "normal", initial mix protocol
252  // Version 0.4 - with new flow control [was only used for tests]
253  // Version 0.5 - end-to-end 1:n channels (only between client and last mix)
254  // Version 0.6 - with new flow control for downstream [productive]
255  // Version 0.7 - with new flow control for downstream AND upstream
256  DOMElement* elemMixProtocolVersion=createDOMElement(doc,"MixProtocolVersion");
257  elemMix->appendChild(elemMixProtocolVersion);
258  #ifdef NEW_MIX_TYPE // TypeB mixes
259  setDOMElementValue(elemMixProtocolVersion,(UINT8*)"0.5");
260  DOM_Element elemDownstreamPackets = doc.createElement("DownstreamPackets");
261  setDOMElementValue(elemDownstreamPackets, (UINT32)CHANNEL_DOWNSTREAM_PACKETS);
262  elemMixProtocolVersion.appendChild(elemDownstreamPackets);
263  DOM_Element elemChannelTimeout = doc.createElement("ChannelTimeout");
264  /* let the client use our channel-timeout + 5 seconds */
265  setDOMElementValue(elemChannelTimeout, (UINT32)(CHANNEL_TIMEOUT + 5));
266  elemMixProtocolVersion.appendChild(elemChannelTimeout);
267  DOM_Element elemChainTimeout = doc.createElement("ChainTimeout");
268  /* let the client use our chain-timeout - 5 seconds */
269  setDOMElementValue(elemChainTimeout, (UINT32)(CHAIN_TIMEOUT - 5));
270  elemMixProtocolVersion.appendChild(elemChainTimeout);
271  #else
272  setDOMElementValue(elemMixProtocolVersion,(UINT8*)"0.6");
273  DOMElement* elemFlowControl=createDOMElement(doc,"FlowControl");
274  DOMElement* elemUpstreamSendMe=createDOMElement(doc,"UpstreamSendMe");
275  DOMElement* elemDownstreamSendMe=createDOMElement(doc,"DownstreamSendMe");
276  elemMix->appendChild(elemFlowControl);
277  elemFlowControl->appendChild(elemUpstreamSendMe);
278  elemFlowControl->appendChild(elemDownstreamSendMe);
281  setDOMElementAttribute(elemFlowControl,"withUpstreamFlowControl",true);
282  #endif
283  //Inserting RSA-Key
284  DOMElement* nodeRsaKey=NULL;
285  m_pRSA->getPublicKeyAsDOMElement(nodeRsaKey,doc);
286  elemMix->appendChild(nodeRsaKey);
287 
288  appendCompatibilityInfo(elemMix);
289 
290  //inserting Nonce
291  DOMElement* elemNonce=createDOMElement(doc,"Nonce");
292  UINT8 arNonce[16];
293  getRandom(arNonce,16);
294  UINT8 tmpBuff[50];
295  UINT32 tmpLen=50;
296  CABase64::encode(arNonce,16,tmpBuff,&tmpLen);
297  tmpBuff[tmpLen]=0;
298  setDOMElementValue(elemNonce,tmpBuff);
299  elemMix->appendChild(elemNonce);
300 
301 
302 
303 // Add Info about KeepAlive traffic
304  DOMElement* elemKeepAlive=NULL;
305  UINT32 u32KeepAliveSendInterval=CALibProxytest::getOptions()->getKeepAliveSendInterval();
306  UINT32 u32KeepAliveRecvInterval=CALibProxytest::getOptions()->getKeepAliveRecvInterval();
307  elemKeepAlive=createDOMElement(doc,"KeepAlive");
308  DOMElement* elemKeepAliveSendInterval=NULL;
309  DOMElement* elemKeepAliveRecvInterval=NULL;
310  elemKeepAliveSendInterval=createDOMElement(doc,"SendInterval");
311  elemKeepAliveRecvInterval=createDOMElement(doc,"ReceiveInterval");
312  elemKeepAlive->appendChild(elemKeepAliveSendInterval);
313  elemKeepAlive->appendChild(elemKeepAliveRecvInterval);
314  setDOMElementValue(elemKeepAliveSendInterval,u32KeepAliveSendInterval);
315  setDOMElementValue(elemKeepAliveRecvInterval,u32KeepAliveRecvInterval);
316  elemMix->appendChild(elemKeepAlive);
317 
318  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Offering -- SendInterval %u -- Receive Interval %u\n",u32KeepAliveSendInterval,u32KeepAliveRecvInterval);
319 
320 #ifdef PAYMENT
321  /* append the terms and conditions, if there are any, to the KeyInfo
322  * Extensions, (nodes that can be removed from the KeyInfo without
323  * destroying the signature of the "Mix"-node).
324  */
325  if(CALibProxytest::getOptions()->getTermsAndConditions() != NULL)
326  {
327  appendTermsAndConditionsExtension(doc, elemMixes);
328  elemMix->appendChild(termsAndConditionsInfoNode(doc));
329  }
330 #endif
331 
332  // create signature
333  if (signXML(elemMix) != E_SUCCESS)
334  {
335  CAMsg::printMsg(LOG_DEBUG,"Could not sign KeyInfo sent to users...\n");
336  }
337 
338  UINT32 len=0;
339  UINT8* messageBuff=DOM_Output::dumpToMem(doc,&len);
340  if (doc != NULL)
341  {
342  doc->release();
343  doc = NULL;
344  }
345  UINT32 tmp = htonl(len);
346  CAMsg::printMsg(LOG_INFO,"Sending Infos (chain length and RSA-Key, Message-Size %u)\n",len);
347 
348  if (len > 100000)
349  {
350  CAMsg::printMsg(LOG_WARNING,"Unrealistic length for key info: %u We might not be able to get a connection.\n",len);
351  }
352 
353  if( (m_pMuxIn->getCASocket()->send((UINT8*)&tmp, sizeof(tmp)) != sizeof(tmp)) ||
354  m_pMuxIn->getCASocket()->send(messageBuff,len)!=(SINT32)len)
355  {
356  CAMsg::printMsg(LOG_ERR,"Error sending Key-Info!\n");
357  delete []messageBuff;
358  messageBuff = NULL;
359  return E_UNKNOWN;
360  }
361  delete[] messageBuff;
362  messageBuff = NULL;
363 
364  SINT32 ret;
365  //Now receiving the symmetric key
366  CAMsg::printMsg(LOG_INFO,"Waiting for length of symmetric key from previous Mix...\n");
367 #ifdef __BUILD_AS_SHADOW_PLUGIN__
368  if ((ret = m_pMuxIn->receiveFully((UINT8*)&tmp, sizeof(tmp))) != E_SUCCESS)
369 #else
370  if((ret = m_pMuxIn->receiveFully((UINT8*) &tmp, sizeof(tmp), TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT)) != E_SUCCESS)
371 #endif
372  {
373  if (ret != E_UNKNOWN)
374  {
375  CAMsg::printMsg(LOG_CRIT,"Error receiving symmetric key info length! Reason: '%s' (%i)\n",
377  }
378  else
379  {
380  CAMsg::printMsg(LOG_CRIT,"Error receiving symmetric key info length!\n");
381  }
382  return ret;
383  }
384  len = ntohl(tmp);
385 
386  if (len > 100000)
387  {
388  CAMsg::printMsg(LOG_WARNING,"Unrealistic length for key info: %u We might not be able to get a connection.\n",len);
389  }
390 
391  messageBuff=new UINT8[len+1]; //+1 for the closing Zero
392  CAMsg::printMsg(LOG_INFO,"Waiting for symmetric key from previous Mix with length %i...\n", len);
394  {
395  if (ret != E_UNKNOWN)
396  {
397  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",
399  }
400  else
401  {
402  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");
403  }
404  delete []messageBuff;
405  messageBuff = NULL;
406  return ret;
407  }
408  messageBuff[len]=0;
409  CAMsg::printMsg(LOG_INFO,"Symmetric Key Info received from previous mix is:\n");
410  CAMsg::printMsg(LOG_INFO,"%s\n",(char*)messageBuff);
411  //get document
412  doc=parseDOMDocument(messageBuff,len);
413  if(doc == NULL)
414  {
415  CAMsg::printMsg(LOG_CRIT,"Could not parse symmetric key of the previous mix!\n");
416  delete []messageBuff;
417  messageBuff = NULL;
418  return E_UNKNOWN;
419  }
420  DOMElement* elemRoot=doc->getDocumentElement();
421  if(elemRoot == NULL)
422  {
423  CAMsg::printMsg(LOG_CRIT,"Symmetric key XML structure of previous mix is invalid!\n");
424  delete []messageBuff;
425  messageBuff = NULL;
426  if (doc != NULL)
427  {
428  doc->release();
429  doc = NULL;
430  }
431  return E_UNKNOWN;
432  }
433  //verify certificate from previous mix if enabled
434  if(CALibProxytest::getOptions()->verifyMixCertificates())
435  {
437  if(prevMixCert != NULL)
438  {
439  CAMsg::printMsg(LOG_DEBUG, "Previous mix certificate was verified by a trusted root CA.\n");
441  }
442  else
443  {
444  CAMsg::printMsg(LOG_ERR, "Could not verify certificate received from previous mix!\n");
445  return E_UNKNOWN;
446  }
447  }
448  //verify signature
449  //CASignature oSig;
451  SINT32 result = CAMultiSignature::verifyXML(messageBuff, len, pCert);
452  //oSig.setVerifyKey(pCert);
453  delete pCert;
454  pCert = NULL;
455  //if(oSig.verifyXML(messageBuff,len)!=E_SUCCESS)
456  if(result != E_SUCCESS)
457  {
458  CAMsg::printMsg(LOG_CRIT,"Could not verify the symmetric key!\n");
459  delete []messageBuff;
460  messageBuff = NULL;
461  return E_UNKNOWN;
462  }
463 
464  if ((result = checkCompatibility(elemRoot, "previous")) != E_SUCCESS)
465  {
466  delete []messageBuff;
467  messageBuff = NULL;
468  if (doc != NULL)
469  {
470  doc->release();
471  doc = NULL;
472  }
473  return result;
474  }
475 
476 
477  elemNonce=NULL;
478  getDOMChildByName(elemRoot,"Nonce",elemNonce,false);
479  tmpLen=50;
480  memset(tmpBuff,0,tmpLen);
481  if(elemNonce==NULL||getDOMElementValue(elemNonce,tmpBuff,&tmpLen)!=E_SUCCESS||
482  CABase64::decode(tmpBuff,tmpLen,tmpBuff,&tmpLen)!=E_SUCCESS||
483  tmpLen!=SHA_DIGEST_LENGTH ||
484  memcmp(SHA1(arNonce,16,NULL),tmpBuff,SHA_DIGEST_LENGTH)!=0
485  )
486  {
487  CAMsg::printMsg(LOG_CRIT,"Could not verify the nonce from previous mix!\n");
488  delete []messageBuff;
489  messageBuff = NULL;
490  if (doc != NULL)
491  {
492  doc->release();
493  doc = NULL;
494  }
495  return E_UNKNOWN;
496  }
497  CAMsg::printMsg(LOG_INFO,"Verified the symmetric key from previous mix!\n");
498 
499  UINT8 key[150];
500  UINT32 keySize=150;
501  ret=decodeXMLEncryptedKey(key,&keySize,messageBuff,len,m_pRSA);
502  delete []messageBuff;
503  messageBuff = NULL;
504  if(ret!=E_SUCCESS||keySize!=64)
505  {
506  CAMsg::printMsg(LOG_CRIT,"Could not decrypt the symmetric key from previous mix!\n");
507  if (doc != NULL)
508  {
509  doc->release();
510  doc = NULL;
511  }
512  return E_UNKNOWN;
513  }
514  if(m_pMuxIn->setReceiveKey(key,32)!=E_SUCCESS||m_pMuxIn->setSendKey(key+32,32)!=E_SUCCESS)
515  {
516  CAMsg::printMsg(LOG_CRIT,"Could not set the symmetric key to be used by the MuxSocket!\n");
517  if (doc != NULL)
518  {
519  doc->release();
520  doc = NULL;
521  }
522  return E_UNKNOWN;
523  }
524  m_pMuxIn->setCrypt(true);
526  elemKeepAlive=NULL;
527  elemKeepAliveSendInterval=NULL;
528  elemKeepAliveRecvInterval=NULL;
529  getDOMChildByName(elemRoot,"KeepAlive",elemKeepAlive);
530  getDOMChildByName(elemKeepAlive,"SendInterval",elemKeepAliveSendInterval);
531  getDOMChildByName(elemKeepAlive,"ReceiveInterval",elemKeepAliveRecvInterval);
532  UINT32 tmpSendInterval,tmpRecvInterval;
533  getDOMElementValue(elemKeepAliveSendInterval,tmpSendInterval,0xFFFFFFFF); //if now send interval was given set it to "infinite"
534  getDOMElementValue(elemKeepAliveRecvInterval,tmpRecvInterval,0xFFFFFFFF); //if no recv interval was given --> set it to "infinite"
535  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Getting offer -- SendInterval %u -- Receive Interval %u\n",tmpSendInterval,tmpRecvInterval);
536  m_u32KeepAliveSendInterval = u32KeepAliveSendInterval;
537  if (m_u32KeepAliveSendInterval > tmpRecvInterval - 10000)
538  m_u32KeepAliveSendInterval-=10000; //make the send interval a little bit smaller than the related receive interval
539  m_u32KeepAliveRecvInterval=max(u32KeepAliveRecvInterval,tmpSendInterval);
540  if (m_u32KeepAliveRecvInterval - 10000 < tmpSendInterval)
541  {
543  }
544  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Calculated -- SendInterval %u -- Receive Interval %u\n",m_u32KeepAliveSendInterval,m_u32KeepAliveRecvInterval);
545 
546  if (doc != NULL)
547  {
548  doc->release();
549  doc = NULL;
550  }
551 
552  return E_SUCCESS;
553  }
SINT32 getDOMElementValue(const DOMNode *const pElem, UINT8 *value, UINT32 *valuelen)
Returns the content of the text node(s) under elem as null-terminated C String.
Definition: CAUtil.cpp:746
SINT32 setDOMElementValue(DOMElement *pElem, SINT32 value)
Definition: CAUtil.cpp:939
XERCES_CPP_NAMESPACE::DOMDocument * parseDOMDocument(const UINT8 *const buff, UINT32 len)
Parses a buffer containing an XML document and returns this document.
Definition: CAUtil.cpp:663
SINT32 getRandom(UINT32 *val)
Gets 32 random bits.
Definition: CAUtil.cpp:346
XERCES_CPP_NAMESPACE::DOMDocument * createDOMDocument()
Parses a timestamp in JDBC timestamp escape format (as it comes from the BI) and outputs the value in...
Definition: CAUtil.cpp:1568
DOMElement * createDOMElement(XERCES_CPP_NAMESPACE::DOMDocument *pOwnerDoc, const char *const name)
Creates a new DOMElement with the given name which belongs to the DOMDocument owernDoc.
Definition: CAUtil.cpp:814
SINT32 getDOMChildByName(const DOMNode *pNode, const char *const name, DOMElement *&child, bool deep)
Definition: CAUtil.cpp:458
SINT32 decodeXMLEncryptedKey(UINT8 *key, UINT32 *keylen, const UINT8 *const xml, UINT32 xmllen, CAASymCipher *pRSA)
Definition: CAUtil.cpp:1625
#define FLOW_CONTROL_SENDME_SOFT_LIMIT
Definition: StdAfx.h:223
#define max(a, b)
Definition: StdAfx.h:654
SINT32 getPublicKeyAsDOMElement(DOMElement *&elemRoot, XERCES_CPP_NAMESPACE::DOMDocument *docOwner)
static SINT32 encode(const UINT8 *in, UINT32 len, UINT8 *out, UINT32 *outlen)
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff...
Definition: CABase64.cpp:102
static SINT32 decode(const UINT8 *in, UINT32 len, UINT8 *out, UINT32 *outlen)
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff...
Definition: CABase64.cpp:41
CACertificate * verifyMixCert(DOMNode *mixNode)
This function parses the certificates from a <Mix>-node and tries to build a certPath to the trusted ...
SINT32 setPrevMixTestCertificate(CACertificate *cert)
UINT32 getKeepAliveRecvInterval()
UINT32 getKeepAliveSendInterval()
CACertStore * getTrustedCertificateStore()
CACertificate * getPrevMixTestCertificate()
SINT32 appendCompatibilityInfo(DOMNode *a_parent)
Definition: CAMix.cpp:634
SINT32 checkCompatibility(DOMNode *a_parent, const char *a_mixPosition)
Definition: CAMix.cpp:670
SINT32 signXML(DOMNode *a_element)
Definition: CAMix.cpp:806
static const UINT32 TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT
Definition: CAMix.hpp:59
SINT32 addMixInfo(DOMNode *a_element, bool a_bForceFirstNode)
Definition: CAMix.cpp:437
UINT32 m_u32KeepAliveRecvInterval
Definition: CAMix.hpp:186
UINT32 m_u32KeepAliveSendInterval
Definition: CAMix.hpp:187
static SINT32 verifyXML(const UINT8 *const in, UINT32 inlen, CACertificate *a_cert)
SINT32 setSendKey(UINT8 *key, UINT32 keyLen)
SINT32 setReceiveKey(UINT8 *key, UINT32 keyLen)
SINT32 setCrypt(bool b)
SINT32 receiveFully(UINT8 *buff, UINT32 len)
Receives some "plain" bytes from the underlying socket - just a convenient function....
Definition: CAMuxSocket.hpp:69
virtual SINT32 send(const UINT8 *buff, UINT32 len)
Sends some data over the network.
Definition: CASocket.cpp:400
static SINT32 dumpToMem(const DOMNode *node, UINT8 *buff, UINT32 *size)
Dumps the node and all childs into buff.
Definition: DOM_Output.hpp:161
UINT16 len
Definition: typedefs.hpp:0
#define CHAIN_TIMEOUT
Definition: typedefsb.hpp:37
#define CHANNEL_TIMEOUT
Definition: typedefsb.hpp:36
#define CHANNEL_DOWNSTREAM_PACKETS
Definition: typedefsb.hpp:35

References CAMix::addMixInfo(), CAMix::appendCompatibilityInfo(), CHAIN_TIMEOUT, CHANNEL_DOWNSTREAM_PACKETS, CHANNEL_TIMEOUT, CAMix::checkCompatibility(), createDOMDocument(), createDOMElement(), CABase64::decode(), decodeXMLEncryptedKey(), DOM_Output::dumpToMem(), E_SUCCESS, E_UNKNOWN, CABase64::encode(), FLOW_CONTROL_SENDME_SOFT_LIMIT, GET_NET_ERROR, GET_NET_ERROR_STR, CAMuxSocket::getCASocket(), getDOMChildByName(), getDOMElementValue(), CACmdLnOptions::getKeepAliveRecvInterval(), CACmdLnOptions::getKeepAliveSendInterval(), CALibProxytest::getOptions(), CACmdLnOptions::getPrevMixTestCertificate(), CAASymCipher::getPublicKeyAsDOMElement(), getRandom(), CACmdLnOptions::getTrustedCertificateStore(), len, m_pMuxIn, m_pRSA, CAMix::m_u32KeepAliveRecvInterval, CAMix::m_u32KeepAliveSendInterval, max, parseDOMDocument(), CAMsg::printMsg(), CAMuxSocket::receiveFully(), CASocket::send(), CAMuxSocket::setCrypt(), setDOMElementAttribute(), setDOMElementValue(), CACmdLnOptions::setPrevMixTestCertificate(), CAMuxSocket::setReceiveKey(), CAMuxSocket::setSendKey(), CAMix::signXML(), CAMix::TIMEOUT_MIX_CONNECTION_ESTABLISHEMENT, CACertStore::verifyMixCert(), and CAMultiSignature::verifyXML().

Referenced by init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reconfigure()

SINT32 CALastMix::reconfigure ( )
virtual

Reimplemented from CAMix.

Definition at line 560 of file CALastMix.cpp.

561  {
562  CAMsg::printMsg(LOG_DEBUG,"Reconfiguring Last Mix\n");
563  CAMsg::printMsg(LOG_DEBUG,"Re-read cache proxies\n");
564  if(setTargets()!=E_SUCCESS)
565  CAMsg::printMsg(LOG_DEBUG,"Could not set new cache proxies\n");
566 #ifdef LOG_CRIME
567  CAMsg::printMsg(LOG_DEBUG,"Re-read crime settings\n");
568 
569 #endif
570  #ifndef NEW_MIX_TYPE // not TypeB mixes
571  #if defined (DELAY_CHANNELS)||defined (DELAY_CHANNELS_LATENCY)
572  CAMsg::printMsg(LOG_DEBUG,"Set new resources limitation parameters\n");
573  if(m_pChannelList!=NULL) {
574  #if defined (DELAY_CHANNELS)
575  m_pChannelList->setDelayParameters( CALibProxytest::getOptions()->getDelayChannelUnlimitTraffic(),
576  CALibProxytest::getOptions()->getDelayChannelBucketGrow(),
577  CALibProxytest::getOptions()->getDelayChannelBucketGrowIntervall());
578  #endif
579  #if defined (DELAY_CHANNELS_LATENCY)
580  UINT32 utemp=CALibProxytest::getOptions()->getDelayChannelLatency();
581  m_pChannelList->setDelayLatencyParameters( utemp);
582  #endif
583  }
584  #endif
585  #else // TypeB mixes
586  reconfigureMix();
587  #endif
588  return E_SUCCESS;
589  }

References E_SUCCESS, CALibProxytest::getOptions(), m_pChannelList, CAMsg::printMsg(), and setTargets().

Here is the call graph for this function:

◆ setTargets()

SINT32 CALastMix::setTargets ( )
protected

Reads the configured proxies from options.

Return values
E_UNKNOWNif no proxies are specified
E_SUCCESSif successfully configured the proxies

Definition at line 971 of file CALastMix.cpp.

972  {
974  if(cntTargets==0)
975  {
976  CAMsg::printMsg(LOG_CRIT,"No Targets (proxies) specified!\n");
977  return E_UNKNOWN;
978  }
979  m_pCacheLB->clean();
980  m_pSocksLB->clean();
981  m_pVPNLB->clean();
982  UINT32 i;
983  for(i=1;i<=cntTargets;i++)
984  {
985  CATargetInterface oTargetInterface;
986  CALibProxytest::getOptions()->getTargetInterface(oTargetInterface,i);
987  if(oTargetInterface.getTargetType()==TARGET_HTTP_PROXY)
988  {
989  m_pCacheLB->add(oTargetInterface.getAddr());
990  }
991  else if(oTargetInterface.getTargetType()==TARGET_SOCKS_PROXY)
992  {
993  m_pSocksLB->add(oTargetInterface.getAddr());
994  }
995  else if (oTargetInterface.getTargetType() == TARGET_VPN_PROXY)
996  {
997  m_pVPNLB->add(oTargetInterface.getAddr());
998  }
999  oTargetInterface.cleanAddr();
1000  }
1001  CAMsg::printMsg(LOG_DEBUG,"This mix will use the following proxies:\n");
1002  for(i=0;i<m_pCacheLB->getElementCount();i++)
1003  {
1004  CASocketAddrINet* pAddr=m_pCacheLB->get();
1005  UINT8 ip[4];
1006  pAddr->getIP(ip);
1007  UINT32 port=pAddr->getPort();
1008  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);
1009  }
1010  for(i=0;i<m_pSocksLB->getElementCount();i++)
1011  {
1012  CASocketAddrINet* pAddr=m_pSocksLB->get();
1013  UINT8 ip[4];
1014  pAddr->getIP(ip);
1015  UINT32 port=pAddr->getPort();
1016  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);
1017  }
1018  for (i = 0; i<m_pVPNLB->getElementCount(); i++)
1019  {
1020  CASocketAddrINet* pAddr = m_pVPNLB->get();
1021  UINT8 ip[4];
1022  pAddr->getIP(ip);
1023  UINT32 port = pAddr->getPort();
1024  CAMsg::printMsg(LOG_DEBUG, "%u. VPN Proxy's Address: %u.%u.%u.%u:%u\n", i + 1, ip[0], ip[1], ip[2], ip[3], port);
1025  }
1026 
1027 
1028  return E_SUCCESS;
1029  }
SINT32 add(CASocketAddr *const pAddr)
CASocketAddrINet * get()
Gets the 'next' Address according to the Load-Balancing algorithm.
SINT32 clean()
Deletes all information.
UINT32 getTargetInterfaceCount()
SINT32 getTargetInterface(CATargetInterface &oTargetInterface, UINT32 nr)
Fills a TargetInterface struct with the values which belongs to the target interface nr.
This class represents a socket address for Internet (IP) connections.
UINT16 getPort() const
Returns the port value of the address.
SINT32 getIP(UINT8 buff[4]) const
Returns the IP-Numbers for this address.
TargetType getTargetType() const
CASocketAddr * getAddr() const
@ TARGET_VPN_PROXY
Definition: typedefs.hpp:32
@ TARGET_SOCKS_PROXY
Definition: typedefs.hpp:32
@ TARGET_HTTP_PROXY
Definition: typedefs.hpp:32

References CACacheLoadBalancing::add(), CACacheLoadBalancing::clean(), CATargetInterface::cleanAddr(), E_SUCCESS, E_UNKNOWN, CACacheLoadBalancing::get(), CATargetInterface::getAddr(), CACacheLoadBalancing::getElementCount(), CASocketAddrINet::getIP(), CALibProxytest::getOptions(), CASocketAddrINet::getPort(), CACmdLnOptions::getTargetInterface(), CACmdLnOptions::getTargetInterfaceCount(), CATargetInterface::getTargetType(), m_pCacheLB, m_pSocksLB, m_pVPNLB, CAMsg::printMsg(), TARGET_HTTP_PROXY, TARGET_SOCKS_PROXY, and TARGET_VPN_PROXY.

Referenced by initOnce(), and reconfigure().

Here is the call graph for this function:
Here is the caller graph for this function:

Friends And Related Function Documentation

◆ lm_loopLog

THREAD_RETURN lm_loopLog ( void *  )
friend

Definition at line 591 of file CALastMix.cpp.

592  {
593  CALastMix* pLastMix=static_cast<CALastMix*>(param);
594  UINT32 countLog=0;
595  UINT8 buff[256];
596  while(pLastMix->m_bRunLog)
597  {
598  if((countLog%10)==0)
599  {
600  logMemoryUsage();
601  }
602  if(countLog==0)
603  {
604  CAMsg::printMsg(LOG_DEBUG,"Uploaded Packets: %u\n",pLastMix->m_logUploadedPackets);
605  CAMsg::printMsg(LOG_DEBUG,"Downloaded Packets: %u\n",pLastMix->m_logDownloadedPackets);
606  print64(buff,(UINT64&)pLastMix->m_logUploadedBytes);
607  CAMsg::printMsg(LOG_DEBUG,"Uploaded Bytes : %s\n",buff);
608  print64(buff,(UINT64&)pLastMix->m_logDownloadedBytes);
609  CAMsg::printMsg(LOG_DEBUG,"Downloaded Bytes : %s\n",buff);
610  countLog=30;
611  }
612  sSleep(30);
613  countLog--;
614  }
616  }
SINT32 sSleep(UINT32 sec)
Sleeps sec Seconds.
Definition: CAUtil.cpp:425
void logMemoryUsage()
Log information about the current memory (heap) usage.
Definition: CAUtil.cpp:177
void print64(UINT8 *buff, UINT64 num)
Definition: CAUtil.hpp:482
#define THREAD_RETURN_SUCCESS
Definition: StdAfx.h:542
volatile UINT32 m_logDownloadedPackets
Definition: CALastMix.hpp:192
volatile UINT64 m_logDownloadedBytes
Definition: CALastMix.hpp:193
volatile UINT64 m_logUploadedBytes
Definition: CALastMix.hpp:191
volatile UINT32 m_logUploadedPackets
Definition: CALastMix.hpp:190

Referenced by CALastMixA::loop(), and CALastMixB::loop().

◆ lm_loopReadFromMix

THREAD_RETURN lm_loopReadFromMix ( void *  pParam)
friend

ToDo: check if keep-alive is really correct here - should it not be moved upwards?

Definition at line 731 of file CALastMix.cpp.

732  {
733  #ifdef ENABLE_GPERFTOOLS_CPU_PROFILER
734  ProfilerRegisterThread();
735  #endif
736  CALastMix* pLastMix = static_cast<CALastMix*>(pParam);
737  CAMuxSocket* pMuxSocket=pLastMix->m_pMuxIn;
738  CAQueue* pQueue=pLastMix->m_pQueueReadFromMix;
739  tQueueEntry* pQueueEntry=new tQueueEntry;
740  MIXPACKET* pMixPacket=&pQueueEntry->packet;
741  CASingleSocketGroup* pSocketGroup=new CASingleSocketGroup(false);
742  pSocketGroup->add(*pMuxSocket);
743  #ifdef USE_POOL
744  CAPool* pPool=new CAPool(MIX_POOL_SIZE);
745  #endif
746  UINT64 keepaliveNow,keepaliveLast;
747  UINT32 u32KeepAliveRecvInterval=pLastMix->m_u32KeepAliveRecvInterval;
748  getcurrentTimeMillis(keepaliveLast);
749  while(!pLastMix->m_bRestart)
750  {
752  {
753 #ifdef DEBUG
754  CAMsg::printMsg(LOG_DEBUG,"CAFirstMix::Queue is full!\n");
755 #endif
756  msSleep(200);
757  getcurrentTimeMillis(keepaliveLast);
758  continue;
759  }
760  //check if the connection is broken because we did not receive a Keep_alive-Message
761  getcurrentTimeMillis(keepaliveNow);
762  UINT32 keepaliveDiff=diff64(keepaliveNow,keepaliveLast);
763  if(keepaliveDiff>u32KeepAliveRecvInterval)
764  {
765  CAMsg::printMsg(LOG_ERR,"CALastMix::loopReadFromMix() -- restart because of KeepAlive-Traffic Timeout!\n");
766  pLastMix->m_bRestart=true;
768  break;
769  }
770  SINT32 ret=pSocketGroup->select(MIX_POOL_TIMEOUT);
771  if(ret < 0)
772  {
773  if (ret == E_TIMEDOUT)
774  {
775  #ifdef USE_POOL
776  pMixPacket->flags=CHANNEL_DUMMY;
777  pMixPacket->channel=DUMMY_CHANNEL;
778  getRandom(pMixPacket->data,DATA_SIZE);
779  #ifdef LOG_PACKET_TIMES
780  setZero64(pQueueEntry->timestamp_proccessing_start);
781  #endif
782  #else
783  continue;
784  #endif
785  }
786  else
787  {
788  /* another error occured (happens sometimes while debugging because
789  * of interruption, if a breakpoint is reached -> poll() returns
790  * errorcode EINTR)
791  * Note: Any Error on select() does not mean, that the underliny connections have some error state, because
792  * in this case select() returns the socket and than this socket returns the error
793  */
794  continue;
795  }
796  }
797  else if(ret>0)
798  {
799  ret=pMuxSocket->receive(pMixPacket); //receives a whole MixPacket
800  #ifdef LOG_PACKET_TIMES
801  getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_start);
802  #endif
803  #ifdef DATA_RETENTION_LOG
804  pQueueEntry->dataRetentionLogEntry.t_in=htonl(time(NULL));
805  #endif
806  if(ret!=MIXPACKET_SIZE)
807  {//something goes wrong...
808  CAMsg::printMsg(LOG_ERR,"CALastMix::lm_loopReadFromMix - received returned: %i\n",ret);
809  pLastMix->m_bRestart=true;
811  break;
812  }
813  }
814  #ifdef USE_POOL
815  #ifdef LOG_PACKET_TIMES
816  getcurrentTimeMicros(pQueueEntry->pool_timestamp_in);
817  #endif
818  pPool->pool((tPoolEntry*) pQueueEntry);
819  #ifdef LOG_PACKET_TIMES
820  getcurrentTimeMicros(pQueueEntry->pool_timestamp_out);
821  #endif
822  #endif
823  pQueue->add(pQueueEntry,sizeof(tQueueEntry));
824  getcurrentTimeMillis(keepaliveLast);
825  }
826  delete pQueueEntry;
827  pQueueEntry = NULL;
828  delete pSocketGroup;
829  pSocketGroup = NULL;
830  #ifdef USE_POOL
831  delete pPool;
832  pPool = NULL;
833  #endif
835  }
SINT32 getcurrentTimeMillis(UINT64 &u64Time)
Gets the current Systemtime in milli seconds.
Definition: CAUtil.cpp:252
SINT32 getcurrentTimeMicros(UINT64 &u64Time)
Gets the current Systemtime in micros seconds.
Definition: CAUtil.cpp:280
SINT32 msSleep(UINT32 ms)
Sleeps ms milliseconds.
Definition: CAUtil.cpp:406
UINT32 diff64(const UINT64 &bigop, const UINT64 &smallop)
Definition: CAUtil.hpp:398
void setZero64(UINT64 &op1)
Definition: CAUtil.hpp:355
#define MAX_READ_FROM_PREV_MIX_QUEUE_SIZE
Definition: StdAfx.h:226
#define MIX_POOL_TIMEOUT
Definition: StdAfx.h:245
#define DUMMY_CHANNEL
Definition: StdAfx.h:246
#define MIX_POOL_SIZE
Definition: StdAfx.h:243
SINT32 receive(MIXPACKET *pPacket)
Receives a whole MixPacket.
This class implements the pool strategie of a Mix.
Definition: CAPool.hpp:43
SINT32 pool(tPoolEntry *pPoolEntry)
Definition: CAPool.cpp:83
UINT32 getSize()
Returns the size of stored data in byte.
Definition: CAQueue.hpp:101
SINT32 add(SOCKET &s)
#define E_TIMEDOUT
Definition: errorcodes.hpp:10
HCHANNEL channel
Definition: typedefs.hpp:117
UINT8 data[DATA_SIZE]
Definition: typedefs.hpp:121
UINT16 flags
Definition: typedefs.hpp:118
MIXPACKET packet
Definition: typedefs.hpp:170
#define CHANNEL_DUMMY
Definition: typedefs.hpp:50
#define DATA_SIZE
Definition: typedefs.hpp:69

◆ lm_loopSendToMix

THREAD_RETURN lm_loopSendToMix ( void *  param)
friend

How to end this thread: 0.

set m_bRestart=true;

  1. Close connection to next mix
  2. put a byte in the Mix-Output-Queue

Definition at line 623 of file CALastMix.cpp.

624  {
625  #ifdef ENABLE_GPERFTOOLS_CPU_PROFILER
626  ProfilerRegisterThread();
627  #endif
628 
629  CALastMix* pLastMix = static_cast<CALastMix*>(param);
630  CAQueue* pQueue=pLastMix->m_pQueueSendToMix;
631  CAMuxSocket* pMuxSocket=pLastMix->m_pMuxIn;
632  SINT32 ret;
633  UINT32 len;
634  UINT32 u32KeepAliveSendInterval=pLastMix->m_u32KeepAliveSendInterval;
635 #ifndef USE_POOL
636  tQueueEntry* pQueueEntry=new tQueueEntry;
637  MIXPACKET* pMixPacket=&pQueueEntry->packet;
638 
639  while(!pLastMix->m_bRestart)
640  {
641  len=sizeof(tQueueEntry);
642  ret=pQueue->getOrWait((UINT8*)pQueueEntry,&len,u32KeepAliveSendInterval);
643  if(ret==E_TIMEDOUT)
644  {
645  pMixPacket->flags=CHANNEL_DUMMY;
646  pMixPacket->channel=DUMMY_CHANNEL;
647  getRandom(pMixPacket->data,DATA_SIZE);
648  }
649  else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry))
650  {
651  CAMsg::printMsg(LOG_ERR,"CALastMix::lm_loopSendToMix - Error in dequeueing MixPaket\n");
652  CAMsg::printMsg(LOG_ERR,"ret=%i len=%i\n",ret,len);
654  break;
655  }
656 #ifdef ANON_DEBUG_MODE
657  if (pMixPacket->flags&CHANNEL_DEBUG)
658  {
659  UINT8 base64Payload[DATA_SIZE << 1];
660  EVP_EncodeBlock(base64Payload, pMixPacket->data, DATA_SIZE);//base64 encoding (without newline!)
661  CAMsg::printMsg(LOG_DEBUG, "Send Downstream AN.ON packet to previous Mix debug: %s\n", base64Payload);
662  }
663 #endif
664  if (pMuxSocket->send(pMixPacket) != MIXPACKET_SIZE)
665  {
666  CAMsg::printMsg(LOG_ERR,"CALastMix::lm_loopSendToMix - Error in sending MixPaket\n");
668  break;
669  }
670 #ifdef LOG_PACKET_TIMES
671  if(!isZero64(pQueueEntry->timestamp_proccessing_start))
672  {
673  getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end);
674  pLastMix->m_pLogPacketStats->addToTimeingStats(*pQueueEntry,CHANNEL_DATA,false);
675  }
676 #endif
677  }
678  delete pQueueEntry;
679  pQueueEntry = NULL;
680 #else
681  CAPool* pPool=new CAPool(MIX_POOL_SIZE);
682  tPoolEntry* pPoolEntry=new tPoolEntry;
683  MIXPACKET* pMixPacket=&pPoolEntry->packet;
684  while(!pLastMix->m_bRestart)
685  {
686  len=sizeof(tQueueEntry);
687  SINT32 ret=pQueue->getOrWait((UINT8*)pPoolEntry,&len,MIX_POOL_TIMEOUT);
688  if(ret==E_TIMEDOUT)
689  {
690  pMixPacket->flags=CHANNEL_DUMMY;
691  pMixPacket->channel=DUMMY_CHANNEL;
692  getRandom(pMixPacket->data,DATA_SIZE);
693  #ifdef LOG_PACKET_TIMES
694  setZero64(pPoolEntry->timestamp_proccessing_start);
695  #endif
696  }
697  else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry))
698  {
699  break;
700  }
701  #ifdef LOG_PACKET_TIMES
702  getcurrentTimeMicros(pPoolEntry->pool_timestamp_in);
703  #endif
704  pPool->pool(pPoolEntry);
705  #ifdef LOG_PACKET_TIMES
706  getcurrentTimeMicros(pPoolEntry->pool_timestamp_out);
707  #endif
708  if(pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE)
709  break;
710 #ifdef LOG_PACKET_TIMES
711  if(!isZero64(pPoolEntry->timestamp_proccessing_start))
712  {
713  getcurrentTimeMicros(pPoolEntry->timestamp_proccessing_end);
714  pLastMix->m_pLogPacketStats->addToTimeingStats(*pPoolEntry,CHANNEL_DATA,false);
715  }
716 #endif
717  }
718  delete pPoolEntry;
719  pPoolEntry = NULL;
720  delete pPool;
721  pPool = NULL;
722 #endif
723  CAMsg::printMsg(LOG_DEBUG,"Exiting Thread SendToMix\n");
725  }
bool isZero64(UINT64 &op1)
Definition: CAUtil.hpp:464
SINT32 send(MIXPACKET *pPacket)
Sends a MixPacket over the Network.
SINT32 getOrWait(UINT8 *pbuff, UINT32 *psize)
Gets data from the Queue or waits until some data is available, if the Queue is empty.
Definition: CAQueue.cpp:209
#define CHANNEL_DATA
Definition: typedefs.hpp:42
#define CHANNEL_DEBUG
Definition: typedefs.hpp:51
tQueueEntry tPoolEntry
Definition: typedefs.hpp:192

Member Data Documentation

◆ m_bRestart

volatile bool CALastMix::m_bRestart
protected

Definition at line 151 of file CALastMix.hpp.

Referenced by clean(), CALastMixA::loop(), and CALastMixB::loop().

◆ m_bRunLog

volatile bool CALastMix::m_bRunLog
protected

Definition at line 189 of file CALastMix.hpp.

Referenced by clean(), CALastMixA::loop(), and CALastMixB::loop().

◆ m_logDownloadedBytes

volatile UINT64 CALastMix::m_logDownloadedBytes
protected

Definition at line 193 of file CALastMix.hpp.

Referenced by CALastMixA::loop(), and CALastMixB::loop().

◆ m_logDownloadedPackets

volatile UINT32 CALastMix::m_logDownloadedPackets
protected

Definition at line 192 of file CALastMix.hpp.

Referenced by CALastMixA::loop(), and CALastMixB::loop().

◆ m_logUploadedBytes

volatile UINT64 CALastMix::m_logUploadedBytes
protected

Definition at line 191 of file CALastMix.hpp.

Referenced by CALastMixA::loop(), and CALastMixB::loop().

◆ m_logUploadedPackets

volatile UINT32 CALastMix::m_logUploadedPackets
protected

Definition at line 190 of file CALastMix.hpp.

Referenced by CALastMixA::loop(), and CALastMixB::loop().

◆ m_pCacheLB

CACacheLoadBalancing* CALastMix::m_pCacheLB
protected

Definition at line 158 of file CALastMix.hpp.

Referenced by CALastMix(), CALastMixA::loop(), CALastMixB::loop(), setTargets(), and ~CALastMix().

◆ m_pChannelList

CALastMixChannelList* CALastMix::m_pChannelList
protected

Definition at line 166 of file CALastMix.hpp.

Referenced by CALastMix(), clean(), CALastMixA::loop(), and reconfigure().

◆ m_pMuxIn

CAMuxSocket* CALastMix::m_pMuxIn
protected

◆ m_pQueueReadFromMix

CAQueue* CALastMix::m_pQueueReadFromMix
protected

Definition at line 154 of file CALastMix.hpp.

Referenced by CALastMix(), clean(), CALastMixA::loop(), and CALastMixB::loop().

◆ m_pQueueSendToMix

CAQueue* CALastMix::m_pQueueSendToMix
protected

Definition at line 153 of file CALastMix.hpp.

Referenced by CALastMix(), clean(), CALastMixA::loop(), and CALastMixB::loop().

◆ m_pRSA

CAASymCipher* CALastMix::m_pRSA
protected

◆ m_pSocksLB

CACacheLoadBalancing* CALastMix::m_pSocksLB
protected

Definition at line 159 of file CALastMix.hpp.

Referenced by CALastMix(), CALastMixA::loop(), CALastMixB::loop(), setTargets(), and ~CALastMix().

◆ m_pthreadReadFromMix

CAThread* CALastMix::m_pthreadReadFromMix
protected

Definition at line 163 of file CALastMix.hpp.

Referenced by CALastMix(), clean(), and CALastMixB::loop().

◆ m_pthreadSendToMix

CAThread* CALastMix::m_pthreadSendToMix
protected

Definition at line 162 of file CALastMix.hpp.

Referenced by CALastMix(), clean(), and CALastMixB::loop().

◆ m_pVPNLB

CACacheLoadBalancing* CALastMix::m_pVPNLB
protected

Definition at line 160 of file CALastMix.hpp.

Referenced by CALastMix(), CALastMixA::loop(), setTargets(), and ~CALastMix().


The documentation for this class was generated from the following files: