PARCBitVector * athenaTransportLinkAdapter_Send(AthenaTransportLinkAdapter *athenaTransportLinkAdapter, CCNxMetaMessage *ccnxMetaMessage, PARCBitVector *linkOutputVector) { PARCBitVector *resultVector = parcBitVector_Create(); int nextLinkToWrite = 0; if (athenaTransportLinkAdapter->instanceList == NULL) { return resultVector; } while ((nextLinkToWrite = parcBitVector_NextBitSet(linkOutputVector, nextLinkToWrite)) >= 0) { athenaTransportLinkAdapter->stats.messageSend_Attempted++; if (nextLinkToWrite >= parcArrayList_Size(athenaTransportLinkAdapter->instanceList)) { athenaTransportLinkAdapter->stats.messageSend_LinkDoesNotExist++; nextLinkToWrite++; continue; } AthenaTransportLink *athenaTransportLink = parcArrayList_Get(athenaTransportLinkAdapter->instanceList, nextLinkToWrite); if (athenaTransportLink == NULL) { athenaTransportLinkAdapter->stats.messageSend_LinkDoesNotExist++; nextLinkToWrite++; continue; } if (!(athenaTransportLink_GetEvent(athenaTransportLink) & AthenaTransportLinkEvent_Send)) { athenaTransportLinkAdapter->stats.messageSend_LinkNotAcceptingSendRequests++; nextLinkToWrite++; continue; } // If we're sending an interest to a non-local link, // check that it has a sufficient hoplimit. if (ccnxMetaMessage_IsInterest(ccnxMetaMessage)) { if (athenaTransportLink_IsNotLocal(athenaTransportLink)) { if (ccnxInterest_GetHopLimit(ccnxMetaMessage) == 0) { athenaTransportLinkAdapter->stats.messageSend_HopLimitExceeded++; nextLinkToWrite++; continue; } } } int result = athenaTransportLink_Send(athenaTransportLink, ccnxMetaMessage); if (result == 0) { athenaTransportLinkAdapter->stats.messageSent++; parcBitVector_Set(resultVector, nextLinkToWrite); } else { athenaTransportLinkAdapter->stats.messageSend_LinkSendFailed++; } nextLinkToWrite++; } return resultVector; }
bool athenaTransportLinkAdapter_IsNotLocal(AthenaTransportLinkAdapter *athenaTransportLinkAdapter, int linkId) { if (athenaTransportLinkAdapter->instanceList == NULL) { return false; } if ((linkId >= 0) && (linkId < parcArrayList_Size(athenaTransportLinkAdapter->instanceList))) { AthenaTransportLink *athenaTransportLink = parcArrayList_Get(athenaTransportLinkAdapter->instanceList, linkId); if (athenaTransportLink) { return athenaTransportLink_IsNotLocal(athenaTransportLink); } } return false; }
static AthenaTransportLink * _newLink(AthenaTransportLink *athenaTransportLink, _UDPLinkData *newLinkData) { // Accept a new tunnel connection. // Clone a new link from the current listener. const char *derivedLinkName = _createNameFromLinkData(&newLinkData->link); AthenaTransportLink *newTransportLink = athenaTransportLink_Clone(athenaTransportLink, derivedLinkName, _UDPSend, _UDPReceiveProxy, _UDPClose); if (newTransportLink == NULL) { parcLog_Error(athenaTransportLink_GetLogger(athenaTransportLink), "athenaTransportLink_Clone failed"); parcMemory_Deallocate(&derivedLinkName); _UDPLinkData_Destroy(&newLinkData); return NULL; } _setConnectLinkState(newTransportLink, newLinkData); // Send the new link up to be added. int result = athenaTransportLink_AddLink(athenaTransportLink, newTransportLink); if (result == -1) { parcLog_Error(athenaTransportLink_GetLogger(athenaTransportLink), "athenaTransportLink_AddLink failed: %s", strerror(errno)); _UDPLinkData_Destroy(&newLinkData); athenaTransportLink_Release(&newTransportLink); } else { parcLog_Info(athenaTransportLink_GetLogger(athenaTransportLink), "new link accepted by %s: %s %s", athenaTransportLink_GetName(athenaTransportLink), derivedLinkName, athenaTransportLink_IsNotLocal(athenaTransportLink) ? "" : "(Local)"); } parcMemory_Deallocate(&derivedLinkName); // Could pass a message back here regarding the new link. return newTransportLink; }
static CCNxMetaMessage * _create_linkList_response(AthenaTransportLinkAdapter *athenaTransportLinkAdapter, CCNxName *ccnxName) { PARCJSONArray *jsonLinkList = parcJSONArray_Create(); for (int index = 0; index < parcArrayList_Size(athenaTransportLinkAdapter->listenerList); index++) { AthenaTransportLink *athenaTransportLink = parcArrayList_Get(athenaTransportLinkAdapter->listenerList, index); const char *linkName = athenaTransportLink_GetName(athenaTransportLink); bool notLocal = athenaTransportLink_IsNotLocal(athenaTransportLink); bool localForced = athenaTransportLink_IsForceLocal(athenaTransportLink); PARCJSON *jsonItem = parcJSON_Create(); parcJSON_AddString(jsonItem, "linkName", linkName); parcJSON_AddInteger(jsonItem, "index", -1); parcJSON_AddBoolean(jsonItem, "notLocal", notLocal); parcJSON_AddBoolean(jsonItem, "localForced", localForced); PARCJSONValue *jsonItemValue = parcJSONValue_CreateFromJSON(jsonItem); parcJSON_Release(&jsonItem); parcJSONArray_AddValue(jsonLinkList, jsonItemValue); parcJSONValue_Release(&jsonItemValue); if (notLocal) { parcLog_Debug(athenaTransportLinkAdapter->log, "\n Link listener%s: %s", localForced ? " (forced remote)" : "", linkName); } else { parcLog_Debug(athenaTransportLinkAdapter->log, "\n Link listener%s: %s", localForced ? " (forced local)" : "", linkName); } } for (int index = 0; index < parcArrayList_Size(athenaTransportLinkAdapter->instanceList); index++) { AthenaTransportLink *athenaTransportLink = parcArrayList_Get(athenaTransportLinkAdapter->instanceList, index); if (athenaTransportLink) { const char *linkName = athenaTransportLink_GetName(athenaTransportLink); bool notLocal = athenaTransportLink_IsNotLocal(athenaTransportLink); bool localForced = athenaTransportLink_IsForceLocal(athenaTransportLink); PARCJSON *jsonItem = parcJSON_Create(); parcJSON_AddString(jsonItem, "linkName", linkName); parcJSON_AddInteger(jsonItem, "index", index); parcJSON_AddBoolean(jsonItem, "notLocal", notLocal); parcJSON_AddBoolean(jsonItem, "localForced", localForced); PARCJSONValue *jsonItemValue = parcJSONValue_CreateFromJSON(jsonItem); parcJSON_Release(&jsonItem); parcJSONArray_AddValue(jsonLinkList, jsonItemValue); parcJSONValue_Release(&jsonItemValue); if (notLocal) { parcLog_Debug(athenaTransportLinkAdapter->log, "\n Link instance [%d] %s: %s", index, localForced ? "(forced remote)" : "(remote)", linkName); } else { parcLog_Debug(athenaTransportLinkAdapter->log, "\n Link instance [%d] %s: %s", index, localForced ? "(forced local)" : "(local)", linkName); } } } char *jsonString = parcJSONArray_ToString(jsonLinkList); parcJSONArray_Release(&jsonLinkList); PARCBuffer *payload = parcBuffer_CreateFromArray(jsonString, strlen(jsonString)); CCNxContentObject *contentObject = ccnxContentObject_CreateWithDataPayload(ccnxName, parcBuffer_Flip(payload)); struct timeval tv; gettimeofday(&tv, NULL); uint64_t nowInMillis = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); ccnxContentObject_SetExpiryTime(contentObject, nowInMillis + 100); // this response is good for 100 millis CCNxMetaMessage *result = ccnxMetaMessage_CreateFromContentObject(contentObject); ccnxContentObject_Release(&contentObject); parcBuffer_Release(&payload); parcMemory_Deallocate(&jsonString); athena_EncodeMessage(result); return result; }