41 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_MIDDLE_MIX
47 #ifndef ONLY_LOCAL_PROXY
60 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_MIDDLE_MIX
92 CAMsg::printMsg(LOG_DEBUG,
"CAInfoService - InfoLoop() PID: %i\n", getpid());
95 bool bOneUpdateDone =
false;
106 lastCascadeUpdate = lastMixInfoUpdate = lastStatusUpdate = (
UINT32)time(NULL);
111 UINT32 statusSentErrorBurst = 0;
130 currentTime = time(NULL);
136 lastStatusUpdate = time(NULL);
138 bOneUpdateDone =
true;
139 statusSentErrorBurst = 0;
145 statusSentErrorBurst++;
146 CAMsg::printMsg(LOG_WARNING,
"InfoService: Could not send Status information.\n");
153 currentTime = time(NULL);
161 lastCascadeUpdate = time(NULL);
162 bOneUpdateDone =
true;
163 CAMsg::printMsg(LOG_INFO,
"InfoService: Successfully sent Cascade information.\n");
168 CAMsg::printMsg(LOG_WARNING,
"InfoService: Could not send Cascade information.\n");
171 currentTime = time(NULL);
177 CAMsg::printMsg(LOG_WARNING,
"InfoService: Could not send MixInfo information.\n");
181 lastMixInfoUpdate = time(NULL);
182 bOneUpdateDone =
true;
183 CAMsg::printMsg(LOG_INFO,
"InfoService: Successfully sent MixInfo information.\n");
197 pInfoService->dynamicCascadeConfiguration();
200 currentTime = time(NULL);
233 if (bOneUpdateDone && (statusSentErrorBurst > 0))
243 interval = nextUpdate / 4;
244 CAMsg::printMsg(LOG_DEBUG,
"InfoService: Next update in %i seconds...interval %i\n", nextUpdate, interval);
249 CAMsg::printMsg(LOG_DEBUG,
"InfoService: Next update in %i seconds...\n", nextUpdate);
289 #ifndef ONLY_LOCAL_PROXY
308 bool CAInfoService::newCascadeAvailable()
315 UINT32 status, contentLength;
320 sprintf((
char*)buff,
"/newcascadeinformationavailable/%s",bufMixId );
323 CAMsg::printMsg( LOG_ERR,
"Unable to get a random InfoService - This will cause problems! Check your configuration!\n");
354 SINT32 CAInfoService::dynamicCascadeConfiguration()
357 CADynamicCascadeConfigurator *configurator = NULL;
359 if(!newCascadeAvailable())
372 configurator =
new CADynamicCascadeConfigurator( m_pSignature,
m_pMix );
373 ret = configurator->configure();
380 m_pMix->dynaReconfigure(
false);
397 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_MIDDLE_MIX
446 #if !defined ONLY_LOCAL_PROXY
457 #if ! defined ONLY_LOCAL_PROXY
477 CAMsg::printMsg(LOG_DEBUG,
"CAInfoService::start() - starting InfoService thread\n");
527 if (strStatusXML == NULL)
534 CAMsg::printMsg(LOG_INFO,
"Mix not connected. Skip sending already created status message.\n");
541 delete[] strStatusXML;
549 SINT32 tmpUser, tmpRisk, tmpTraffic;
556 tmpUser = tmpTraffic = tmpRisk = -1;
558 getLevel(&tmpUser, &tmpRisk, &tmpTraffic);
566 if (diffTraffic == 0)
577 double dTmp = (double)diffTraffic / (
double)avgTraffic;
584 #define XML_MIX_CASCADE_STATUS "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\
585 <MixCascadeStatus LastUpdate=\"%s\" currentRisk=\"%i\" id=\"%s\" mixedPackets=\"%s\" nrOfActiveUsers=\"%i\" trafficSituation=\"%i\"\
586 ></MixCascadeStatus>"
590 memset(buff, 0, buffLen);
592 UINT8 buffMixedPackets[50];
593 print64(buffMixedPackets, tmpPackets);
595 UINT8 tmpStrCurrentMillis[50];
598 print64(tmpStrCurrentMillis, currentMillis);
602 tmpStrCurrentMillis[0] = 0;
604 sprintf((
char*)tmpBuff,
XML_MIX_CASCADE_STATUS, tmpStrCurrentMillis, tmpRisk, strMixId, buffMixedPackets, tmpUser, tmpTraffic);
627 for (
UINT32 i = 0; i < nrAddresses; i++)
631 messages[i]->
len = a_len;
632 messages[i]->
strXML = a_strXML;
633 messages[i]->
is =
this;
635 messages[i]->
param = param;
636 #if !defined(NO_INFOSERVICE_TRHEADS)
637 threads[i] =
new CAThread(a_strThreadName);
639 threads[i]->
start((
void*)(messages[i]),
false,
true);
641 (*a_thread)(messages[i]);
649 for (
UINT32 i = 0; i < nrAddresses; i++)
651 #if !defined(NO_INFOSERVICE_TRHEADS)
663 delete messages[i]->
addr;
664 messages[i]->
addr = NULL;
690 UINT8 buffHeader[512];
694 UINT64 startupTime, currentMillis;
705 if (a_pSocketAddress == NULL)
716 CAMsg::printMsg(LOG_DEBUG,
"InfoService: Could not connect to InfoService %s:%d. Reason: %s (%i)\n",
721 CAMsg::printMsg(LOG_DEBUG,
"InfoService: Could not connect to InfoService (host unknown) at port %d. Reason: %s (%i)\n",
730 CAMsg::printMsg(LOG_DEBUG,
"InfoService: Sending current status to InfoService %s:%d.\n", hostname, a_pSocketAddress->
getPort());
731 sprintf((
char*)buffHeader,
"POST /feedback HTTP/1.0\r\nContent-Length: %u\r\n\r\n", a_len);
737 currentTimeout -= (currentMillis - startupTime);
746 CAMsg::printMsg(LOG_DEBUG,
"InfoService: Sending status failed, ret: %d \n", ret);
755 if (strMixHeloXML == NULL)
757 CAMsg::printMsg(LOG_DEBUG,
"InfoService:sendMixHelo() -- Error: getMixHeloXMLAsString() returned NULL!\n");
765 delete[] strMixHeloXML;
766 strMixHeloXML = NULL;
772 XERCES_CPP_NAMESPACE::DOMDocument* docMixInfo = NULL;
773 DOMElement* mixInfoRoot = NULL;
776 (docMixInfo == NULL))
783 mixInfoRoot = docMixInfo->getDocumentElement();
784 if (mixInfoRoot != NULL)
797 UINT8* sendBuff = NULL;
809 if (sendBuff == NULL)
822 UINT8* recvBuff = NULL;
828 UINT8 buffHeader[255];
832 UINT64 startupTime, currentMillis;
835 bool receiveAnswer =
false;
837 if (a_pSocketAddress == NULL)
842 if (requestCommand < 0)
847 receiveAnswer =
true;
852 receiveAnswer =
true;
859 receiveAnswer =
true;
873 CAMsg::printMsg(LOG_DEBUG,
"InfoService: Sending [%s] %s to InfoService %s:%d.\r\n", strRequestType, strRequestCommand, hostname, a_pSocketAddress->
getPort());
876 sprintf((
char*)buffHeader,
"%s /%s%s HTTP/1.0\r\nContent-Length: %u\r\n\r\n", strRequestType, strRequestCommand, param, a_len);
880 sprintf((
char*)buffHeader,
"%s /%s HTTP/1.0\r\nContent-Length: %u\r\n\r\n", strRequestType, strRequestCommand, a_len);
891 currentTimeout -= (currentMillis - startupTime);
892 if (currentTimeout <= 0 ||
902 currentTimeout -= (currentMillis - startupTime);
912 currentTimeout -= (currentMillis - startupTime);
916 if (currentTimeout <= 0 ||
931 if (recvBuff != NULL)
988 CAMsg::printMsg(LOG_ERR,
"InfoService: sendMixHelo() connecting to InfoService %s:%d failed for reason: %s (%i)\n",
993 CAMsg::printMsg(LOG_ERR,
"InfoService: sendMixHelo() connecting to InfoService %s:%d failed!\n",
994 hostname, a_pSocketAddress->
getPort());
1007 #ifndef ONLY_LOCAL_PROXY
1080 DOMNodeList *docTnCsList =
1083 if (docTnCsList == NULL)
1088 UINT8 **elementList = NULL;
1089 DOMNode *iterator = NULL;
1096 if (tmpOpSKILen == 0)
1105 if (tmpDateLen == 0)
1113 UINT8* serial = NULL;
1116 if (tmpVersionLen > 0)
1118 serial =
new UINT8[tmpDateLen + tmpVersionLen + 1];
1119 memcpy(serial, tmpDate, tmpDateLen);
1120 memcpy(serial + tmpDateLen, tmpVersion, tmpVersionLen);
1121 serial[tmpDateLen + tmpVersionLen] = 0;
1125 serial =
new UINT8[tmpDateLen + 1];
1126 memcpy(serial, tmpDate, tmpDateLen);
1127 serial[tmpDateLen] = 0;
1131 UINT8*
id =
new UINT8[tmpOpSKILen + locale_len + 1];
1134 locale[locale_len - 1] = 0;
1136 memcpy(
id, tmpOpSKIBuff, tmpOpSKILen);
1137 id[tmpOpSKILen] = 0;
1138 id[tmpOpSKILen + (locale_len - 1) + 1] = 0;
1140 (*nrOfTnCs) = docTnCsList->getLength();
1141 elementList =
new UINT8 *[(*nrOfTnCs)];
1142 (*lengths) =
new UINT32[(*nrOfTnCs)];
1143 for (; i < (*nrOfTnCs); i++)
1147 iterator = docTnCsList->item(i);
1150 if (locale_len == 0)
1152 elementList[i] = NULL;
1159 id[tmpOpSKILen] = 0;
1163 id[tmpOpSKILen] =
'_';
1164 memcpy((
id + tmpOpSKILen + 1), locale, locale_len);
1169 elementList[i] = NULL;
1174 elementList[i] = NULL;
1179 elementList[i] = NULL;
1208 if (strCascadeHeloXML == NULL)
1218 delete[] strCascadeHeloXML;
1219 strCascadeHeloXML = NULL;
1224 delete[] strCascadeHeloXML;
1225 strCascadeHeloXML = NULL;
1233 UINT8* sendBuff = NULL;
1234 XERCES_CPP_NAMESPACE::DOMDocument* docMixInfo = NULL;
1235 DOMElement* elemTimeStamp = NULL;
1236 DOMElement* elemRoot = NULL;
1244 elemRoot = docMixInfo->getDocumentElement();
1249 elemRoot->appendChild(elemTimeStamp);
1253 UINT8 tmpStrCurrentMillis[50];
1254 print64(tmpStrCurrentMillis, currentMillis);
1269 if (sendBuff == NULL)
1274 a_len = sendBuffLen;
1297 UINT8 hostname[255];
1298 UINT8 buffHeader[255];
1300 UINT64 startupTime, currentMillis;
1302 if (a_pSocketAddress == NULL)
1315 CAMsg::printMsg(LOG_DEBUG,
"InfoService: Sending cascade helo to InfoService %s:%d.\r\n", hostname, a_pSocketAddress->
getPort());
1319 CAMsg::printMsg(LOG_DEBUG,
"InfoService: Sending cascade configuration request to InfoService %s:%d.\r\n", hostname, a_pSocketAddress->
getPort());
1326 sprintf((
char*)buffHeader,
"POST /dynacascade HTTP/1.0\r\nContent-Length: %u\r\n\r\n", a_len);
1330 sprintf((
char*)buffHeader,
"POST /cascade HTTP/1.0\r\nContent-Length: %u\r\n\r\n", a_len);
1339 currentTimeout -= (currentMillis - startupTime);
1340 if (currentTimeout <= 0 ||
1348 currentTimeout -= (currentMillis - startupTime);
1349 if (currentTimeout <= 0 ||
1354 if (memcmp(buffHeader + 9,
"200", 3) != 0)
1450 for (
UINT32 i = 0; i < nrAddresses; i++)
1456 returnValue = currentValue;
1476 UINT8 hostname[255];
1479 UINT32 status, contentLength;
1497 CAMsg::printMsg(LOG_DEBUG,
"CAInfoService::getPaymentInstance() - connected to InfoService %s:%d\n",hostname, a_socketAddress->
getPort());
1502 sprintf((
char*) request,
"/paymentinstance/%s", (
char*) a_pstrPIID);
1506 CAMsg::printMsg(LOG_DEBUG,
"CAInfoService::getPaymentInstance() - Request sent, HTTP status: %i, content length: %i\n", status, contentLength);
1508 if(status!=200||contentLength>0x00FFFF)
1524 XERCES_CPP_NAMESPACE::DOMDocument* doc =
parseDOMDocument(content,contentLength);
1531 DOMElement* elemRoot=doc->getDocumentElement();
1533 *a_pXMLBI = CAXMLBI::getInstance(elemRoot);
1534 CAMsg::printMsg(LOG_DEBUG,
"CAInfoService::getPaymentInstance(): XML doc not needed anymore\n");
1535 if (*a_pXMLBI != NULL)
#define OPTIONS_ATTRIBUTE_TNC_ID
#define OPTIONS_ATTRIBUTE_TNC_VERSION
#define OPTIONS_ATTRIBUTE_TNC_SERIAL
#define OPTIONS_ATTRIBUTE_TNC_DATE
#define OPTIONS_ATTRIBUTE_TNC_LOCALE
#define OPTIONS_NODE_TNCS_TRANSLATION
const char * STRINGS_REQUEST_TYPES[NR_REQUEST_TYPES]
const char * STRINGS_REQUEST_COMMANDS[NR_REQUEST_COMMANDS]
#define XML_MIX_CASCADE_STATUS
#define REQUEST_TYPE_POST
#define REQUEST_COMMAND_MIXINFO
#define NR_REQUEST_COMMANDS
#define REQUEST_COMMAND_CONFIGURE
#define REQUEST_COMMAND_STATUS
#define REQUEST_COMMAND_HELO
#define REQUEST_COMMAND_CASCADE
#define BEGIN_STACK(methodName)
#define FINISH_STACK(methodName)
SINT32 setDOMElementAttribute(DOMNode *pElem, const char *attrName, const char *value)
SINT32 getcurrentTimeMillis(UINT64 &u64Time)
Gets the current Systemtime in milli seconds.
SINT32 setDOMElementValue(DOMElement *pElem, SINT32 value)
SINT32 setCurrentTimeMilliesAsDOMAttribute(DOMNode *pElem)
SINT32 sSleep(UINT32 sec)
Sleeps sec Seconds.
XERCES_CPP_NAMESPACE::DOMDocument * parseDOMDocument(const UINT8 *const buff, UINT32 len)
Parses a buffer containing an XML document and returns this document.
DOMNodeList * getElementsByTagName(DOMElement *pElem, const char *const name)
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.
SINT32 getDOMChildByName(const DOMNode *pNode, const char *const name, DOMElement *&child, bool deep)
SINT32 getDOMElementAttribute(const DOMNode *const elem, const char *attrName, UINT8 *value, UINT32 *len)
UINT32 diff64(const UINT64 &bigop, const UINT64 &smallop)
UINT32 div64(UINT64 &op1, UINT32 op2)
void print64(UINT8 *buff, UINT64 num)
void set64(UINT64 &op1, UINT32 op2)
#define GET_NET_ERROR_STR(x)
#define THREAD_RETURN_SUCCESS
#define MIX_TO_INFOSERVICE_TIMEOUT
SINT32 getMixId(UINT8 *id, UINT32 len)
DOMElement * getTermsAndConditions()
SINT32 getOperatorSubjectKeyIdentifier(UINT8 *buffer, UINT32 *length)
Returns a COPY of the public test certifcate for that mix.
CAListenerInterface ** getInfoServices(UINT32 &r_size)
SINT32 signal()
Signals this object.
SINT32 wait()
Waits for a signal or for a timeout.
SINT32 sendGetRequest(const UINT8 *url)
Sends a HTTP GET request to the server.
SINT32 getContent(UINT8 *a_pContent, UINT32 *a_pLength)
Retruns the content of the response.
SINT32 parseHTTPHeader(UINT32 *contentLength, UINT32 *statusCode=NULL, UINT32 msTimeOut=3000)
receives the HTTP header and parses the content length
SINT32 setSocket(CASocket *pSocket)
CAThread * m_pthreadRunLoop
CAConditionVariable * m_pLoopCV
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)
SINT32 setMultiSignature(CAMultiSignature *pMultiSignature)
UINT8 * getMixHeloXMLAsString(UINT32 &len)
static const UINT32 REPEAT_ON_STATUS_SENT_ERROR
static THREAD_RETURN TCascadeStatus(void *p)
SINT32 getMixedPackets(UINT64 &ppackets)
SINT32 sendStatus(bool bIncludeCerts)
static const UINT64 SEND_STATUS_INFO_WAIT
CAMultiSignature * m_pMultiSignature
SINT32 sendMixHelo(SINT32 requestCommand=-1, const UINT8 *param=NULL)
SINT32 m_expectedMixRelPos
static const UINT64 SEND_MIX_INFO_WAIT
static const UINT64 SEND_LOOP_SLEEP
UINT8 * getStatusXMLAsString(bool bIncludeCerts, UINT32 &len)
UINT64 m_lastMixedPackets
static const UINT32 SEND_INFO_TIMEOUT_MS
UINT8 ** getOperatorTnCsAsStrings(UINT32 **lengths, UINT32 *nrOfTnCs)
POSTs the MIXINFO message for a mix to the InfoService.
static const UINT64 MINUTE
SINT32 sendOperatorTnCData()
SINT32 getLevel(SINT32 *puser, SINT32 *prisk, SINT32 *ptraffic)
static THREAD_RETURN TCascadeHelo(void *p)
UINT8 * xmlDocToStringWithSignature(DOMNode *a_node, UINT32 &a_len, bool bIncludeCerts)
UINT8 * getCascadeHeloXMLAsString(UINT32 &len)
static THREAD_RETURN TMixHelo(void *p)
static const UINT64 SEND_CASCADE_INFO_WAIT
SINT32 handleConfigEvent(XERCES_CPP_NAMESPACE::DOMDocument *doc) const
static THREAD_RETURN InfoLoop(void *p)
static CACmdLnOptions * getOptions()
UINT32 getLastConnectionTime()
SINT32 getMixCascadeInfo(XERCES_CPP_NAMESPACE::DOMDocument *&docMixCascadeInfo)
Returns the Mix-Cascade info which should be send to the InfoService.
static SINT32 printMsg(UINT32 typ, const char *format,...)
Writes a given message to the log.
SINT32 signXML(DOMNode *a_node, bool appendCerts)
This class represents a socket address for Internet (IP) connections.
SINT32 setAddr(const UINT8 *szIP, UINT16 port)
Sets the address to szIP and port.
SINT32 getIPAsStr(UINT8 *buff, UINT32 len) const
Returns the IP-Number as an address string (doted-format).
UINT16 getPort() const
Returns the port value of the address.
virtual SINT32 setRecvBuff(UINT32 r)
virtual SINT32 receiveFullyT(UINT8 *buff, UINT32 len, UINT32 msTimeOut)
Trys to receive all bytes.
virtual SINT32 sendFullyTimeOut(const UINT8 *buff, UINT32 len, UINT32 msTimeOut, UINT32 msTimeOutSingleSend)
Sends all data over the network.
virtual SINT32 connect(const CASocketAddr &psa)
SINT32 start(void *param, bool bDaemon=false, bool bSilent=false)
Starts the execution of the main function of this thread.
SINT32 setMainLoop(THREAD_MAIN_TYP fnc)
Sets the main function which will be executed within this thread.
SINT32 join()
Waits for the main function to finish execution.
static SINT32 dumpToMem(const DOMNode *node, UINT8 *buff, UINT32 *size)
Dumps the node and all childs into buff.