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

#include <CAFirstMix.hpp>

Inheritance diagram for CAFirstMix:
Collaboration diagram for CAFirstMix:

Public Member Functions

 CAFirstMix ()
 
virtual ~CAFirstMix ()
 
tMixType getType () const
 
bool forceKickout (fmHashTableEntry *pHashTableEntry, const XERCES_CPP_NAMESPACE::DOMDocument *pErrDoc=NULL)
 
CAMutexgetLoginMutex ()
 
SINT32 connectToNextMix (CASocketAddr *a_pAddrNext)
 
SINT32 getMixedPackets (UINT64 &ppackets)
 
UINT32 getNrOfUsers ()
 
SINT32 getLevel (SINT32 *puser, SINT32 *prisk, SINT32 *ptraffic)
 
TermsAndConditionsgetTermsAndConditions (const UINT8 *opSki)
 
DOMNode * getTermsAndConditionsTemplate (UINT8 *templateRefID)
 
SINT32 getMixCount ()
 
tMixParametersgetMixParameters ()
 Returns the ordered list of the mix parameters from the first mix to the last mix. More...
 
SINT32 setMixParameters (const tMixParameters &params)
 Sets the parameters for the mix specified in the params.m_strMixID field. More...
 
SINT32 handleKeyInfoExtensions (DOMElement *root)
 
SINT32 handleTermsAndConditionsExtension (DOMElement *extensionRoot)
 
- 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 ()
 

Public Attributes

UINT64 m_u64LastTimestampReceived
 
- Public Attributes inherited from CAMixWithReplayDB
UINT64 m_u64ReferenceTime
 

Protected Member Functions

virtual SINT32 loop ()=0
 
bool isShuttingDown ()
 
SINT32 init ()
 
SINT32 clean ()
 
virtual SINT32 initOnce ()
 
virtual SINT32 processKeyExchange ()
 
SINT32 initMixParameters (DOMElement *elemMixes)
 Initialises the MixParameters info for each mix form the <Mixes> element received from the second mix. More...
 
SINT32 incUsers (LP_fmHashTableEntry pHashEntry)
 
SINT32 decUsers (LP_fmHashTableEntry pHashEntry)
 
SINT32 incMixedPackets ()
 
SINT32 doUserLogin (CAMuxSocket *pNewUSer, UINT8 perrIP[4])
 
SINT32 reconfigure ()
 
SINT32 deleteCountryStats ()
 
- 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)
 
virtual SINT32 initMixCascadeInfo (DOMElement *elemMixes)
 This will initialize the XML Cascade Info struct XMLFirstMixToInfoService that is sent to the InfoService in CAInfoService::sendCascadeHelo() More...
 
SINT32 signXML (DOMNode *a_element)
 

Protected Attributes

CAIPListm_pIPList
 
CATempIPBlockListm_pIPBlockList
 
CAQueuem_pQueueSendToMix
 
CAQueuem_pQueueReadFromMix
 
volatile UINT32 m_nUser
 
UINT32 m_nSocketsIn
 
volatile bool m_bRestart
 
CASocket ** m_arrSocketsIn
 
UINT32 m_u32MixCount
 
tMixParametersm_arMixParameters
 
CAFirstMixChannelListm_pChannelList
 
CASocketGroupEpollm_psocketgroupUsersRead
 
CASocketGroupEpollm_psocketgroupUsersWrite
 
CAMuxSocketm_pMuxOut
 
UINT8m_xmlKeyInfoBuff
 
UINT16 m_xmlKeyInfoSize
 
XERCES_CPP_NAMESPACE::DOMDocument * m_docMixCascadeInfo
 
UINT64 m_nMixedPackets
 
CAASymCipherm_pRSA
 
CAMutexm_pmutexUser
 
CAMutexm_pmutexMixedPackets
 
CAMutexm_pmutexLoginThreads
 
CAThreadm_pthreadAcceptUsers
 
CAThreadPoolm_pthreadsLogin
 
CAThreadm_pthreadSendToMix
 
CAThreadm_pthreadReadFromMix
 
UINT32 m_nrOfTermsAndConditionsDefs
 
TermsAndConditions ** m_tnCDefs
 
UINT32 m_nrOfTermsAndConditionsTemplates
 
DOMNode ** m_tcTemplates
 
XERCES_CPP_NAMESPACE::DOMDocument * m_templatesOwner
 
const XMLCh * TNC_REQUEST
 
const XMLCh * TNC_CONFIRM
 
const XMLCh * TNC_INTERRUPT
 
tUINT32withLockm_PacketsPerCountryIN
 
tUINT32withLockm_PacketsPerCountryOUT
 
bool m_bIsShuttingDown
 
volatile bool m_bRunLog
 
CAMutexm_pmutexLogin
 
- 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
 

Private Member Functions

SINT32 initCountryStats (char *db_host, char *db_user, char *db_passwd)
 
SINT32 updateCountryStats (const UINT8 ip[4], UINT32 a_countryID, bool bRemove)
 Update the statisitics of the countries users come from. More...
 
SINT32 sendReplayTimestampRequestsToAllMixes ()
 
SINT32 doUserLogin_internal (CAMuxSocket *pNewUSer, UINT8 perrIP[4])
 Sends and receives all data neccessary for a User to "login". More...
 
SINT32 isAllowedToPassRestrictions (CASocket *pNewMuxSocket)
 
termsAndConditionMixAnswer_thandleTermsAndConditionsLogin (XERCES_CPP_NAMESPACE::DOMDocument *request)
 
void incNewConnections ()
 
void decNewConnections ()
 

Private Attributes

volatile bool m_bRunLogCountries
 
volatile UINT32m_CountryStats
 
CAThreadm_threadLogLoop
 
MYSQL * m_mysqlCon
 
volatile UINT32 m_newConnections
 
CAMutexm_pmutexNewConnections
 

Static Private Attributes

static const UINT32 MAX_CONCURRENT_NEW_CONNECTIONS = NUM_LOGIN_WORKER_TRHEADS * 2
 

Friends

THREAD_RETURN fm_loopSendToMix (void *)
 How to end this thread: 0. More...
 
THREAD_RETURN fm_loopReadFromMix (void *)
 
THREAD_RETURN fm_loopAcceptUsers (void *)
 
THREAD_RETURN fm_loopDoUserLogin (void *param)
 
THREAD_RETURN iplist_loopDoLogCountries (void *param)
 
THREAD_RETURN fm_loopLog (void *)
 

Additional Inherited Members

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

Detailed Description

Definition at line 229 of file CAFirstMix.hpp.

Constructor & Destructor Documentation

◆ CAFirstMix()

CAFirstMix::CAFirstMix ( )
inline

Definition at line 237 of file CAFirstMix.hpp.

238  {
239  m_pmutexUser=new CAMutex();
243 #ifdef CH_LOG_STUDY
244  //log nr of opened channels per minute
245  nrOfChOpMutex = new CAMutex();
246  nrOfChThread = NULL;
247  nrOfOpenedChannels = 0;
248  currentOpenedChannels = 0;
249  lastLogTime = 0;
250 #endif //CH_LOG_STUDY
251  m_nMixedPackets=0;
252  m_nUser=0;
253  m_nSocketsIn=0;
254  m_pQueueSendToMix=NULL;
255  m_pQueueReadFromMix=NULL;
256  m_pIPList=NULL;
257  m_arrSocketsIn=NULL;
258  m_pRSA=NULL;
259  m_pInfoService=NULL;
260 #ifndef MULTI_THREADED_PACKET_PROCESSING
263  m_pChannelList=NULL;
264 #else
265  m_numThreads = 10;
266 #endif
267  m_pMuxOut=NULL;
268  m_docMixCascadeInfo=NULL;
269  m_xmlKeyInfoBuff=NULL;
270  m_pthreadSendToMix=NULL;
273  m_pthreadsLogin=NULL;
275  m_tnCDefs = NULL;
277  m_templatesOwner = NULL;
278  m_tcTemplates = NULL;
279  m_bIsShuttingDown=false;
280  m_pIPBlockList = NULL;
281 #ifdef LOG_PACKET_TIMES
282  m_pLogPacketStats=NULL;
283 #endif
284 #ifdef COUNTRY_STATS
286  m_CountryStats=NULL;
287  m_mysqlCon=NULL;
288  m_threadLogLoop=NULL;
289 #endif
290  m_arMixParameters=NULL;
291 #ifdef DYNAMIC_MIX
292  m_bBreakNeeded = false;
293 #endif
294  TNC_REQUEST = XMLString::transcode(TNC_SREQUEST);
295  TNC_CONFIRM = XMLString::transcode(TNC_CONFIRM_REQ);
296  TNC_INTERRUPT = XMLString::transcode(TNC_SINTERRUPT);
297 #ifdef PAYMENT
298  m_pmutexLogin=new CAMutex();
299 #endif
300  }
#define TNC_CONFIRM_REQ
Definition: CAFirstMix.hpp:69
#define TNC_SINTERRUPT
Definition: CAFirstMix.hpp:61
#define TNC_SREQUEST
Definition: CAFirstMix.hpp:59
CAThread * m_pthreadReadFromMix
Definition: CAFirstMix.hpp:507
CASocket ** m_arrSocketsIn
Definition: CAFirstMix.hpp:457
const XMLCh * TNC_CONFIRM
Definition: CAFirstMix.hpp:517
UINT32 m_nrOfTermsAndConditionsTemplates
Definition: CAFirstMix.hpp:511
CAMutex * m_pmutexNewConnections
Definition: CAFirstMix.hpp:569
tMixParameters * m_arMixParameters
Definition: CAFirstMix.hpp:461
DOMNode ** m_tcTemplates
Definition: CAFirstMix.hpp:512
CAMuxSocket * m_pMuxOut
Definition: CAFirstMix.hpp:490
CAThread * m_pthreadAcceptUsers
Definition: CAFirstMix.hpp:504
UINT64 m_nMixedPackets
Definition: CAFirstMix.hpp:496
CAQueue * m_pQueueSendToMix
Definition: CAFirstMix.hpp:448
CAIPList * m_pIPList
Definition: CAFirstMix.hpp:446
bool m_bIsShuttingDown
Definition: CAFirstMix.hpp:550
CASocketGroupEpoll * m_psocketgroupUsersWrite
Definition: CAFirstMix.hpp:467
UINT32 m_nrOfTermsAndConditionsDefs
Definition: CAFirstMix.hpp:509
XERCES_CPP_NAMESPACE::DOMDocument * m_templatesOwner
Definition: CAFirstMix.hpp:513
CAThread * m_threadLogLoop
Definition: CAFirstMix.hpp:539
volatile UINT32 m_nUser
Definition: CAFirstMix.hpp:454
const XMLCh * TNC_INTERRUPT
Definition: CAFirstMix.hpp:518
CAThread * m_pthreadSendToMix
Definition: CAFirstMix.hpp:506
CAMutex * m_pmutexLogin
Definition: CAFirstMix.hpp:555
CASocketGroupEpoll * m_psocketgroupUsersRead
Definition: CAFirstMix.hpp:466
CATempIPBlockList * m_pIPBlockList
Definition: CAFirstMix.hpp:447
tUINT32withLock * m_PacketsPerCountryOUT
Definition: CAFirstMix.hpp:537
CAMutex * m_pmutexUser
Definition: CAFirstMix.hpp:500
CAMutex * m_pmutexMixedPackets
Definition: CAFirstMix.hpp:501
MYSQL * m_mysqlCon
Definition: CAFirstMix.hpp:540
CAFirstMixChannelList * m_pChannelList
Definition: CAFirstMix.hpp:464
tUINT32withLock * m_PacketsPerCountryIN
Definition: CAFirstMix.hpp:536
UINT32 m_nSocketsIn
Definition: CAFirstMix.hpp:455
UINT8 * m_xmlKeyInfoBuff
Definition: CAFirstMix.hpp:492
CAASymCipher * m_pRSA
Definition: CAFirstMix.hpp:497
CAThreadPool * m_pthreadsLogin
Definition: CAFirstMix.hpp:505
TermsAndConditions ** m_tnCDefs
Definition: CAFirstMix.hpp:510
const XMLCh * TNC_REQUEST
Definition: CAFirstMix.hpp:516
CAQueue * m_pQueueReadFromMix
Definition: CAFirstMix.hpp:449
volatile UINT32 * m_CountryStats
Definition: CAFirstMix.hpp:533
CAMutex * m_pmutexLoginThreads
Definition: CAFirstMix.hpp:502
XERCES_CPP_NAMESPACE::DOMDocument * m_docMixCascadeInfo
Definition: CAFirstMix.hpp:495
CAInfoService * m_pInfoService
Definition: CAMix.hpp:184

References m_arMixParameters, m_arrSocketsIn, m_bIsShuttingDown, m_CountryStats, m_docMixCascadeInfo, m_mysqlCon, m_nMixedPackets, m_nrOfTermsAndConditionsDefs, m_nrOfTermsAndConditionsTemplates, m_nSocketsIn, m_nUser, m_PacketsPerCountryIN, m_PacketsPerCountryOUT, m_pChannelList, CAMix::m_pInfoService, m_pIPBlockList, m_pIPList, m_pmutexLogin, m_pmutexLoginThreads, m_pmutexMixedPackets, m_pmutexNewConnections, m_pmutexUser, m_pMuxOut, m_pQueueReadFromMix, m_pQueueSendToMix, m_pRSA, m_psocketgroupUsersRead, m_psocketgroupUsersWrite, m_pthreadAcceptUsers, m_pthreadReadFromMix, m_pthreadSendToMix, m_pthreadsLogin, m_tcTemplates, m_templatesOwner, m_threadLogLoop, m_tnCDefs, m_xmlKeyInfoBuff, TNC_CONFIRM, TNC_CONFIRM_REQ, TNC_INTERRUPT, TNC_REQUEST, TNC_SINTERRUPT, and TNC_SREQUEST.

◆ ~CAFirstMix()

virtual CAFirstMix::~CAFirstMix ( )
inlinevirtual

Definition at line 303 of file CAFirstMix.hpp.

304  {
305  clean(); // speeds up shutdown
306  delete m_pmutexUser;
307  m_pmutexUser = NULL;
308  delete m_pmutexMixedPackets;
309  m_pmutexMixedPackets = NULL;
310  delete m_pmutexLoginThreads;
311  m_pmutexLoginThreads = NULL;
312  delete m_pmutexNewConnections ;
314 #ifdef PAYMENT
315  delete m_pmutexLogin;
316 #endif
317  }
SINT32 clean()

References clean(), m_pmutexLogin, m_pmutexLoginThreads, m_pmutexMixedPackets, m_pmutexNewConnections, and m_pmutexUser.

Here is the call graph for this function:

Member Function Documentation

◆ clean()

SINT32 CAFirstMix::clean ( )
protectedvirtual

Implements CAMix.

Definition at line 2622 of file CAFirstMix.cpp.

2623  {
2624  //#ifdef _DEBUG
2625  CAMsg::printMsg(LOG_DEBUG,"CAFirstMix::clean() start\n");
2626  //#endif
2627  m_bRunLog=false;
2628  m_bRestart=true;
2629  if(m_pMuxOut!=NULL)
2630  {
2631  m_pMuxOut->close();
2632  }
2633 
2634  //writing some bytes to the queue...
2635  if(m_pQueueSendToMix!=NULL)
2636  {
2637  UINT8 b[sizeof(tQueueEntry)+1];
2638  m_pQueueSendToMix->add(b,sizeof(tQueueEntry)+1);
2639  }
2640 
2641  if(m_pthreadAcceptUsers!=NULL)
2642  {
2643  CAMsg::printMsg(LOG_CRIT,"Wait for LoopAcceptUsers!\n");
2645  delete m_pthreadAcceptUsers;
2646  }
2647  m_pthreadAcceptUsers=NULL;
2648  if(m_pthreadsLogin!=NULL)
2649  delete m_pthreadsLogin;
2650  m_pthreadsLogin=NULL;
2651  if(m_pInfoService!=NULL)
2652  {
2653  CAMsg::printMsg(LOG_CRIT,"Stopping InfoService....\n");
2654  CAMsg::printMsg (LOG_CRIT,"Memory usage before: %u\n",getMemoryUsage());
2655  m_pInfoService->stop();
2656  CAMsg::printMsg (LOG_CRIT,"Memory usage after: %u\n",getMemoryUsage());
2657  CAMsg::printMsg(LOG_CRIT,"Stopped InfoService!\n");
2658  // delete m_pInfoService;
2659  }
2660  // m_pInfoService=NULL;
2661 
2662  if(m_pthreadSendToMix!=NULL)
2663  {
2664  CAMsg::printMsg(LOG_CRIT,"Wait for LoopSendToMix!\n");
2666  delete m_pthreadSendToMix;
2667  }
2668  m_pthreadSendToMix=NULL;
2669  if(m_pthreadReadFromMix!=NULL)
2670  {
2671  CAMsg::printMsg(LOG_CRIT,"Wait for LoopReadFromMix!\n");
2673  delete m_pthreadReadFromMix;
2674  }
2675  m_pthreadReadFromMix=NULL;
2676 
2677 #ifdef CH_LOG_STUDY
2678  if(nrOfChThread != NULL)
2679  {
2680  nrOfChThread->join();
2681  delete nrOfChThread;
2682  nrOfChThread = NULL;
2683  }
2684 #endif
2685 
2686 #ifdef LOG_PACKET_TIMES
2687  if(m_pLogPacketStats!=NULL)
2688  {
2689  CAMsg::printMsg(LOG_CRIT,"Wait for LoopLogPacketStats to terminate!\n");
2690  m_pLogPacketStats->stop();
2691  delete m_pLogPacketStats;
2692  }
2693  m_pLogPacketStats=NULL;
2694 #endif
2695  if(m_arrSocketsIn!=NULL)
2696  {
2697  for(UINT32 i=0;i<m_nSocketsIn;i++)
2698  {
2699  if (m_arrSocketsIn[i] != NULL)
2700  {
2701  m_arrSocketsIn[i]->close();
2702  delete m_arrSocketsIn[i];
2703  m_arrSocketsIn[i] = NULL;
2704  }
2705  }
2706  delete[] m_arrSocketsIn;
2707  }
2708  m_arrSocketsIn=NULL;
2709 #ifdef REPLAY_DETECTION
2710  if(m_pReplayMsgProc!=NULL)
2711  {
2712  delete m_pReplayMsgProc;
2713  }
2714  m_pReplayMsgProc=NULL;
2715 #endif
2716 
2718  {
2720  }
2722 
2723  if(m_pMuxOut!=NULL)
2724  {
2725  m_pMuxOut->close();
2726  delete m_pMuxOut;
2727  }
2728  m_pMuxOut=NULL;
2729 #ifdef COUNTRY_STATS
2731 #endif
2732  if(m_pIPList!=NULL)
2733  delete m_pIPList;
2734  m_pIPList=NULL;
2735  if(m_pQueueSendToMix!=NULL)
2736  delete m_pQueueSendToMix;
2737  m_pQueueSendToMix=NULL;
2738  if(m_pQueueReadFromMix!=NULL)
2739  delete m_pQueueReadFromMix;
2740  m_pQueueReadFromMix=NULL;
2741 
2742 #ifndef MULTI_THREADED_PACKET_PROCESSING
2743  if(m_pChannelList!=NULL)
2744  {
2745  CAMsg::printMsg(LOG_CRIT,"Before deleting CAFirstMixChannelList()!\n");
2746  CAMsg::printMsg (LOG_CRIT,"Memory usage before: %u\n",getMemoryUsage());
2747  fmHashTableEntry* pHashEntry=m_pChannelList->getFirst();
2748  while(pHashEntry!=NULL)
2749  {
2750  CAMuxSocket * pMuxSocket=pHashEntry->pMuxSocket;
2751  delete pHashEntry->pQueueSend;
2752  pHashEntry->pQueueSend = NULL;
2753  delete pHashEntry->pSymCipher;
2754  pHashEntry->pSymCipher = NULL;
2755 
2757  while(pEntry!=NULL)
2758  {
2759  delete pEntry->pCipher;
2760  pEntry->pCipher = NULL;
2761  pEntry=m_pChannelList->getNextChannel(pEntry);
2762  }
2763  m_pChannelList->remove(pHashEntry->pMuxSocket);
2764  pMuxSocket->close();
2765  delete pMuxSocket;
2766  pMuxSocket = NULL;
2767  pHashEntry=m_pChannelList->getNext();
2768  }
2769  }
2770 
2771  if(m_pChannelList!=NULL)
2772  delete m_pChannelList;
2773  m_pChannelList=NULL;
2774 #endif
2775  CAMsg::printMsg (LOG_CRIT,"Memory usage after: %u\n",getMemoryUsage());
2776 #ifdef PAYMENT
2779 #endif
2780 #ifndef MULTI_THREADED_PACKET_PROCESSING
2781  if(m_psocketgroupUsersRead!=NULL)
2782  delete m_psocketgroupUsersRead;
2784  if(m_psocketgroupUsersWrite!=NULL)
2785  delete m_psocketgroupUsersWrite;
2787 #endif
2788  if(m_pRSA!=NULL)
2789  delete m_pRSA;
2790  m_pRSA=NULL;
2791  if(m_xmlKeyInfoBuff!=NULL)
2792  delete[] m_xmlKeyInfoBuff;
2793  m_xmlKeyInfoBuff=NULL;
2794  m_docMixCascadeInfo=NULL;
2795  if(m_arMixParameters!=NULL)
2796  {
2797  for(UINT32 i=0;i<m_u32MixCount-1;i++)
2798  {
2799  delete[] m_arMixParameters[i].m_strMixID;
2800  }
2801  delete[] m_arMixParameters;
2802  }
2803  m_arMixParameters=NULL;
2804  m_u32MixCount=0;
2805  m_nMixedPackets=0; //reset to zero after each restart (at the moment neccessary for infoservice)
2806  m_nUser=0;
2807 
2808 
2809  delete m_pIPBlockList;
2810  m_pIPBlockList = NULL;
2811 
2812  CAMsg::printMsg (LOG_CRIT,"before tc cleanup\n");
2813  for (UINT32 i = 0; i < m_nrOfTermsAndConditionsDefs; i++)
2814  {
2815  delete m_tnCDefs[i];
2816  m_tnCDefs[i] = NULL;
2817  }
2818  delete [] m_tnCDefs;
2819  m_tnCDefs = NULL;
2821  CAMsg::printMsg (LOG_CRIT,"before template cleanup\n");
2822  for(UINT32 i = 0; i < m_nrOfTermsAndConditionsTemplates; i++)
2823  {
2824  m_tcTemplates[i]->release();
2825  m_tcTemplates[i] = NULL;
2826  }
2827  delete [] m_tcTemplates;
2828  m_tcTemplates = NULL;
2829  CAMsg::printMsg (LOG_CRIT,"before template owner release\n");
2830  if(m_templatesOwner != NULL)
2831  {
2832  m_templatesOwner->release();
2833  m_templatesOwner = NULL;
2834  }
2835  CAMsg::printMsg (LOG_CRIT,"after template owner release\n");
2837  //#ifdef _DEBUG
2838  CAMsg::printMsg(LOG_DEBUG,"CAFirstMix::clean() finished\n");
2839  //#endif
2840 
2841  return E_SUCCESS;
2842  }
UINT32 getMemoryUsage()
Definition: CAUtil.cpp:443
unsigned char UINT8
Definition: basetypedefs.h:135
unsigned int UINT32
Definition: basetypedefs.h:131
fmChannelListEntry * getFirstChannelForSocket(CAMuxSocket *pMuxSocket)
Gets the first channel for a given connection.
fmHashTableEntry * getFirst()
Gets the first connection of all connections in the list.
fmHashTableEntry * getNext()
Gets the next entry in the connections-list.
fmChannelListEntry * getNextChannel(fmChannelListEntry *pEntry)
Gets the next channel for a given connection.
SINT32 remove(CAMuxSocket *pMuxSocket)
Removes all channels, which belongs to the given connection and the connection itself from the list.
volatile bool m_bRestart
Definition: CAFirstMix.hpp:456
volatile bool m_bRunLog
Definition: CAFirstMix.hpp:552
UINT32 m_u32MixCount
Definition: CAFirstMix.hpp:459
SINT32 deleteCountryStats()
CAControlChannelDispatcher * m_pMuxOutControlChannelDispatcher
Definition: CAMix.hpp:195
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
CASymChannelCipher * pCipher
CASymChannelCipher * pSymCipher
UINT8 * m_strMixID
Definition: typedefs.hpp:216
Definition: typedefs.hpp:169
struct t_queue_entry tQueueEntry
Definition: typedefs.hpp:188

References CAQueue::add(), CAAccountingInstance::clean(), CAAccountingDBInterface::cleanup(), CAMuxSocket::close(), CASocket::close(), deleteCountryStats(), E_SUCCESS, CAFirstMixChannelList::getFirst(), CAFirstMixChannelList::getFirstChannelForSocket(), getMemoryUsage(), CAFirstMixChannelList::getNext(), CAFirstMixChannelList::getNextChannel(), CAThread::join(), m_arMixParameters, m_arrSocketsIn, m_bRestart, m_bRunLog, m_docMixCascadeInfo, m_nMixedPackets, m_nrOfTermsAndConditionsDefs, m_nrOfTermsAndConditionsTemplates, m_nSocketsIn, m_nUser, m_pChannelList, CAMix::m_pInfoService, m_pIPBlockList, m_pIPList, m_pMuxOut, CAMix::m_pMuxOutControlChannelDispatcher, m_pQueueReadFromMix, m_pQueueSendToMix, CAMixWithReplayDB::m_pReplayMsgProc, m_pRSA, m_psocketgroupUsersRead, m_psocketgroupUsersWrite, m_pthreadAcceptUsers, m_pthreadReadFromMix, m_pthreadSendToMix, m_pthreadsLogin, t_mix_parameters::m_strMixID, m_tcTemplates, m_templatesOwner, m_tnCDefs, m_u32MixCount, m_xmlKeyInfoBuff, t_firstmixchannellist::pCipher, t_fmhashtableentry::pMuxSocket, t_fmhashtableentry::pQueueSend, CAMsg::printMsg(), t_fmhashtableentry::pSymCipher, CAFirstMixChannelList::remove(), and CAInfoService::stop().

Referenced by CAFirstMixA::loop(), and ~CAFirstMix().

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

◆ connectToNextMix()

SINT32 CAFirstMix::connectToNextMix ( CASocketAddr a_pAddrNext)

Definition at line 307 of file CAFirstMix.cpp.

308 {
309  UINT8 buff[255];
310  a_pAddrNext->toString(buff,255);
311  CAMsg::printMsg(LOG_INFO,"Try to connect to next Mix on %s ...\n",buff);
312  SINT32 err = E_UNKNOWN;
313  SINT32 errLast = E_SUCCESS;
314 
315  for(UINT32 i=0; i < 100; i++)
316  {
317 #ifdef DYNAMIC_MIX
319  if(m_bBreakNeeded != m_bReconfigured)
320  {
321  CAMsg::printMsg(LOG_DEBUG, "CAFirstMix::connectToNextMix - Broken the connect loop!\n");
322  break;
323  }
324 #endif
325  err = m_pMuxOut->connect(*a_pAddrNext);
326  if(err != E_SUCCESS)
327  {
328  err=GET_NET_ERROR;
329 
331  {
332  CAMsg::printMsg(LOG_ERR, "Cannot connect to next Mix on %s. Reason: %s (%i)\n",
333  buff, GET_NET_ERROR_STR(err), err);
334  break;
335  }
336 
337  if (errLast != err || i % 10 == 0)
338  {
339  CAMsg::printMsg(LOG_ERR, "Cannot connect to next Mix on %s. Reason: %s (%i). Retrying...\n",
340  buff, GET_NET_ERROR_STR(err), err);
341  errLast = err;
342  }
343  else
344  {
345 #ifdef _DEBUG
346  CAMsg::printMsg(LOG_DEBUG,"Cannot connect... retrying\n");
347 #endif
348  }
349  sSleep(10);
350  }
351  else
352  {
353  break;
354  }
355  }
356  return err;
357 }
SINT32 sSleep(UINT32 sec)
Sleeps sec Seconds.
Definition: CAUtil.cpp:425
#define GET_NET_ERROR
Definition: StdAfx.h:469
#define GET_NET_ERROR_STR(x)
Definition: StdAfx.h:471
#define ERR_INTERN_CONNREFUSED
Definition: StdAfx.h:475
#define ERR_INTERN_TIMEDOUT
Definition: StdAfx.h:474
signed int SINT32
Definition: basetypedefs.h:132
SINT32 connect(CASocketAddr &psa)
virtual SINT32 toString(UINT8 *buff, UINT32 bufflen) const =0
Returns a string which describes this address in a human readable form.
#define E_UNKNOWN
Definition: errorcodes.hpp:3

References CAMuxSocket::connect(), E_SUCCESS, E_UNKNOWN, ERR_INTERN_CONNREFUSED, ERR_INTERN_TIMEDOUT, GET_NET_ERROR, GET_NET_ERROR_STR, m_pMuxOut, CAMsg::printMsg(), sSleep(), and CASocketAddr::toString().

Referenced by init().

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

◆ decNewConnections()

void CAFirstMix::decNewConnections ( )
inlineprivate

Definition at line 578 of file CAFirstMix.hpp.

579  {
583  }
volatile UINT32 m_newConnections
Definition: CAFirstMix.hpp:568
SINT32 unlock()
Definition: CAMutex.hpp:52
SINT32 lock()
Definition: CAMutex.hpp:41

References CAMutex::lock(), m_newConnections, m_pmutexNewConnections, and CAMutex::unlock().

Here is the call graph for this function:

◆ decUsers()

SINT32 CAFirstMix::decUsers ( LP_fmHashTableEntry  pHashEntry)
inlineprotected

Definition at line 415 of file CAFirstMix.hpp.

417  {
418  m_pmutexUser->lock();
419  m_nUser--;
420  #ifdef COUNTRY_STATS
421  updateCountryStats(NULL,pHashEntry->countryID,true);
422  #endif
423  m_pmutexUser->unlock();
424  return E_SUCCESS;
425  }
SINT32 updateCountryStats(const UINT8 ip[4], UINT32 a_countryID, bool bRemove)
Update the statisitics of the countries users come from.

References t_fmhashtableentry::countryID, E_SUCCESS, CAMutex::lock(), m_nUser, m_pmutexUser, CAMutex::unlock(), and updateCountryStats().

Referenced by CAFirstMixA::closeConnection(), and CAFirstMixB::loop().

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

◆ deleteCountryStats()

SINT32 CAFirstMix::deleteCountryStats ( )
protected

Definition at line 2979 of file CAFirstMix.cpp.

2980  {
2981  m_bRunLogCountries=false;
2982  if(m_threadLogLoop!=NULL)
2983  {
2984  m_threadLogLoop->join();
2985  delete m_threadLogLoop;
2986  m_threadLogLoop=NULL;
2987  }
2988  if(m_mysqlCon!=NULL)
2989  {
2990  mysql_thread_end();
2991  mysql_close(m_mysqlCon);
2992  m_mysqlCon=NULL;
2993  }
2994 
2995  delete[] m_CountryStats;
2996  m_CountryStats=NULL;
2997 
2998  delete[] m_PacketsPerCountryIN;
2999  m_PacketsPerCountryIN=NULL;
3000 
3001  delete[] m_PacketsPerCountryOUT;
3003  return E_SUCCESS;
3004  }
volatile bool m_bRunLogCountries
Definition: CAFirstMix.hpp:532

References E_SUCCESS, CAThread::join(), m_bRunLogCountries, m_CountryStats, m_mysqlCon, m_PacketsPerCountryIN, m_PacketsPerCountryOUT, and m_threadLogLoop.

Referenced by clean().

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

◆ doUserLogin()

SINT32 CAFirstMix::doUserLogin ( CAMuxSocket pNewUSer,
UINT8  perrIP[4] 
)
protected

Definition at line 1742 of file CAFirstMix.cpp.

1743 {
1744  INIT_STACK;
1745  SINT32 ret = doUserLogin_internal(pNewUser, peerIP);
1746  FINISH_STACK("CAFirstMix::doUserLogin");
1747  return ret;
1748 }
#define INIT_STACK
Definition: CAThread.hpp:48
#define FINISH_STACK(methodName)
Definition: CAThread.hpp:50
SINT32 doUserLogin_internal(CAMuxSocket *pNewUSer, UINT8 perrIP[4])
Sends and receives all data neccessary for a User to "login".

References doUserLogin_internal(), FINISH_STACK, INIT_STACK, T_UserLoginData::peerIP, and T_UserLoginData::pNewUser.

Here is the call graph for this function:

◆ doUserLogin_internal()

SINT32 CAFirstMix::doUserLogin_internal ( CAMuxSocket pNewUser,
UINT8  peerIP[4] 
)
private

Sends and receives all data neccessary for a User to "login".

This means sending the public key of the Mixes and receiving the sym keys of JAP. This is done in a thread on a per user basis

Todo:
Cleanup of runing thread if mix restarts...

TODO: move to the if-statement above

Definition at line 1755 of file CAFirstMix.cpp.

1756  {
1757  SINT32 ret;
1758 
1759  INIT_STACK;
1760  BEGIN_STACK("CAFirstMix::doUserLogin");
1761 
1762 #ifdef __BUILD_AS_SHADOW_PLUGIN__ //the shadow simulator seems to love non-blocking I/O...
1763  pNewUser->getCASocket()->setNonBlocking(true);
1764 #endif
1765 
1766  ret=pNewUser->getCASocket()->setKeepAlive(true);
1767  if(ret!=E_SUCCESS)
1768  CAMsg::printMsg(LOG_DEBUG,"Error setting KeepAlive for user login connection!");
1769 
1770  #ifdef DEBUG
1771  CAMsg::printMsg(LOG_DEBUG,"User login: start\n");
1772  #endif
1773 
1774  SAVE_STACK("CAFirstMix::doUserLogin", "after setting keep alive");
1775 
1776  // send the mix-keys to JAP
1777  if ((ret = pNewUser->getCASocket()->sendFullyTimeOut(m_xmlKeyInfoBuff,m_xmlKeyInfoSize, 40000, 10000)) != E_SUCCESS)
1778  {
1779  if (ret != E_UNKNOWN)
1780  {
1781  CAMsg::printMsg(LOG_DEBUG,"User login: Sending login data to client %u.%u.x.x has been interrupted! Reason: '%s' (%i)\n",
1782  peerIP[0],peerIP[1], GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
1783  }
1784  else
1785  {
1786  CAMsg::printMsg(LOG_DEBUG,"User login: Sending login data to client %u.%u.x.x has been interrupted!\n", peerIP[0],peerIP[1]);
1787  }
1788 
1789  m_pIPBlockList->insertIP(peerIP);
1790 
1791  delete pNewUser;
1792  pNewUser = NULL;
1793  m_pIPList->removeIP(peerIP);
1794  return E_UNKNOWN;
1795  }
1796  #ifdef DEBUG
1797  CAMsg::printMsg(LOG_DEBUG,"User login: login data sent\n");
1798  #endif
1799  SAVE_STACK("CAFirstMix::doUserLogin", "after sending login data");
1800 
1801  //(pNewUser)->send(m_xmlKeyInfoBuff,m_xmlKeyInfoSize);
1802  // es kann nicht blockieren unter der Annahme das der TCP-Sendbuffer > m_xmlKeyInfoSize ist....
1803 
1804  //wait for keys from user
1805  UINT16 xml_len=0;
1806  if(pNewUser->getCASocket()->isClosed())
1807  {
1808  CAMsg::printMsg(LOG_DEBUG,"User login: Socket was closed while waiting for first symmetric key from client!\n");
1809  }
1810  else if ((ret = pNewUser->getCASocket()->receiveFullyT((UINT8*)&xml_len,2,FIRST_MIX_RECEIVE_SYM_KEY_FROM_JAP_TIME_OUT)) != E_SUCCESS)
1811  {
1812  if (ret != E_UNKNOWN)
1813  {
1814  CAMsg::printMsg(LOG_DEBUG,"User login: Waiting for first symmetric key from client %u.%u.x.x! failed for reason: '%s' (%i)\n",
1815  peerIP[0], peerIP[1], GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
1816  }
1817  else
1818  {
1819  CAMsg::printMsg(LOG_DEBUG,"User login: Waiting for first symmetric key from client %u.%u.x.x! failed.\n",
1820  peerIP[0], peerIP[1]);
1821  }
1822  m_pIPBlockList->insertIP(peerIP);
1823 
1824  delete pNewUser;
1825  pNewUser = NULL;
1826  m_pIPList->removeIP(peerIP);
1827  return E_UNKNOWN;
1828  }
1829  #ifdef DEBUG
1830  CAMsg::printMsg(LOG_DEBUG,"User login: received first symmetric key from client\n");
1831  #endif
1832  SAVE_STACK("CAFirstMix::doUserLogin", "received first symmetric key");
1833 
1834  xml_len=ntohs(xml_len);
1835  UINT8* xml_buff=new UINT8[xml_len+2]; //+2 for size...
1836  if(pNewUser->getCASocket()->isClosed() ||
1837  (ret = pNewUser->getCASocket()->receiveFullyT(xml_buff+2,xml_len,FIRST_MIX_RECEIVE_SYM_KEY_FROM_JAP_TIME_OUT)) !=E_SUCCESS)
1838  {
1839  if (pNewUser->getCASocket()->isClosed())
1840  {
1842  }
1843 
1844 
1845  if (ret != E_UNKNOWN)
1846  {
1847  CAMsg::printMsg(LOG_DEBUG,"User login: Waiting for second symmetric key from client failed for reason: '%s' (%i)\n",
1849  }
1850  else
1851  {
1852  CAMsg::printMsg(LOG_DEBUG,"User login: Waiting for second symmetric key from client failed.\n");
1853  }
1854 
1855  m_pIPBlockList->insertIP(peerIP);
1856 
1857  delete pNewUser;
1858  pNewUser = NULL;
1859  delete[] xml_buff;
1860  xml_buff = NULL;
1861  m_pIPList->removeIP(peerIP);
1862  return E_UNKNOWN;
1863  }
1864 
1865  #ifdef DEBUG
1866  CAMsg::printMsg(LOG_DEBUG,"User login: received second symmetric key from client\n");
1867  #endif
1868  SAVE_STACK("CAFirstMix::doUserLogin", "received second symmetric key");
1869 
1870  XERCES_CPP_NAMESPACE::DOMDocument* doc=parseDOMDocument(xml_buff+2,xml_len);
1871  DOMElement* elemRoot=NULL;
1872  if(doc==NULL||(elemRoot=doc->getDocumentElement())==NULL||
1873  decryptXMLElement(elemRoot,m_pRSA)!=E_SUCCESS)
1874  {
1875  delete[] xml_buff;
1876  xml_buff = NULL;
1877  delete pNewUser;
1878  pNewUser = NULL;
1879  m_pIPList->removeIP(peerIP);
1880  if(doc!=NULL)
1881  {
1882  doc->release();
1883  doc = NULL;
1884  }
1885  return E_UNKNOWN;
1886  }
1887  elemRoot=doc->getDocumentElement();
1888  if(!equals(elemRoot->getNodeName(),"JAPKeyExchange"))
1889  {
1890  if (doc != NULL)
1891  {
1892  doc->release();
1893  doc = NULL;
1894  }
1895  delete[] xml_buff;
1896  xml_buff = NULL;
1897  delete pNewUser;
1898  pNewUser = NULL;
1899  m_pIPList->removeIP(peerIP);
1900  return E_UNKNOWN;
1901  }
1902  DOMElement* elemLinkEnc=NULL;
1903  DOMElement* elemMixEnc=NULL;
1904  getDOMChildByName(elemRoot,"LinkEncryption",elemLinkEnc,false);
1905  getDOMChildByName(elemRoot,"MixEncryption",elemMixEnc,false);
1906  UINT8 linkKey[255],mixKey[255];
1907  UINT32 linkKeyLen=255,mixKeyLen=255;
1908  if( getDOMElementValue(elemLinkEnc,linkKey,&linkKeyLen)!=E_SUCCESS||
1909  getDOMElementValue(elemMixEnc,mixKey,&mixKeyLen)!=E_SUCCESS||
1910  CABase64::decode(linkKey,linkKeyLen,linkKey,&linkKeyLen)!=E_SUCCESS||
1911  CABase64::decode(mixKey,mixKeyLen,mixKey,&mixKeyLen)!=E_SUCCESS||
1912  linkKeyLen!=64||mixKeyLen!=32)
1913  {
1914  if (doc != NULL)
1915  {
1916  doc->release();
1917  doc = NULL;
1918  }
1919  delete[] xml_buff;
1920  xml_buff = NULL;
1921  delete pNewUser;
1922  pNewUser = NULL;
1923  m_pIPList->removeIP(peerIP);
1924  return E_UNKNOWN;
1925  }
1926  //Check access control credential if access control is enabled...
1927  if (CALibProxytest::getOptions()->isAccessControlEnabled())
1928  {
1929  DOMElement* elemCredential = NULL;
1930  UINT8 buffUserCredential[255], buffMixCredential[255];
1931  UINT32 lenUserCredential = 255, lenMixCredential = 255;
1932  getDOMChildByName(elemRoot, "AccessControlCredential", elemCredential, false);
1933  if(getDOMElementValue(elemCredential, buffUserCredential, &lenUserCredential)!=E_SUCCESS ||
1934  CALibProxytest::getOptions()->getAccessControlCredential(buffMixCredential, &lenMixCredential)!=E_SUCCESS ||
1935  lenUserCredential!= lenMixCredential ||
1936  memcmp(buffMixCredential, buffUserCredential, lenMixCredential)!=0)
1937  {
1938  if (doc != NULL)
1939  {
1940  doc->release();
1941  doc = NULL;
1942  }
1943  delete[] xml_buff;
1944  xml_buff = NULL;
1945  delete pNewUser;
1946  pNewUser = NULL;
1947  m_pIPList->removeIP(peerIP);
1948  return E_UNKNOWN;
1949  }
1950  }
1951 
1952 
1953  //Getting control channel keys if available
1955  DOMElement* elemControlChannelEnc=NULL;
1956  getDOMChildByName(elemRoot,"ControlChannelEncryption",elemControlChannelEnc,false);
1957  UINT8 controlchannelKey[255];
1958  UINT32 controlchannelKeyLen=255;
1959  UINT8* controlchannelRecvKey=NULL;
1960  UINT8* controlchannelSentKey=NULL;
1961  if( getDOMElementValue(elemControlChannelEnc,controlchannelKey,&controlchannelKeyLen)==E_SUCCESS&&
1962  CABase64::decode(controlchannelKey,controlchannelKeyLen,controlchannelKey,&controlchannelKeyLen)==E_SUCCESS&&
1963  controlchannelKeyLen==32)
1964  {
1965  controlchannelRecvKey=controlchannelKey;
1966  controlchannelSentKey=controlchannelKey+16;
1967  }
1968 
1969  //Sending Signature....
1970  xml_buff[0]=(UINT8)(xml_len>>8);
1971  xml_buff[1]=(UINT8)(xml_len&0xFF);
1972  UINT8* sig=new UINT8[255];
1973  UINT32 siglen=255;
1974  //TODO change me to fully support MultiSig
1975  //m_pSignature->sign(xml_buff,xml_len+2,sig,&siglen);
1976  m_pMultiSignature->sign(xml_buff,xml_len+2,sig,&siglen);
1977  XERCES_CPP_NAMESPACE::DOMDocument* docSig=createDOMDocument();
1978 
1979  DOMElement *elemSig=NULL;
1980 
1981 #ifdef LOG_DIALOG
1982  DOMElement* elemDialog=NULL;
1983  getDOMChildByName(elemRoot,"Dialog",elemDialog,false);
1984  UINT8 strDialog[255];
1985  memset(strDialog,0,255);
1986  UINT32 dialogLen=255;
1987  getDOMElementValue(elemDialog,strDialog,&dialogLen);
1988 #endif
1989 #ifdef REPLAY_DETECTION
1990  //checking if Replay-Detection is enabled
1991  DOMElement *elemReplay=NULL;
1992  UINT8 replay[6];
1993  UINT32 replay_len=5;
1994  if( (getDOMChildByName(elemRoot,"ReplayDetection",elemReplay,false)==E_SUCCESS)&&
1995  (getDOMElementValue(elemReplay,replay,&replay_len)==E_SUCCESS)&&
1996  (strncmp((char*)replay,"true",5)==0)){
1997  elemRoot=createDOMElement(docSig,"MixExchange");
1998  elemReplay=createDOMElement(docSig,"Replay");
1999  docSig->appendChild(elemRoot);
2000  elemRoot->appendChild(elemReplay);
2001 
2002  UINT32 diff=(UINT32)(time(NULL)-m_u64LastTimestampReceived);
2003  for(SINT32 i=0;i<getMixCount()-1;i++)
2004  {
2005  DOMElement* elemMix=createDOMElement(docSig,"Mix");
2006  setDOMElementAttribute(elemMix,"id",m_arMixParameters[i].m_strMixID);
2007  DOMElement* elemReplayOffset=createDOMElement(docSig,"ReplayOffset");
2008  setDOMElementValue(elemReplayOffset,(UINT32) (m_arMixParameters[i].m_u32ReplayOffset+diff));
2009  elemMix->appendChild(elemReplayOffset);
2010  DOMElement* elemReplayBase=createDOMElement(docSig,"ReplayBase");
2011  setDOMElementValue(elemReplayBase,(UINT32) (m_arMixParameters[i].m_u32ReplayBase));
2012  elemMix->appendChild(elemReplayBase);
2013  elemReplay->appendChild(elemMix);
2014  }
2015 
2016  DOMElement* elemMix=createDOMElement(docSig,"Mix");
2017  UINT8 buff[255];
2018  CALibProxytest::getOptions()->getMixId(buff,255);
2019  setDOMElementAttribute(elemMix,"id",buff);
2020  DOMElement* elemReplayOffset=createDOMElement(docSig,"ReplayOffset");
2021  setDOMElementValue(elemReplayOffset,(UINT32) (time(NULL)-m_u64ReferenceTime));
2022  elemMix->appendChild(elemReplayOffset);
2023  DOMElement* elemReplayBase=createDOMElement(docSig,"ReplayBase");
2024  setDOMElementValue(elemReplayBase,(UINT32) (REPLAY_BASE));
2025  elemMix->appendChild(elemReplayOffset);
2026  elemReplay->appendChild(elemMix);
2027 
2028  elemSig=createDOMElement(docSig,"Signature");
2029  elemRoot->appendChild(elemSig);
2030 
2031  CAMsg::printMsg(LOG_DEBUG,"Replay Detection requested\n");
2032  }
2033  else {
2034  elemSig=createDOMElement(docSig,"Signature");
2035  docSig->appendChild(elemSig);
2036  }
2037 #endif
2038 #ifndef REPLAY_DETECTION
2039  elemSig=createDOMElement(docSig,"Signature");
2040  docSig->appendChild(elemSig);
2041 #endif
2042  DOMElement* elemSigValue=createDOMElement(docSig,"SignatureValue");
2043  elemSig->appendChild(elemSigValue);
2044  UINT32 u32=siglen;
2045  CABase64::encode(sig,u32,sig,&siglen);
2046  sig[siglen]=0;
2047  setDOMElementValue(elemSigValue,sig);
2048  delete[] sig;
2049  u32=xml_len;
2050  DOM_Output::dumpToMem(docSig,xml_buff+2,&u32);
2051  if (docSig != NULL)
2052  {
2053  docSig->release();
2054  docSig = NULL;
2055  }
2056  xml_buff[0]=(UINT8)(u32>>8);
2057  xml_buff[1]=(UINT8)(u32&0xFF);
2058 
2059  if (pNewUser->getCASocket()->isClosed() ||
2060  pNewUser->getCASocket()->sendFullyTimeOut(xml_buff,u32+2, 30000, 10000) != E_SUCCESS)
2061  {
2062  if (doc != NULL)
2063  {
2064  doc->release();
2065  doc = NULL;
2066  }
2067  CAMsg::printMsg(LOG_DEBUG,"User login: Sending key exchange signature has been interrupted!\n");
2068  m_pIPBlockList->insertIP(peerIP);
2069 
2070  delete[] xml_buff;
2071  xml_buff = NULL;
2072  delete pNewUser;
2073  pNewUser = NULL;
2074  m_pIPList->removeIP(peerIP);
2075  return E_UNKNOWN;
2076  }
2077  #ifdef DEBUG
2078  CAMsg::printMsg(LOG_DEBUG,"User login: key exchange signature sent\n");
2079  #endif
2080  delete[] xml_buff;
2081  xml_buff = NULL;
2082 #if 0 //terms and conditions sending disabled.
2083  /* handle Terms And Conditions */
2084  bool loginFailed = false;
2085  bool tcProcedureFinished = false;
2086 
2087  while( !(tcProcedureFinished || loginFailed) )
2088  {
2089  UINT16 tcRequestDataLen = 0;
2090  if (pNewUser->getCASocket()->isClosed() ||
2091  (ret = pNewUser->getCASocket()->receiveFullyT((UINT8*)&tcRequestDataLen, 2, 10000)) != E_SUCCESS)
2092  {
2093  if (pNewUser->getCASocket()->isClosed())
2094  {
2096  }
2097 
2098  loginFailed = true;
2099  if (ret != E_UNKNOWN)
2100  {
2101  CAMsg::printMsg(LOG_ERR,"User login: Receiving t&c protocol data size has been interrupted. Reason: '%s' (%i)\n",
2103  }
2104  else
2105  {
2106  CAMsg::printMsg(LOG_ERR,"User login: Receiving t&c protocol data size has been interrupted.\n");
2107  }
2108  break;
2109  }
2110 
2111  tcRequestDataLen = ntohs(tcRequestDataLen);
2112  //CAMsg::printMsg(LOG_DEBUG,"User login: expecting %u bytes!\n", tcRequestDataLen);
2113  UINT8 tcDataBuf[tcRequestDataLen+1];
2114  tcDataBuf[tcRequestDataLen] = 0;
2115  if (pNewUser->getCASocket()->isClosed() ||
2116  (ret = pNewUser->getCASocket()->receiveFullyT(tcDataBuf, tcRequestDataLen, 10000)) != E_SUCCESS)
2117  {
2118  if (pNewUser->getCASocket()->isClosed())
2119  {
2121  }
2122 
2123  loginFailed = true;
2124 
2125  if (ret != E_UNKNOWN)
2126  {
2127  CAMsg::printMsg(LOG_ERR,"User login: Receiving t&c protocol data has been interrupted. Reason: '%s' (%i)\n",
2129  }
2130  else
2131  {
2132  CAMsg::printMsg(LOG_ERR,"User login: Receiving t&c protocol data has been interrupted.\n");
2133  }
2134  break;
2135  }
2136 
2137  XERCES_CPP_NAMESPACE::DOMDocument *tcData = parseDOMDocument(tcDataBuf, tcRequestDataLen);
2138  if( (tcData == NULL) || (tcData->getDocumentElement() == NULL) )
2139  {
2140  CAMsg::printMsg(LOG_ERR,"Could not parse t&c data!\n");
2141  loginFailed = true;
2142  break;
2143  }
2144 
2146  if(answer == NULL)
2147  {
2148  loginFailed = true;
2149  tcData->release();
2150  tcData = NULL;
2151  break;
2152  }
2153 
2154  if( (answer->xmlAnswer != NULL) )
2155  {
2156  UINT32 size = 0;
2157  UINT8 *answerBuff = DOM_Output::dumpToMem(answer->xmlAnswer, &size);
2158  if(answerBuff != NULL)
2159  {
2160  //CAMsg::printMsg(LOG_DEBUG,"User login: answer %s\n", answerBuff);
2161 
2162  UINT32 netSize = htonl(size);
2163 
2164  if (pNewUser->getCASocket()->isClosed() ||
2165  pNewUser->getCASocket()->sendFullyTimeOut((UINT8 *) &netSize, 4, 30000, 10000) != E_SUCCESS)
2166  {
2167  CAMsg::printMsg(LOG_DEBUG,"User login: sending t&c protocol data size has been interrupted!\n");
2168  loginFailed = true;
2169  }
2170  else if (pNewUser->getCASocket()->isClosed() ||
2171  pNewUser->getCASocket()->sendFullyTimeOut(answerBuff, size, 30000, 10000) != E_SUCCESS)
2172  {
2173  CAMsg::printMsg(LOG_DEBUG,"User login: Sending t&c protocol data has been interrupted!\n");
2174  loginFailed = true;
2175  }
2176  delete [] answerBuff;
2177  }
2178  }
2179  tcProcedureFinished = (answer->result != TC_UNFINISHED);
2180  loginFailed = (answer->result == TC_FAILED);
2181  cleanupTnCMixAnswer(answer);
2182  delete answer;
2183  answer = NULL;
2184  tcData->release();
2185  tcData = NULL;
2186  }
2187 
2188  //Only if a positive confirm message was received, the client may pass!
2189 
2190  if(loginFailed)
2191  {
2192  if (doc != NULL)
2193  {
2194  doc->release();
2195  doc = NULL;
2196  }
2197  CAMsg::printMsg(LOG_DEBUG,"User login: failed!\n");
2198  delete[] xml_buff;
2199  xml_buff = NULL;
2200  delete pNewUser;
2201  pNewUser = NULL;
2202  m_pIPList->removeIP(peerIP);
2203  return E_UNKNOWN;
2204  }
2205  /* end Terms And Conditions negotiation */
2206 #endif
2207  SAVE_STACK("CAFirstMix::doUserLogin", "sent key exchange signature");
2208 
2209  pNewUser->getCASocket()->setNonBlocking(true);
2210 
2211  SAVE_STACK("CAFirstMix::doUserLogin", "Creating CAQueue...");
2212  CAQueue* tmpQueue=new CAQueue(sizeof(tQueueEntry));
2213 
2214  SAVE_STACK("CAFirstMix::doUserLogin", "Adding user to connection list...");
2215 #ifdef LOG_DIALOG
2216  fmHashTableEntry* pHashEntry=m_pChannelList->add(pNewUser,peerIP,tmpQueue,strDialog);
2217 #else
2218 #ifndef MULTI_THREADED_PACKET_PROCESSING
2219  fmHashTableEntry* pHashEntry=m_pChannelList->add(pNewUser,peerIP,tmpQueue,controlchannelSentKey,controlchannelRecvKey);
2220 #else
2221  UINT32 threadID = pNewUser->getHashKey()%m_numThreads;
2222  CAFirstMixChannelList* pChannelList = m_arpChannelList[threadID];
2223  fmHashTableEntry* pHashEntry=pChannelList->add(pNewUser,peerIP,tmpQueue,controlchannelSentKey,controlchannelRecvKey);
2224 #endif
2225 #endif
2226  if( (pHashEntry == NULL) ||
2227  (pHashEntry->pControlMessageQueue == NULL) )// adding user connection to mix->JAP channel list (stefan: sollte das nicht connection list sein? --> es handelt sich um eine Datenstruktu fr Connections/Channels ).
2228  {
2229  if (doc != NULL)
2230  {
2231  doc->release();
2232  doc = NULL;
2233  }
2234  CAMsg::printMsg(LOG_ERR,"User login: Could not add new socket to connection list!\n");
2235  if (pHashEntry != NULL)
2236  {
2237 #ifndef MULTI_THREADED_PACKET_PROCESSING
2238  m_pChannelList->remove(pNewUser);
2239 #else
2240  pChannelList->remove(pNewUser);
2241 #endif
2242  }
2243  m_pIPList->removeIP(peerIP);
2244  delete tmpQueue;
2245  tmpQueue = NULL;
2246  delete pNewUser;
2247  pNewUser = NULL;
2248  return E_UNKNOWN;
2249  }
2250 
2251  SAVE_STACK("CAFirstMix::doUserLogin", "socket added to connection list");
2252 #ifdef PAYMENT
2253  #ifdef DEBUG
2254  CAMsg::printMsg(LOG_DEBUG,"User login: registering payment control channel\n");
2255  #endif
2257  SAVE_STACK("CAFirstMix::doUserLogin", "payment registered");
2258 #endif
2259  pHashEntry->pSymCipher=CASymChannelCipherFactory::createCipher(CALibProxytest::getOptions()->getSymChannelCipherAlgorithm());
2260  pHashEntry->pSymCipher->setKey(mixKey);
2261  pHashEntry->pSymCipher->setIVs(mixKey+16);
2262  pNewUser->setReceiveKey(linkKey,32);
2263  pNewUser->setSendKey(linkKey+32,32);
2264  pNewUser->setCrypt(true);
2265 
2266  if (doc != NULL)
2267  {
2268  doc->release();
2269  doc = NULL;
2270  }
2271 #ifdef PAYMENT
2272 
2273  SAVE_STACK("CAFirstMix::doUserLogin", "Starting AI login procedure");
2274 #ifdef DEBUG
2275  CAMsg::printMsg(LOG_DEBUG,"Starting AI login procedure for owner %x \n", pHashEntry);
2276 #endif
2277  SINT32 ai_ret;
2278  MIXPACKET *paymentLoginPacket = new MIXPACKET;
2279  tQueueEntry *aiAnswerQueueEntry=new tQueueEntry;
2280  CAQueue *controlMessages = pHashEntry->pControlMessageQueue;
2281  UINT32 qlen=sizeof(tQueueEntry);
2282  SINT32 aiLoginStatus = 0;
2283  aiLoginStatus = CAAccountingInstance::loginProcessStatus(pHashEntry);
2284  while(aiLoginStatus & AUTH_LOGIN_NOT_FINISHED)
2285  {
2286  if(pNewUser->receive(paymentLoginPacket, AI_LOGIN_SO_TIMEOUT) != MIXPACKET_SIZE)
2287  {
2288  CAMsg::printMsg(LOG_INFO,"AI login: client receive timeout.\n");
2289  aiLoginStatus = AUTH_LOGIN_FAILED;
2290  break;
2291  }
2292  if(paymentLoginPacket->channel > 0 && paymentLoginPacket->channel < 256)
2293  {
2294  if(!pHashEntry->pControlChannelDispatcher->proccessMixPacket(paymentLoginPacket))
2295  {
2296  aiLoginStatus = AUTH_LOGIN_FAILED;
2297  break;
2298  }
2299 
2300  while(controlMessages->getSize()>0)
2301  {
2302  controlMessages->get((UINT8*)aiAnswerQueueEntry,&qlen);
2303  pNewUser->prepareForSend(&(aiAnswerQueueEntry->packet));
2304  ai_ret = pNewUser->getCASocket()->
2305  sendFullyTimeOut(((UINT8*)&(aiAnswerQueueEntry->packet)), MIXPACKET_SIZE, 3*(AI_LOGIN_SO_TIMEOUT), AI_LOGIN_SO_TIMEOUT);
2306  if (ai_ret != E_SUCCESS)
2307  {
2308  if(ai_ret == E_TIMEDOUT )
2309  {
2310  CAMsg::printMsg(LOG_INFO,"timeout occurred during AI login.");
2311  }
2312  aiLoginStatus = AUTH_LOGIN_FAILED;
2313  goto loop_break;
2314  }
2315  }
2316  if(aiLoginStatus == AUTH_LOGIN_FAILED)
2317  {
2318  break;
2319  }
2320  }
2321  aiLoginStatus = CAAccountingInstance::loginProcessStatus(pHashEntry);
2322  }
2323 loop_break:
2324  SAVE_STACK("CAFirstMix::doUserLogin", "AI login packages exchanged.");
2325  /* We have exchanged all AI login packets:
2326  * 1. AccountCert
2327  * 2. ChallengeResponse
2328  * 3. Cost confirmation.
2329  * Now start settlement to ensure that the clients account is balanced
2330  */
2331  if(!(aiLoginStatus & AUTH_LOGIN_FAILED))
2332  {
2333  if(!(aiLoginStatus & (AUTH_LOGIN_SKIP_SETTLEMENT )) || (aiLoginStatus & (AUTH_WAITING_FOR_FIRST_SETTLED_CC)) )
2334  {
2335 //#ifdef DEBUG
2336  CAMsg::printMsg(LOG_DEBUG,"AI login messages successfully exchanged: now starting settlement for user account balancing check\n");
2337 //#endif
2339  {
2340  aiLoginStatus |= AUTH_LOGIN_FAILED;
2341  }
2342  }
2343 //#ifdef DEBUG
2344  else
2345  {
2346  CAMsg::printMsg(LOG_DEBUG,"AI login messages successfully exchanged: skipping settlement, user has valid prepaid amount\n");
2347  }
2348 //#endif
2349  }
2350 
2351  if(!(aiLoginStatus & AUTH_LOGIN_FAILED))
2352  {
2353  aiLoginStatus = CAAccountingInstance::finishLoginProcess(pHashEntry);
2354  if(pNewUser != NULL)
2355  {
2356  while(controlMessages->getSize()>0)
2357  {
2358  controlMessages->get((UINT8*)aiAnswerQueueEntry,&qlen);
2359  pNewUser->prepareForSend(&(aiAnswerQueueEntry->packet));
2360 
2361  //not really elegant but works: if the client closed the socket during the settlement
2362  //the first send will succeed but the second one will fail.
2363  ai_ret = pNewUser->getCASocket()->
2364  sendFullyTimeOut(((UINT8*)&(aiAnswerQueueEntry->packet)), 499, 3*(AI_LOGIN_SO_TIMEOUT), AI_LOGIN_SO_TIMEOUT);
2365 
2366  ai_ret = pNewUser->getCASocket()->
2367  sendFullyTimeOut(((UINT8*)&(aiAnswerQueueEntry->packet)+499), 499, 3*(AI_LOGIN_SO_TIMEOUT), AI_LOGIN_SO_TIMEOUT);
2368  if (ai_ret != E_SUCCESS)
2369  {
2370  int errnum = errno;
2371  CAMsg::printMsg(LOG_INFO,"AI login: net error occured after settling: %s\n", strerror(errnum));
2372  aiLoginStatus |= AUTH_LOGIN_FAILED;
2373  break;
2374  }
2375  }
2376  }
2377  else
2378  {
2379  CAMsg::printMsg(LOG_DEBUG,"Socket was disposed.\n");
2380  aiLoginStatus |= AUTH_LOGIN_FAILED;
2381  }
2382  }
2383 
2384  delete paymentLoginPacket;
2385  paymentLoginPacket = NULL;
2386  delete aiAnswerQueueEntry;
2387  aiAnswerQueueEntry = NULL;
2388 
2389  SAVE_STACK("CAFirstMix::doUserLogin", "AI login procedure finished.");
2390 
2391  if((aiLoginStatus & AUTH_LOGIN_FAILED))
2392  {
2393 #ifdef DEBUG
2394  CAMsg::printMsg(LOG_INFO,"User AI login failed: deleting socket %x\n", pHashEntry);
2395 #endif
2397  m_pChannelList->remove(pNewUser);
2398  delete pNewUser;
2399  pNewUser = NULL;
2400  m_pIPList->removeIP(peerIP);
2401  return E_UNKNOWN;
2402  }
2403  /* Hot fix: push timeout entry only if login was succesful, otherwise
2404  * socket may be deleted due to timeout, login fails and the socket will be deleted
2405  * for second time causing a segfault.
2406  */
2407  m_pChannelList->pushTimeoutEntry(pHashEntry);
2408 
2409 
2410 #ifdef LOG_CRIME
2411  UINT64 accountNumber = CAAccountingInstance::unlockLogin(pHashEntry);
2412  UINT64* surveillanceAccounts = CALibProxytest::getOptions()->getCrimeSurveillanceAccounts();
2413  UINT32 nrOfSurveillanceAccounts = CALibProxytest::getOptions()->getNrOfCrimeSurveillanceAccounts();
2414 
2415  for (UINT32 iAccount = 0; iAccount < nrOfSurveillanceAccounts; iAccount++)
2416  {
2417  if (accountNumber == surveillanceAccounts[iAccount])
2418  {
2419  CAMsg::printMsg(LOG_CRIT,"Crime detection: User logged in with account %llu has IP %u.%u.%u.%u\n",accountNumber, peerIP[0], peerIP[1], peerIP[2], peerIP[3]);
2420  break;
2421  }
2422  }
2423 #else
2425 #endif
2426 
2427 #ifdef DEBUG
2428  CAMsg::printMsg(LOG_INFO,"User AI login successful for owner %x\n", pHashEntry);
2429 #endif
2430 #endif
2431 
2432 #ifdef WITH_CONTROL_CHANNELS_TEST
2433  pHashEntry->pControlChannelDispatcher->registerControlChannel(new CAControlChannelTest());
2434 #endif
2435 #ifdef REPLAY_DETECTION
2437 #endif
2438 #ifdef COUNTRY_STATS
2439  incUsers(pHashEntry);
2440 #else
2441  incUsers();
2442 #endif
2443 #ifdef HAVE_EPOLL
2444 #ifndef MULTI_THREADED_PACKET_PROCESSING
2445  m_psocketgroupUsersRead->add(*pNewUser,m_pChannelList->get(pNewUser)); // add user socket to the established ones that we read data from.
2446  m_psocketgroupUsersWrite->add(*pNewUser,m_pChannelList->get(pNewUser));
2447 #else
2448  m_arpsocketgroupUsersRead[threadID]->add(*pNewUser,pChannelList->get(pNewUser)); // add user socket to the established ones that we read data from.
2449  m_arpsocketgroupUsersWrite[threadID]->add(*pNewUser,pChannelList->get(pNewUser));
2450 #endif
2451 #else //no E_POLL
2452 #ifndef MULTI_THREADED_PACKET_PROCESSING
2453  if(m_psocketgroupUsersRead->add(*pNewUser)!=E_SUCCESS)// add user socket to the established ones that we read data from.
2454  {
2455  CAMsg::printMsg(LOG_DEBUG,"User login: Adding to m_psocketgroupUsersRead failed!\n");
2456  }
2457  if( m_psocketgroupUsersWrite->add(*pNewUser)!=E_SUCCESS)
2458  {
2459  CAMsg::printMsg(LOG_DEBUG,"User login: Adding to m_psocketgroupUsersWrite failed!\n");
2460  }
2461 #else
2462  if(m_arpsocketgroupUsersRead[threadID]->add(*pNewUser)!=E_SUCCESS)// add user socket to the established ones that we read data from.
2463  {
2464  CAMsg::printMsg(LOG_DEBUG,"User login: Adding to m_psocketgroupUsersRead failed!\n");
2465  }
2466  if( m_arpsocketgroupUsersWrite[threadID]->add(*pNewUser)!=E_SUCCESS)
2467  {
2468  CAMsg::printMsg(LOG_DEBUG,"User login: Adding to m_psocketgroupUsersWrite failed!\n");
2469  }
2470 #endif
2471 #endif
2472 
2473 #ifndef LOG_DIALOG
2474  CAMsg::printMsg(LOG_INFO,"User login: finished\n");
2475 #else
2476  CAMsg::printMsg(LOG_INFO,"User login: finished -- connection-ID: %Lu -- country-id: %u -- dialog: %s\n",pHashEntry->id,pHashEntry->countryID,pHashEntry->strDialog);
2477 #endif
2478  return E_SUCCESS;
2479  }
#define REPLAY_BASE
#define BEGIN_STACK(methodName)
Definition: CAThread.hpp:49
#define SAVE_STACK(methodName, methodPosition)
Definition: CAThread.hpp:51
SINT32 setDOMElementAttribute(DOMNode *pElem, const char *attrName, const char *value)
Definition: CAUtil.cpp:831
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
bool equals(const XMLCh *const e1, const char *const e2)
Definition: CAUtil.cpp:645
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 decryptXMLElement(DOMNode *node, CAASymCipher *pRSA)
Replaces a DOM element with a deencrypted version of this element.
Definition: CAUtil.cpp:1224
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
#define SET_NET_ERROR(x)
Definition: StdAfx.h:470
#define FIRST_MIX_RECEIVE_SYM_KEY_FROM_JAP_TIME_OUT
Definition: StdAfx.h:197
#define AI_LOGIN_SO_TIMEOUT
Definition: StdAfx.h:199
void cleanupTnCMixAnswer(termsAndConditionMixAnswer_t *answer)
IMPORTANT NOTE: all methods does NOT incorporate locking over the translation store and thus are NOT ...
@ TC_FAILED
@ TC_UNFINISHED
unsigned short UINT16
Definition: basetypedefs.h:133
implementation of a per-user control-channel for the AccountingInstance.
static SINT32 loginProcessStatus(fmHashTableEntry *pHashEntry)
static SINT32 newSettlementTransaction()
static UINT64 unlockLogin(fmHashTableEntry *ownerRef)
release login (particularly for use in error case) this function is thread-safe.
static SINT32 finishLoginProcess(fmHashTableEntry *pHashEntry)
this method is for the corresponding CAFirstMix login thread to verify the result of the settlement.
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
SINT32 getMixId(UINT8 *id, UINT32 len)
SINT32 registerControlChannel(CAAbstractControlChannel *pControlChannel)
Registers a control channel for receiving messages.
bool proccessMixPacket(const MIXPACKET *pPacket)
Data structure that stores all information about the currently open Mix channels.
fmChannelListEntry * get(CAMuxSocket *pMuxSocket, HCHANNEL channelIn)
Returns the information for a given Input-Channel-ID.
fmHashTableEntry * add(CAMuxSocket *pMuxSocket, const UINT8 peerIP[4], CAQueue *pQueueSend, UINT8 *controlChannelKeyRecv, UINT8 *controlChannelKeySent)
Adds a new TCP/IP connection (a new user) to the channel list.
SINT32 pushTimeoutEntry(fmHashTableEntry *pHashTableEntry, bool kickoutForced=!KICKOUT_FORCED)
adds the entry to the timeout queue with mutex
termsAndConditionMixAnswer_t * handleTermsAndConditionsLogin(XERCES_CPP_NAMESPACE::DOMDocument *request)
SINT32 incUsers(LP_fmHashTableEntry pHashEntry)
Definition: CAFirstMix.hpp:400
UINT64 m_u64LastTimestampReceived
Definition: CAFirstMix.hpp:393
SINT32 getMixCount()
Definition: CAFirstMix.hpp:374
UINT16 m_xmlKeyInfoSize
Definition: CAFirstMix.hpp:493
SINT32 removeIP(const UINT8 ip[4])
Removes the IP-Address from the list.
Definition: CAIPList.cpp:189
static CACmdLnOptions * getOptions()
CAMultiSignature * m_pMultiSignature
Definition: CAMix.hpp:183
SINT32 sign(UINT8 *in, UINT32 inlen, UINT8 *sig, UINT32 *siglen)
Method for producing a single Signature for Key Exchange.
SINT32 receive(MIXPACKET *pPacket)
Receives a whole MixPacket.
SINT32 setSendKey(UINT8 *key, UINT32 keyLen)
SINT32 setReceiveKey(UINT8 *key, UINT32 keyLen)
SINT32 setCrypt(bool b)
SINT32 getHashKey()
Returns a Hashkey which uniquely identifies this socket.
Definition: CAMuxSocket.hpp:52
CASocket * getCASocket()
Definition: CAMuxSocket.hpp:84
SINT32 prepareForSend(MIXPACKET *inoutPacket)
This is a simple FIFO-Queue.
Definition: CAQueue.hpp:50
SINT32 get(UINT8 *pbuff, UINT32 *psize)
Gets up to psize number of bytes from the Queue.
Definition: CAQueue.cpp:148
UINT32 getSize()
Returns the size of stored data in byte.
Definition: CAQueue.hpp:101
A Control channel for the exchange of the current replay detection timestamps.
SINT32 add(CASocket &s)
Adds the socket s to the socket group.
virtual SINT32 setKeepAlive(bool b)
Enables/disables the socket keep-alive option.
Definition: CASocket.cpp:906
virtual SINT32 receiveFullyT(UINT8 *buff, UINT32 len, UINT32 msTimeOut)
Trys to receive all bytes.
Definition: CASocket.cpp:677
virtual bool isClosed()
Definition: CASocket.hpp:132
virtual SINT32 setNonBlocking(bool b)
Definition: CASocket.cpp:947
virtual SINT32 sendFullyTimeOut(const UINT8 *buff, UINT32 len, UINT32 msTimeOut, UINT32 msTimeOutSingleSend)
Sends all data over the network.
Definition: CASocket.cpp:488
static CASymChannelCipher * createCipher(SYMCHANNELCIPHER_ALGORITHM alg)
virtual SINT32 setKey(const UINT8 *key)=0
Sets the keys for crypt1() and crypt2() to the same key.
virtual SINT32 setIVs(const UINT8 *p_iv)=0
Sets iv1 and iv2 to p_iv.
SINT32 insertIP(const UINT8 ip[4])
inserts an IP into the blocklist
static SINT32 dumpToMem(const DOMNode *node, UINT8 *buff, UINT32 *size)
Dumps the node and all childs into buff.
Definition: DOM_Output.hpp:161
#define E_SOCKETCLOSED
Definition: errorcodes.hpp:11
#define E_TIMEDOUT
Definition: errorcodes.hpp:10
HCHANNEL channel
Definition: typedefs.hpp:117
CAControlChannelDispatcher * pControlChannelDispatcher
XERCES_CPP_NAMESPACE::DOMDocument * xmlAnswer
#define MIXPACKET_SIZE
Definition: typedefs.hpp:40
#define AUTH_LOGIN_NOT_FINISHED
Definition: typedefs.hpp:288
#define AUTH_LOGIN_FAILED
Definition: typedefs.hpp:289
#define AUTH_WAITING_FOR_FIRST_SETTLED_CC
First CC from client has not been settled yet.
Definition: typedefs.hpp:239
t_MixPacket MIXPACKET
Definition: typedefs.hpp:127
#define AUTH_LOGIN_SKIP_SETTLEMENT
Definition: typedefs.hpp:290

References CAFirstMixChannelList::add(), AI_LOGIN_SO_TIMEOUT, AUTH_LOGIN_FAILED, AUTH_LOGIN_NOT_FINISHED, AUTH_LOGIN_SKIP_SETTLEMENT, AUTH_WAITING_FOR_FIRST_SETTLED_CC, BEGIN_STACK, t_MixPacket::channel, cleanupTnCMixAnswer(), CASymChannelCipherFactory::createCipher(), createDOMDocument(), createDOMElement(), CABase64::decode(), decryptXMLElement(), DOM_Output::dumpToMem(), E_SOCKETCLOSED, E_SUCCESS, E_TIMEDOUT, E_UNKNOWN, CABase64::encode(), equals(), CAAccountingInstance::finishLoginProcess(), FIRST_MIX_RECEIVE_SYM_KEY_FROM_JAP_TIME_OUT, CAQueue::get(), GET_NET_ERROR, GET_NET_ERROR_STR, CAMuxSocket::getCASocket(), getDOMChildByName(), getDOMElementValue(), CAMuxSocket::getHashKey(), getMixCount(), CACmdLnOptions::getMixId(), CALibProxytest::getOptions(), CAQueue::getSize(), handleTermsAndConditionsLogin(), INIT_STACK, CATempIPBlockList::insertIP(), CASocket::isClosed(), CAAccountingInstance::loginProcessStatus(), m_arMixParameters, m_pChannelList, m_pIPBlockList, m_pIPList, CAMix::m_pMultiSignature, m_pRSA, m_u64LastTimestampReceived, CAMixWithReplayDB::m_u64ReferenceTime, m_xmlKeyInfoBuff, m_xmlKeyInfoSize, MIXPACKET_SIZE, CAAccountingInstance::newSettlementTransaction(), parseDOMDocument(), t_fmhashtableentry::pControlChannelDispatcher, t_fmhashtableentry::pControlMessageQueue, T_UserLoginData::peerIP, T_UserLoginData::pNewUser, CAMuxSocket::prepareForSend(), CAMsg::printMsg(), CAControlChannelDispatcher::proccessMixPacket(), t_fmhashtableentry::pSymCipher, CAMuxSocket::receive(), CASocket::receiveFullyT(), CAControlChannelDispatcher::registerControlChannel(), CAFirstMixChannelList::remove(), CAIPList::removeIP(), REPLAY_BASE, termsAndConditionMixAnswer_t::result, SAVE_STACK, CASocket::sendFullyTimeOut(), SET_NET_ERROR, CAMuxSocket::setCrypt(), setDOMElementAttribute(), setDOMElementValue(), CASymChannelCipher::setIVs(), CASocket::setKeepAlive(), CASymChannelCipher::setKey(), CASocket::setNonBlocking(), CAMuxSocket::setReceiveKey(), CAMuxSocket::setSendKey(), CAMultiSignature::sign(), TC_FAILED, TC_UNFINISHED, and termsAndConditionMixAnswer_t::xmlAnswer.

Referenced by doUserLogin().

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

◆ forceKickout()

bool CAFirstMix::forceKickout ( fmHashTableEntry pHashTableEntry,
const XERCES_CPP_NAMESPACE::DOMDocument *  pErrDoc = NULL 
)

Definition at line 2482 of file CAFirstMix.cpp.

2483 {
2484  return m_pChannelList->forceKickout(pHashTableEntry, pErrDoc);
2485 }
bool forceKickout(fmHashTableEntry *pHashTableEntry, const XERCES_CPP_NAMESPACE::DOMDocument *pErrDoc)
forces a kickout for this entry if the entry is still valid and sends an errorMessage via the control...

References CAFirstMixChannelList::forceKickout(), and m_pChannelList.

Referenced by CAAccountingInstance::handleChallengeResponse_internal().

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

◆ getLevel()

SINT32 CAFirstMix::getLevel ( SINT32 puser,
SINT32 prisk,
SINT32 ptraffic 
)

Definition at line 2901 of file CAFirstMix.cpp.

2902 {
2903  *puser=(SINT32)getNrOfUsers();
2904  *prisk=-1;
2905  *ptraffic=-1;
2906  return E_SUCCESS;
2907 }
UINT32 getNrOfUsers()

References E_SUCCESS, and getNrOfUsers().

Here is the call graph for this function:

◆ getLoginMutex()

CAMutex* CAFirstMix::getLoginMutex ( )
inline

Definition at line 325 of file CAFirstMix.hpp.

326  {
327  return m_pmutexLogin;
328  }

References m_pmutexLogin.

Referenced by CAAccountingInstance::handleChallengeResponse_internal().

Here is the caller graph for this function:

◆ getMixCount()

SINT32 CAFirstMix::getMixCount ( )
inline

Definition at line 374 of file CAFirstMix.hpp.

375  {
376  return m_u32MixCount;
377  }

References m_u32MixCount.

Referenced by doUserLogin_internal().

Here is the caller graph for this function:

◆ getMixedPackets()

SINT32 CAFirstMix::getMixedPackets ( UINT64 ppackets)

Definition at line 2895 of file CAFirstMix.cpp.

2896 {
2897  set64(ppackets,m_nMixedPackets);
2898  return E_SUCCESS;
2899 }
void set64(UINT64 &op1, UINT32 op2)
Definition: CAUtil.hpp:321

References E_SUCCESS, m_nMixedPackets, and set64().

Here is the call graph for this function:

◆ getMixParameters()

tMixParameters* CAFirstMix::getMixParameters ( )
inline

Returns the ordered list of the mix parameters from the first mix to the last mix.

Definition at line 379 of file CAFirstMix.hpp.

380  {
381  return m_arMixParameters;
382  }

References m_arMixParameters.

◆ getNrOfUsers()

UINT32 CAFirstMix::getNrOfUsers ( )

Definition at line 2886 of file CAFirstMix.cpp.

2887 {
2888  #ifdef PAYMENT
2890  #else
2891  return m_nUser;
2892  #endif
2893 }

References CAAccountingInstance::getNrOfUsers(), and m_nUser.

Referenced by getLevel().

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

◆ getTermsAndConditions()

TermsAndConditions * CAFirstMix::getTermsAndConditions ( const UINT8 opSki)

Definition at line 932 of file CAFirstMix.cpp.

933 {
934  if( (m_tnCDefs == NULL) || (opSki == NULL) )
935  {
936  return NULL;
937  }
938  for(UINT32 i = 0; i < m_nrOfTermsAndConditionsDefs; i++)
939  {
940  if(m_tnCDefs[i] != NULL)
941  {
942  if(strncasecmp((char *) m_tnCDefs[i]->getID(),
943  (const char *) opSki,
944  strlen((char *) m_tnCDefs[i]->getID())) == 0)
945  {
946  return m_tnCDefs[i];
947  }
948  }
949  }
950  return NULL;
951 }

References m_nrOfTermsAndConditionsDefs, and m_tnCDefs.

Referenced by handleTermsAndConditionsLogin().

Here is the caller graph for this function:

◆ getTermsAndConditionsTemplate()

DOMNode * CAFirstMix::getTermsAndConditionsTemplate ( UINT8 templateRefID)

Definition at line 953 of file CAFirstMix.cpp.

954 {
955  UINT8 *currentRefId = NULL;
956  bool match = false;
957 
958  for (UINT32 i = 0; i < m_nrOfTermsAndConditionsTemplates; i++)
959  {
961  match = (currentRefId != NULL) &&
962  (strncmp((char *)templateRefID, (char *)currentRefId, TEMPLATE_REFID_MAXLEN ) == 0);
963  delete [] currentRefId;
964  currentRefId = NULL;
965  if(match)
966  {
967  return m_tcTemplates[i];
968  }
969  }
970  return NULL;
971 }
UINT8 * getTermsAndConditionsTemplateRefId(DOMNode *tcTemplateRoot)
Definition: CAUtil.cpp:865
#define TEMPLATE_REFID_MAXLEN
Definition: CAUtil.hpp:42

References getTermsAndConditionsTemplateRefId(), m_nrOfTermsAndConditionsTemplates, m_tcTemplates, and TEMPLATE_REFID_MAXLEN.

Referenced by handleTermsAndConditionsExtension().

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

◆ getType()

tMixType CAFirstMix::getType ( ) const
inlinevirtual

Implements CAMix.

Definition at line 319 of file CAFirstMix.hpp.

320  {
321  return CAMix::FIRST_MIX;
322  }
@ FIRST_MIX
Definition: CAMix.hpp:53

References CAMix::FIRST_MIX.

◆ handleKeyInfoExtensions()

SINT32 CAFirstMix::handleKeyInfoExtensions ( DOMElement *  root)

Definition at line 805 of file CAFirstMix.cpp.

806 {
807  if(root == NULL)
808  {
809  return E_UNKNOWN;
810  }
811 
812  SINT32 ret = E_SUCCESS;
813  DOMElement *extensionRoot = NULL;
814  getDOMChildByName(root, KEYINFO_NODE_EXTENSIONS, extensionRoot);
815 
816  if(extensionRoot != NULL)
817  {
818  extensionRoot = (DOMElement *) root->removeChild(extensionRoot);
819  ret = handleTermsAndConditionsExtension(extensionRoot);
820  extensionRoot->release();
821  }
822  return ret;
823 }
#define KEYINFO_NODE_EXTENSIONS
Definition: CAMix.hpp:45
SINT32 handleTermsAndConditionsExtension(DOMElement *extensionRoot)
Definition: CAFirstMix.cpp:825

References E_SUCCESS, E_UNKNOWN, getDOMChildByName(), handleTermsAndConditionsExtension(), and KEYINFO_NODE_EXTENSIONS.

Here is the call graph for this function:

◆ handleTermsAndConditionsExtension()

SINT32 CAFirstMix::handleTermsAndConditionsExtension ( DOMElement *  extensionRoot)

Definition at line 825 of file CAFirstMix.cpp.

826 {
827  if(extensionsRoot == NULL)
828  {
829  return E_UNKNOWN;
830  }
831 
832  DOMElement *tncDefs = NULL;
833  DOMElement *tncTemplates = NULL;
834  getDOMChildByName(extensionsRoot, KEYINFO_NODE_TNC_EXTENSION, tncDefs);
835  if(tncDefs == NULL)
836  {
837  CAMsg::printMsg(LOG_CRIT,"No TNCs in TNC extension found.\n");
838  return E_UNKNOWN;
839  }
840  getDOMChildByName(tncDefs, OPTIONS_NODE_TNCS_TEMPLATES, tncTemplates);
841 
842  UINT8 currentTnC_id[TMP_BUFF_SIZE];
843  UINT32 currentTnC_id_len = TMP_BUFF_SIZE;
844 
845  UINT8 currentTnCEntry_templateRefid[TMP_BUFF_SIZE];
846  UINT32 currentTnCEntry_templateRefid_len = TMP_BUFF_SIZE;
847 
848  UINT8 currentTnCEntry_locale[TMP_LOCALE_SIZE];
849  UINT32 currentTnCEntry_locale_len = TMP_LOCALE_SIZE;
850 
851  DOMElement *currentTnCList = NULL;
852  DOMElement *currentTnCEntry = NULL;
853  memset(currentTnC_id, 0, TMP_BUFF_SIZE);
854  memset(currentTnCEntry_templateRefid, 0, TMP_BUFF_SIZE);
855 
856  if(tncTemplates != NULL)
857  {
858  DOMNodeList *tncTemplateList = getElementsByTagName(tncDefs, TNC_TEMPLATE_ROOT_ELEMENT);
859  m_nrOfTermsAndConditionsTemplates = tncTemplateList->getLength();
860  CAMsg::printMsg(LOG_INFO, "Storing %u TC Templates.\n", m_nrOfTermsAndConditionsTemplates);
862  {
864  for (UINT32 i = 0; i < m_nrOfTermsAndConditionsTemplates; i++)
865  {
866  m_tcTemplates[i] = m_templatesOwner->importNode(tncTemplateList->item(i), true);
867  }
868  }
869  else
870  {
871  CAMsg::printMsg(LOG_ERR, "Not a single TC Template specified! the Cascade is not properly configured.\n");
872  return E_UNKNOWN;
873  }
874  }
875  else
876  {
877  CAMsg::printMsg(LOG_ERR, "No TC Template node found! Cascade is not properly configured.\n");
878  return E_UNKNOWN;
879  }
880 
881  DOMNodeList *tncDefList = getElementsByTagName(tncDefs, OPTIONS_NODE_TNCS);
882  if(tncDefList->getLength() == 0)
883  {
884  CAMsg::printMsg(LOG_CRIT, "No TNCs definitions found.\n");
885  return E_UNKNOWN;
886  }
887 
888  m_nrOfTermsAndConditionsDefs = tncDefList->getLength();
891 
892  for (UINT32 i = 0; i < m_nrOfTermsAndConditionsDefs; i++)
893  {
894  currentTnCList = (DOMElement *) tncDefList->item(i);
895  DOMNodeList *tncDefEntryList = getElementsByTagName(currentTnCList, OPTIONS_NODE_TNCS_TRANSLATION);
896  getDOMElementAttribute(currentTnCList, OPTIONS_ATTRIBUTE_TNC_ID, currentTnC_id, &currentTnC_id_len);
897 
898  m_tnCDefs[i] = new TermsAndConditions(currentTnC_id, tncDefEntryList->getLength());
899 
900  for (XMLSize_t j = 0; j < tncDefEntryList->getLength(); j++)
901  {
902  currentTnCEntry = (DOMElement *) tncDefEntryList->item(j);
903 
905  currentTnCEntry_templateRefid, &currentTnCEntry_templateRefid_len);
907  currentTnCEntry_locale, &currentTnCEntry_locale_len);
908 
909  DOMNode *templateNode = getTermsAndConditionsTemplate(currentTnCEntry_templateRefid);
910  if(templateNode != NULL)
911  {
912  //m_tnCDefs[i]->synchLock->lock();
913  m_tnCDefs[i]->addTranslation(currentTnCEntry_locale, currentTnCEntry, templateNode);
914  //m_tnCDefs[i]->synchLock->unlock();
915  }
916  else
917  {
918  CAMsg::printMsg(LOG_CRIT,"Could not find template %s for T&C %s.\n", currentTnCEntry_templateRefid, currentTnC_id);
919  return E_UNKNOWN;
920  }
921  memset(currentTnCEntry_templateRefid, 0, TMP_BUFF_SIZE);
922  currentTnCEntry_templateRefid_len = TMP_BUFF_SIZE;
923  memset(currentTnCEntry_locale, 0, TMP_LOCALE_SIZE);
924  currentTnCEntry_locale_len = TMP_LOCALE_SIZE;
925  }
926  memset(currentTnC_id, 0, TMP_BUFF_SIZE);
927  currentTnC_id_len = TMP_BUFF_SIZE;
928  }
929  return E_SUCCESS;
930 }
#define OPTIONS_ATTRIBUTE_TNC_ID
#define OPTIONS_NODE_TNCS_TEMPLATES
#define OPTIONS_NODE_TNCS
#define OPTIONS_ATTRIBUTE_TNC_LOCALE
#define OPTIONS_ATTRIBUTE_TNC_TEMPLATE_REFID
#define OPTIONS_NODE_TNCS_TRANSLATION
#define TNC_TEMPLATE_ROOT_ELEMENT
Definition: CAFirstMix.hpp:65
#define KEYINFO_NODE_TNC_EXTENSION
Definition: CAMix.hpp:46
DOMNodeList * getElementsByTagName(DOMElement *pElem, const char *const name)
Definition: CAUtil.cpp:1711
SINT32 getDOMElementAttribute(const DOMNode *const elem, const char *attrName, UINT8 *value, UINT32 *len)
Definition: CAUtil.cpp:780
#define TMP_LOCALE_SIZE
Definition: CAUtil.hpp:39
#define TMP_BUFF_SIZE
Definition: CAUtil.hpp:38
DOMNode * getTermsAndConditionsTemplate(UINT8 *templateRefID)
Definition: CAFirstMix.cpp:953
void addTranslation(const UINT8 *locale, DOMNode *tnc_customized, DOMNode *tnc_template)
add a language specific terms and Conditions document, which can be retrieved by *getTermsAndConditio...

References TermsAndConditions::addTranslation(), E_SUCCESS, E_UNKNOWN, getDOMChildByName(), getDOMElementAttribute(), getElementsByTagName(), getTermsAndConditionsTemplate(), KEYINFO_NODE_TNC_EXTENSION, m_nrOfTermsAndConditionsDefs, m_nrOfTermsAndConditionsTemplates, m_tcTemplates, m_templatesOwner, m_tnCDefs, OPTIONS_ATTRIBUTE_TNC_ID, OPTIONS_ATTRIBUTE_TNC_LOCALE, OPTIONS_ATTRIBUTE_TNC_TEMPLATE_REFID, OPTIONS_NODE_TNCS, OPTIONS_NODE_TNCS_TEMPLATES, OPTIONS_NODE_TNCS_TRANSLATION, CAMsg::printMsg(), TMP_BUFF_SIZE, TMP_LOCALE_SIZE, and TNC_TEMPLATE_ROOT_ELEMENT.

Referenced by handleKeyInfoExtensions().

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

◆ handleTermsAndConditionsLogin()

termsAndConditionMixAnswer_t * CAFirstMix::handleTermsAndConditionsLogin ( XERCES_CPP_NAMESPACE::DOMDocument *  request)
private

Definition at line 1573 of file CAFirstMix.cpp.

1574 {
1577 
1578  const XMLCh* reqName = request->getDocumentElement()->getTagName();
1579 
1580  //Client requests lacking T&C resources.
1581  if(XMLString::equals(reqName, TNC_REQUEST))
1582  {
1583  answer->result = TC_UNFINISHED;
1584  CAMsg::printMsg(LOG_DEBUG,"Handling TC request.\n");
1585  XERCES_CPP_NAMESPACE::DOMDocument *response = createDOMDocument();
1586  DOMElement *responseRoot = createDOMElement(response, TNC_RESPONSE);
1587  response->appendChild(responseRoot);
1588  //All elements with tag name 'Resources' (direct children of 'TermsAndConditionsRequest')
1589  DOMNodeList *requestedResources = getElementsByTagName(request->getDocumentElement(), TNC_RESOURCES);
1590  //All elements with tag name 'Translation' (direct children of 'Resources')
1591  DOMNodeList *requestedResourceItems = NULL;
1592 
1593  DOMNode *currentNode = NULL;
1594  DOMNode *currentAnswerNode = NULL;
1595  DOMNode *currentAnswerResourceNode = NULL;
1596 
1597  UINT32 idLen = TMP_BUFF_SIZE;
1598  UINT8 id[TMP_BUFF_SIZE];
1599  memset(id, 0, idLen);
1600 
1601  UINT32 localeLen = TMP_LOCALE_SIZE;
1602  UINT8 locale[TMP_LOCALE_SIZE];
1603  memset(locale, 0, localeLen);
1604 
1605  bool resourceError = false;
1606 
1607  if(requestedResources->getLength() == 0)
1608  {
1609  response->release();
1610  response = createDOMDocument();
1611  response->appendChild(createDOMElement(response, TNC_RESPONSE_INVALID_REQUEST));
1612  answer->result = TC_FAILED;
1613  }
1614 
1615  for (XMLSize_t i = 0; i < requestedResources->getLength(); i++)
1616  {
1617  idLen = TMP_BUFF_SIZE;
1618  localeLen = TMP_LOCALE_SIZE;
1619  bool validResource = false;
1620 
1621  currentNode = requestedResources->item(i);
1622  //check validity of the T&C resource request. attributes "id" and locale must be proper set.
1623  if( (getDOMElementAttribute(currentNode, OPTIONS_ATTRIBUTE_TNC_ID, id, &idLen) != E_SUCCESS) ||
1624  (strlen((char *)id) < 1) )
1625  {
1626  CAMsg::printMsg(LOG_DEBUG,"Error: invalid id.\n");
1627  resourceError = true;
1628  }
1629 
1630  if(!currentNode->hasChildNodes())
1631  {
1632  //Empty Resource node is invalid!
1633  CAMsg::printMsg(LOG_DEBUG,"Error: No children.\n");
1634  resourceError = true;
1635  }
1636 
1637  if(!resourceError)
1638  {
1639 
1640  TermsAndConditions *requestedTnC = getTermsAndConditions(id);
1641  if(requestedTnC != NULL)
1642  {
1643  requestedResourceItems = getElementsByTagName((DOMElement *)currentNode, TNC_REQ_TRANSLATION);
1644  for(XMLSize_t j = 0; j < requestedResourceItems->getLength(); j++)
1645  {
1646  validResource = false;
1647  localeLen = TMP_LOCALE_SIZE;
1648  if( (getDOMElementAttribute(requestedResourceItems->item(j),
1650  locale, &localeLen) != E_SUCCESS) ||
1651  (strlen((char *)locale) != ((TMP_LOCALE_SIZE) - 1) ) )
1652  {
1653  CAMsg::printMsg(LOG_DEBUG,"Error: Invalid locale for tnc %s\n", id);
1654  break;
1655  }
1656 
1657  const termsAndConditionsTranslation_t *requestedTranslation =
1658  requestedTnC->getTranslation(locale);
1659  //NOTE: No need to lock while working with the TC translation
1660  //because the translation containers are only modified during
1661  //inter-mix-keyexchange and cleanup.
1662  //Both must never run concurrently to this method
1663  if(requestedTranslation != NULL)
1664  {
1665 
1666  currentAnswerNode = response->importNode(currentNode, false);
1667  responseRoot->appendChild(currentAnswerNode);
1668  if( getDOMChildByName(requestedResourceItems->item(j), TNC_RESOURCE_TEMPLATE,
1669  currentAnswerResourceNode, false) == E_SUCCESS)
1670  {
1671  currentAnswerResourceNode = response->importNode(currentAnswerResourceNode, true);
1672  currentAnswerResourceNode->appendChild(
1673  response->importNode(requestedTranslation->tnc_template, true));
1674  currentAnswerNode->appendChild(currentAnswerResourceNode);
1675  validResource = true;
1676  }
1677 
1678  if( getDOMChildByName(requestedResourceItems->item(j), TNC_RESOURCE_CUSTOMIZED_SECT,
1679  currentAnswerResourceNode, false) == E_SUCCESS)
1680  {
1681  currentAnswerResourceNode = response->importNode(currentAnswerResourceNode, true);
1682  currentAnswerResourceNode->appendChild(
1683  response->importNode(requestedTranslation->tnc_customized, true));
1684  currentAnswerNode->appendChild(currentAnswerResourceNode);
1685  validResource = true;
1686  }
1687  }
1688  else
1689  {
1690  CAMsg::printMsg(LOG_DEBUG,"Error: no translation def found.\n");
1691  break;
1692  }
1693  }
1694  }
1695  else
1696  {
1697  CAMsg::printMsg(LOG_DEBUG,"Error: no tc def found.\n");
1698  }
1699  }
1700 
1701  if(!validResource)
1702  {
1703  //only a manipulated client sends an invalid T&C resource request.
1704  //Manipulation is interpreted as a rejection of the terms & conditions,
1705  //so abort login immediately.
1706  response->release();
1707  response = createDOMDocument();
1708  response->appendChild(createDOMElement(response, TNC_RESPONSE_INVALID_REQUEST));
1709  answer->result = TC_FAILED;
1710  break;
1711  }
1712  }
1713  answer->xmlAnswer = response;
1714  }
1715  //Client accepts/rejects the T&Cs.
1716  else if(XMLString::equals(reqName, TNC_CONFIRM))
1717  {
1718  CAMsg::printMsg(LOG_DEBUG,"handling TC confirm.\n");
1719  bool tcAccepted = false;
1720  getDOMElementAttribute(request->getDocumentElement(), "accepted", tcAccepted);
1721  CAMsg::printMsg(LOG_DEBUG,"Client has%s accepted the T&Cs.\n", (tcAccepted ? "" : " not") );
1722 
1723  answer->xmlAnswer = NULL;
1724  answer->result = tcAccepted ? TC_CONFIRMED : TC_FAILED;
1725  }
1726  //stops the message exchange (if client needs time for showing the T & Cs, etc.)
1727  else if(XMLString::equals(reqName, TNC_INTERRUPT))
1728  {
1729  CAMsg::printMsg(LOG_DEBUG,"client requested interrupting the tc login.\n");
1730  answer->xmlAnswer = NULL;
1731  answer->result = TC_FAILED;
1732  }
1733  //Client sends an invalid message
1734  else
1735  {
1736  answer->xmlAnswer = NULL; //TODO: set errorMessage here
1737  answer->result = TC_FAILED;
1738  }
1739  return answer;
1740 }
#define TNC_RESPONSE_INVALID_REQUEST
Definition: CAFirstMix.hpp:68
#define TNC_RESOURCE_TEMPLATE
Definition: CAFirstMix.hpp:64
#define TNC_RESPONSE
Definition: CAFirstMix.hpp:60
#define TNC_REQ_TRANSLATION
Definition: CAFirstMix.hpp:62
#define TNC_RESOURCES
Definition: CAFirstMix.hpp:63
#define TNC_RESOURCE_CUSTOMIZED_SECT
Definition: CAFirstMix.hpp:66
@ TC_CONFIRMED
TermsAndConditions * getTermsAndConditions(const UINT8 *opSki)
Definition: CAFirstMix.cpp:932
const termsAndConditionsTranslation_t * getTranslation(const UINT8 *locale)
returns the specific TermsAndconditions translation for the the language with the specified language ...

References createDOMDocument(), createDOMElement(), E_SUCCESS, equals(), getDOMChildByName(), getDOMElementAttribute(), getElementsByTagName(), getTermsAndConditions(), TermsAndConditions::getTranslation(), OPTIONS_ATTRIBUTE_TNC_ID, OPTIONS_ATTRIBUTE_TNC_LOCALE, CAMsg::printMsg(), termsAndConditionMixAnswer_t::result, TC_CONFIRMED, TC_FAILED, TC_UNFINISHED, TMP_BUFF_SIZE, TMP_LOCALE_SIZE, TNC_CONFIRM, termsAndConditionsTranslation_t::tnc_customized, TNC_INTERRUPT, TNC_REQ_TRANSLATION, TNC_REQUEST, TNC_RESOURCE_CUSTOMIZED_SECT, TNC_RESOURCE_TEMPLATE, TNC_RESOURCES, TNC_RESPONSE, TNC_RESPONSE_INVALID_REQUEST, termsAndConditionsTranslation_t::tnc_template, and termsAndConditionMixAnswer_t::xmlAnswer.

Referenced by doUserLogin_internal().

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

◆ incMixedPackets()

SINT32 CAFirstMix::incMixedPackets ( )
inlineprotected

Definition at line 427 of file CAFirstMix.hpp.

428  {
432  return E_SUCCESS;
433  }
void inc64(UINT64 &op1)
Definition: CAUtil.hpp:387

References E_SUCCESS, inc64(), CAMutex::lock(), m_nMixedPackets, m_pmutexMixedPackets, and CAMutex::unlock().

Referenced by CAFirstMixA::loop(), and CAFirstMixB::loop().

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

◆ incNewConnections()

void CAFirstMix::incNewConnections ( )
inlineprivate

Definition at line 571 of file CAFirstMix.hpp.

572  {
576  }

References CAMutex::lock(), m_newConnections, m_pmutexNewConnections, and CAMutex::unlock().

Here is the call graph for this function:

◆ incUsers()

SINT32 CAFirstMix::incUsers ( LP_fmHashTableEntry  pHashEntry)
inlineprotected

Definition at line 400 of file CAFirstMix.hpp.

402  {
403  m_pmutexUser->lock();
404  m_nUser++;
405  #ifdef COUNTRY_STATS
406  pHashEntry->countryID=updateCountryStats(pHashEntry->peerIP,0,false);
407  #endif
408  m_pmutexUser->unlock();
409  return E_SUCCESS;
410  }

References t_fmhashtableentry::countryID, E_SUCCESS, CAMutex::lock(), m_nUser, m_pmutexUser, t_fmhashtableentry::peerIP, CAMutex::unlock(), and updateCountryStats().

Here is the call graph for this function:

◆ init()

SINT32 CAFirstMix::init ( )
protectedvirtual

Connect to the next mix

Implements CAMix.

Definition at line 108 of file CAFirstMix.cpp.

109  {
110  if (isShuttingDown())
111  {
112  return E_SHUTDOWN;
113  }
114 
115 #ifdef DYNAMIC_MIX
116  m_bBreakNeeded = m_bReconfigured;
117 #endif
118 
119  CAMsg::printMsg(LOG_DEBUG,"Starting FirstMix Init\n");
120  m_nMixedPackets=0; //reset to zero after each restart (at the moment neccessary for infoservice)
121  m_bRestart=false;
122  //Establishing all Listeners
123  UINT32 i;
125  for (i = 0; i < m_nSocketsIn; i++)
126  {
127  m_arrSocketsIn[i] = NULL;
128  }
129  //initiate ownerDocument for tc templates
131 
133 
134 
135  if (retSockets != E_SUCCESS)
136  {
137  return retSockets;
138  }
139 
140  CASocketAddr* pAddrNext=NULL;
142  {
143  CATargetInterface oNextMix;
145  if(oNextMix.getTargetType()==TARGET_MIX)
146  {
147  pAddrNext=oNextMix.getAddr();
148  break;
149  }
150  oNextMix.cleanAddr();
151  }
152  if(pAddrNext==NULL)
153  {
154  CAMsg::printMsg(LOG_CRIT,"No next Mix specified! Please insert the address of a next mix into your configuration.\n");
155  return E_UNKNOWN;
156  }
157  m_pMuxOut = new CAMuxSocket(OFB);
158  if(m_pMuxOut->getCASocket()->create(pAddrNext->getType())!=E_SUCCESS)
159  {
160  CAMsg::printMsg(LOG_CRIT,
161  "Cannot create SOCKET for connection to next Mix! Please check if the network and socket settings in your system are correct.\n");
162  return E_UNKNOWN;
163  }
166  //if(((*m_pMuxOut))->setSendLowWat(MIXPACKET_SIZE)!=E_SUCCESS)
167  // CAMsg::printMsg(LOG_INFO,"SOCKET Option SENDLOWWAT not set!\n");
168  CAMsg::printMsg(LOG_INFO,"MUXOUT-SOCKET RecvBuffSize: %i\n",m_pMuxOut->getCASocket()->getRecvBuff());
169  CAMsg::printMsg(LOG_INFO,"MUXOUT-SOCKET SendBuffSize: %i\n",m_pMuxOut->getCASocket()->getSendBuff());
170  //CAMsg::printMsg(LOG_INFO,"MUXOUT-SOCKET SendLowWatSize: %i\n",((*m_pMuxOut))->getSendLowWat());
171 
173  if((retSockets = connectToNextMix(pAddrNext)) != E_SUCCESS)
174  {
175  delete pAddrNext;
176  pAddrNext = NULL;
177  CAMsg::printMsg(LOG_DEBUG, "CAFirstMix::init - Unable to connect to next mix. Reason: %s (%i)\n", GET_NET_ERROR_STR(retSockets), retSockets);
178  return E_UNKNOWN;
179  }
180  delete pAddrNext;
181  pAddrNext = NULL;
183  CAMsg::printMsg(LOG_INFO,"Established socket connection to next mix. Starting key exchange...\n");
185 #ifdef __BUILD_AS_SHADOW_PLUGIN__
187 #endif
188 
189 
191  {
193  CAMsg::printMsg(LOG_CRIT,"Error in establishing secure communication with next Mix. Disconnecting...\n");
194  return E_UNKNOWN;
195  }
196  else
197  {
198  CAMsg::printMsg(LOG_INFO,"Secure connection to next Mix was established successfully.\n");
199  }
200  m_pIPList=new CAIPList();
201  m_pIPBlockList = new CATempIPBlockList(1000 * 60 * 2);
202 #ifdef COUNTRY_STATS
203  char* db_host;
204  char* db_user;
205  char* db_passwd;
206  CALibProxytest::getOptions()->getCountryStatsDBConnectionLoginData(&db_host,&db_user,&db_passwd);
207  SINT32 retcountrydb=initCountryStats(db_host,db_user,db_passwd);
208  delete[] db_host;
209  db_host = NULL;
210  delete[] db_user;
211  db_user = NULL;
212  delete[] db_passwd;
213  db_passwd = NULL;
214  if(retcountrydb!=E_SUCCESS)
215  return E_UNKNOWN;
216 #endif
219 #ifndef MULTI_THREADED_PACKET_PROCESSING
221 #ifdef HAVE_EPOLL
224 #else
227 #endif
228 #else // with MULTI_THREADED_PACKET_PROCESSING
229  m_pChannelToQueueList=new CAFirstMixChannelToQueueList() ;
230 
231  m_arpChannelList = new CAFirstMixChannelList*[m_numThreads];
232 #ifdef HAVE_EPOLL
233  m_arpsocketgroupUsersRead=new CASocketGroupEpoll*[m_numThreads];
234  m_arpsocketgroupUsersWrite=new CASocketGroupEpoll*[m_numThreads];
235 #else
236  m_arpsocketgroupUsersRead=new CASocketGroup*[m_numThreads];
237  m_arpsocketgroupUsersWrite=new CASocketGroup*[m_numThreads];
238 #endif
239  for (UINT32 i = 0; i < m_numThreads; i++)
240  {
241  m_arpChannelList[i] = new CAFirstMixChannelList();
242 #ifdef HAVE_EPOLL
243  m_arpsocketgroupUsersRead[i] = new CASocketGroupEpoll(false);
244  m_arpsocketgroupUsersWrite[i] = new CASocketGroupEpoll(true);
245 #else
246  m_arpsocketgroupUsersRead[i] = new CASocketGroup(false);
247  m_arpsocketgroupUsersWrite[i] = new CASocketGroup(true);
248 #endif
249  }
250 
251 
252 #endif //with MULTI_THREADED_PACKET_PROCESSING
253 
255 #ifdef REPLAY_DETECTION
256  m_pReplayDB=new CADatabase();
257  m_pReplayDB->start();
259  m_u64ReferenceTime=time(NULL);
260  m_u64LastTimestampReceived=time(NULL);
261 #endif
262 
263 #ifdef PAYMENT
265  {
266  return E_UNKNOWN;
267  }
269 #endif
270 
272 
273  //Starting thread for Step 1
274  m_pthreadAcceptUsers=new CAThread((UINT8*)"CAFirstMix - AcceptUsers");
277 
278  //Starting thread for Step 3
279  m_pthreadSendToMix=new CAThread((UINT8*)"CAFirstMix - SendToMix");
281  m_pthreadSendToMix->start(this);
282 
283  //Startting thread for Step 4a
284  m_pthreadReadFromMix=new CAThread((UINT8*)"CAFirstMix - ReadFromMix");
287 #ifdef CH_LOG_STUDY
288  nrOfChThread = new CAThread((UINT8*)"CAFirstMix - Channel open logging thread");
289  nrOfChThread->setMainLoop(fm_loopLogChannelsOpened);
290  nrOfChThread->start(this);
291  currentOpenedChannels = 0;
292 #endif //CH_LOG_STUDY
293  //Starting thread for logging
294 #ifdef LOG_PACKET_TIMES
295  m_pLogPacketStats=new CALogPacketStats();
296  m_pLogPacketStats->setLogIntervallInMinutes(FM_PACKET_STATS_LOG_INTERVALL);
297  m_pLogPacketStats->start();
298 #endif
299 #ifdef REPLAY_DETECTION
300 // sendReplayTimestampRequestsToAllMixes();
301 #endif
302  CAMsg::printMsg(LOG_DEBUG,"CAFirstMix init() succeeded\n");
304  return E_SUCCESS;
305 }
#define MONITORING_FIRE_NET_EVENT(e_type)
#define NUM_LOGIN_WORKER_TRHEADS
Definition: StdAfx.h:202
#define MAX_LOGIN_QUEUE
Definition: StdAfx.h:203
#define FM_PACKET_STATS_LOG_INTERVALL
Definition: StdAfx.h:248
static SINT32 init(CAFirstMix *callingMix)
Returns a reference to the Singleton instance.
SINT32 createSockets(bool a_bPrintMessages, CASocket **a_sockets, UINT32 a_socketsLen)
SINT32 getCountryStatsDBConnectionLoginData(char **db_host, char **db_user, char **db_passwd)
UINT32 getTargetInterfaceCount()
SINT32 getTargetInterface(CATargetInterface &oTargetInterface, UINT32 nr)
Fills a TargetInterface struct with the values which belongs to the target interface nr.
This class "dispatches" messages which it receives via proccessMixPacket() to the associated control ...
SINT32 start()
Definition: CADatabase.cpp:220
friend THREAD_RETURN fm_loopSendToMix(void *)
How to end this thread: 0.
Definition: CAFirstMix.cpp:978
virtual SINT32 processKeyExchange()
Definition: CAFirstMix.cpp:362
SINT32 initCountryStats(char *db_host, char *db_user, char *db_passwd)
friend THREAD_RETURN fm_loopAcceptUsers(void *)
bool isShuttingDown()
Definition: CAFirstMix.cpp:64
friend THREAD_RETURN fm_loopReadFromMix(void *)
SINT32 connectToNextMix(CASocketAddr *a_pAddrNext)
Definition: CAFirstMix.cpp:307
The purpose of this class is to store a list of IP-Addresses.
Definition: CAIPList.hpp:62
CADatabase * m_pReplayDB
This is an abstract class for representing a socket address used in CASocket, CADatagramSocket and CA...
virtual SINT32 getType() const =0
The type (family) of socket for which this address is useful.
virtual SINT32 setRecvBuff(UINT32 r)
Definition: CASocket.cpp:846
virtual SINT32 getSendBuff()
Definition: CASocket.cpp:873
virtual SINT32 setSendBuff(SINT32 r)
Returns < 0 on error, otherwise the new sendbuffersize (which may be less than r)
Definition: CASocket.cpp:862
virtual SINT32 getRecvBuff()
Definition: CASocket.cpp:852
virtual SINT32 create()
Definition: CASocket.cpp:73
TargetType getTargetType() const
CASocketAddr * getAddr() const
The purpose of this class is storing the IPs of JAP users who tried to hack/attack the payment system...
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
This class bla bla.
#define E_SHUTDOWN
Definition: errorcodes.hpp:4
@ ev_net_nextConnectionClosed
@ ev_net_keyExchangeNextSuccessful
@ ev_net_nextConnected
@ TARGET_MIX
Definition: typedefs.hpp:32

References CATargetInterface::cleanAddr(), connectToNextMix(), CASocket::create(), createDOMDocument(), CACmdLnOptions::createSockets(), E_SHUTDOWN, E_SUCCESS, E_UNKNOWN, ev_net_keyExchangeNextSuccessful, ev_net_nextConnected, ev_net_nextConnectionClosed, fm_loopAcceptUsers, fm_loopReadFromMix, fm_loopSendToMix, FM_PACKET_STATS_LOG_INTERVALL, GET_NET_ERROR_STR, CATargetInterface::getAddr(), CAMuxSocket::getCASocket(), CACmdLnOptions::getCountryStatsDBConnectionLoginData(), CALibProxytest::getOptions(), CASocket::getRecvBuff(), CASocket::getSendBuff(), CACmdLnOptions::getTargetInterface(), CACmdLnOptions::getTargetInterfaceCount(), CATargetInterface::getTargetType(), CASocketAddr::getType(), CAAccountingDBInterface::init(), CAAccountingInstance::init(), initCountryStats(), isShuttingDown(), m_arrSocketsIn, m_bRestart, m_nMixedPackets, m_nSocketsIn, m_pChannelList, m_pIPBlockList, m_pIPList, m_pMuxOut, CAMix::m_pMuxOutControlChannelDispatcher, m_pQueueReadFromMix, m_pQueueSendToMix, CAMixWithReplayDB::m_pReplayDB, CAMixWithReplayDB::m_pReplayMsgProc, m_psocketgroupUsersRead, m_psocketgroupUsersWrite, m_pthreadAcceptUsers, m_pthreadReadFromMix, m_pthreadSendToMix, m_pthreadsLogin, m_templatesOwner, m_u64LastTimestampReceived, CAMixWithReplayDB::m_u64ReferenceTime, MAX_LOGIN_QUEUE, MIXPACKET_SIZE, MONITORING_FIRE_NET_EVENT, NUM_LOGIN_WORKER_TRHEADS, OFB, CAMsg::printMsg(), processKeyExchange(), CASocket::setKeepAlive(), CAThread::setMainLoop(), CASocket::setNonBlocking(), CASocket::setRecvBuff(), CASocket::setSendBuff(), CADatabase::start(), CAThread::start(), and TARGET_MIX.

Here is the call graph for this function:

◆ initCountryStats()

SINT32 CAFirstMix::initCountryStats ( char *  db_host,
char *  db_user,
char *  db_passwd 
)
private

Definition at line 2937 of file CAFirstMix.cpp.

2938  {
2939  m_CountryStats=NULL;
2940  m_mysqlCon=mysql_init(NULL);
2941 #ifdef HAVE_MYSQL_OPT_RECONNECT
2942  my_bool thetrue=1;
2943  mysql_options(m_mysqlCon,MYSQL_OPT_RECONNECT,&thetrue);
2944 #endif
2945  MYSQL* tmp=NULL;
2946  tmp=mysql_real_connect(m_mysqlCon,db_host,db_user,db_passwd,COUNTRY_STATS_DB,0,NULL,0);
2947  if(tmp==NULL)
2948  {
2949  CAMsg::printMsg(LOG_DEBUG,"Could not connect to CountryStats DB!\n");
2950  mysql_thread_end();
2951  mysql_close(m_mysqlCon);
2952  m_mysqlCon=NULL;
2953  return E_UNKNOWN;
2954  }
2955  CAMsg::printMsg(LOG_DEBUG,"Connected to CountryStats DB!\n");
2956  char query[1024];
2957  UINT8 buff[255];
2959  mysqlEscapeTableName(buff);
2960  sprintf(query,"CREATE TABLE IF NOT EXISTS `stats_%s` (date timestamp,id int,count int,packets_in int,packets_out int)",buff);
2961  SINT32 ret=mysql_query(m_mysqlCon,query);
2962  if(ret!=0)
2963  {
2964  CAMsg::printMsg(LOG_INFO,"CountryStats DB - create table for %s failed!\n",buff);
2965  }
2967  memset((void*)m_CountryStats,0,sizeof(UINT32)*(NR_OF_COUNTRIES+1));
2969  //memset((void*)m_PacketsPerCountryIN,0,sizeof(UINT32)*(NR_OF_COUNTRIES+1));
2971  //memset((void*)m_PacketsPerCountryOUT,0,sizeof(UINT32)*(NR_OF_COUNTRIES+1));
2972  m_threadLogLoop=new CAThread((UINT8*)"Country Logger Thread");
2974  m_bRunLogCountries=true;
2975  m_threadLogLoop->start(this,true);
2976  return E_SUCCESS;
2977  }
#define NR_OF_COUNTRIES
#define COUNTRY_STATS_DB
void mysqlEscapeTableName(UINT8 *str)
Escape a string so tha it could be used as table anme.
SINT32 getCascadeName(UINT8 *name, UINT32 len) const
friend THREAD_RETURN iplist_loopDoLogCountries(void *param)

References COUNTRY_STATS_DB, E_SUCCESS, E_UNKNOWN, CACmdLnOptions::getCascadeName(), CALibProxytest::getOptions(), iplist_loopDoLogCountries, m_bRunLogCountries, m_CountryStats, m_mysqlCon, m_PacketsPerCountryIN, m_PacketsPerCountryOUT, m_threadLogLoop, mysqlEscapeTableName(), NR_OF_COUNTRIES, CAMsg::printMsg(), CAThread::setMainLoop(), and CAThread::start().

Referenced by init().

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

◆ initMixParameters()

SINT32 CAFirstMix::initMixParameters ( DOMElement *  elemMixes)
protected

Initialises the MixParameters info for each mix form the <Mixes> element received from the second mix.

set u32MixCount and m_arMixParameters from the <Mixes> element received from the second mix.

Definition at line 2862 of file CAFirstMix.cpp.

2863  {
2864  DOMNodeList* nl=getElementsByTagName(elemMixes,"Mix");
2865  m_u32MixCount=nl->getLength();
2868  UINT8 buff[255];
2869  CALibProxytest::getOptions()->getMixId(buff,255);
2870  UINT32 len=strlen((char*)buff)+1;
2871  UINT32 aktMix=0;
2872  for (UINT32 i = 0; i<m_u32MixCount; i++)
2873  {
2874  DOMNode* child=nl->item(i);
2875  len=255;
2876  getDOMElementAttribute(child,"id",buff,&len);
2877  m_arMixParameters[aktMix].m_strMixID=new UINT8[len+1];
2878  memcpy(m_arMixParameters[aktMix].m_strMixID,buff,len);
2879  m_arMixParameters[aktMix].m_strMixID[len]=0;
2880  aktMix++;
2881  }
2882  m_u32MixCount++;
2883  return E_SUCCESS;
2884  }
UINT16 len
Definition: typedefs.hpp:0

References E_SUCCESS, getDOMElementAttribute(), getElementsByTagName(), CACmdLnOptions::getMixId(), CALibProxytest::getOptions(), len, m_arMixParameters, t_mix_parameters::m_strMixID, and m_u32MixCount.

Here is the call graph for this function:

◆ initOnce()

SINT32 CAFirstMix::initOnce ( )
protectedvirtual

Reimplemented from CAMix.

Definition at line 69 of file CAFirstMix.cpp.

70  {
71  SINT32 ret=CAMix::initOnce();
72  if(ret!=E_SUCCESS)
73  return ret;
74  CAMsg::printMsg(LOG_DEBUG,"Starting FirstMix InitOnce\n");
75  /*m_pSignature=CALibProxytest::getOptions()->getSignKey();
76  if(m_pSignature==NULL)*/
78  if(m_pMultiSignature == NULL)
79  return E_UNKNOWN;
80  //Try to find out how many (real) ListenerInterfaces are specified
82  m_nSocketsIn=0;
83  for(UINT32 i=1;i<=tmpSocketsIn;i++)
84  {
85  CAListenerInterface* pListener=NULL;
87  if(pListener==NULL)
88  continue;
89  if(!pListener->isVirtual())
90  {
91  m_nSocketsIn++;
92  }
93  delete pListener;
94  pListener = NULL;
95  }
96  if(m_nSocketsIn<1)
97  {
98  CAMsg::printMsg(LOG_CRIT,"No usable ListenerInterfaces specified (maybe wrong values or all are 'virtual'!\n");
99  return E_UNKNOWN;
100  }
101 
102  CAMsg::printMsg(LOG_DEBUG,"Starting FirstMix InitOnce - finished\n");
103  return E_SUCCESS;
104  }
UINT32 getListenerInterfaceCount()
CAMultiSignature * getMultiSigner()
CAListenerInterface * getListenerInterface(UINT32 nr)
virtual SINT32 initOnce()
Definition: CAMix.cpp:78

References E_SUCCESS, E_UNKNOWN, CACmdLnOptions::getListenerInterface(), CACmdLnOptions::getListenerInterfaceCount(), CACmdLnOptions::getMultiSigner(), CALibProxytest::getOptions(), CAMix::initOnce(), CAListenerInterface::isVirtual(), m_nSocketsIn, CAMix::m_pMultiSignature, and CAMsg::printMsg().

Here is the call graph for this function:

◆ isAllowedToPassRestrictions()

SINT32 CAFirstMix::isAllowedToPassRestrictions ( CASocket pNewMuxSocket)
private

◆ isShuttingDown()

bool CAFirstMix::isShuttingDown ( )
protected

Definition at line 64 of file CAFirstMix.cpp.

65 {
66  return m_bIsShuttingDown;
67 }

References m_bIsShuttingDown.

Referenced by init().

Here is the caller graph for this function:

◆ loop()

virtual SINT32 CAFirstMix::loop ( )
protectedpure virtual

Implements CAMix.

Implemented in CAFirstMixB, and CAFirstMixA.

◆ processKeyExchange()

SINT32 CAFirstMix::processKeyExchange ( )
protectedvirtual

Getting the KeepAlive Traffic...

initialises MixParameters struct

Implements CAMix.

Definition at line 362 of file CAFirstMix.cpp.

363  {
364  UINT8* recvBuff=NULL;
365  UINT32 len;
366  SINT32 ret;
367  CAMsg::printMsg(LOG_INFO, "Try to read the Key Info length from next Mix...\n");
369  {
370  if (ret != E_UNKNOWN)
371  {
372  CAMsg::printMsg(LOG_CRIT,"Error receiving Key Info length from next mix! Reason: '%s' (%i)\n",GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
373  }
374  else
375  {
376  CAMsg::printMsg(LOG_CRIT,"Error receiving Key Info length from next mix!\n");
377  }
378  return ret;
379  }
380  len=ntohl(len);
381  CAMsg::printMsg(LOG_INFO, "Received next mix Key Info length %u\n",len);
382 
383  if (len > 100000)
384  {
385  CAMsg::printMsg(LOG_WARNING,"Unrealistic length for key info: %u We might not be able to get a connection.\n",len);
386  }
387 
388  recvBuff=new UINT8[len+1];
389 
391  {
392  if (ret != E_UNKNOWN)
393  {
394  CAMsg::printMsg(LOG_CRIT,"Error receiving Key Info from next mix! Reason: '%s' (%i)\n",GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
395  }
396  else
397  {
398  CAMsg::printMsg(LOG_CRIT,"Error receiving Key Info from next mix!\n");
399  }
400  delete []recvBuff;
401  recvBuff = NULL;
402  return E_UNKNOWN;
403  }
404  recvBuff[len]=0;
405  //get the Keys from the other mixes (and the Mix-Id's...!)
406  CAMsg::printMsg(LOG_INFO,"Received Key Info from next mix...\n");
407  CAMsg::printMsg(LOG_DEBUG,"%s\n",recvBuff);
408 
409  XERCES_CPP_NAMESPACE::DOMDocument* doc=parseDOMDocument(recvBuff, len);
410  delete []recvBuff;
411  recvBuff = NULL;
412  DOMElement* elemMixes=doc->getDocumentElement();
413  if(elemMixes == NULL)
414  {
415  if(doc != NULL)
416  {
417  doc->release();
418  doc = NULL;
419  }
420  CAMsg::printMsg(LOG_INFO,"before returning...\n");
421  return E_UNKNOWN;
422  }
423  SINT32 count=0;
424  if(getDOMElementAttribute(elemMixes,"count",&count)!=E_SUCCESS)
425  {
426  if(doc != NULL)
427  {
428  doc->release();
429  doc = NULL;
430  }
431  return E_UNKNOWN;
432  }
433  /*
434  @todo Do not know why we do this here - probably it has something todo with the
435  dynamic mix config, but makes not sense at all for me...
436 
437  getDOMElementAttribute(elemMixescascadeNaem
438  char *cascadeName;
439  cascadeName = elemMixes.getAttribute("cascadeName").transcode();
440  if(cascadeName == NULL)
441  return E_UNKNOWN;
442  CALibProxytest::getOptions()->setCascadeName(cascadeName);
443 */
444 #ifdef PAYMENT
446  {
447  appendTermsAndConditionsExtension(doc, elemMixes);
448  }
449 #endif
450  SINT32 extRet = handleKeyInfoExtensions(elemMixes);
451  if(extRet != E_SUCCESS)
452  {
453  if(doc != NULL)
454  {
455  doc->release();
456  doc = NULL;
457  }
458  return E_UNKNOWN;
459  }
460  m_pRSA=new CAASymCipher;
461 
462 #ifdef EXPORT_ASYM_PRIVATE_KEY
463  if(CALibProxytest::getOptions()->isImportKey())
464  {
465  UINT32 keyFileBuffLen=8096;
466  UINT8* keyFileBuff=new UINT8[keyFileBuffLen];
467  CALibProxytest::getOptions()->getEncryptionKeyImportFile(keyFileBuff,keyFileBuffLen);
468  UINT8* keyBuff=readFile(keyFileBuff,&keyFileBuffLen);
469  m_pRSA->setPrivateKeyAsXML(keyBuff,keyFileBuffLen);
470  delete[] keyFileBuff;
471  delete[] keyBuff;
472  }
473  else
474 #endif
475  {
476  m_pRSA->generateKeyPair(1024);
477  }
478 #ifdef EXPORT_ASYM_PRIVATE_KEY
479  if(CALibProxytest::getOptions()->isExportKey())
480  {
481  UINT32 keyFileBuffLen=8096;
482  UINT8* keyFileBuff=new UINT8[keyFileBuffLen];
483  UINT8* keyBuff=new UINT8[keyFileBuffLen];
484  CALibProxytest::getOptions()->getEncryptionKeyExportFile(keyFileBuff,keyFileBuffLen);
485  m_pRSA->getPrivateKeyAsXML(keyBuff,&keyFileBuffLen);
486  saveFile(keyFileBuff,keyBuff,keyFileBuffLen);
487  delete[] keyFileBuff;
488  delete[] keyBuff;
489  }
490 #endif
491  DOMNode* child=elemMixes->getLastChild();
492 
493  //tmp XML-Structure for constructing the XML which is sent to each user
494  XERCES_CPP_NAMESPACE::DOMDocument* docXmlKeyInfo=createDOMDocument();
495  DOMElement* elemRootKey=createDOMElement(docXmlKeyInfo,"MixCascade");
496  setDOMElementAttribute(elemRootKey,"version",(UINT8*)"0.2"); //set the Version of the XML to 0.2
497  setDOMElementAttribute(elemRootKey, "maxOpenChannels", CHANNELS_PER_CLIENT);
498 #ifdef LOG_DIALOG
499  setDOMElementAttribute(elemRootKey,"study",(UINT8*)"true");
500 #endif
501  docXmlKeyInfo->appendChild(elemRootKey);
502  DOMElement* elemMixProtocolVersion=createDOMElement(docXmlKeyInfo,"MixProtocolVersion");
503  setDOMElementValue(elemMixProtocolVersion,(UINT8*)MIX_CASCADE_PROTOCOL_VERSION);
504  elemRootKey->appendChild(elemMixProtocolVersion);
505  DOMNode* elemMixesKey=docXmlKeyInfo->importNode(elemMixes,true);
506  elemRootKey->appendChild(elemMixesKey);
507 
508  //UINT32 tlen;
509  /* //remove because it seems to be useless...
510  while(child!=NULL)
511  {
512  if(child.getNodeName().equals("Mix"))
513  {
514  DOM_Node rsaKey=child.getFirstChild();
515  CAASymCipher oRSA;
516  oRSA.setPublicKeyAsDOMNode(rsaKey);
517  tlen=256;
518  }
519  child=child.getPreviousSibling();
520  }*/
521  //tlen=256;
522 
523  //Inserting own Key in XML-Key struct
524  DOMElement* elemKey=NULL;
525  m_pRSA->getPublicKeyAsDOMElement(elemKey,docXmlKeyInfo);
526  addMixInfo(elemMixesKey, true);
527  DOMElement* elemOwnMix=NULL;
528  getDOMChildByName(elemMixesKey, "Mix", elemOwnMix, false);
529  elemOwnMix->appendChild(elemKey);
530 #ifdef PAYMENT
531  CAMsg::printMsg(LOG_INFO,"before T&Cs1...\n");
533  {
534  elemOwnMix->appendChild(termsAndConditionsInfoNode(docXmlKeyInfo));
535  }
536  CAMsg::printMsg(LOG_INFO,"after T&Cs1...\n");
537 #endif
538  elemOwnMix->appendChild(createDOMElement(docXmlKeyInfo,"SupportsEncrypedControlChannels"));
539  CAMsg::printMsg(LOG_INFO,"after SupportEncChannels...\n");
540  if (signXML(elemOwnMix) != E_SUCCESS)
541  {
542  CAMsg::printMsg(LOG_DEBUG,"Could not sign MixInfo sent to users...\n");
543  }
544 
545  setDOMElementAttribute(elemMixesKey,"count",count+1);
546 
547 
548  DOMNode* elemPayment=createDOMElement(docXmlKeyInfo,"Payment");
549  elemRootKey->appendChild(elemPayment);
550 #ifdef PAYMENT
551  setDOMElementAttribute(elemPayment,"required",(UINT8*)"true");
552  setDOMElementAttribute(elemPayment,"version",(UINT8*)PAYMENT_VERSION);
553  setDOMElementAttribute(elemPayment,"prepaidInterval", CALibProxytest::getOptions()->getPrepaidInterval());
554  setDOMElementAttribute(elemPayment,"piid", CALibProxytest::getOptions()->getBI()->getID());
555 
556 #else
557  setDOMElementAttribute(elemPayment,"required",(UINT8*)"false");
558 #endif
559 
560  // create signature
561  if (signXML(elemRootKey) != E_SUCCESS)
562  {
563  CAMsg::printMsg(LOG_DEBUG,"Could not sign KeyInfo sent to users...\n");
564  }
565 
566 
567  UINT32 tmp32Len = 0;
568  UINT8* tmpB=DOM_Output::dumpToMem(docXmlKeyInfo, &tmp32Len);
569  if (docXmlKeyInfo != NULL)
570  {
571  docXmlKeyInfo->release();
572  docXmlKeyInfo = NULL;
573  }
574 
575  if(tmp32Len > 0xFFFD) //too bytes are reserved for the length
576  {
577  CAMsg::printMsg(LOG_CRIT, "The key info size of %u bytes is too large for the clients. (maximum is %u)\n", 0xFFFD);
578  if (doc != NULL)
579  {
580  doc->release();
581  doc = NULL;
582  }
583  return E_UNKNOWN;
584  }
585 
586  UINT16 tlen = (UINT16) tmp32Len;
587  m_xmlKeyInfoBuff = new UINT8[tlen+sizeof(tlen)];
588  memcpy(m_xmlKeyInfoBuff+sizeof(tlen), tmpB, tlen);
589  UINT16 s = htons(tlen);
590  memcpy(m_xmlKeyInfoBuff, &s, sizeof(s));
591  m_xmlKeyInfoSize=tlen + sizeof(tlen);
592  delete []tmpB;
593  tmpB = NULL;
594  SINT32 result=E_UNKNOWN;
595 
596  //Sending symmetric key...
597  child=elemMixes->getFirstChild();
598  while(child!=NULL)
599  {
600  if(equals(child->getNodeName(),"Mix"))
601  {
602  //verify certificate from next mix if enabled
604  {
606  if(nextMixCert != NULL)
607  {
608  CAMsg::printMsg(LOG_DEBUG, "Next mix certificate was verified by a trusted root CA.\n");
610  }
611  else
612  {
613  CAMsg::printMsg(LOG_ERR, "Could not verify certificate received from next mix!\n");
614  return E_UNKNOWN;
615  }
616  }
617  //check Signature....
618  CAMsg::printMsg(LOG_DEBUG,"Try to verify next mix signature...\n");
619  //CASignature oSig;
621  /*oSig.setVerifyKey(nextCert);
622  SINT32 ret=oSig.verifyXML(child,NULL);*/
623  result = CAMultiSignature::verifyXML(child, nextCert);
624  delete nextCert;
625  nextCert = NULL;
626  if(result != E_SUCCESS)
627  {
628  //CAMsg::printMsg(LOG_CRIT,"Could not verify the symmetric key from next mix! The operator of the next mix has to send you his current mix certificate, and you will have to import it in your configuration. Alternatively, you might import the proper root certification authority for verifying the certificate.\n");
629  CAMsg::printMsg(LOG_CRIT,"Could not verify the symmetric key from next mix! The operator of the next mix has to send you his current mix certificate, and you will have to import it in your configuration.\n");
630  if (doc != NULL)
631  {
632  doc->release();
633  doc = NULL;
634  }
635  return E_UNKNOWN;
636  }
637  CAMsg::printMsg(LOG_DEBUG,"Successfully verified XML signature of next mix!\n");
638 
639  result = checkCompatibility(child, "next");
640 
641 
642  DOMNode* rsaKey=child->getFirstChild();
643  CAASymCipher oRSA;
644  oRSA.setPublicKeyAsDOMNode(rsaKey);
645  DOMElement* elemNonce=NULL;
646  getDOMChildByName(child,"Nonce",elemNonce,false);
647  UINT8 arNonce[1024];
648  if(elemNonce!=NULL)
649  {
650  UINT32 lenNonce=1024;
651  UINT32 tmpLen=1024;
652  getDOMElementValue(elemNonce,arNonce,&lenNonce);
653  CABase64::decode(arNonce,lenNonce,arNonce,&tmpLen);
654  lenNonce=tmpLen;
655  tmpLen=1024;
656  CABase64::encode(SHA1(arNonce,lenNonce,NULL),SHA_DIGEST_LENGTH,
657  arNonce,&tmpLen);
658  arNonce[tmpLen]=0;
659  }
660  UINT8 key[64];
661 #ifdef SET_STATIC_MUX_SOCKET_KEY
662  CAMsg::printMsg(LOG_CRIT, "Warning! Will use an all zero MuxSocket key - do not use this Mix in a productive environment -- only for testing!\n");
663  memset(key,0,64);
664 #else
665  getRandom(key, 64);
666 #endif
667  //UINT8 buff[400];
668  //UINT32 bufflen=400;
669  XERCES_CPP_NAMESPACE::DOMDocument* docSymKey=createDOMDocument();
670  DOMElement* elemRoot=NULL;
671  encodeXMLEncryptedKey(key,64,elemRoot,docSymKey,&oRSA);
672  docSymKey->appendChild(elemRoot);
673  if(elemNonce!=NULL)
674  {
675  DOMElement* elemNonceHash=createDOMElement(docSymKey,"Nonce");
676  setDOMElementValue(elemNonceHash,arNonce);
677  elemRoot->appendChild(elemNonceHash);
678  }
679 
680  appendCompatibilityInfo(elemRoot);
681 
683  DOMElement* elemKeepAlive=NULL;
684  DOMElement* elemKeepAliveSendInterval=NULL;
685  DOMElement* elemKeepAliveRecvInterval=NULL;
686  getDOMChildByName(child,"KeepAlive",elemKeepAlive,false);
687  getDOMChildByName(elemKeepAlive,"SendInterval",elemKeepAliveSendInterval,false);
688  getDOMChildByName(elemKeepAlive,"ReceiveInterval",elemKeepAliveRecvInterval,false);
689  UINT32 tmpSendInterval,tmpRecvInterval;
690  getDOMElementValue(elemKeepAliveSendInterval,tmpSendInterval,0xFFFFFFFF); //if no send interval was given set it to "infinite"
691  getDOMElementValue(elemKeepAliveRecvInterval,tmpRecvInterval,0xFFFFFFFF); //if no recv interval was given --> set it to "infinite"
692  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Getting offer -- SendInterval %u -- ReceiveInterval %u\n",tmpSendInterval,tmpRecvInterval);
693  // Add Info about KeepAlive traffic
694  UINT32 u32KeepAliveSendInterval=CALibProxytest::getOptions()->getKeepAliveSendInterval();
695  UINT32 u32KeepAliveRecvInterval=CALibProxytest::getOptions()->getKeepAliveRecvInterval();
696  elemKeepAlive=createDOMElement(docSymKey,"KeepAlive");
697  elemKeepAliveSendInterval=createDOMElement(docSymKey,"SendInterval");
698  elemKeepAliveRecvInterval=createDOMElement(docSymKey,"ReceiveInterval");
699  elemKeepAlive->appendChild(elemKeepAliveSendInterval);
700  elemKeepAlive->appendChild(elemKeepAliveRecvInterval);
701  setDOMElementValue(elemKeepAliveSendInterval,u32KeepAliveSendInterval);
702  setDOMElementValue(elemKeepAliveRecvInterval,u32KeepAliveRecvInterval);
703  elemRoot->appendChild(elemKeepAlive);
704  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Offering -- SendInterval %u -- Receive Interval %u\n",u32KeepAliveSendInterval,u32KeepAliveRecvInterval);
705  m_u32KeepAliveSendInterval = u32KeepAliveSendInterval;
706  if (m_u32KeepAliveSendInterval > tmpRecvInterval - 10000)
707  m_u32KeepAliveSendInterval-=10000; //make the send interval a little bit smaller than the related receive interval
708  m_u32KeepAliveRecvInterval=max(u32KeepAliveRecvInterval,tmpSendInterval);
709  if (m_u32KeepAliveRecvInterval - 10000 < tmpSendInterval)
710  {
712  }
713  CAMsg::printMsg(LOG_DEBUG,"KeepAlive-Traffic: Calculated -- SendInterval %u -- Receive Interval %u\n",m_u32KeepAliveSendInterval,m_u32KeepAliveRecvInterval);
714 
715  //m_pSignature->signXML(elemRoot);
716  m_pMultiSignature->signXML(elemRoot, true);
717  UINT32 outlen=0;
718  UINT8* out=DOM_Output::dumpToMem(docSymKey,&outlen);
719  if (docSymKey != NULL)
720  {
721  docSymKey->release();
722  docSymKey = NULL;
723  }
724  m_pMuxOut->setSendKey(key,32);
725  m_pMuxOut->setReceiveKey(key+32,32);
726  UINT32 size = htonl(outlen);
727  CAMsg::printMsg(LOG_DEBUG,"Sending symmetric key to next Mix! Size: %i\n", outlen);
728  m_pMuxOut->getCASocket()->send((UINT8*) &size, sizeof(size));
729  m_pMuxOut->getCASocket()->send(out, outlen);
730  m_pMuxOut->setCrypt(true);
731  delete[] out;
732  out = NULL;
733  break;
734  }
735  child=child->getNextSibling();
736  }
737 
738  if (result != E_SUCCESS)
739  {
740  if (doc != NULL)
741  {
742  doc->release();
743  doc = NULL;
744  }
745  return result;
746  }
747 
748 
750  if(initMixParameters(elemMixes)!=E_SUCCESS)
751  {
752  if (doc != NULL)
753  {
754  doc->release();
755  doc = NULL;
756  }
757  return E_UNKNOWN;
758  }
759  if(initMixCascadeInfo(elemMixes)!=E_SUCCESS)
760  {
761  if (doc != NULL)
762  {
763  doc->release();
764  doc = NULL;
765  }
766  CAMsg::printMsg(LOG_CRIT,"Error initializing cascade info.\n");
767  return E_UNKNOWN;
768  }
769 /* else
770  {
771  if(m_pInfoService != NULL)
772  m_pInfoService->sendCascadeHelo();
773  }*/
774  CAMsg::printMsg(LOG_DEBUG,"Key exchange finished!\n");
775  if (doc != NULL)
776  {
777  doc->release();
778  doc = NULL;
779  }
780  return E_SUCCESS;
781 }
UINT8 * readFile(const UINT8 *const name, UINT32 *size)
ONLY_LOCAL_PROXY or first.
Definition: CAUtil.cpp:1330
SINT32 getRandom(UINT32 *val)
Gets 32 random bits.
Definition: CAUtil.cpp:346
SINT32 saveFile(const UINT8 *const name, const UINT8 *const buff, UINT32 buffSize)
Definition: CAUtil.cpp:1352
SINT32 encodeXMLEncryptedKey(UINT8 *key, UINT32 keylen, UINT8 *xml, UINT32 *xmllen, CAASymCipher *pRSA)
Definition: CAUtil.cpp:1683
#define MIX_CASCADE_PROTOCOL_VERSION
Definition: StdAfx.h:264
#define PAYMENT_VERSION
Definition: StdAfx.h:274
#define CHANNELS_PER_CLIENT
Definition: StdAfx.h:195
#define max(a, b)
Definition: StdAfx.h:654
SINT32 getPublicKeyAsDOMElement(DOMElement *&elemRoot, XERCES_CPP_NAMESPACE::DOMDocument *docOwner)
SINT32 setPublicKeyAsDOMNode(DOMNode *node)
SINT32 generateKeyPair(UINT32 size)
Generates a new random key-pair of size bits.
CACertificate * verifyMixCert(DOMNode *mixNode)
This function parses the certificates from a <Mix>-node and tries to build a certPath to the trusted ...
UINT32 getKeepAliveRecvInterval()
CACertificate * getNextMixTestCertificate()
SINT32 setNextMixTestCertificate(CACertificate *cert)
UINT32 getKeepAliveSendInterval()
CACertStore * getTrustedCertificateStore()
bool verifyMixCertificates()
SINT32 initMixParameters(DOMElement *elemMixes)
Initialises the MixParameters info for each mix form the <Mixes> element received from the second mix...
SINT32 handleKeyInfoExtensions(DOMElement *root)
Definition: CAFirstMix.cpp:805
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
virtual SINT32 initMixCascadeInfo(DOMElement *elemMixes)
This will initialize the XML Cascade Info struct XMLFirstMixToInfoService that is sent to the InfoSer...
Definition: CAMix.cpp:299
UINT32 m_u32KeepAliveSendInterval
Definition: CAMix.hpp:187
static SINT32 verifyXML(const UINT8 *const in, UINT32 inlen, CACertificate *a_cert)
SINT32 signXML(DOMNode *a_node, bool appendCerts)
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

Referenced by init().

Here is the caller graph for this function:

◆ reconfigure()

SINT32 CAFirstMix::reconfigure ( )
protectedvirtual

Reimplemented from CAMix.

Definition at line 2845 of file CAFirstMix.cpp.

2846  {
2847  CAMsg::printMsg(LOG_DEBUG,"Reconfiguring First Mix\n");
2848 #ifdef DELAY_USERS
2849  CAMsg::printMsg(LOG_DEBUG,"Set new ressources limitation parameters\n");
2850 #ifndef MULTI_THREADED_PACKET_PROCESSING
2851  if(m_pChannelList!=NULL)
2852  m_pChannelList->setDelayParameters( CALibProxytest::getOptions()->getDelayChannelUnlimitTraffic(),
2853  CALibProxytest::getOptions()->getDelayChannelBucketGrow(),
2854  CALibProxytest::getOptions()->getDelayChannelBucketGrowIntervall());
2855 #endif
2856 #endif
2857  return E_SUCCESS;
2858  }
void setDelayParameters(UINT32 unlimitTraffic, UINT32 bucketGrow, UINT32 intervall)

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

Here is the call graph for this function:

◆ sendReplayTimestampRequestsToAllMixes()

SINT32 CAFirstMix::sendReplayTimestampRequestsToAllMixes ( )
private

Definition at line 2910 of file CAFirstMix.cpp.

2911  {
2912  for(UINT32 i=0;i<m_u32MixCount-1;i++)
2913  {
2915  }
2916  return E_SUCCESS;
2917  }
SINT32 sendGetTimestamp(const UINT8 *strMixID)
Sends upstram a request for the replay timestamp for the given mix.

References E_SUCCESS, m_arMixParameters, CAMixWithReplayDB::m_pReplayMsgProc, m_u32MixCount, and CAReplayCtrlChannelMsgProc::sendGetTimestamp().

Here is the call graph for this function:

◆ setMixParameters()

SINT32 CAFirstMix::setMixParameters ( const tMixParameters params)

Sets the parameters for the mix specified in the params.m_strMixID field.

Only the values which are set are copied to the stored parameters of the mixes of this cascade.

Definition at line 784 of file CAFirstMix.cpp.

785  {
786 #ifdef REPLAY_DETECTION
787  UINT32 diff=time(NULL)-m_u64LastTimestampReceived;
788  for(UINT32 i=0;i<m_u32MixCount-1;i++)
789  {
790 //@todo dangerous strcmp
791  if(strcmp((char*)m_arMixParameters[i].m_strMixID,(char*)params.m_strMixID)==0)
792  {
795  }
796  else{
797  if (m_arMixParameters[i].m_u32ReplayOffset!=0) m_arMixParameters[i].m_u32ReplayOffset+=diff;
798  }
799  }
800 #endif
801  return E_SUCCESS;
802  }
UINT16 m_u32ReplayBase
Definition: typedefs.hpp:219
UINT32 m_u32ReplayOffset
Definition: typedefs.hpp:218

References E_SUCCESS, m_arMixParameters, t_mix_parameters::m_strMixID, m_u32MixCount, t_mix_parameters::m_u32ReplayBase, t_mix_parameters::m_u32ReplayOffset, and m_u64LastTimestampReceived.

◆ updateCountryStats()

SINT32 CAFirstMix::updateCountryStats ( const UINT8  ip[4],
UINT32  a_countryID,
bool  bRemove 
)
private

Update the statisitics of the countries users come from.

The dependency between the argumenst is as follow:

Parameters
bRemoveif true the number of users of a given country is decreased, if false it is increased
a_countryIDthe country the user comes from. Must be set if bRemove==true. If bRemove==false and ip==NULL, than if also must be set to the country the user comes from. In case ip!=NULL if holdes the default country id, if no country for the ip could be found
ipthe ip the user comes from. this ip is looked up in the databse to find the corresponding country. it is only used if bRemove==false. If no country for that ip could be found a_countryID is used as default value
Returns
the countryID which was asigned to the user. This may be the default value a_countryID, if no country could be found.

Definition at line 3014 of file CAFirstMix.cpp.

3015  {
3016  if(!bRemove)
3017  {
3018  UINT32 countryID=a_countryID;
3019  if(ip!=NULL)
3020  {
3021  UINT32 u32ip=ip[0]<<24|ip[1]<<16|ip[2]<<8|ip[3];
3022  char query[1024];
3023  sprintf(query,"SELECT id FROM ip2c WHERE ip_lo<=\"%u\" and ip_hi>=\"%u\" LIMIT 1",u32ip,u32ip);
3024  int ret=mysql_query(m_mysqlCon,query);
3025  if(ret!=0)
3026  {
3027  CAMsg::printMsg(LOG_INFO,"CountryStatsDB - updateCountryStats - error (%i) in finding countryid for ip %u\n",ret,u32ip);
3028  goto RET;
3029  }
3030  MYSQL_RES* result=mysql_store_result(m_mysqlCon);
3031  if(result==NULL)
3032  {
3033  CAMsg::printMsg(LOG_INFO,"CountryStatsDB - updateCountryStats - error in retriving results of the query\n");
3034  goto RET;
3035  }
3036  MYSQL_ROW row=mysql_fetch_row(result);
3037  SINT32 t;
3038  if(row!=NULL&&(t=atoi(row[0]))>0&&t<=NR_OF_COUNTRIES)
3039  {
3040  countryID=t;
3041  #ifdef DEBUG
3042  CAMsg::printMsg(LOG_DEBUG,"Country ID for ip %u is %u\n",u32ip,countryID);
3043  #endif
3044  //temp hack
3045  if(countryID==99)
3046  {
3047  CAMsg::printMsg(LOG_DEBUG,"Country ID for ip %u.%u.%u.%u is %u\n",ip[0],ip[1],ip[2],ip[3],countryID);
3048  }
3049  }
3050  else
3051  {
3052  CAMsg::printMsg(LOG_DEBUG,"DO country stats query result no result for ip %u)\n",u32ip);
3053  }
3054  mysql_free_result(result);
3055  }
3056 RET:
3057  m_CountryStats[countryID]++;
3058  return countryID;
3059  }
3060  else//bRemove
3061  {
3062  m_CountryStats[a_countryID]--;
3063  }
3064  return a_countryID;
3065  }

References m_CountryStats, m_mysqlCon, NR_OF_COUNTRIES, and CAMsg::printMsg().

Referenced by decUsers(), and incUsers().

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

Friends And Related Function Documentation

◆ fm_loopAcceptUsers

THREAD_RETURN fm_loopAcceptUsers ( void *  )
friend

Definition at line 1276 of file CAFirstMix.cpp.

1277  {
1278  INIT_STACK;
1279  BEGIN_STACK("CAFirstMix::fm_loopAcceptUsers");
1280  CAMsg::printMsg(LOG_DEBUG, "Start acceptusers\n");
1281 
1282  CAFirstMix* pFirstMix=(CAFirstMix*)param;
1283  CASocket** socketsIn=pFirstMix->m_arrSocketsIn;
1284  CAIPList* pIPList=pFirstMix->m_pIPList;
1285  CATempIPBlockList* pIPBlockList = pFirstMix->m_pIPBlockList;
1286  CAThreadPool* pthreadsLogin=pFirstMix->m_pthreadsLogin;
1287  UINT32 nSocketsIn=pFirstMix->m_nSocketsIn;
1288 #ifdef __BUILD_AS_SHADOW_PLUGIN__
1289  CASocketGroupEpoll* psocketgroupAccept=new CASocketGroupEpoll(false);
1290 #else
1291  CASocketGroup* psocketgroupAccept = new CASocketGroup(false);
1292 #endif
1293  CAMuxSocket* pNewMuxSocket;
1294  UINT8* peerIP=new UINT8[4];
1295  UINT32 i=0;
1296  SINT32 countRead;
1297  SINT32 ret;
1298  SINT32 retPeerIP = E_SUCCESS;
1299 
1300  pFirstMix->m_newConnections = 0;
1301 
1302  // kick out users that already have connected
1303  for(i=0;i<nSocketsIn;i++)
1304  {
1305  while (socketsIn[i]->close() != E_SUCCESS)
1306  {
1307  sSleep(1);
1308  }
1309  delete socketsIn[i];
1310  }
1311  CAMsg::printMsg(LOG_DEBUG, "Creating incoming sockets\n");
1312 
1313  if (CALibProxytest::getOptions()->createSockets(false,pFirstMix-> m_arrSocketsIn, pFirstMix->m_nSocketsIn) != E_SUCCESS)
1314  {
1315  goto END_THREAD;
1316  }
1317  CAMsg::printMsg(LOG_DEBUG, "Add sockets to select group\n");
1318  for(i=0;i<nSocketsIn;i++)
1319  {
1320  psocketgroupAccept->add(*socketsIn[i]);
1321  }
1322 #ifdef REPLAY_DETECTION //before we can start to accept users we have to ensure that we received the replay timestamps form the over mixes
1323  CAMsg::printMsg(LOG_DEBUG,"Waiting for Replay Timestamp from next mixes\n");
1324  i=0;
1325  while(!pFirstMix->m_bRestart && i < pFirstMix->m_u32MixCount-1)
1326  {
1327  if(pFirstMix->m_arMixParameters[i].m_u32ReplayOffset==0)//not set yet
1328  {
1329  msSleep(100);//wait a little bit and try again
1330  continue;
1331  }
1332  i++;
1333  }
1334  CAMsg::printMsg(LOG_DEBUG,"All Replay Timestamp received\n");
1335 #endif
1336  CAMsg::printMsg(LOG_DEBUG, "Start accept users inner loop\n");
1337 
1338  while(!pFirstMix->m_bRestart)
1339  {
1340  if (pIPBlockList->count()>40)
1341  {
1342  CAMsg::printMsg(LOG_DEBUG,"UserAcceptLoop: login timeout list counts %d. We have %d users, %d open sockets and %d new connections. Restarting server sockets...\n",pIPBlockList->count(), pFirstMix->getNrOfUsers() ,CASocket::countOpenSockets(), pFirstMix->m_newConnections);
1343  for(i=0;i<nSocketsIn;i++)
1344  {
1345  psocketgroupAccept->remove(*socketsIn[i]);
1346  while (socketsIn[i]->close() != E_SUCCESS)
1347  {
1348  sSleep(1);
1349  }
1350  }
1351 
1352  if (CALibProxytest::getOptions()->createSockets(false,pFirstMix-> m_arrSocketsIn, pFirstMix->m_nSocketsIn) != E_SUCCESS)
1353  {
1354  // could not listen
1355  goto END_THREAD;
1356  }
1357  for(i=0;i<nSocketsIn;i++)
1358  {
1359  psocketgroupAccept->add(*socketsIn[i]);
1360  }
1361  sSleep(1);
1362  }
1363 #ifdef __BUILD_AS_SHADOW_PLUGIN__
1364  CAMsg::printMsg(LOG_DEBUG, "Before acceptusers->select()\n");
1365  countRead=psocketgroupAccept->select();
1366  CAMsg::printMsg(LOG_DEBUG, "after acceptusers->select()\n");
1367 #else
1368  countRead = psocketgroupAccept->select(10000);
1369 #endif
1370  if(countRead<0)
1371  { //check for Error - are we restarting ?
1372  if(pFirstMix->m_bRestart ||countRead!=E_TIMEDOUT)
1373  goto END_THREAD;
1374  }
1375  i=0;
1376 #ifdef _DEBUG
1377  CAMsg::printMsg(LOG_DEBUG,"UserAcceptLoop: countRead=%i\n",countRead);
1378 #endif
1379  while(countRead>0&&i<nSocketsIn)
1380  {
1381  if(psocketgroupAccept->isSignaled(*socketsIn[i]))
1382  {
1383  countRead--;
1384  #ifdef _DEBUG
1385  CAMsg::printMsg(LOG_DEBUG,"New direct Connection from Client!\n");
1386  #endif
1387  #ifdef SYM_CHANNEL_CIPHER_CTR
1388  pNewMuxSocket=new CAMuxSocket(CTR);
1389  #elif defined NO_ENCRYPTION
1390  pNewMuxSocket = new CAMuxSocket(NULL_CIPHER);
1391 #else
1392  pNewMuxSocket=new CAMuxSocket(OFB);
1393  #endif
1394  ret=socketsIn[i]->accept(*(pNewMuxSocket->getCASocket()));
1395  pFirstMix->incNewConnections();
1396 
1397  if(ret!=E_SUCCESS)
1398  {
1399  // may return E_SOCKETCLOSED or E_SOCKET_LIMIT
1400  CAMsg::printMsg(LOG_ERR,"Accept Error %u - direct Connection from Client!\n",GET_NET_ERROR);
1401  }
1402  else if( (CALibProxytest::getOptions()->getMaxNrOfUsers() > 0 &&
1404  && (isAllowedToPassRestrictions(pNewMuxSocket->getCASocket()) != E_SUCCESS)
1405 
1406  )
1407  {
1408  CAMsg::printMsg(LOG_DEBUG,"CAFirstMix User control: Too many users (Maximum:%d)! Rejecting user...\n", pFirstMix->getNrOfUsers(),CALibProxytest::getOptions()->getMaxNrOfUsers());
1409  ret = E_UNKNOWN;
1410  }
1412  && (isAllowedToPassRestrictions(pNewMuxSocket->getCASocket()) != E_SUCCESS)
1413  )
1414 
1415  {
1416  /* This should protect the mix from flooding attacks
1417  * No more than MAX_CONCURRENT_NEW_CONNECTIONS are allowed.
1418  */
1419 #ifdef _DEBUG
1420  CAMsg::printMsg(LOG_DEBUG,"CAFirstMix Flooding protection: Too many concurrent new connections (Maximum:%d)! Rejecting user...\n", CAFirstMix::MAX_CONCURRENT_NEW_CONNECTIONS);
1421 #endif
1422  ret = E_UNKNOWN;
1423  }
1424 //#ifndef PAYMENT
1425  else if ((ret = pNewMuxSocket->getCASocket()->getPeerIP(peerIP)) != E_SUCCESS ||
1426  (retPeerIP = pIPList->insertIP(peerIP)) < 0)
1427  // || (pIPBlockList->checkIP(peerIP) == E_UNKNOWN && isAllowedToPassRestrictions(pNewMuxSocket->getCASocket()) != E_SUCCESS))
1428  {
1429  if (ret != E_SUCCESS)
1430  {
1431  CAMsg::printMsg(LOG_DEBUG,"Could not insert IP address as IP could not be retrieved! We have %d login threads currently running.\n", pthreadsLogin->countRequests());
1432 
1433  }
1434  else if (retPeerIP < 0)
1435  {
1436  CAMsg::printMsg(LOG_DEBUG,"CAFirstMix Flooding protection: Could not insert IP address! We have %d login threads currently running.\n", pthreadsLogin->countRequests());
1437  pIPBlockList->insertIP(peerIP);
1438  }
1439  else if (pIPBlockList->checkIP(peerIP) == E_UNKNOWN)
1440  {
1441  CAMsg::printMsg(LOG_DEBUG, "Client IP address %u.%u.x.x is temporarily blocked! User login denied. We have %d open sockets and %d new connections.\n", peerIP[0],peerIP[1], CASocket::countOpenSockets(), pFirstMix->m_newConnections);
1442  pIPList->removeIP(peerIP);
1443  }
1444  ret = E_UNKNOWN;
1445  }
1446 //#endif
1447  else
1448  {
1450  d->pNewUser=pNewMuxSocket;
1451  d->pMix=pFirstMix;
1452  memcpy(d->peerIP,peerIP,4);
1453 #ifdef DEBUG
1454  CAMsg::printMsg(LOG_DEBUG,"%d concurrent client connections.\n", pFirstMix->m_newConnections);
1455 #endif
1456  if(pthreadsLogin->addRequest(fm_loopDoUserLogin,d)!=E_SUCCESS)
1457  {
1458  CAMsg::printMsg(LOG_ERR,"Could not add an login request to the login thread pool!\n");
1459  ret=E_UNKNOWN;
1460  }
1461  }
1462 
1463  if (ret != E_SUCCESS)
1464  {
1465  delete pNewMuxSocket;
1466  pNewMuxSocket = NULL;
1467  pFirstMix->decNewConnections();
1468  if(ret==E_SOCKETCLOSED&&pFirstMix->m_bRestart) //Hm, should we restart ??
1469  {
1470  goto END_THREAD;
1471  }
1472  else //if(ret==E_SOCKET_LIMIT) // Hm no free sockets - wait some time to hope to get a free one...
1473  {
1474  msSleep(400);
1475  }
1476  }
1477  }
1478  i++;
1479  }
1480  }
1481 END_THREAD:
1482  FINISH_STACK("CAFirstMix::fm_loopAcceptUsers");
1483 
1484  delete[] peerIP;
1485  peerIP = NULL;
1486  delete psocketgroupAccept;
1487  psocketgroupAccept = NULL;
1488 
1489  CAMsg::printMsg(LOG_DEBUG,"Exiting Thread AcceptUser\n");
1491  }
struct T_UserLoginData t_UserLoginData
@ NULL_CIPHER
SINT32 msSleep(UINT32 ms)
Sleeps ms milliseconds.
Definition: CAUtil.cpp:406
#define THREAD_RETURN_SUCCESS
Definition: StdAfx.h:542
UINT32 getMaxNrOfUsers()
friend THREAD_RETURN fm_loopDoUserLogin(void *param)
static const UINT32 MAX_CONCURRENT_NEW_CONNECTIONS
Definition: CAFirstMix.hpp:566
void incNewConnections()
Definition: CAFirstMix.hpp:571
void decNewConnections()
Definition: CAFirstMix.hpp:578
SINT32 isAllowedToPassRestrictions(CASocket *pNewMuxSocket)
SINT32 insertIP(const UINT8 ip[4])
Inserts the IP-Address into the list.
Definition: CAIPList.cpp:103
SINT32 remove(CASocket &s)
bool isSignaled(CASocket &s)
virtual SINT32 getPeerIP(UINT8 ip[4])
Definition: CASocket.cpp:820
virtual SINT32 accept(CASocket &s)
Accepts a new connection.
Definition: CASocket.cpp:192
static UINT32 countOpenSockets()
Definition: CASocket.hpp:128
SINT32 checkIP(const UINT8 ip[4])
check whether an IP is blocked
SINT32 addRequest(THREAD_MAIN_TYP, void *args)
Adds a new request (task) to this threadpool.
UINT32 countRequests()
CAFirstMix * pMix
CAMuxSocket * pNewUser

Referenced by init().

◆ fm_loopDoUserLogin

THREAD_RETURN fm_loopDoUserLogin ( void *  param)
friend

Definition at line 1549 of file CAFirstMix.cpp.

1550  {
1551  INIT_STACK;
1552  BEGIN_STACK("CAFirstMix::fm_loopDoUserLogin");
1553 #ifdef COUNTRY_STATS
1554  my_thread_init();
1555 #endif
1556 
1557  t_UserLoginData* d=(t_UserLoginData*)param;
1558  d->pMix->doUserLogin(d->pNewUser,d->peerIP);
1559 
1560  SAVE_STACK("CAFirstMix::fm_loopDoUserLogin", "after user login");
1561  d->pMix->decNewConnections();
1562  delete d;
1563  d = NULL;
1564 
1565 #ifdef COUNTRY_STATS
1566  my_thread_end();
1567 #endif
1568  FINISH_STACK("CAFirstMix::fm_loopDoUserLogin");
1569 
1571  }
SINT32 doUserLogin(CAMuxSocket *pNewUSer, UINT8 perrIP[4])

◆ fm_loopLog

THREAD_RETURN fm_loopLog ( void *  )
friend

Definition at line 1494 of file CAFirstMix.cpp.

1495  {
1496  CAFirstMix* pFirstMix=(CAFirstMix*)param;
1497  pFirstMix->m_bRunLog=true;
1498  UINT32 countLog=0;
1499  while(pFirstMix->m_bRunLog)
1500  {
1501  if(countLog==0)
1502  {
1503  logMemoryUsage();
1504  countLog=10;
1505  }
1506  sSleep(30);
1507  countLog--;
1508  }
1510  }
void logMemoryUsage()
Log information about the current memory (heap) usage.
Definition: CAUtil.cpp:177

Referenced by CAFirstMixA::loop().

◆ fm_loopReadFromMix

THREAD_RETURN fm_loopReadFromMix ( void *  )
friend

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

Definition at line 1092 of file CAFirstMix.cpp.

1093  {
1094  INIT_STACK;
1095  BEGIN_STACK("CAFirstMix::fm_loopReadFromMix");
1096 
1097  CAFirstMix* pFirstMix=(CAFirstMix*)pParam;
1098  CAMuxSocket* pMuxSocket=pFirstMix->m_pMuxOut;
1099  CAQueue* pQueue=pFirstMix->m_pQueueReadFromMix;
1100  tQueueEntry* pQueueEntry=new tQueueEntry;
1101  MIXPACKET* pMixPacket=&pQueueEntry->packet;
1102  CASingleSocketGroup* pSocketGroup=new CASingleSocketGroup(false);
1103  pSocketGroup->add(*pMuxSocket);
1104  #ifdef USE_POOL
1105  CAPool* pPool=new CAPool(MIX_POOL_SIZE);
1106  #endif
1107  UINT64 keepaliveNow,keepaliveLast;
1108  UINT32 u32KeepAliveRecvInterval=pFirstMix->m_u32KeepAliveRecvInterval;
1109  getcurrentTimeMillis(keepaliveLast);
1110  CAControlChannelDispatcher* pControlChannelDispatcher=pFirstMix->m_pMuxOutControlChannelDispatcher;
1111  while (!pFirstMix->m_bRestart)
1112  {
1114  {
1115 #ifdef DEBUG
1116  CAMsg::printMsg(LOG_DEBUG, "CAFirstMix::Queue is full!\n");
1117 #endif
1118  msSleep(200);
1119  getcurrentTimeMillis(keepaliveLast);
1120  continue;
1121  }
1122  //check if the connection is broken because we did not received a Keep_alive-Message
1123  getcurrentTimeMillis(keepaliveNow);
1124  UINT32 keepaliveDiff = diff64(keepaliveNow, keepaliveLast);
1125  if (keepaliveDiff > u32KeepAliveRecvInterval)
1126  {
1127  CAMsg::printMsg(LOG_DEBUG, "CAFirstMix::loopReadFromMix() -- restart because of KeepAlive-Traffic Timeout!\n");
1128  pFirstMix->m_bRestart = true;
1130  break;
1131  }
1132  SINT32 ret = pSocketGroup->select(MIX_POOL_TIMEOUT);
1133  if (ret < 0)
1134  {
1135  if (ret == E_TIMEDOUT)
1136  {
1137 #ifdef USE_POOL
1138  pMixPacket->flags=CHANNEL_DUMMY;
1139  pMixPacket->channel=DUMMY_CHANNEL;
1140  getRandom(pMixPacket->data,DATA_SIZE);
1141 #ifdef LOG_PACKET_TIMES
1142  setZero64(pQueueEntry->timestamp_proccessing_start);
1143 #endif
1144 #else
1145  continue;
1146 #endif
1147  }
1148  else
1149  {
1150  /* another error occured (happens sometimes while debugging because
1151  * of interruption, if a breakpoint is reached -> poll() returns
1152  * errorcode EINTR)
1153  * Note: Any Error on select() does not mean, that the underliny connections have some error state, because
1154  * in this case select() returns the socket and than this socket returns the error
1155  */
1156 #ifdef DEBUG
1157  CAMsg::printMsg(LOG_DEBUG, "CAFirstMix::loopReadFromMix() - socket select error: %i\n",ret);
1158 #endif
1159  continue;
1160  }
1161  }
1162  else if (ret > 0)
1163  {
1164  ret = pMuxSocket->receive(pMixPacket);
1165 #ifdef LOG_PACKET_TIMES
1166  getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_start);
1167 #endif
1168  if (ret != MIXPACKET_SIZE)
1169  {
1170  pFirstMix->m_bRestart = true;
1171  CAMsg::printMsg(LOG_ERR, "CAFirstMix::lm_loopReadFromMix - received returned: %i -- restarting!\n", ret);
1173  break;
1174  }
1175  if (pMixPacket->channel > 0 && pMixPacket->channel < 256)
1176  {
1177 #ifdef DEBUG
1178  CAMsg::printMsg(LOG_DEBUG, "CAFirstMix - sent a packet from the next mix to the ControlChanelDispatcher... \n");
1179 #endif
1180  pControlChannelDispatcher->proccessMixPacket(pMixPacket);
1181  getcurrentTimeMillis(keepaliveLast);
1182  continue;
1183  }
1184  }
1185 #ifdef USE_POOL
1186 #ifdef LOG_PACKET_TIMES
1187  getcurrentTimeMicros(pQueueEntry->pool_timestamp_in);
1188 #endif
1189  pPool->pool((tPoolEntry*)pQueueEntry);
1190 #ifdef LOG_PACKET_TIMES
1191  getcurrentTimeMicros(pQueueEntry->pool_timestamp_out);
1192 #endif
1193 #endif
1194 #ifdef ANON_DEBUG_MODE
1195  if (pMixPacket->flags&CHANNEL_DEBUG)
1196  {
1197  UINT8 base64Payload[DATA_SIZE << 1];
1198  EVP_EncodeBlock(base64Payload, pMixPacket->data, DATA_SIZE);//base64 encoding (without newline!)
1199  CAMsg::printMsg(LOG_DEBUG, "Received Downstream AN.ON packet from previous Mix debug: %s\n", base64Payload);
1200  }
1201 
1202 #endif
1203  pQueue->add(pQueueEntry, sizeof(tQueueEntry));
1204  getcurrentTimeMillis(keepaliveLast);
1205  }
1206  delete pQueueEntry;
1207  pQueueEntry = NULL;
1208  delete pSocketGroup;
1209  pSocketGroup = NULL;
1210  #ifdef USE_POOL
1211  delete pPool;
1212  pPool = NULL;
1213  #endif
1214 
1215  FINISH_STACK("CAFirstMix::fm_loopReadFromMix");
1217  }
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
UINT32 diff64(const UINT64 &bigop, const UINT64 &smallop)
Definition: CAUtil.hpp:398
void setZero64(UINT64 &op1)
Definition: CAUtil.hpp:355
#define MIX_POOL_TIMEOUT
Definition: StdAfx.h:245
#define MAX_READ_FROM_NEXT_MIX_QUEUE_SIZE
Definition: StdAfx.h:227
#define DUMMY_CHANNEL
Definition: StdAfx.h:246
#define MIX_POOL_SIZE
Definition: StdAfx.h:243
This class implements the pool strategie of a Mix.
Definition: CAPool.hpp:43
SINT32 pool(tPoolEntry *pPoolEntry)
Definition: CAPool.cpp:83
SINT32 add(SOCKET &s)
UINT8 data[DATA_SIZE]
Definition: typedefs.hpp:121
UINT16 flags
Definition: typedefs.hpp:118
MIXPACKET packet
Definition: typedefs.hpp:170
#define CHANNEL_DEBUG
Definition: typedefs.hpp:51
#define CHANNEL_DUMMY
Definition: typedefs.hpp:50
#define DATA_SIZE
Definition: typedefs.hpp:69

Referenced by init().

◆ fm_loopSendToMix

THREAD_RETURN fm_loopSendToMix ( void *  )
friend

How to end this thread: 0.

set bRestart=true;

  1. Close connection to next mix
  2. put some bytes (len>MIX_PACKET_SIZE) in the Mix-Output-Queue

Definition at line 978 of file CAFirstMix.cpp.

979  {
980  INIT_STACK;
981  BEGIN_STACK("CAFirstMix::fm_loopSendToMix");
982 
983  CAFirstMix* pFirstMix=(CAFirstMix*)param;
984  CAQueue* pQueue=((CAFirstMix*)param)->m_pQueueSendToMix;
985  CAMuxSocket* pMuxSocket=pFirstMix->m_pMuxOut;
986 
987  UINT32 len;
988  SINT32 ret;
989 
990 /*#ifdef DATA_RETENTION_LOG
991  t_dataretentionLogEntry* pDataRetentionLogEntry=new t_dataretentionLogEntry;
992 #endif
993 */
994 #ifndef USE_POOL
995  tQueueEntry* pQueueEntry=new tQueueEntry;
996  MIXPACKET* pMixPacket=&pQueueEntry->packet;
997  UINT32 u32KeepAliveSendInterval=pFirstMix->m_u32KeepAliveSendInterval;
998  while(!pFirstMix->m_bRestart)
999  {
1000  len=sizeof(tQueueEntry);
1001  ret=pQueue->getOrWait((UINT8*)pQueueEntry,&len,u32KeepAliveSendInterval);
1002  if(ret==E_TIMEDOUT)
1003  {//send a dummy as keep-alvie-traffic
1004  pMixPacket->flags=CHANNEL_DUMMY;
1005  pMixPacket->channel=DUMMY_CHANNEL;
1006  getRandom(pMixPacket->data,DATA_SIZE);
1007  }
1008  else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry))
1009  {
1010  CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMix - Error in dequeueing MixPaket\n");
1011  CAMsg::printMsg(LOG_ERR,"ret=%i len=%i\n",ret,len);
1012  break;
1013  }
1014 
1015  if(pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE)
1016  {
1017  CAMsg::printMsg(LOG_ERR,"CAFirstMix::lm_loopSendToMix - Error in sending MixPaket\n");
1018  break;
1019  }
1020 #if defined (LOG_PACKET_TIMES)
1021  if(!isZero64(pQueueEntry->timestamp_proccessing_start))
1022  {
1023  getcurrentTimeMicros(pQueueEntry->timestamp_proccessing_end);
1024  pFirstMix->m_pLogPacketStats->addToTimeingStats(*pQueueEntry,pMixPacket->flags,true);
1025  }
1026 #endif
1027 #ifdef DATA_RETENTION_LOG
1028  if((pQueueEntry->packet.flags&CHANNEL_OPEN)!=0)
1029  {
1030  pQueueEntry->dataRetentionLogEntry.t_out=htonl(time(NULL));
1031  pFirstMix->m_pDataRetentionLog->log(&(pQueueEntry->dataRetentionLogEntry));
1032  }
1033 #endif
1034  }
1035  delete pQueueEntry;
1036  pQueueEntry = NULL;
1037 #else
1038  CAPool* pPool=new CAPool(MIX_POOL_SIZE);
1039  tPoolEntry* pPoolEntry=new tPoolEntry;
1040  MIXPACKET* pMixPacket=&pPoolEntry->packet;
1041  while(!pFirstMix->m_bRestart)
1042  {
1043  len=sizeof(tQueueEntry);
1044  ret=pQueue->getOrWait((UINT8*)pPoolEntry,&len,MIX_POOL_TIMEOUT);
1045  if(ret==E_TIMEDOUT)
1046  {
1047  pMixPacket->flags=CHANNEL_DUMMY;
1048  pMixPacket->channel=DUMMY_CHANNEL;
1049  getRandom(pMixPacket->data,DATA_SIZE);
1050  #ifdef LOG_PACKET_TIMES
1051  setZero64(pPoolEntry->timestamp_proccessing_start);
1052  #endif
1053  }
1054  else if(ret!=E_SUCCESS||len!=sizeof(tQueueEntry))
1055  break;
1056  #ifdef LOG_PACKET_TIMES
1057  getcurrentTimeMicros(pPoolEntry->pool_timestamp_in);
1058  #endif
1059  pPool->pool(pPoolEntry);
1060  #ifdef LOG_PACKET_TIMES
1061  getcurrentTimeMicros(pPoolEntry->pool_timestamp_out);
1062  #endif
1063  if(pMuxSocket->send(pMixPacket)!=MIXPACKET_SIZE)
1064  break;
1065  #ifdef LOG_PACKET_TIMES
1066  if(!isZero64(pPoolEntry->timestamp_proccessing_start))
1067  {
1068  getcurrentTimeMicros(pPoolEntry->timestamp_proccessing_end);
1069  pFirstMix->m_pLogPacketStats->addToTimeingStats(*pPoolEntry,pMixPacket->flags,true);
1070  }
1071  #endif
1072  }
1073  delete pPoolEntry;
1074  pPoolEntry = NULL;
1075  delete pPool;
1076  pPool = NULL;
1077 #endif
1078 
1079 /*#ifdef DATA_RETENTION_LOG
1080  delete pDataRetentionLogEntry;
1081 #endif
1082 */
1083  FINISH_STACK("CAFirstMix::fm_loopSendToMix");
1084 
1085  CAMsg::printMsg(LOG_DEBUG,"Exiting Thread SendToMix\n");
1087  }
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
tQueueEntry tPoolEntry
Definition: typedefs.hpp:192
#define CHANNEL_OPEN
Definition: typedefs.hpp:43

Referenced by init().

◆ iplist_loopDoLogCountries

THREAD_RETURN iplist_loopDoLogCountries ( void *  param)
friend

Definition at line 3067 of file CAFirstMix.cpp.

3068  {
3069  mysql_thread_init();
3070  CAMsg::printMsg(LOG_DEBUG,"Starting iplist_loopDoLogCountries\n");
3071  CAFirstMix* pFirstMix=(CAFirstMix*)param;
3072  UINT32 s=0;
3073  UINT8 buff[255];
3074  memset(buff,0,255);
3076  mysqlEscapeTableName(buff);
3077  while(pFirstMix->m_bRunLogCountries)
3078  {
3080  {
3081  UINT8 aktDate[255];
3082  time_t aktTime=time(NULL);
3083  strftime((char*)aktDate,255,"%Y%m%d%H%M%S",gmtime(&aktTime));
3084  char query[1024];
3085  sprintf(query,"INSERT into `stats_%s` (date,id,count,packets_in,packets_out) VALUES (\"%s\",\"%%u\",\"%%u\",\"%%u\",\"%%u\")",buff,aktDate);
3086  pFirstMix->m_pmutexUser->lock();
3087  for(UINT32 i=0;i<NR_OF_COUNTRIES+1;i++)
3088  {
3089  if(pFirstMix->m_CountryStats[i]>0)
3090  {
3091  char aktQuery[1024];
3092  sprintf(aktQuery,query,i,pFirstMix->m_CountryStats[i],pFirstMix->m_PacketsPerCountryIN[i].getAndzero(),pFirstMix->m_PacketsPerCountryOUT[i].getAndzero());
3093  SINT32 ret=mysql_query(pFirstMix->m_mysqlCon,aktQuery);
3094  if(ret!=0)
3095  {
3096  CAMsg::printMsg(LOG_INFO,"CountryStats DB - failed to update CountryStats DB with new values - error %i\n",ret);
3097  }
3098  }
3099  }
3100  pFirstMix->m_pmutexUser->unlock();
3101  s=0;
3102  }
3103  sSleep(10);
3104  s++;
3105  }
3106  CAMsg::printMsg(LOG_DEBUG,"Exiting iplist_loopDoLogCountries\n");
3107  mysql_thread_end();
3109  }
#define LOG_COUNTRIES_INTERVALL
Definition: StdAfx.h:133

Referenced by initCountryStats().

Member Data Documentation

◆ m_arMixParameters

tMixParameters* CAFirstMix::m_arMixParameters
protected

◆ m_arrSocketsIn

CASocket** CAFirstMix::m_arrSocketsIn
protected

Definition at line 457 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), clean(), init(), and CAFirstMixB::loop().

◆ m_bIsShuttingDown

bool CAFirstMix::m_bIsShuttingDown
protected

Definition at line 550 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), isShuttingDown(), and CAFirstMixA::shutDown().

◆ m_bRestart

volatile bool CAFirstMix::m_bRestart
protected

◆ m_bRunLog

volatile bool CAFirstMix::m_bRunLog
protected

Definition at line 552 of file CAFirstMix.hpp.

Referenced by clean(), and CAFirstMixA::loop().

◆ m_bRunLogCountries

volatile bool CAFirstMix::m_bRunLogCountries
private

Definition at line 532 of file CAFirstMix.hpp.

Referenced by deleteCountryStats(), and initCountryStats().

◆ m_CountryStats

volatile UINT32* CAFirstMix::m_CountryStats
private

◆ m_docMixCascadeInfo

XERCES_CPP_NAMESPACE::DOMDocument* CAFirstMix::m_docMixCascadeInfo
protected

Definition at line 495 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), and clean().

◆ m_mysqlCon

MYSQL* CAFirstMix::m_mysqlCon
private

◆ m_newConnections

volatile UINT32 CAFirstMix::m_newConnections
private

Definition at line 568 of file CAFirstMix.hpp.

Referenced by decNewConnections(), and incNewConnections().

◆ m_nMixedPackets

UINT64 CAFirstMix::m_nMixedPackets
protected

Definition at line 496 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), clean(), getMixedPackets(), incMixedPackets(), and init().

◆ m_nrOfTermsAndConditionsDefs

UINT32 CAFirstMix::m_nrOfTermsAndConditionsDefs
protected

◆ m_nrOfTermsAndConditionsTemplates

UINT32 CAFirstMix::m_nrOfTermsAndConditionsTemplates
protected

◆ m_nSocketsIn

UINT32 CAFirstMix::m_nSocketsIn
protected

Definition at line 455 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), clean(), init(), initOnce(), and CAFirstMixB::loop().

◆ m_nUser

volatile UINT32 CAFirstMix::m_nUser
protected

◆ m_PacketsPerCountryIN

tUINT32withLock* CAFirstMix::m_PacketsPerCountryIN
protected

◆ m_PacketsPerCountryOUT

tUINT32withLock* CAFirstMix::m_PacketsPerCountryOUT
protected

◆ m_pChannelList

CAFirstMixChannelList* CAFirstMix::m_pChannelList
protected

◆ m_pIPBlockList

CATempIPBlockList* CAFirstMix::m_pIPBlockList
protected

Definition at line 447 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), clean(), doUserLogin_internal(), and init().

◆ m_pIPList

CAIPList* CAFirstMix::m_pIPList
protected

◆ m_pmutexLogin

CAMutex* CAFirstMix::m_pmutexLogin
protected

Definition at line 555 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), getLoginMutex(), CAFirstMixA::loop(), and ~CAFirstMix().

◆ m_pmutexLoginThreads

CAMutex* CAFirstMix::m_pmutexLoginThreads
protected

Definition at line 502 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), and ~CAFirstMix().

◆ m_pmutexMixedPackets

CAMutex* CAFirstMix::m_pmutexMixedPackets
protected

Definition at line 501 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), incMixedPackets(), and ~CAFirstMix().

◆ m_pmutexNewConnections

CAMutex* CAFirstMix::m_pmutexNewConnections
private

Definition at line 569 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), decNewConnections(), incNewConnections(), and ~CAFirstMix().

◆ m_pmutexUser

CAMutex* CAFirstMix::m_pmutexUser
protected

Definition at line 500 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), decUsers(), incUsers(), and ~CAFirstMix().

◆ m_pMuxOut

CAMuxSocket* CAFirstMix::m_pMuxOut
protected

Definition at line 490 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), clean(), connectToNextMix(), init(), and CAFirstMixB::loop().

◆ m_pQueueReadFromMix

CAQueue* CAFirstMix::m_pQueueReadFromMix
protected

Definition at line 449 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), clean(), init(), CAFirstMixA::loop(), and CAFirstMixB::loop().

◆ m_pQueueSendToMix

CAQueue* CAFirstMix::m_pQueueSendToMix
protected

◆ m_pRSA

CAASymCipher* CAFirstMix::m_pRSA
protected

Definition at line 497 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), clean(), and doUserLogin_internal().

◆ m_psocketgroupUsersRead

CASocketGroupEpoll* CAFirstMix::m_psocketgroupUsersRead
protected

◆ m_psocketgroupUsersWrite

CASocketGroupEpoll* CAFirstMix::m_psocketgroupUsersWrite
protected

◆ m_pthreadAcceptUsers

CAThread* CAFirstMix::m_pthreadAcceptUsers
protected

Definition at line 504 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), clean(), init(), CAFirstMixB::loop(), and CAFirstMixA::shutDown().

◆ m_pthreadReadFromMix

CAThread* CAFirstMix::m_pthreadReadFromMix
protected

Definition at line 507 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), clean(), init(), and CAFirstMixB::loop().

◆ m_pthreadSendToMix

CAThread* CAFirstMix::m_pthreadSendToMix
protected

Definition at line 506 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), clean(), init(), and CAFirstMixB::loop().

◆ m_pthreadsLogin

CAThreadPool* CAFirstMix::m_pthreadsLogin
protected

Definition at line 505 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), clean(), init(), and CAFirstMixB::loop().

◆ m_tcTemplates

DOMNode** CAFirstMix::m_tcTemplates
protected

◆ m_templatesOwner

XERCES_CPP_NAMESPACE::DOMDocument* CAFirstMix::m_templatesOwner
protected

Definition at line 513 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), clean(), handleTermsAndConditionsExtension(), and init().

◆ m_threadLogLoop

CAThread* CAFirstMix::m_threadLogLoop
private

Definition at line 539 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), deleteCountryStats(), and initCountryStats().

◆ m_tnCDefs

TermsAndConditions** CAFirstMix::m_tnCDefs
protected

◆ m_u32MixCount

UINT32 CAFirstMix::m_u32MixCount
protected

◆ m_u64LastTimestampReceived

UINT64 CAFirstMix::m_u64LastTimestampReceived

Definition at line 393 of file CAFirstMix.hpp.

Referenced by doUserLogin_internal(), init(), and setMixParameters().

◆ m_xmlKeyInfoBuff

UINT8* CAFirstMix::m_xmlKeyInfoBuff
protected

Definition at line 492 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), clean(), and doUserLogin_internal().

◆ m_xmlKeyInfoSize

UINT16 CAFirstMix::m_xmlKeyInfoSize
protected

Definition at line 493 of file CAFirstMix.hpp.

Referenced by doUserLogin_internal().

◆ MAX_CONCURRENT_NEW_CONNECTIONS

const UINT32 CAFirstMix::MAX_CONCURRENT_NEW_CONNECTIONS = NUM_LOGIN_WORKER_TRHEADS * 2
staticprivate

Definition at line 566 of file CAFirstMix.hpp.

◆ TNC_CONFIRM

const XMLCh* CAFirstMix::TNC_CONFIRM
protected

Definition at line 517 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), and handleTermsAndConditionsLogin().

◆ TNC_INTERRUPT

const XMLCh* CAFirstMix::TNC_INTERRUPT
protected

Definition at line 518 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), and handleTermsAndConditionsLogin().

◆ TNC_REQUEST

const XMLCh* CAFirstMix::TNC_REQUEST
protected

Definition at line 516 of file CAFirstMix.hpp.

Referenced by CAFirstMix(), and handleTermsAndConditionsLogin().


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