Mixe for Privacy and Anonymity in the Internet
Classes | Public Member Functions | Static Public Attributes | Private Member Functions | Static Private Member Functions | Private Attributes
CAInfoService Class Reference

#include <CAInfoService.hpp>

Collaboration diagram for CAInfoService:
[legend]

List of all members.

Classes

struct  InfoServiceHeloMsg

Public Member Functions

 CAInfoService ()
 CAInfoService (CAMix *pMix)
 ~CAInfoService ()
SINT32 sendMixHelo (SINT32 requestCommand=-1, const UINT8 *param=NULL)
 POSTs the MIXINFO message for a mix to the InfoService.
SINT32 sendCascadeHelo ()
SINT32 sendStatus (bool bIncludeCerts)
SINT32 start ()
SINT32 stop ()
SINT32 signal ()
SINT32 getLevel (SINT32 *puser, SINT32 *prisk, SINT32 *ptraffic)
SINT32 getMixedPackets (UINT64 &ppackets)
SINT32 getPaymentInstance (const UINT8 *a_pstrPIID, CAXMLBI **pXMLBI)
bool isRunning ()
SINT32 setMultiSignature (CAMultiSignature *pMultiSignature)
bool isConfiguring ()
void setConfiguring (bool a_configuring)
void setSerial (UINT64 a_serial)
UINT8getStatusXMLAsString (bool bIncludeCerts, UINT32 &len)

Static Public Attributes

static const UINT64 MINUTE = 60
static const UINT64 SEND_LOOP_SLEEP = 60
static const UINT64 SEND_CASCADE_INFO_WAIT = MINUTE * 10
static const UINT64 SEND_MIX_INFO_WAIT = MINUTE * 10
static const UINT64 SEND_STATUS_INFO_WAIT = MINUTE
static const UINT32 SEND_INFO_TIMEOUT_MS = 3000
static const UINT32 REPEAT_ON_STATUS_SENT_ERROR = 3

Private Member Functions

SINT32 getPaymentInstance (const UINT8 *a_pstrPIID, CAXMLBI **pXMLBI, CASocketAddrINet *a_socketAddress)
 Gets a payment instance from the InfoService.
SINT32 sendHelo (UINT8 *a_strXML, UINT32 a_len, THREAD_RETURN(*a_thread)(void *), UINT8 *a_strThreadName, SINT32 requestCommand, const UINT8 *param=NULL)
UINT8getCascadeHeloXMLAsString (UINT32 &len)
SINT32 sendCascadeHelo (const UINT8 *xml, UINT32 len, const CASocketAddrINet *a_socketAddress) const
 POSTs the HELO message for a whole cascade to the InfoService.
SINT32 sendStatus (const UINT8 *strStatusXML, UINT32 len, const CASocketAddrINet *a_socketAddress) const
 POSTs mix status to the InfoService.
UINT8 ** getOperatorTnCsAsStrings (UINT32 **lengths, XMLSize_t *nrOfTnCs)
 returns a string array with all signed Terms and Condition-Objects NOTE: this method has a side-effect: the DOMNodes are all signed and thus modified
SINT32 sendOperatorTnCData ()
UINT8getMixHeloXMLAsString (UINT32 &len)
UINT8xmlDocToStringWithSignature (DOMNode *a_node, UINT32 &a_len, bool bIncludeCerts)
SINT32 sendMixHelo (const UINT8 *strMixHeloXML, UINT32 len, SINT32 requestCommand, const UINT8 *param, const CASocketAddrINet *a_socketAddress)
 POSTs the HELO message for a mix to the InfoService.
SINT32 handleConfigEvent (XERCES_CPP_NAMESPACE::DOMDocument *doc) const

Static Private Member Functions

static THREAD_RETURN TCascadeHelo (void *p)
static THREAD_RETURN TCascadeStatus (void *p)
static THREAD_RETURN TMixHelo (void *p)
static THREAD_RETURN InfoLoop (void *p)

Private Attributes

volatile bool m_bRun
CAMultiSignaturem_pMultiSignature
CAMixm_pMix
CAThreadm_pthreadRunLoop
CAConditionVariablem_pLoopCV
UINT64 m_lastMixedPackets
UINT64 m_serial
UINT32 m_minuts
SINT32 m_expectedMixRelPos
bool m_bConfiguring

Detailed Description

Definition at line 56 of file CAInfoService.hpp.


Constructor & Destructor Documentation

Definition at line 360 of file CAInfoService.cpp.

References m_bRun, m_expectedMixRelPos, m_lastMixedPackets, m_minuts, m_pLoopCV, m_pMix, m_pMultiSignature, and m_pthreadRunLoop.

{
    m_pMix=NULL;
    m_bRun=false;
    //m_pSignature=NULL;
    m_pMultiSignature=NULL;
    m_minuts=0;
    m_lastMixedPackets=0;
    m_expectedMixRelPos = 0;
      m_pLoopCV = new CAConditionVariable();
    m_pthreadRunLoop=new CAThread((UINT8*)"InfoServiceThread");
#ifdef DYNAMIC_MIX
    m_bReconfig = false;
#endif
}

Definition at line 376 of file CAInfoService.cpp.

References m_bRun, m_expectedMixRelPos, m_lastMixedPackets, m_minuts, m_pLoopCV, m_pMix, m_pMultiSignature, m_pthreadRunLoop, and pMix.

  {
    m_pMix=NULL;
    m_bRun=false;
    //m_pSignature=NULL;
    m_pMultiSignature=NULL;
    m_minuts=0;
    m_lastMixedPackets=0;
    m_expectedMixRelPos = 0;
    m_pLoopCV = new CAConditionVariable();
    m_pthreadRunLoop=new CAThread((UINT8*)"InfoServiceThread");
    m_pMix=pMix;
#ifdef DYNAMIC_MIX
    m_bReconfig = false;
#endif
  }

Definition at line 393 of file CAInfoService.cpp.

References m_pLoopCV, m_pthreadRunLoop, and stop().

  {
    stop();
    delete m_pLoopCV;
    m_pLoopCV = NULL;
    delete m_pthreadRunLoop;
    m_pthreadRunLoop = NULL;
  }

Here is the call graph for this function:


Member Function Documentation

Definition at line 1172 of file CAInfoService.cpp.

References ATTRIBUTE_SERIAL, createDOMElement(), DOM_Output::dumpToMem(), E_SUCCESS, getcurrentTimeMillis(), getDOMChildByName(), CAMix::getMixCascadeInfo(), m_pMix, m_pMultiSignature, m_serial, print64(), setDOMElementAttribute(), setDOMElementValue(), and CAMultiSignature::signXML().

Referenced by sendCascadeHelo().

  {
    a_len=0;
    UINT32 sendBuffLen;
    UINT8* sendBuff=NULL;
    XERCES_CPP_NAMESPACE::DOMDocument* docMixInfo=NULL;
    DOMElement* elemTimeStamp=NULL;
    DOMElement* elemRoot=NULL;

    if(m_pMix->getMixCascadeInfo(docMixInfo)!=E_SUCCESS)
    {
      // CAMsg::printMsg(LOG_INFO,"InfoService: Cascade not yet configured.\n");
      goto ERR;
    }
    //insert (or update) the Timestamp
    elemRoot=docMixInfo->getDocumentElement();

    if(getDOMChildByName(elemRoot,"LastUpdate",elemTimeStamp,false)!=E_SUCCESS)
    {
      elemTimeStamp=createDOMElement(docMixInfo,"LastUpdate");
      elemRoot->appendChild(elemTimeStamp);
    }
    UINT64 currentMillis;
    getcurrentTimeMillis(currentMillis);
    UINT8 tmpStrCurrentMillis[50];
    print64(tmpStrCurrentMillis, currentMillis);
    setDOMElementValue(elemTimeStamp, tmpStrCurrentMillis);

    if (m_serial != 0)
    {
      print64(tmpStrCurrentMillis, m_serial);
      setDOMElementAttribute(elemRoot, ATTRIBUTE_SERIAL, tmpStrCurrentMillis);
    }

    if(m_pMultiSignature->signXML(docMixInfo, true)!=E_SUCCESS)
    {
      goto ERR;
    }

    sendBuff=DOM_Output::dumpToMem(docMixInfo,&sendBuffLen);
    if(sendBuff==NULL)
      goto ERR;

    a_len=sendBuffLen;
    return sendBuff;
ERR:
    delete []sendBuff;
    sendBuff = NULL;
    return NULL;
  }

Here is the call graph for this function:

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

Definition at line 409 of file CAInfoService.cpp.

References E_UNKNOWN, CALibProxytest::getOptions(), and m_pMix.

Referenced by getStatusXMLAsString().

{
    if(m_pMix!=NULL && CALibProxytest::getOptions()->isFirstMix())
        return ((CAFirstMix*)m_pMix)->getLevel(puser,prisk,ptraffic);
    return E_UNKNOWN;
}

Here is the call graph for this function:

Definition at line 416 of file CAInfoService.cpp.

References E_UNKNOWN, CALibProxytest::getOptions(), and m_pMix.

Referenced by getStatusXMLAsString().

  {
    if(m_pMix!=NULL && CALibProxytest::getOptions()->isFirstMix())
      return ((CAFirstMix*)m_pMix)->getMixedPackets(ppackets);
    return E_UNKNOWN;
  }

Here is the call graph for this function:

Definition at line 844 of file CAInfoService.cpp.

References ATTRIBUTE_SERIAL, E_SUCCESS, CALibProxytest::getOptions(), m_serial, setDOMElementAttribute(), and xmlDocToStringWithSignature().

Referenced by sendMixHelo().

{
  XERCES_CPP_NAMESPACE::DOMDocument* docMixInfo = NULL;
  XERCES_CPP_NAMESPACE::DOMElement* mixInfoRoot = NULL;

  if( (CALibProxytest::getOptions()->getMixXml(docMixInfo) != E_SUCCESS) ||
    (docMixInfo == NULL) )
  {
    return NULL;
  }

  if(m_serial != 0)
  {
    mixInfoRoot = docMixInfo->getDocumentElement();
    if( mixInfoRoot != NULL )
    {
      setDOMElementAttribute(mixInfoRoot, ATTRIBUTE_SERIAL, m_serial);
    }
  }
  return xmlDocToStringWithSignature(docMixInfo, a_len, true);
}

Here is the call graph for this function:

UINT8 ** CAInfoService::getOperatorTnCsAsStrings ( UINT32 **  lengths,
XMLSize_t *  nrOfTnCs 
) [private]

returns a string array with all signed Terms and Condition-Objects NOTE: this method has a side-effect: the DOMNodes are all signed and thus modified

Parameters:
lengthscontains the lengths of each corresponding object. Its memory is allocated by this method and has to be freed explicitly by calling delete []
nrOfTnCsis the length of the returned array
Return values:
alist with all Terms and conditions object which has to be freed explicitly by calling delete []

Definition at line 722 of file CAInfoService.cpp.

References E_SUCCESS, getDOMElementAttribute(), getElementsByTagName(), CACmdLnOptions::getOperatorSubjectKeyIdentifier(), CALibProxytest::getOptions(), CACmdLnOptions::getTermsAndConditions(), LOCALE_DEFAULT, OPTIONS_ATTRIBUTE_TNC_DATE, OPTIONS_ATTRIBUTE_TNC_ID, OPTIONS_ATTRIBUTE_TNC_LOCALE, OPTIONS_ATTRIBUTE_TNC_SERIAL, OPTIONS_ATTRIBUTE_TNC_VERSION, OPTIONS_NODE_TNCS_TRANSLATION, setCurrentTimeMilliesAsDOMAttribute(), setDOMElementAttribute(), TMP_BUFF_SIZE, and xmlDocToStringWithSignature().

{

  XERCES_CPP_NAMESPACE::DOMElement *tnCs = CALibProxytest::getOptions()->getTermsAndConditions();
  if(tnCs == NULL)
  {
    return NULL;
  }

  XERCES_CPP_NAMESPACE::DOMNodeList *docTnCsList =
    getElementsByTagName(tnCs, OPTIONS_NODE_TNCS_TRANSLATION);

  if(docTnCsList == NULL)
  {
    return NULL;
  }

  UINT8 **elementList = NULL;
  DOMNode *iterator = NULL;
  XMLSize_t i = 0;

  UINT8 tmpOpSKIBuff[TMP_BUFF_SIZE];
  UINT32 tmpOpSKILen = TMP_BUFF_SIZE;

  CALibProxytest::getOptions()->getOperatorSubjectKeyIdentifier(tmpOpSKIBuff, &tmpOpSKILen);
  if( tmpOpSKILen == 0 )
  {
    return NULL;
  }

  UINT8 tmpDate[TMP_BUFF_SIZE];
  UINT32 tmpDateLen = TMP_BUFF_SIZE;

  getDOMElementAttribute(tnCs, OPTIONS_ATTRIBUTE_TNC_DATE, tmpDate, &tmpDateLen);
  if(tmpDateLen == 0)
  {
    return NULL;
  }

  UINT8 tmpVersion[TMP_BUFF_SIZE];
  UINT32 tmpVersionLen = TMP_BUFF_SIZE;

  UINT8* serial = NULL;

  getDOMElementAttribute(tnCs, OPTIONS_ATTRIBUTE_TNC_VERSION, tmpVersion, &tmpVersionLen);
  if(tmpVersionLen > 0)
  {
    serial = new UINT8[tmpDateLen+tmpVersionLen+1];
    memcpy(serial, tmpDate, tmpDateLen);
    memcpy(serial + tmpDateLen, tmpVersion, tmpVersionLen);
    serial[tmpDateLen + tmpVersionLen] = 0;
  }
  else
  {
    serial = new UINT8[tmpDateLen+1];
    memcpy(serial, tmpDate, tmpDateLen);
    serial[tmpDateLen] = 0;
  }

  UINT32 locale_len = 3;
  UINT8* id=new UINT8[tmpOpSKILen+locale_len+1];
  UINT8* locale=new UINT8[locale_len];

  locale[locale_len-1]=0;

  memcpy(id, tmpOpSKIBuff, tmpOpSKILen);
  id[tmpOpSKILen]=0;
  id[tmpOpSKILen+(locale_len-1)+1] = 0;

  (*nrOfTnCs) = docTnCsList->getLength();
  elementList = new UINT8 *[(*nrOfTnCs)];
  (*lengths) = new UINT32[(*nrOfTnCs)];
  for (; i < (*nrOfTnCs); i++)
  {
    //after every loop turn locale is explicitly reset to 3 because ...
    locale_len = 3;
    iterator = docTnCsList->item(i);
    //... it is modified by getDOMElementAttribute
    getDOMElementAttribute(iterator, OPTIONS_ATTRIBUTE_TNC_LOCALE, locale, &locale_len);
    if(locale_len == 0)
    {
      elementList[i] = NULL;
      continue;
    }
    //only append the locale code to the id when it is
    //not the default locale
    if( strncasecmp((char *)locale, LOCALE_DEFAULT, 2) == 0 )
    {
      id[tmpOpSKILen] = 0;
    }
    else
    {
      id[tmpOpSKILen] = '_';
      memcpy((id+tmpOpSKILen+1), locale, locale_len);
    }

    if(setDOMElementAttribute(iterator, OPTIONS_ATTRIBUTE_TNC_ID, id) != E_SUCCESS)
    {
      elementList[i] = NULL;
      continue;
    }
    if(setDOMElementAttribute(iterator, OPTIONS_ATTRIBUTE_TNC_DATE, tmpDate) != E_SUCCESS)
    {
      elementList[i] = NULL;
      continue;
    }
    if(setDOMElementAttribute(iterator, OPTIONS_ATTRIBUTE_TNC_SERIAL, serial) != E_SUCCESS)
    {
      elementList[i] = NULL;
      continue;
    }
    setCurrentTimeMilliesAsDOMAttribute(iterator);
    elementList[i] = xmlDocToStringWithSignature(iterator, (*lengths)[i], true);
  }

  delete[] serial;
  delete[] id;
  delete[] locale;
  return elementList;

}

Here is the call graph for this function:

SINT32 CAInfoService::getPaymentInstance ( const UINT8 a_pstrPIID,
CAXMLBI **  a_pXMLBI,
CASocketAddrINet a_socketAddress 
) [private]

Gets a payment instance from the InfoService.

Parameters:
a_pstrPIIDid of the payment instance for which the information is requested
a_pXMLBIa pointer to a pointer which on a successful return will point to a newly created CAXMLBI object
a_socketAddressadress of the InfoService from which the information is to be requested
Return values:
E_SUCCESSif succesful
E_UNKNOWNif an error occured
Returns:
a_pXMLBI will point to a pointer to the newly created CAXMLBI object or to NULL

Definition at line 1412 of file CAInfoService.cpp.

References CASocket::close(), CASocket::connect(), E_SUCCESS, E_UNKNOWN, CAHttpClient::getContent(), CAXMLBI::getInstance(), CASocketAddrINet::getIPAsStr(), CASocketAddrINet::getPort(), parseDOMDocument(), CAHttpClient::parseHTTPHeader(), CAMsg::printMsg(), CAHttpClient::sendGetRequest(), CASocketAddrINet::setAddr(), and CAHttpClient::setSocket().

Referenced by getPaymentInstance().

  {
    CASocket socket;
    CASocketAddrINet address;
    UINT8 hostname[255];
    UINT8 request[255];
    CAHttpClient httpClient;
    UINT32 status, contentLength;
    *a_pXMLBI=NULL;
    //Connect to InfoService
    if(a_socketAddress->getIPAsStr(hostname, 255)!=E_SUCCESS)
    {
      socket.close();
      return E_UNKNOWN;
    }

    address.setAddr(hostname,a_socketAddress->getPort());

    if(socket.connect(address)!=E_SUCCESS)
    {
      socket.close();
      return E_UNKNOWN;
    }

    //#ifdef DEBUG
      CAMsg::printMsg(LOG_DEBUG, "CAInfoService::getPaymentInstance() - connected to InfoService %s:%d\n",hostname, a_socketAddress->getPort());
    //#endif

    //Send request
    httpClient.setSocket(&socket);
    sprintf((char*) request, "/paymentinstance/%s", (char*) a_pstrPIID);
    httpClient.sendGetRequest(request);
    httpClient.parseHTTPHeader(&contentLength, &status);
    #ifdef DEBUG
      CAMsg::printMsg(LOG_DEBUG, "CAInfoService::getPaymentInstance() - Request sent, HTTP status: %i, content length: %i\n", status, contentLength);
    #endif
    if(status!=200||contentLength>0x00FFFF)
      {
        socket.close();
        return E_UNKNOWN;
      }

    UINT8* content=new UINT8[contentLength+1];
    if(httpClient.getContent(content, &contentLength)!=E_SUCCESS)
      {
        delete []content;
        content = NULL;
        socket.close();
        return E_UNKNOWN;
      }
    socket.close();
    //Parse XML
    XERCES_CPP_NAMESPACE::DOMDocument* doc = parseDOMDocument(content,contentLength);
    delete []content;
    content = NULL;
    if(doc==NULL)
      return E_UNKNOWN;
    DOMElement* elemRoot=doc->getDocumentElement();

    *a_pXMLBI = CAXMLBI::getInstance(elemRoot);
    CAMsg::printMsg(LOG_DEBUG, "CAInfoService::getPaymentInstance(): XML doc not needed anymore\n");
    if (*a_pXMLBI != NULL)
      {
        return E_SUCCESS;
      }
    else
      {
        return E_UNKNOWN;
      }
  }

Here is the call graph for this function:

SINT32 CAInfoService::getPaymentInstance ( const UINT8 a_pstrPIID,
CAXMLBI **  pXMLBI 
)

Definition at line 1385 of file CAInfoService.cpp.

References E_SUCCESS, E_UNKNOWN, CACmdLnOptions::getInfoServices(), CALibProxytest::getOptions(), and getPaymentInstance().

{
  SINT32 returnValue = E_UNKNOWN;
  SINT32 currentValue;
  UINT32 nrAddresses;
  CAListenerInterface** socketAddresses = CALibProxytest::getOptions()->getInfoServices(nrAddresses);
  for (UINT32 i = 0; i < nrAddresses; i++)
  {
    currentValue = getPaymentInstance(a_pstrPIID, a_pXMLBI,
            (CASocketAddrINet*)socketAddresses[i]->getAddr());
    if (currentValue == E_SUCCESS)
    {
      returnValue = currentValue;
    }
  }
  return returnValue;
}

Here is the call graph for this function:

UINT8 * CAInfoService::getStatusXMLAsString ( bool  bIncludeCerts,
UINT32 len 
)

Definition at line 505 of file CAInfoService.cpp.

References diff64(), div64(), E_SUCCESS, getcurrentTimeMillis(), getLevel(), getMixedPackets(), CACmdLnOptions::getMixId(), CALibProxytest::getOptions(), m_lastMixedPackets, m_minuts, m_pMultiSignature, print64(), set64(), CAMultiSignature::signXML(), and XML_MIX_CASCADE_STATUS.

Referenced by sendStatus().

  {
    SINT32 tmpUser,tmpRisk,tmpTraffic;
    UINT64 tmpPackets;

    //httpClient.setSocket(&oSocket);
    UINT8 strMixId[255];
    CALibProxytest::getOptions()->getMixId(strMixId,255);

    tmpUser=tmpTraffic=tmpRisk=-1;
    set64(tmpPackets,(UINT32)-1);
    getLevel(&tmpUser,&tmpRisk,&tmpTraffic);
    SINT32 ret=getMixedPackets(tmpPackets);
    if(ret==E_SUCCESS)
      {
        UINT32 avgTraffic=div64(tmpPackets,m_minuts);
        UINT32 diffTraffic=diff64(tmpPackets,m_lastMixedPackets);
        if(avgTraffic==0)
          {
            if(diffTraffic==0)
              tmpTraffic=0;
            else
              tmpTraffic=100;
          }
        else
          {
            double dTmp=(double)diffTraffic/(double)avgTraffic;
            tmpTraffic=min(SINT32(50.*dTmp),100);
          }
        set64(m_lastMixedPackets,tmpPackets);
      }
    m_minuts++;
//let the attributes in alphabetical order..
#define XML_MIX_CASCADE_STATUS "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\
<MixCascadeStatus LastUpdate=\"%s\" currentRisk=\"%i\" id=\"%s\" mixedPackets=\"%s\" nrOfActiveUsers=\"%i\" trafficSituation=\"%i\"\
></MixCascadeStatus>"

    UINT32 buffLen=8192;
    UINT8* buff=new UINT8[buffLen];
    memset(buff, 0, buffLen);
    UINT8 tmpBuff[1024];
    UINT8 buffMixedPackets[50];
    print64(buffMixedPackets,tmpPackets);
    UINT64 currentMillis;
    UINT8 tmpStrCurrentMillis[50];
    if(getcurrentTimeMillis(currentMillis)==E_SUCCESS)
      print64(tmpStrCurrentMillis,currentMillis);
    else
      tmpStrCurrentMillis[0]=0;
    sprintf((char*)tmpBuff,XML_MIX_CASCADE_STATUS,tmpStrCurrentMillis,tmpRisk,strMixId,buffMixedPackets,tmpUser,tmpTraffic);


    if(m_pMultiSignature->signXML(tmpBuff, strlen((char*)tmpBuff), buff, &buffLen, bIncludeCerts) != E_SUCCESS)
    {
      delete[] buff;
      buff = NULL;
    }
    else
    {
      len=buffLen;
    }
    return buff;
  }

Here is the call graph for this function:

SINT32 CAInfoService::handleConfigEvent ( XERCES_CPP_NAMESPACE::DOMDocument *  doc) const [private]

*** Nedd redesigning!*/

Definition at line 1307 of file CAInfoService.cpp.

References E_SUCCESS.

{
/*    CAMsg::printMsg(LOG_INFO,"InfoService: Cascade info received from InfoService\n");

    DOM_Element root=doc.getDocumentElement();
    DOM_Node mixesElement;
    getDOMChildByName(root,(UINT8*)"Mixes", mixesElement, false);
    char* mixId;
    char* prevMixId = NULL;
    char* myNextMixId = NULL;
    char* myPrevMixId = NULL;
    bool bFoundMix = false;
    UINT8 myMixId[64];
    CALibProxytest::getOptions()->getMixId(myMixId,64);
    DOM_Node child = mixesElement.getFirstChild();
    while(child!=NULL)
    {
        if(child.getNodeName().equals("Mix") && child.getNodeType() == DOM_Node::ELEMENT_NODE)
        {
            mixId = static_cast<const DOM_Element&>(child).getAttribute("id").transcode();
            if(strcmp(mixId,(char*)myMixId) == 0)
            {
                bFoundMix = true;
                myPrevMixId = prevMixId;
            }
            else if(bFoundMix == true)
            {
                myNextMixId = mixId;
                break;
            }
            prevMixId = mixId;
        }
        child = child.getNextSibling();
    }

    SINT32 ret = 0;
    //char* c;

    if(myPrevMixId != NULL)
    {
        CAMsg::printMsg(LOG_INFO,"InfoService: Asking InfoService about previous mix ...\n");

        m_expectedMixRelPos = -1;
        //c = new char[8+strlen(myPrevMixId)+1];
        //strcpy(c,"mixinfo/");
        //strcat(c,myPrevMixId);
        ret = sendMixInfo((UINT8*)myPrevMixId);
        //delete[] c;
        if(ret != E_SUCCESS)
        {
            CAMsg::printMsg(LOG_CRIT,"InfoService: Error retrieving mix info from InfoService!\n");
            return ret;
        }
    }

    if(myNextMixId != NULL)
    {
        CAMsg::printMsg(LOG_INFO,"InfoService: Asking InfoService about next mix ...\n");

        m_expectedMixRelPos = 1;
        //c = new char[8+strlen(myNextMixId)+1];
        //strcpy(c,"mixinfo/");
        //strcat(c,myNextMixId);
        ret = sendMixInfo((UINT8*)myNextMixId);
        //delete[] c;
        if(ret != E_SUCCESS)
        {
            CAMsg::printMsg(LOG_CRIT,"InfoService: Error retrieving mix info from InfoService!\n");
            return ret;
        }

    }
    */
    return E_SUCCESS;
}
THREAD_RETURN CAInfoService::InfoLoop ( void *  p) [static, private]

Definition at line 56 of file CAInfoService.cpp.

References BEGIN_STACK, E_SUCCESS, FINISH_STACK, CAMix::getLastConnectionTime(), CALibProxytest::getOptions(), INIT_STACK, isConfiguring(), CAMix::isConnected(), CACmdLnOptions::isFirstMix(), CACmdLnOptions::isLastMix(), isRunning(), CAMutex::lock(), m_pLoopCV, m_pMix, CAMsg::printMsg(), REPEAT_ON_STATUS_SENT_ERROR, SEND_CASCADE_INFO_WAIT, SEND_LOOP_SLEEP, SEND_MIX_INFO_WAIT, SEND_STATUS_INFO_WAIT, sendCascadeHelo(), sendMixHelo(), sendStatus(), sSleep(), THREAD_RETURN_SUCCESS, CAMutex::unlock(), and CAConditionVariable::wait().

Referenced by start().

  {
    INIT_STACK;
    BEGIN_STACK("CAInfoService::InfoLoop");

    CAMsg::printMsg(LOG_DEBUG, "CAInfoService - InfoLoop() started\n");
    CAMsg::printMsg(LOG_DEBUG, "CAInfoService - InfoLoop() PID: %i\n",getpid());
    CAInfoService* pInfoService=(CAInfoService*)p;
    bool bIsFirst=true; //send our own certifcate only the first time
    bool bOneUpdateDone = false;

    UINT32 currentTime;
    UINT32 lastCascadeUpdate;
    UINT32 lastStatusUpdate;
    UINT32 lastMixInfoUpdate;
    UINT32 nextUpdate;
#ifdef DYNAMIC_MIX
    UINT32 loops = 4;
    UINT32 interval = 0;
#endif
    lastCascadeUpdate=lastMixInfoUpdate=lastStatusUpdate=(UINT32)time(NULL);
    // tell the algorithm it is time to update
    lastCascadeUpdate -= CAInfoService::SEND_CASCADE_INFO_WAIT;
    lastMixInfoUpdate -= CAInfoService::SEND_MIX_INFO_WAIT;
    lastStatusUpdate -= CAInfoService::SEND_STATUS_INFO_WAIT;
    UINT32 statusSentErrorBurst = 0;

    pInfoService->m_pLoopCV->lock();
    pInfoService->m_pLoopCV->wait(CAInfoService::SEND_LOOP_SLEEP * 1000);
    pInfoService->m_pLoopCV->unlock();

    while(pInfoService->isRunning())
    {
#ifdef DYNAMIC_MIX

      if(loops < 4)
      {
        sSleep(interval);
        loops++;
        continue;
      }
#endif
  // TODO: the "pInfoService->m_pMix->getLastConnectionTime() < (currentTime - (SEND_LOOP_SLEEP / 2))" is just a work-around until we have a proper synchronization with the xml nodes...

      currentTime=time(NULL);
      if (currentTime >= (lastStatusUpdate + CAInfoService::SEND_STATUS_INFO_WAIT))
      {
        if(pInfoService->m_pMix->isConnected() && pInfoService->m_pMix->getLastConnectionTime() < (currentTime - (SEND_LOOP_SLEEP / 2)) && 
          pInfoService->sendStatus(bIsFirst)==E_SUCCESS)
        {
          lastStatusUpdate=time(NULL);
          bIsFirst=false;
          bOneUpdateDone = true;
          statusSentErrorBurst = 0;
          //CAMsg::printMsg(LOG_DEBUG,"InfoService: Successfully sent Status information.\n");
        }
        else if (pInfoService->m_pMix->isConnected() && pInfoService->m_pMix->getLastConnectionTime() < (currentTime - (SEND_LOOP_SLEEP / 2)))
        {
          statusSentErrorBurst++;
          CAMsg::printMsg(LOG_WARNING,"InfoService: Could not send Status information.\n");
        }
        /* send terms and conditions */
        //pInfoService->sendOperatorTnCData();
      }

      // check every minute if configuring, every 10 minutes otherwise
      currentTime=time(NULL);
      if (currentTime >= (lastCascadeUpdate + CAInfoService::SEND_CASCADE_INFO_WAIT) || pInfoService->isConfiguring())
      {
        if (CALibProxytest::getOptions()->isFirstMix() || (CALibProxytest::getOptions()->isLastMix() && pInfoService->isConfiguring()))
        {
          if(pInfoService->m_pMix->isConnected() && pInfoService->m_pMix->getLastConnectionTime() < (currentTime - (SEND_LOOP_SLEEP / 2)) 
            && pInfoService->sendCascadeHelo() == E_SUCCESS)
          {
            lastCascadeUpdate=time(NULL);
            bOneUpdateDone = true;
            CAMsg::printMsg(LOG_INFO,"InfoService: Successfully sent Cascade information.\n");
          }
          else if (pInfoService->m_pMix->isConnected() && pInfoService->m_pMix->getLastConnectionTime() < (currentTime - (SEND_LOOP_SLEEP / 2)))
          {
            CAMsg::printMsg(LOG_WARNING,"InfoService: Could not send Cascade information.\n");
          }
        }
        currentTime=time(NULL);
        if ((currentTime >= (lastMixInfoUpdate + CAInfoService::SEND_MIX_INFO_WAIT) &&
          pInfoService->m_pMix->getLastConnectionTime() < (currentTime - (SEND_LOOP_SLEEP / 2))) || pInfoService->isConfiguring())
        {
          if (pInfoService->sendMixHelo() != E_SUCCESS)
          {
            CAMsg::printMsg(LOG_WARNING,"InfoService: Could not send MixInfo information.\n");
          }
          else
          {
            lastMixInfoUpdate=time(NULL);
            bOneUpdateDone = true;
            CAMsg::printMsg(LOG_INFO,"InfoService: Successfully sent MixInfo information.\n");
          }
        }
      }
#ifdef DYNAMIC_MIX
      // LERNGRUPPE
      // Check regulary for new cascade information
      if( CALibProxytest::getOptions()->isDynamic() )
      {
        pInfoService->dynamicCascadeConfiguration();
      }
#endif
      currentTime=time(NULL);
      //@TODO BUGGy -- because it assumes knowledge about update times, which are configurable in StdAfx.hpp
      // wait CAInfoService::SEND_LOOP_SLEEP seconds at most
      /*temp = (currentTime - lastStatusUpdate);
      if (bOneUpdateDone && temp > 0)
      {
          if (temp <= CAInfoService::SEND_LOOP_SLEEP)
          {
            bPreventLoop = false;
            nextUpdate = CAInfoService::SEND_LOOP_SLEEP - temp;
          }
          else if (bPreventLoop)
          {
            // prevent infinite loops
            bPreventLoop = false;
            nextUpdate = CAInfoService::SEND_LOOP_SLEEP;
          }
          else
          {
            bPreventLoop = true;
            nextUpdate = 0;
          }
      }
      else
      {
        bPreventLoop = false;
        nextUpdate = CAInfoService::SEND_LOOP_SLEEP;
      }*/

      /* Not the optimal solution; would be best, if infoservice send
       * routines can be called by other threads if certain events occur, i.e.
       * cascade reconnection, etc.
       */
      if ( bOneUpdateDone && (statusSentErrorBurst > 0) )
      {
        //TODO: handle case when status sent error burst exceeds an upper limit */
        nextUpdate = CAInfoService::REPEAT_ON_STATUS_SENT_ERROR;
      }
      else
      {
        nextUpdate = CAInfoService::SEND_LOOP_SLEEP;
      }
#ifdef DYNAMIC_MIX
      interval = nextUpdate / 4;
      CAMsg::printMsg(LOG_DEBUG,"InfoService: Next update in %i seconds...interval %i\n", nextUpdate, interval);
      loops = 0;
#else
      if(nextUpdate > 20)
      {
        CAMsg::printMsg(LOG_DEBUG,"InfoService: Next update in %i seconds...\n", nextUpdate);
      }
      /* We can interrupt this thread if the mix is shutting down */
      pInfoService->m_pLoopCV->lock();
      pInfoService->m_pLoopCV->wait(nextUpdate * 1000);
      pInfoService->m_pLoopCV->unlock();

      //sSleep(nextUpdate);
#endif
    }
    CAMsg::printMsg(LOG_DEBUG, "CAInfoService - InfoLoop() exited\n");
    FINISH_STACK("CAInfoService::InfoLoop");
    THREAD_RETURN_SUCCESS;
  }

Here is the call graph for this function:

bool CAInfoService::isConfiguring ( ) [inline]

Definition at line 89 of file CAInfoService.hpp.

References m_bConfiguring.

Referenced by InfoLoop().

      {
          return m_bConfiguring;
      }
bool CAInfoService::isRunning ( ) [inline]

Definition at line 79 of file CAInfoService.hpp.

References m_bRun.

Referenced by InfoLoop(), and CAMix::start().

        {
          return m_bRun;
        }

Definition at line 1141 of file CAInfoService.cpp.

References E_SUCCESS, E_UNKNOWN, getCascadeHeloXMLAsString(), CALibProxytest::getOptions(), CAMix::isConnected(), len, m_pMix, CAMsg::printMsg(), REQUEST_COMMAND_CASCADE, sendHelo(), and TCascadeHelo().

Referenced by InfoLoop(), CAMix::start(), and TCascadeHelo().

{
  if(CALibProxytest::getOptions()->isMiddleMix())
    {
    return E_SUCCESS;
    }

  UINT32 len;
  SINT32 ret;
  UINT8* strCascadeHeloXML=getCascadeHeloXMLAsString(len);
  if(strCascadeHeloXML==NULL)
  {
    return E_UNKNOWN;
  }

  if( !(m_pMix->isConnected()) )
  {
#ifdef DEBUG
    CAMsg::printMsg(LOG_INFO, "not connected: skipping cascade helo.\n");
#endif
    delete[] strCascadeHeloXML;
    strCascadeHeloXML = NULL;
    return E_UNKNOWN;
  }

  ret = sendHelo(strCascadeHeloXML, len, TCascadeHelo, (UINT8*)"Cascade Helo Thread", REQUEST_COMMAND_CASCADE);
  delete[] strCascadeHeloXML;
  strCascadeHeloXML = NULL;
  return ret;
}

Here is the call graph for this function:

SINT32 CAInfoService::sendCascadeHelo ( const UINT8 a_strCascadeHeloXML,
UINT32  a_len,
const CASocketAddrINet a_pSocketAddress 
) const [private]

POSTs the HELO message for a whole cascade to the InfoService.

If the running mix is a last mix, this method is used to inform the InfoService that it wants to create a new cascade. The InfoService then tells all involved mixes to join this cascade. If the current mix is a middle mix, this method does nothing.

Return values:
E_SUCCESSon success
E_UNKNOWNon any error

Definition at line 1231 of file CAInfoService.cpp.

References CASocket::close(), CASocket::connect(), E_SUCCESS, E_UNKNOWN, getcurrentTimeMillis(), CASocketAddrINet::getIPAsStr(), CALibProxytest::getOptions(), CASocketAddrINet::getPort(), CACmdLnOptions::isFirstMix(), CACmdLnOptions::isLastMix(), m_bConfiguring, MIX_TO_INFOSERVICE_TIMEOUT, CAMsg::printMsg(), CASocket::receiveFullyT(), SEND_INFO_TIMEOUT_MS, and CASocket::sendFullyTimeOut().

{
  if(CALibProxytest::getOptions()->isMiddleMix() || (CALibProxytest::getOptions()->isLastMix() && !m_bConfiguring))
  {
    return E_SUCCESS;
  }
  CASocket oSocket(true);
  UINT8 hostname[255];
  UINT8 buffHeader[255];
  UINT64 currentTimeout = MIX_TO_INFOSERVICE_TIMEOUT;
  UINT64 startupTime, currentMillis;

  if (a_pSocketAddress == NULL)
  {
    goto ERR;
  }

  if(a_pSocketAddress->getIPAsStr(hostname, 255)!=E_SUCCESS)
  {
    goto ERR;
  }
  if(oSocket.connect(*a_pSocketAddress, MIX_TO_INFOSERVICE_TIMEOUT)==E_SUCCESS)
  {
     if(CALibProxytest::getOptions()->isFirstMix())
    {
            CAMsg::printMsg(LOG_DEBUG,"InfoService: Sending cascade helo to InfoService %s:%d.\r\n", hostname, a_pSocketAddress->getPort());
    }
      else
    {
            CAMsg::printMsg(LOG_DEBUG,"InfoService: Sending cascade configuration request to InfoService %s:%d.\r\n", hostname, a_pSocketAddress->getPort());
    }
        // LERNGRUPPE
        // Semi-dynamic cascades are temporary cascades, not yet established! InfoService can cope with them now
        // using the /dynacascade command
    if( CALibProxytest::getOptions()->isLastMix() && m_bConfiguring )
    {
      sprintf((char*)buffHeader,"POST /dynacascade HTTP/1.0\r\nContent-Length: %u\r\n\r\n",a_len);
    }
    else
    {
      sprintf((char*)buffHeader,"POST /cascade HTTP/1.0\r\nContent-Length: %u\r\n\r\n",a_len);
    }

    getcurrentTimeMillis(startupTime);
    if( oSocket.sendFullyTimeOut(buffHeader, strlen((char*)buffHeader), currentTimeout, SEND_INFO_TIMEOUT_MS)!=E_SUCCESS)
    {
      goto ERR;
    }
    getcurrentTimeMillis(currentMillis);
    currentTimeout -= (currentMillis - startupTime);
    if (currentTimeout <= 0 ||
        oSocket.sendFullyTimeOut(a_strCascadeHeloXML, a_len, currentTimeout, SEND_INFO_TIMEOUT_MS)!=E_SUCCESS)
    {
      goto ERR;
    }
    //Receive answer --> 200 Ok or failure
    //HTTP/1.1 200 Ok
    getcurrentTimeMillis(currentMillis);
    currentTimeout -= (currentMillis - startupTime);
    if(currentTimeout <= 0 ||
       oSocket.receiveFullyT(buffHeader, 12, currentTimeout)!=E_SUCCESS)
    {
      goto ERR;
    }
    if(memcmp(buffHeader+9,"200",3)!=0)
    {
      goto ERR;
    }
    oSocket.close();
    return E_SUCCESS;
  }
ERR:
  oSocket.close();
  return E_UNKNOWN;
}

Here is the call graph for this function:

SINT32 CAInfoService::sendHelo ( UINT8 a_strXML,
UINT32  a_len,
THREAD_RETURN(*)(void *)  a_thread,
UINT8 a_strThreadName,
SINT32  requestCommand,
const UINT8 param = NULL 
) [private]

Definition at line 1079 of file CAInfoService.cpp.

References CAInfoService::InfoServiceHeloMsg::addr, E_SUCCESS, E_UNKNOWN, CACmdLnOptions::getInfoServices(), CALibProxytest::getOptions(), CAInfoService::InfoServiceHeloMsg::is, CAInfoService::InfoServiceHeloMsg::len, CAInfoService::InfoServiceHeloMsg::param, CAInfoService::InfoServiceHeloMsg::requestCommand, CAThread::setMainLoop(), CAThread::start(), CAInfoService::InfoServiceHeloMsg::strXML, and THREAD_RETURN.

Referenced by sendCascadeHelo(), sendMixHelo(), and sendStatus().

{
  SINT32 returnValue = E_UNKNOWN;
  UINT32 nrAddresses;
  CAListenerInterface** socketAddresses = CALibProxytest::getOptions()->getInfoServices(nrAddresses);
  CAThread** threads = new CAThread*[nrAddresses];
  InfoServiceHeloMsg** messages = new InfoServiceHeloMsg*[nrAddresses];

  for (UINT32 i = 0; i < nrAddresses; i++)
  {
    messages[i] = new InfoServiceHeloMsg();
    messages[i]->addr = (CASocketAddrINet*)socketAddresses[i]->getAddr();
    messages[i]->len = a_len;
    messages[i]->strXML = a_strXML;
    messages[i]->is = this;
    messages[i]->requestCommand = requestCommand;
    messages[i]->param = param;
#if !defined(NO_INFOSERVICE_TRHEADS) 
    threads[i] = new CAThread(a_strThreadName);
    threads[i]->setMainLoop((THREAD_RETURN (*)(void *))a_thread);
    threads[i]->start((void*)(messages[i]), false, true);
#else
    (*a_thread)(messages[i]);
      if (messages[i]->retVal == E_SUCCESS)
      {
        returnValue = E_SUCCESS;
      }
#endif
  }

  for (UINT32 i = 0; i < nrAddresses; i++)
  {
#if !defined(NO_INFOSERVICE_TRHEADS)
    if (threads[i]->join() == E_SUCCESS)
    {
      // CAMsg::printMsg(LOG_DEBUG,"InfoService: helo thread %u joined.\n", i);
      if (messages[i]->retVal == E_SUCCESS)
      {
        returnValue = E_SUCCESS;
      }
    }
    delete threads[i];
    threads[i] = NULL;
#endif
    delete messages[i]->addr;
    messages[i]->addr = NULL;
    delete messages[i];
    messages[i] = NULL;
  }
  //Message looks senseless but please keep it because Rolf reported a helo thread deadlock.
  //Perhaps there is a problem when the threads are joined.
  // CAMsg::printMsg(LOG_DEBUG,"InfoService: all helo threads joined. continue.\n");
  delete[] messages;
  messages = NULL;
  delete[] threads;
  threads = NULL;

  return returnValue;
}

Here is the call graph for this function:

SINT32 CAInfoService::sendMixHelo ( SINT32  requestCommand = -1,
const UINT8 param = NULL 
)

POSTs the MIXINFO message for a mix to the InfoService.

Definition at line 691 of file CAInfoService.cpp.

References E_UNKNOWN, getMixHeloXMLAsString(), len, CAMsg::printMsg(), sendHelo(), and TMixHelo().

Referenced by InfoLoop(), and TMixHelo().

{
  UINT32 len;
  SINT32 ret;
  UINT8* strMixHeloXML=getMixHeloXMLAsString(len);

  if(strMixHeloXML==NULL)
  {
    CAMsg::printMsg(LOG_DEBUG,"InfoService:sendMixHelo() -- Error: getMixHeloXMLAsString() returned NULL!\n");
    return E_UNKNOWN;
  }

  // CAMsg::printMsg(LOG_DEBUG,"InfoService:sendMixHelo(): Initialising helo thread...\n");
  ret = sendHelo(strMixHeloXML, len, TMixHelo, (UINT8*)"Mix Helo Thread", requestCommand, param);
  // CAMsg::printMsg(LOG_DEBUG,"InfoService:sendMixHelo(): Finished helo thread!\n");

  delete[] strMixHeloXML;
  strMixHeloXML = NULL;
  return ret;
}

Here is the call graph for this function:

SINT32 CAInfoService::sendMixHelo ( const UINT8 strMixHeloXML,
UINT32  len,
SINT32  requestCommand,
const UINT8 param,
const CASocketAddrINet a_socketAddress 
) [private]

POSTs the HELO message for a mix to the InfoService.

Definition at line 893 of file CAInfoService.cpp.

References CASocket::close(), CASocket::connect(), E_SUCCESS, E_UNKNOWN, GET_NET_ERROR, GET_NET_ERROR_STR, getcurrentTimeMillis(), CASocketAddrINet::getIPAsStr(), CASocketAddrINet::getPort(), len, m_bConfiguring, MIX_TO_INFOSERVICE_TIMEOUT, CAHttpClient::parseHTTPHeader(), CAMsg::printMsg(), CASocket::receiveFullyT(), REQUEST_COMMAND_CONFIGURE, REQUEST_COMMAND_HELO, REQUEST_COMMAND_MIXINFO, REQUEST_TYPE_GET, REQUEST_TYPE_POST, SEND_INFO_TIMEOUT_MS, CASocket::sendFullyTimeOut(), CASocket::setRecvBuff(), CAHttpClient::setSocket(), STRINGS_REQUEST_COMMANDS, and STRINGS_REQUEST_TYPES.

  {
    UINT8* recvBuff = NULL;
    SINT32 ret = E_SUCCESS;
    UINT32 len = 0;

  CASocket oSocket(true);
  UINT8 hostname[255];
  UINT8 buffHeader[255];
  CAHttpClient httpClient;

  UINT64 currentTimeout = MIX_TO_INFOSERVICE_TIMEOUT;
  UINT64 startupTime, currentMillis;

    UINT32 requestType = REQUEST_TYPE_POST;
    bool receiveAnswer = false;

    if (a_pSocketAddress == NULL)
    {
      goto ERR;
    }

    if(requestCommand<0)
  {
        if(m_bConfiguring)
    {
      requestCommand = REQUEST_COMMAND_CONFIGURE;
      receiveAnswer = true;
    }
        else
    {
      requestCommand = REQUEST_COMMAND_HELO;
      receiveAnswer = true;
    }
  }
  else if(requestCommand==REQUEST_COMMAND_MIXINFO)
  {
    requestType=REQUEST_TYPE_GET;
    receiveAnswer = true;
  }

  if(a_pSocketAddress->getIPAsStr(hostname, 255)!=E_SUCCESS)
  {
    goto ERR;
  }

    oSocket.setRecvBuff(255);
  if((ret = oSocket.connect(*a_pSocketAddress, MIX_TO_INFOSERVICE_TIMEOUT))==E_SUCCESS)
  {
    httpClient.setSocket(&oSocket);
    const char* strRequestCommand=STRINGS_REQUEST_COMMANDS[requestCommand];
    const char* strRequestType=STRINGS_REQUEST_TYPES[requestType];
    CAMsg::printMsg(LOG_DEBUG,"InfoService: Sending [%s] %s to InfoService %s:%d.\r\n", strRequestType,strRequestCommand, hostname, a_pSocketAddress->getPort());
    if(requestCommand==REQUEST_COMMAND_MIXINFO)
    {
      sprintf((char*)buffHeader,"%s /%s%s HTTP/1.0\r\nContent-Length: %u\r\n\r\n", strRequestType, strRequestCommand, param,a_len);
    }
    else
    {
      sprintf((char*)buffHeader,"%s /%s HTTP/1.0\r\nContent-Length: %u\r\n\r\n", strRequestType, strRequestCommand, a_len);
    }

    getcurrentTimeMillis(startupTime);
    if (oSocket.sendFullyTimeOut(buffHeader,strlen((char*)buffHeader), currentTimeout, SEND_INFO_TIMEOUT_MS)!=E_SUCCESS)
    {
      goto ERR;
    }

    // CAMsg::printMsg(LOG_DEBUG,"InfoService: Sending XML data...\n");
    getcurrentTimeMillis(currentMillis);
    currentTimeout -= (currentMillis - startupTime);
    if (currentTimeout <= 0 ||
      oSocket.sendFullyTimeOut(a_strMixHeloXML, a_len, currentTimeout, SEND_INFO_TIMEOUT_MS)!=E_SUCCESS)
    {
      goto ERR;
    }

    if(receiveAnswer)
    {
      // CAMsg::printMsg(LOG_DEBUG,"InfoService: Parsing header...\n");
      getcurrentTimeMillis(currentMillis);
      currentTimeout -= (currentMillis - startupTime);
      if(currentTimeout <= 0 || httpClient.parseHTTPHeader(&len) != E_SUCCESS)
      {
        goto ERR;
      }
      // CAMsg::printMsg(LOG_DEBUG,"InfoService: Header parsed!\n");

      if(len > 0)
      {
        getcurrentTimeMillis(currentMillis);
        currentTimeout -= (currentMillis - startupTime);

          recvBuff = new UINT8[len+1];
          CAMsg::printMsg(LOG_DEBUG,"InfoService: Receiving answer...\n");
          if (currentTimeout <= 0 ||
          oSocket.receiveFullyT(recvBuff, len, currentTimeout) != E_SUCCESS)
          {
          delete []recvBuff;
              recvBuff=NULL;
              goto ERR;
          }
        recvBuff[len]=0;
        CAMsg::printMsg(LOG_DEBUG,"Received from Infoservice:\n");
        CAMsg::printMsg(LOG_DEBUG,(char*)recvBuff);
        CAMsg::printMsg(LOG_DEBUG,"\n");
      }
        }
        oSocket.close();

        if(recvBuff != NULL)
        {
            delete[] recvBuff;
            recvBuff=NULL;
        }
        /* REMOVED by Rolf Wendolsky on 2009-12-11 becuase this looks  dangerous: each InfoService may reconfigure the Mix! Without verificaton!
        if(recvBuff != NULL)
        {
            XERCES_CPP_NAMESPACE::DOMDocument* doc=parseDOMDocument(recvBuff,len);
            delete[] recvBuff;
            recvBuff=NULL;
            DOMElement* root=NULL;
            if(doc!=NULL && (root = doc->getDocumentElement()) != NULL)
            {
                if(equals(root->getNodeName(),"MixCascade"))
                {
                    ret = handleConfigEvent(doc);
                    if(ret == E_SUCCESS)
                        m_bConfiguring = false;
                    else
                        return ret;
                }
                else if(equals(root->getNodeName(),"Mix"))
                {
                    if(m_expectedMixRelPos < 0)
          {
            XMLCh* id=XMLString::transcode("id");
            char* tmpStr=XMLString::transcode(root->getAttribute(id));
                        CAMsg::printMsg(LOG_DEBUG,"InfoService: Setting new previous mix: %s\n",tmpStr);
                        XMLString::release(&tmpStr);
                        XMLString::release(&id);
                        CALibProxytest::getOptions()->setPrevMix(doc);
          }
                    else if(m_expectedMixRelPos > 0)
          {
            XMLCh* id=XMLString::transcode("id");
            char* tmpStr=XMLString::transcode(root->getAttribute(id));
                        CAMsg::printMsg(LOG_DEBUG,"InfoService: Setting new next mix: %s\n",tmpStr);
                        XMLString::release(&id);
                        XMLString::release(&tmpStr);
                        CALibProxytest::getOptions()->setNextMix(doc);
          }
                }
                CAMsg::printMsg(LOG_DEBUG,"InfoService::sendMixHelo(): XML infoservice doc 0x%x not needed anymore.\n",
                    doc);
            }
            else
            {
                CAMsg::printMsg(LOG_CRIT,"InfoService: Error parsing answer from InfoService!\n");
            }
        }*/
    return E_SUCCESS;
  }
  else
  {
    if (ret != E_UNKNOWN)
    {
      CAMsg::printMsg(LOG_ERR,"InfoService: sendMixHelo() connecting to InfoService %s:%d failed for reason: %s (%i)\n",
          hostname, a_pSocketAddress->getPort(), GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
    }
    else
    {
      CAMsg::printMsg(LOG_ERR,"InfoService: sendMixHelo() connecting to InfoService %s:%d failed!\n",
                hostname, a_pSocketAddress->getPort());
    }
  }
ERR:

  //CAMsg::printMsg(LOG_DEBUG,"InfoService: Closing socket to %s:%d due to error...\n", hostname, a_pSocketAddress->getPort());
  oSocket.close();
  //CAMsg::printMsg(LOG_DEBUG,"InfoService: Socket closed to %s:%d due to error.\n", hostname, a_pSocketAddress->getPort());
  return E_UNKNOWN;
}

Here is the call graph for this function:

Definition at line 639 of file CAInfoService.cpp.

References E_SUCCESS.

{
  /*SINT32 ret = E_SUCCESS;
  UINT32 *lengths_ptr = NULL;
  XMLSize_t nrOfTnCs = 0;
  UINT32 i = 0;
  UINT8 **tncData = getOperatorTnCsAsStrings(&lengths_ptr, &nrOfTnCs);

  if(tncData != NULL)
  {
    for (;i < nrOfTnCs; i++)
    {
#ifdef DEBUG
      CAMsg::printMsg(LOG_DEBUG,"InfoService:sendMixTnCData(), object: %s, len: %u\n",
          tncData[i], lengths_ptr[i]);
#endif
      if( tncData[i] != NULL )
      {
        ret |= sendHelo(tncData[i], lengths_ptr[i],
            TMixHelo, (UINT8*)"Mix TnC Thread",
            REQUEST_COMMAND_TNC_DATA, NULL);
        delete [] tncData[i];
        tncData[i] = NULL;
      }
      else
      {
        CAMsg::printMsg(LOG_ERR,"InfoService:sendMixTnCData() -- Element %u is invalid!\n", (i+1) );
        ret |= E_UNKNOWN;
      }

    }
    delete [] lengths_ptr;
    lengths_ptr = NULL;

    delete [] tncData;
  }
  else
  {
    CAMsg::printMsg(LOG_DEBUG,"InfoService:sendMixTnCData() -- No TnC data specified!\n");
    return E_SUCCESS;
  }
  return ret;*/
  return E_SUCCESS;
}
SINT32 CAInfoService::sendStatus ( bool  bIncludeCerts)

Definition at line 464 of file CAInfoService.cpp.

References E_SUCCESS, E_UNKNOWN, CALibProxytest::getOptions(), getStatusXMLAsString(), CAMix::isConnected(), len, m_pMix, CAMsg::printMsg(), REQUEST_COMMAND_STATUS, sendHelo(), and TCascadeStatus().

Referenced by InfoLoop(), and TCascadeStatus().

{
  if(!CALibProxytest::getOptions()->isFirstMix())
  {
    return E_SUCCESS;
  }


  if( !(m_pMix->isConnected())) // && !bIncludeCerts )
  {
#ifdef DEBUG
    CAMsg::printMsg(LOG_INFO, "Mix not connected. Skipping status.\n");
#endif
    return E_UNKNOWN;
  }

  UINT32 len=0;
  SINT32 ret=E_UNKNOWN;
  UINT8* strStatusXML=getStatusXMLAsString(bIncludeCerts,len);

  if(strStatusXML==NULL)
  {
    return E_UNKNOWN;
  }

  if( !(m_pMix->isConnected()))
  {
    CAMsg::printMsg(LOG_INFO, "Mix not connected. Skip sending already created status message.\n");
  }
  else
  {
    ret = sendHelo(strStatusXML, len, TCascadeStatus, (UINT8*)"Status Thread", REQUEST_COMMAND_STATUS);
  }

  delete[] strStatusXML;
  strStatusXML = NULL;
  return ret;
}

Here is the call graph for this function:

SINT32 CAInfoService::sendStatus ( const UINT8 a_strStatusXML,
UINT32  a_len,
const CASocketAddrINet a_pSocketAddress 
) const [private]

POSTs mix status to the InfoService.

[only first mix does this at the moment]

Return values:
E_UNKNOWNif something goes wrong
E_SUCCESSotherwisetodo use httpclient class

Definition at line 576 of file CAInfoService.cpp.

References CASocket::close(), CASocket::connect(), E_SUCCESS, E_UNKNOWN, GET_NET_ERROR, GET_NET_ERROR_STR, getcurrentTimeMillis(), CASocketAddrINet::getIPAsStr(), CALibProxytest::getOptions(), CASocketAddrINet::getPort(), MIX_TO_INFOSERVICE_TIMEOUT, CAMsg::printMsg(), SEND_INFO_TIMEOUT_MS, and CASocket::sendFullyTimeOut().

  {
    UINT8 buffHeader[512];
    SINT32 ret = E_UNKNOWN;
    UINT8 hostname[255];
    UINT32 currentTimeout = MIX_TO_INFOSERVICE_TIMEOUT;
    UINT64 startupTime, currentMillis;


    #ifdef DEBUG
      CAMsg::printMsg(LOG_DEBUG, "CAInfoService::sendStatus()\n");
    #endif
    if(!CALibProxytest::getOptions()->isFirstMix())
    {
      return E_SUCCESS;
    }
    CASocket oSocket(true);
    if (a_pSocketAddress == NULL)
    {
      oSocket.close();
      return E_UNKNOWN;
    }

    
    if(oSocket.connect(*a_pSocketAddress, MIX_TO_INFOSERVICE_TIMEOUT)!=E_SUCCESS)
    {
      if(a_pSocketAddress->getIPAsStr(hostname, 255) == E_SUCCESS)
      {
        CAMsg::printMsg(LOG_DEBUG, "InfoService: Could not connect to InfoService %s:%d. Reason: %s (%i)\n", 
          hostname, a_pSocketAddress->getPort(), GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
      }
      else
      {
        CAMsg::printMsg(LOG_DEBUG, "InfoService: Could not connect to InfoService (host unknown) at port %d. Reason: %s (%i)\n", 
          a_pSocketAddress->getPort(), GET_NET_ERROR_STR(GET_NET_ERROR), GET_NET_ERROR);
      }
      oSocket.close();
      return E_UNKNOWN;
    }

    if(a_pSocketAddress->getIPAsStr(hostname, 255) == E_SUCCESS)
    {
      CAMsg::printMsg(LOG_DEBUG, "InfoService: Sending current status to InfoService %s:%d.\n", hostname, a_pSocketAddress->getPort());
      sprintf((char*)buffHeader,"POST /feedback HTTP/1.0\r\nContent-Length: %u\r\n\r\n",a_len);

      getcurrentTimeMillis(startupTime);
      oSocket.sendFullyTimeOut(buffHeader,strlen((char*)buffHeader), currentTimeout, SEND_INFO_TIMEOUT_MS);

      getcurrentTimeMillis(currentMillis);
      currentTimeout -= (currentMillis - startupTime);
      ret=oSocket.sendFullyTimeOut(a_strStatusXML, a_len, currentTimeout, SEND_INFO_TIMEOUT_MS);
    }

    oSocket.close();
    if(ret==E_SUCCESS)
    {
      return E_SUCCESS;
    }
    CAMsg::printMsg(LOG_DEBUG, "InfoService: Sending status failed, ret: %d \n", ret);
    return E_UNKNOWN;
  }

Here is the call graph for this function:

void CAInfoService::setConfiguring ( bool  a_configuring) [inline]

Definition at line 94 of file CAInfoService.hpp.

References m_bConfiguring.

Referenced by CAMix::start().

      {
          m_bConfiguring = a_configuring;
      }

Definition at line 403 of file CAInfoService.cpp.

References E_SUCCESS, and m_pMultiSignature.

Referenced by CAMix::start().

{
  m_pMultiSignature = pMultiSig;
  return E_SUCCESS;
}
void CAInfoService::setSerial ( UINT64  a_serial) [inline]

Definition at line 99 of file CAInfoService.hpp.

References m_serial.

Referenced by CAMix::start().

      {
        m_serial = a_serial;
      }

Definition at line 441 of file CAInfoService.cpp.

References E_SUCCESS, CAMutex::lock(), m_pLoopCV, CAConditionVariable::signal(), and CAMutex::unlock().

Referenced by CAMix::start().

Here is the call graph for this function:

Definition at line 423 of file CAInfoService.cpp.

References E_UNKNOWN, InfoLoop(), m_bRun, m_lastMixedPackets, m_minuts, m_pMultiSignature, m_pthreadRunLoop, CAMsg::printMsg(), set64(), CAThread::setMainLoop(), and CAThread::start().

Referenced by CAMix::start().

  {
    if(m_pMultiSignature==NULL)
    {
      return E_UNKNOWN;
    }
    m_bRun=true;
    set64(m_lastMixedPackets,(UINT32)0);
    m_minuts=1;
    m_pthreadRunLoop->setMainLoop(InfoLoop);
    #ifdef DEBUG
      CAMsg::printMsg(LOG_DEBUG, "CAInfoService::start() - starting InfoService thread\n");
    #endif

    return m_pthreadRunLoop->start(this);
  }

Here is the call graph for this function:

Definition at line 449 of file CAInfoService.cpp.

References E_SUCCESS, CAThread::join(), CAMutex::lock(), m_bRun, m_pLoopCV, m_pthreadRunLoop, CAConditionVariable::signal(), and CAMutex::unlock().

Referenced by CAFirstMixA::shutDown(), CAMix::start(), and ~CAInfoService().

  {
    if(m_bRun)
      {
        m_bRun=false;
        /* Interrupt this thread */
        m_pLoopCV->lock();
        m_pLoopCV->signal();
        m_pLoopCV->unlock();

        m_pthreadRunLoop->join();
      }
    return E_SUCCESS;
  }

Here is the call graph for this function:

THREAD_RETURN CAInfoService::TCascadeHelo ( void *  p) [static, private]

Definition at line 244 of file CAInfoService.cpp.

References CAInfoService::InfoServiceHeloMsg::addr, BEGIN_STACK, FINISH_STACK, INIT_STACK, CAInfoService::InfoServiceHeloMsg::is, CAInfoService::InfoServiceHeloMsg::len, CAInfoService::InfoServiceHeloMsg::retVal, sendCascadeHelo(), CAInfoService::InfoServiceHeloMsg::strXML, and THREAD_RETURN_SUCCESS.

Referenced by sendCascadeHelo().

{
  INIT_STACK;
  BEGIN_STACK("CAInfoService::TCascadeHelo");

  InfoServiceHeloMsg* message = (InfoServiceHeloMsg*)p;
  message->retVal = message->is->sendCascadeHelo(message->strXML, message->len, message->addr);
  FINISH_STACK("CAInfoService::TCascadeHelo");
  THREAD_RETURN_SUCCESS;
}

Here is the call graph for this function:

THREAD_RETURN CAInfoService::TCascadeStatus ( void *  p) [static, private]

Definition at line 255 of file CAInfoService.cpp.

References CAInfoService::InfoServiceHeloMsg::addr, BEGIN_STACK, FINISH_STACK, INIT_STACK, CAInfoService::InfoServiceHeloMsg::is, CAInfoService::InfoServiceHeloMsg::len, CAInfoService::InfoServiceHeloMsg::retVal, sendStatus(), CAInfoService::InfoServiceHeloMsg::strXML, and THREAD_RETURN_SUCCESS.

Referenced by sendStatus().

{
  INIT_STACK;
  BEGIN_STACK("CAInfoService::TCascadeStatus");

  InfoServiceHeloMsg* message = (InfoServiceHeloMsg*)p;
  message->retVal = message->is->sendStatus(message->strXML, message->len, message->addr);

  FINISH_STACK("CAInfoService::TCascadeStatus");
  THREAD_RETURN_SUCCESS;
}

Here is the call graph for this function:

THREAD_RETURN CAInfoService::TMixHelo ( void *  p) [static, private]

Definition at line 267 of file CAInfoService.cpp.

References CAInfoService::InfoServiceHeloMsg::addr, BEGIN_STACK, FINISH_STACK, INIT_STACK, CAInfoService::InfoServiceHeloMsg::is, CAInfoService::InfoServiceHeloMsg::len, CAInfoService::InfoServiceHeloMsg::param, CAInfoService::InfoServiceHeloMsg::requestCommand, CAInfoService::InfoServiceHeloMsg::retVal, sendMixHelo(), CAInfoService::InfoServiceHeloMsg::strXML, and THREAD_RETURN_SUCCESS.

Referenced by sendMixHelo().

{
  INIT_STACK;
  BEGIN_STACK("CAInfoService::TMixHelo");

  InfoServiceHeloMsg* message = (InfoServiceHeloMsg*)p;
  message->retVal = message->is->sendMixHelo(message->strXML, message->len, message->requestCommand, message->param, message->addr);

  FINISH_STACK("CAInfoService::TMixHelo");
  THREAD_RETURN_SUCCESS;
}

Here is the call graph for this function:

UINT8 * CAInfoService::xmlDocToStringWithSignature ( DOMNode *  a_node,
UINT32 a_len,
bool  bIncludeCerts 
) [private]

Definition at line 866 of file CAInfoService.cpp.

References DOM_Output::dumpToMem(), E_SUCCESS, m_pMultiSignature, and CAMultiSignature::signXML().

Referenced by getMixHeloXMLAsString(), and getOperatorTnCsAsStrings().

{
  a_len = 0;

  UINT32 sendBuffLen = 0;
  UINT8* sendBuff = NULL;

  if( a_node == NULL)
  {
    return NULL;
  }
  if(m_pMultiSignature->signXML(a_node, bIncludeCerts) != E_SUCCESS)
  {
    return NULL;
  }

  sendBuff = DOM_Output::dumpToMem(a_node, &sendBuffLen);
  if(sendBuff == NULL)
  {
    return NULL;
  }
  a_len = sendBuffLen;
  return sendBuff;
}

Here is the call graph for this function:


Member Data Documentation

Definition at line 151 of file CAInfoService.hpp.

Referenced by isConfiguring(), sendCascadeHelo(), sendMixHelo(), and setConfiguring().

volatile bool CAInfoService::m_bRun [private]

Definition at line 140 of file CAInfoService.hpp.

Referenced by CAInfoService(), isRunning(), start(), and stop().

Definition at line 150 of file CAInfoService.hpp.

Referenced by CAInfoService().

Definition at line 147 of file CAInfoService.hpp.

Referenced by CAInfoService(), getStatusXMLAsString(), and start().

Definition at line 149 of file CAInfoService.hpp.

Referenced by CAInfoService(), getStatusXMLAsString(), and start().

Definition at line 146 of file CAInfoService.hpp.

Referenced by CAInfoService(), InfoLoop(), signal(), stop(), and ~CAInfoService().

Definition at line 145 of file CAInfoService.hpp.

Referenced by CAInfoService(), start(), stop(), and ~CAInfoService().

Definition at line 148 of file CAInfoService.hpp.

Referenced by getCascadeHeloXMLAsString(), getMixHeloXMLAsString(), and setSerial().

const UINT64 CAInfoService::MINUTE = 60 [static]

Definition at line 112 of file CAInfoService.hpp.

Definition at line 118 of file CAInfoService.hpp.

Referenced by InfoLoop().

Definition at line 114 of file CAInfoService.hpp.

Referenced by InfoLoop().

Definition at line 117 of file CAInfoService.hpp.

Referenced by sendCascadeHelo(), sendMixHelo(), and sendStatus().

Definition at line 113 of file CAInfoService.hpp.

Referenced by InfoLoop().

Definition at line 115 of file CAInfoService.hpp.

Referenced by InfoLoop().

Definition at line 116 of file CAInfoService.hpp.

Referenced by InfoLoop().


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