Beispiel #1
0
void
metisConfiguration_Receive(MetisConfiguration *config, MetisMessage *message)
{
    assertNotNull(config, "Parameter config must be non-null");
    assertNotNull(message, "Parameter message must be non-null");
    assertTrue(metisMessage_GetType(message) == MetisMessagePacketType_Control,
               "Message must be type CPI, expected %02x got %02x",
               MetisMessagePacketType_Control, metisMessage_GetType(message));

    CCNxControl *control = metisMessage_CreateControlMessage(message);
    unsigned ingressId = metisMessage_GetIngressConnectionId(message);

    if (metisLogger_IsLoggable(config->logger, MetisLoggerFacility_Config, PARCLogLevel_Debug)) {
        char *str = parcJSON_ToCompactString(ccnxControl_GetJson(control));
        metisLogger_Log(config->logger, MetisLoggerFacility_Config, PARCLogLevel_Debug, __func__,
                        "%s received %s\n", __func__, str);
        parcMemory_Deallocate((void **) &str);
    }

    CCNxControl *response = _processControl(config, control, ingressId);
    metisConfiguration_SendResponse(config, response, ingressId);
    ccnxControl_Release(&response);

    ccnxControl_Release(&control);
    metisMessage_Release(&message);
}
Beispiel #2
0
LONGBOW_TEST_CASE(Global, athena_ProcessControl_CPI_REGISTER_PREFIX)
{
    PARCURI *connectionURI;
    Athena *athena = athena_Create(100);

    CCNxName *name = ccnxName_CreateFromCString("ccnx:/foo/bar");
    CCNxControl *control = ccnxControl_CreateAddRouteToSelfRequest(name); // CPI_REGISTER_PREFIX
    CCNxMetaMessage *registerPrefixCommand = ccnxMetaMessage_CreateFromControl(control);
    ccnxControl_Release(&control);

    control = ccnxControl_CreateRemoveRouteToSelfRequest(name); // CPI_UNREGISTER_PREFIX
    CCNxMetaMessage *unregisterPrefixCommand = ccnxMetaMessage_CreateFromControl(control);
    ccnxControl_Release(&control);
    ccnxName_Release(&name);

    connectionURI = parcURI_Parse("tcp://localhost:50100/listener/name=TCPListener");
    const char *result = athenaTransportLinkAdapter_Open(athena->athenaTransportLinkAdapter, connectionURI);
    assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno));
    parcURI_Release(&connectionURI);

    connectionURI = parcURI_Parse("tcp://localhost:50100/name=TCP_0");
    result = athenaTransportLinkAdapter_Open(athena->athenaTransportLinkAdapter, connectionURI);
    assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno));
    parcURI_Release(&connectionURI);

    int linkId = athenaTransportLinkAdapter_LinkNameToId(athena->athenaTransportLinkAdapter, "TCP_0");
    PARCBitVector *ingressVector = parcBitVector_Create();
    parcBitVector_Set(ingressVector, linkId);

    // Call _Receive() once to prime the link. Messages are dropped until _Receive() is called once.
    PARCBitVector *linksRead = NULL;
    CCNxMetaMessage *msg = athenaTransportLinkAdapter_Receive(athena->athenaTransportLinkAdapter, &linksRead, -1);
    assertNull(msg, "Expected to NOT receive a message after the first call to _Receive()");

    CCNxMetaMessage *cpiMessages[2];
    cpiMessages[0] = registerPrefixCommand;    // CPI_REGISTER_PREFIX
    cpiMessages[1] = unregisterPrefixCommand;  // CPI_UNREGISTER_PREFIX

    for (int i = 0; i < 2; i++) {
        CCNxMetaMessage *cpiMessageToSend = cpiMessages[i];
        athena_ProcessMessage(athena, cpiMessageToSend, ingressVector);
        ccnxMetaMessage_Release(&cpiMessageToSend);

        CCNxMetaMessage *ack = athenaTransportLinkAdapter_Receive(athena->athenaTransportLinkAdapter, &linksRead, -1);
        assertNotNull(ack, "Expected a CPI_ACK message back");
        assertTrue(ccnxMetaMessage_IsControl(ack), "Expected a control message back");
        parcBitVector_Release(&linksRead);

        PARCJSON *json = ccnxControl_GetJson(ack);
        const PARCJSONValue *cpiAckResult = parcJSON_GetByPath(json, "CPI_ACK/REQUEST/RESULT");
        bool commandResult = parcJSONValue_GetBoolean(cpiAckResult);
        assertTrue(commandResult, "Expected the ACK to contain RESULT=true");

        ccnxMetaMessage_Release(&ack);
    }

    parcBitVector_Release(&ingressVector);
    athena_Release(&athena);
}
Beispiel #3
0
static bool
_ccnxPortalRTA_Ignore(void *privateData, const CCNxName *name, const CCNxStackTimeout *microSeconds)
{
    CCNxControl *control = ccnxControl_CreateRemoveRouteToSelfRequest(name);

    CCNxMetaMessage *message = ccnxMetaMessage_CreateFromControl(control);
    ccnxControl_Release(&control);

    bool result = _ccnxPortalRTA_Send(privateData, message, CCNxStackTimeout_Never);

    // There is a problem here if the client invokes this function on a portal that is already receiving messages.
    // This simply absorbs messages until the receipt of the acknowledgement of this listen.
    // Perhaps what should happen is not read any messages and let the client sort it out in its read loop.
    if (result == true) {
        CCNxMetaMessage *response = _ccnxPortalRTA_Receive(privateData, microSeconds);

        if (response != NULL) {
            if (ccnxMetaMessage_IsControl(response)) {
                // TODO: Check that the response was success.
                result = true;
            }
            ccnxMetaMessage_Release(&response);
        } else {
            // We got a NULL reponse (possibly due to timeout). Since we always expect a
            // response from the forwarder, consider this a failure.
            result = false;
        }
    }

    ccnxMetaMessage_Release(&message);

    return result;
}
Beispiel #4
0
/**
 * Called by the command parser for each command.
 *
 * The command parser will make a CCNxControl message inside the CCNxMetaMessage and send it here.
 * This function must return a ACK or NACK in a CCNxControl in a CCNxMetaMessage.
 *
 * @param [in] userdata A void * to MetisConfigurationFile
 * @param [in] msg The CCNxControl message to process
 *
 * @retval CCNxMetaMessage A CPI ACK or NACK in a CCNxControl in a CCNxMetaMessage
 *
 * Example:
 * @code
 * <#example#>
 * @endcode
 */
static CCNxMetaMessage *
_writeRead(void *userdata, CCNxMetaMessage *msgin)
{
    MetisConfigurationFile *configFile = (MetisConfigurationFile *) userdata;

    CCNxControl *request = ccnxMetaMessage_GetControl(msgin);
    CCNxControl *response = metisConfiguration_ReceiveControl(metisForwarder_GetConfiguration(configFile->metis), request, 0);

    CCNxMetaMessage *msgout = ccnxMetaMessage_CreateFromControl(response);
    ccnxControl_Release(&response);

    return msgout;
}
LONGBOW_TEST_CASE(Global, cpiCancelFlow_NameFromControlMessage)
{
    CCNxName *name = ccnxName_CreateFromURI("lci:/who/doesnt/like/pie");
    PARCJSON *cpiRequest = cpiCancelFlow_CreateRequest(name);
    CCNxControl *controlRequest = ccnxControl_CreateCPIRequest(cpiRequest);

    CCNxName *test_name = cpiCancelFlow_NameFromControlMessage(controlRequest);
    assertTrue(ccnxName_Equals(test_name, name),
               "Expected %s actual %s",
               ccnxName_ToString(name),
               ccnxName_ToString(test_name));

    ccnxName_Release(&test_name);
    ccnxControl_Release(&controlRequest);
    parcJSON_Release(&cpiRequest);
    ccnxName_Release(&name);
}
LONGBOW_TEST_CASE(Global, cpiCancelFlow_CreateRequest)
{
    const char truth_format[] = "{\"CPI_REQUEST\":{\"SEQUENCE\":%" PRIu64 ",\"CPI_CANCEL_FLOW\":{\"FLOW_NAME\":\"lci:/who/doesnt/like/pie\"}}}";

    CCNxName *name = ccnxName_CreateFromURI("lci:/who/doesnt/like/pie");
    PARCJSON *cpiRequest = cpiCancelFlow_CreateRequest(name);
    CCNxControl *controlRequest = ccnxControl_CreateCPIRequest(cpiRequest);

    PARCJSON *json = ccnxControl_GetJson(controlRequest);

    char buffer[1024];
    sprintf(buffer, truth_format, cpi_GetSequenceNumber(controlRequest));

    char *test_string = parcJSON_ToCompactString(json);
    assertTrue(strcmp(buffer, test_string) == 0, "Incorrect JSON, expected '%s' got '%s'", buffer, test_string);
    parcMemory_Deallocate((void **) &test_string);

    ccnxControl_Release(&controlRequest);
    parcJSON_Release(&cpiRequest);
    ccnxName_Release(&name);
}
static CCNxControl *
customWriteReadResponse(void *userdata, CCNxMetaMessage *messageToWrite)
{
    CPIConnectionList *connlist = cpiConnectionList_Create();
    CPIConnection *conn = cpiConnection_Create(1, cpiAddress_CreateFromInterface(1), cpiAddress_CreateFromInterface(2), cpiConnection_L2);
    cpiConnectionList_Append(connlist, conn);

    PARCJSON *connectionListAsJson = cpiConnectionList_ToJson(connlist);

    CCNxControl *inboundControlMessage = ccnxMetaMessage_GetControl(messageToWrite);

    // Create a response to the inbound Control message.
    CCNxControl *outboundControlMessage = cpi_CreateResponse(inboundControlMessage, connectionListAsJson);
    parcJSON_Release(&connectionListAsJson);

    ccnxControl_Release(&inboundControlMessage);

    cpiConnectionList_Destroy(&connlist);

    return outboundControlMessage;
}