LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_HashProtectedRegion)
{
    //                         >1234<
    const char string[] = "Hello dev null\n";

    PARCBuffer *buffer = parcBuffer_Wrap((void *) string, sizeof(string), 0, sizeof(string));
    size_t start = 5;
    size_t length = 4;

    CCNxWireFormatMessage *message = ccnxWireFormatMessage_FromContentObjectPacketType(CCNxTlvDictionary_SchemaVersion_V1, buffer);

    ccnxWireFormatMessage_SetProtectedRegionStart(message, start);
    ccnxWireFormatMessage_SetProtectedRegionLength(message, length);

    PARCCryptoHasher *hasher = parcCryptoHasher_Create(PARCCryptoHashType_SHA256);
    PARCCryptoHash *hash = ccnxWireFormatMessage_HashProtectedRegion(message, hasher);

    // the correctness of the has is tested in _ccnxWireFormatFacadeV1_ComputeHash
    assertNotNull(hash, "Got null hash from a good packet");

    ccnxWireFormatMessage_Release(&message);
    parcCryptoHash_Release(&hash);
    parcBuffer_Release(&buffer);
    parcCryptoHasher_Release(&hasher);
}
LONGBOW_TEST_CASE(ContentObject, PayloadType)
{
    // The payload type is translated from the wire format value to the CCNxPayloadType value,
    // so this test cannot use the automated framework as the value in the dictionary will not
    // be the same as the value in the wire format

    TestData *data = longBowTestCase_GetClipBoardData(testCase);

    bool decodeSuccess = ccnxCodecSchemaV1MessageDecoder_Decode(data->decoder, data->dictionary);
    assertTrue(decodeSuccess, "failure on ccnxCodecSchemaV1MessageDecoder_Decode");

    CCNxPayloadType testPayloadType = (CCNxPayloadType) _getPayloadType(data->dictionary);

    // look up the true name buffer from the truth table
    TlvExtent extent = getTruthTableExtent(data->truthTable, V1_MANIFEST_OBJ_PAYLOADTYPE);

    PARCBuffer
        *truthbuffer = parcBuffer_Wrap(data->packet, data->packetLength, extent.offset, extent.offset + extent.length);
    uint64_t truthvalue = -2;
    ccnxCodecTlvUtilities_GetVarInt(truthbuffer, parcBuffer_Remaining(truthbuffer), &truthvalue);

    CCNxPayloadType truthPayloadType = -1;
    bool success =
        _translateWirePayloadTypeToCCNxPayloadType((CCNxCodecSchemaV1Types_PayloadType) truthvalue, &truthPayloadType);
    assertTrue(success, "failure in _translateWirePayloadTypeToCCNxPayloadType for wireFormatValue %"
        PRId64, truthvalue);

    parcBuffer_Release(&truthbuffer);

    assertTrue(truthPayloadType == testPayloadType, "Wrong value, got %d expected %d", testPayloadType,
               truthPayloadType);
}
TestData *
testData_Create(void)
{
    char keyidString[] = "the keyid";
    char keyString[] = "Memory, all alone in the moonlight";
    char certString[] = "The quick brown fox";

    TestData *data = parcMemory_AllocateAndClear(sizeof(TestData));
    assertNotNull(data, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(TestData));

    data->keyid = bufferFromString(sizeof(keyidString), keyidString);
    data->key = bufferFromString(sizeof(keyString), keyString);
    data->cert = bufferFromString(sizeof(certString), certString);
    data->keyname = ccnxName_CreateFromURI("lci:/lazy/dog");

    PARCBuffer *bb_id = parcBuffer_Wrap("choo choo", 9, 0, 9);
    PARCKeyId *keyid = parcKeyId_Create(bb_id);
    parcBuffer_Release(&bb_id);

    PARCKey *key = parcKey_CreateFromDerEncodedPublicKey(keyid, PARCSigningAlgorithm_RSA, data->key);

    data->locatorByKey = ccnxKeyLocator_CreateFromKey(key);
    parcKey_Release(&key);
    parcKeyId_Release(&keyid);

    CCNxLink *link = ccnxLink_Create(data->keyname, NULL, NULL);
    data->locatorByName = ccnxKeyLocator_CreateFromKeyLink(link);
    ccnxLink_Release(&link);

    return data;
}
LONGBOW_TEST_CASE(Dictionary, component_Codec_Tlv_Upcall_Read_Control)
{
    TestData *data = longBowTestCase_GetClipBoardData(testCase);

    PARCBuffer *wireFormat = parcBuffer_Wrap(v1_cpi_add_route_crc32c, sizeof(v1_cpi_add_route_crc32c),
                                             0, sizeof(v1_cpi_add_route_crc32c));
    CCNxTlvDictionary *dictionary = ccnxWireFormatMessage_FromControlPacketType(CCNxTlvDictionary_SchemaVersion_V1, wireFormat);
    parcBuffer_Release(&wireFormat);
    
    // We have not set the message type or schema
    TransportMessage *tm = transportMessage_CreateFromDictionary(dictionary);
    transportMessage_SetInfo(tm, data->mock->connection, NULL);
    ccnxTlvDictionary_Release(&dictionary);

    // ------
    // Now do the actual test of sending the transport message up the stack

    TransportMessage *test_tm = sendUp(data, tm);

    // It should now be parsed into an control message
    CCNxTlvDictionary *testdict = transportMessage_GetDictionary(test_tm);
    assertNotNull(testdict, "Failed to get dictionary from the transport message");

    assertTrue(ccnxTlvDictionary_IsControl(testdict), "Dictionary says it is not a Control");
    assertTrue(ccnxTlvDictionary_GetSchemaVersion(testdict) == CCNxTlvDictionary_SchemaVersion_V1,
               "Wrong schema, got %d expected %d",
               ccnxTlvDictionary_GetSchemaVersion(testdict), CCNxTlvDictionary_SchemaVersion_V1);

    transportMessage_Destroy(&tm);
}
LONGBOW_TEST_CASE(Global, ccnxTlvCodecName_Encode)
{
    uint8_t truthBytes[] = { 0x10, 0x20, 0x00, 0x0E, 0x00, CCNxNameLabelType_NAME, 0x00, 0x0A, 'b', 'r', 'a', 'n', 'd', 'y', 'w', 'i', 'n', 'e' };
    PARCBuffer *truth = parcBuffer_Wrap(truthBytes, sizeof(truthBytes), 0, sizeof(truthBytes));

    CCNxCodecTlvEncoder *encoder = ccnxCodecTlvEncoder_Create();
    ccnxCodecTlvEncoder_Initialize(encoder);

    PARCBuffer *buffer = parcBuffer_WrapCString("brandywine");
    CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buffer);

    CCNxName *name = ccnxName_Append(ccnxName_Create(), segment);
    ccnxNameSegment_Release(&segment);
    parcBuffer_Release(&buffer);

    ccnxCodecSchemaV1NameCodec_Encode(encoder, 0x1020, name);

    ccnxCodecTlvEncoder_Finalize(encoder);
    PARCBuffer *test = ccnxCodecTlvEncoder_CreateBuffer(encoder);

    if (!parcBuffer_Equals(truth, test)) {
        printf("Buffers do not match\n");
        printf("Excpected:\n");
        parcBuffer_Display(truth, 3);
        printf("Got:\n");
        parcBuffer_Display(test, 3);
        assertTrue(parcBuffer_Equals(truth, test), "Buffers do not match");
    }

    ccnxName_Release(&name);
    parcBuffer_Release(&test);
    ccnxCodecTlvEncoder_Destroy(&encoder);
    parcBuffer_Release(&truth);
}
LONGBOW_TEST_CASE(Static, _ccnxWireFormatMessage_CreateWithImpl)
{
    PARCBuffer *wireFormatV1 = parcBuffer_Wrap(v1_interest_nameA, sizeof(v1_interest_nameA), 0, sizeof(v1_interest_nameA));

    CCNxWireFormatMessage *message = _ccnxWireFormatMessage_CreateWithImpl(&CCNxWireFormatFacadeV1_Implementation, wireFormatV1);
    assertNotNull(message, "Expected to create a V1 CCNxWireFormatMessage");

    ccnxWireFormatMessage_Release(&message);
    parcBuffer_Release(&wireFormatV1);
}
LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_Create)
{
    PARCBuffer *wireFormat = parcBuffer_Wrap(v1_interest_nameA, sizeof(v1_interest_nameA), 0, sizeof(v1_interest_nameA));

    CCNxWireFormatMessage *message = ccnxWireFormatMessage_Create(wireFormat);
    assertNotNull(message, "Got null CCNxWireFormatMessage, after attempting to create with buffer");

    ccnxWireFormatMessage_Release(&message);
    parcBuffer_Release(&wireFormat);
}
LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_WriteToFile)
{
    const char string[] = "Hello dev null\n";
    PARCBuffer *buffer = parcBuffer_Wrap((void *) string, sizeof(string), 0, sizeof(string));
    CCNxWireFormatMessage *message = ccnxWireFormatMessage_FromInterestPacketType(CCNxTlvDictionary_SchemaVersion_V1, buffer);

    ccnxWireFormatMessage_WriteToFile(message, "/dev/null");

    ccnxWireFormatMessage_Release(&message);
    parcBuffer_Release(&buffer);
}
LONGBOW_TEST_CASE(Global, ccnxTlvCodecName_Decode_WrongType)
{
    uint8_t decodeBytes[] = { 0x10, 0x20, 0x00, 0x0E, 0x00, CCNxNameLabelType_NAME, 0x00, 0x0A, 'b', 'r', 'a', 'n', 'd', 'y', 'w', 'i', 'n', 'e' };
    PARCBuffer *decodeBuffer = parcBuffer_Wrap(decodeBytes, sizeof(decodeBytes), 0, sizeof(decodeBytes));
    CCNxCodecTlvDecoder *decoder = ccnxCodecTlvDecoder_Create(decodeBuffer);
    CCNxName *test = ccnxCodecSchemaV1NameCodec_Decode(decoder, 0xFFFF);

    assertNull(test, "Name should have returned NULL because the name type does not match");
    assertTrue(ccnxCodecTlvDecoder_Position(decoder) == 0, "Position should not have moved, expected 0, got %zu", ccnxCodecTlvDecoder_Position(decoder));

    ccnxCodecTlvDecoder_Destroy(&decoder);
    parcBuffer_Release(&decodeBuffer);
}
LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_SetProtectedRegionStart)
{
    const char string[] = "Hello dev null\n";
    PARCBuffer *buffer = parcBuffer_Wrap((void *) string, sizeof(string), 0, sizeof(string));

    CCNxWireFormatMessage *message = ccnxWireFormatMessage_FromContentObjectPacketType(CCNxTlvDictionary_SchemaVersion_V1, buffer);

    size_t start = 5;
    bool success = ccnxWireFormatMessage_SetProtectedRegionStart(message, start);
    assertTrue(success, "Failed to put integer in to dictionary");

    assertTrue(ccnxTlvDictionary_IsValueInteger(message, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_ProtectedStart), "ProtectedStart not set");

    ccnxWireFormatMessage_Release(&message);
    parcBuffer_Release(&buffer);
}
Exemple #11
0
LONGBOW_TEST_CASE(Global, metisMessage_CreateFromElasticBuffer)
{
    char message_str[] = "\0x00Once upon a time, in a stack far away, a dangling pointer found its way to the top of the heap.";

    PARCBuffer *buff = parcBuffer_Wrap(message_str, sizeof(message_str), 0, sizeof(message_str));

    PARCLogReporter *reporter = parcLogReporterTextStdout_Create();
    MetisLogger *logger = metisLogger_Create(reporter, parcClock_Wallclock());
    parcLogReporter_Release(&reporter);
    MetisMessage *message = metisMessage_CreateFromParcBuffer(buff, 1, 2, logger);
    metisLogger_Release(&logger);

    assertNotNull(message, "Got null from metisMessage_CreateFromBuffer");
    assertTrue(message->ingressConnectionId == 1, "IngressConnectionId wrong, expected %d got %u", 1, message->ingressConnectionId);
    assertTrue(message->receiveTime == 2, "receiveTime wrong, expected %u got %" PRIu64, 2, message->receiveTime);

    metisMessage_Release(&message);
    parcBuffer_Release(&buff);
}
LONGBOW_TEST_CASE(Global, ccnxTlvCodecName_Decode_RightType)
{
    PARCBuffer *buffer = parcBuffer_WrapCString("brandywine");
    CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buffer);
    CCNxName *truth = ccnxName_Append(ccnxName_Create(), segment);
    ccnxNameSegment_Release(&segment);
    parcBuffer_Release(&buffer);

    uint8_t decodeBytes[] = { 0x10, 0x20, 0x00, 0x0E, 0x00, CCNxNameLabelType_NAME, 0x00, 0x0A, 'b', 'r', 'a', 'n', 'd', 'y', 'w', 'i', 'n', 'e' };
    PARCBuffer *decodeBuffer = parcBuffer_Wrap(decodeBytes, sizeof(decodeBytes), 0, sizeof(decodeBytes));
    CCNxCodecTlvDecoder *decoder = ccnxCodecTlvDecoder_Create(decodeBuffer);
    CCNxName *test = ccnxCodecSchemaV1NameCodec_Decode(decoder, 0x1020);

    assertTrue(ccnxName_Equals(truth, test), "Name segments do not match");

    ccnxName_Release(&test);
    ccnxCodecTlvDecoder_Destroy(&decoder);
    parcBuffer_Release(&decodeBuffer);
    ccnxName_Release(&truth);
}
LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_CreateContentObjectHash)
{
    //                         >1234<
    const char string[] = "Hello dev null\n";

    PARCBuffer *buffer = parcBuffer_Wrap((void *) string, sizeof(string), 0, sizeof(string));

    CCNxWireFormatMessage *message = ccnxWireFormatMessage_FromContentObjectPacketType(CCNxTlvDictionary_SchemaVersion_V1, buffer);

    PARCCryptoHash *hash = ccnxWireFormatMessage_CreateContentObjectHash(message);
    ccnxWireFormatMessage_Release(&message);
    assertNull(hash, "Expect NULL for hash as it hasn't been encoded yet");

    // We need to create a content object that is hashable
    CCNxName *name = ccnxName_CreateFromCString("lci:/test/content");
    CCNxContentObject *contentObject = ccnxContentObject_CreateWithNameAndPayload(name, buffer);
    ccnxName_Release(&name);

    // This next stuff is to force an encode/decode to setup hash extents
    CCNxCodecNetworkBufferIoVec *iovec = ccnxCodecTlvPacket_DictionaryEncode(contentObject, NULL);
    ccnxContentObject_Release(&contentObject);
    PARCBuffer *encodedMessage = _iovecToParcBuffer(iovec);
    ccnxCodecNetworkBufferIoVec_Release(&iovec);
    // Decode
    message = ccnxWireFormatMessage_Create(encodedMessage);
    CCNxTlvDictionary *dictionary = ccnxWireFormatMessage_GetDictionary(message);
    bool success = ccnxCodecTlvPacket_BufferDecode(encodedMessage, dictionary);
    assertTrue(success, "Failed to decode buffer");
    parcBuffer_Release(&encodedMessage);

    hash = ccnxWireFormatMessage_CreateContentObjectHash(message);

    // the correctness of the hash is tested in _ccnxWireFormatFacadeV1_ComputeHash
    assertNotNull(hash, "Got null hash from a good packet");

    ccnxWireFormatMessage_Release(&message);
    parcCryptoHash_Release(&hash);
    parcBuffer_Release(&buffer);
}
PARCBuffer *
athenaTransportLinkModule_CreateMessageBuffer(CCNxMetaMessage *message)
{
    PARCBuffer *buffer = ccnxWireFormatMessage_GetWireFormatBuffer(message);

    // If there is no PARCBuffer present, check for an IO vector and convert that into a contiguous buffer.
    if (buffer == NULL) {
        CCNxCodecNetworkBufferIoVec *iovec = ccnxWireFormatMessage_GetIoVec(message);
        if (iovec == NULL) { // if there's no iovec or buffer, encode the message and return the iovec
            athena_EncodeMessage(message);
            iovec = ccnxWireFormatMessage_GetIoVec(message);
        }
        assertNotNull(iovec, "Null io vector");
        size_t iovcnt = ccnxCodecNetworkBufferIoVec_GetCount((CCNxCodecNetworkBufferIoVec *) iovec);
        const struct iovec *array = ccnxCodecNetworkBufferIoVec_GetArray((CCNxCodecNetworkBufferIoVec *) iovec);

        // If it's a single vector wrap it in a buffer to avoid a copy
        if (iovcnt == 1) {
            buffer = parcBuffer_Wrap(array[0].iov_base, array[0].iov_len, 0, array[0].iov_len);
        } else {
            size_t totalbytes = 0;
            for (int i = 0; i < iovcnt; i++) {
                totalbytes += array[i].iov_len;
            }
            buffer = parcBuffer_Allocate(totalbytes);
            for (int i = 0; i < iovcnt; i++) {
                parcBuffer_PutArray(buffer, array[i].iov_len, array[i].iov_base);
            }
            parcBuffer_Flip(buffer);
        }
    } else {
        buffer = parcBuffer_Acquire(buffer);
    }

    return buffer;
}
Exemple #15
0
PARCBuffer *
parcBuffer_WrapCString(char *string)
{
    size_t length = strlen(string);
    return parcBuffer_Wrap(string, length, 0, length);
}
static int
_UDPSend(AthenaTransportLink *athenaTransportLink, CCNxMetaMessage *ccnxMetaMessage)
{
    struct _UDPLinkData *linkData = athenaTransportLink_GetPrivateData(athenaTransportLink);

    if (ccnxTlvDictionary_GetSchemaVersion(ccnxMetaMessage) == CCNxTlvDictionary_SchemaVersion_V0) {
        parcLog_Debug(athenaTransportLink_GetLogger(athenaTransportLink),
                      "sending deprecated version %d message\n", ccnxTlvDictionary_GetSchemaVersion(ccnxMetaMessage));
    }

    // Get a wire format buffer and write it out.
    PARCBuffer *wireFormatBuffer = ccnxWireFormatMessage_GetWireFormatBuffer(ccnxMetaMessage);

    if (wireFormatBuffer == NULL) {
        CCNxCodecNetworkBufferIoVec *iovec = ccnxWireFormatMessage_GetIoVec(ccnxMetaMessage);
        assertNotNull(iovec, "Null io vector");

        size_t iovcnt = ccnxCodecNetworkBufferIoVec_GetCount((CCNxCodecNetworkBufferIoVec *) iovec);
        const struct iovec *array = ccnxCodecNetworkBufferIoVec_GetArray((CCNxCodecNetworkBufferIoVec *) iovec);

        // If it's a single vector wrap it in a buffer to avoid a copy
        if (iovcnt == 1) {
            wireFormatBuffer = parcBuffer_Wrap(array[0].iov_base, array[0].iov_len, 0, array[0].iov_len);
        } else {
            size_t totalbytes = 0;
            for (int i = 0; i < iovcnt; i++) {
                totalbytes += array[i].iov_len;
            }
            wireFormatBuffer = parcBuffer_Allocate(totalbytes);
            for (int i = 0; i < iovcnt; i++) {
                parcBuffer_PutArray(wireFormatBuffer, array[i].iov_len, array[i].iov_base);
            }
            parcBuffer_Flip(wireFormatBuffer);
        }
    } else {
        wireFormatBuffer = parcBuffer_Acquire(wireFormatBuffer);
    }

    size_t length = parcBuffer_Limit(wireFormatBuffer);
    char *buffer = parcBuffer_Overlay(wireFormatBuffer, length);

    if (linkData->link.mtu) {
        if (length > linkData->link.mtu) {
            errno = EMSGSIZE;
            parcBuffer_Release(&wireFormatBuffer);
            return -1;
        }
    }

    parcLog_Debug(athenaTransportLink_GetLogger(athenaTransportLink),
                  "sending message (size=%d)", length);

    ssize_t writeCount = 0;
#ifdef LINUX_IGNORESIGPIPE
    writeCount = sendto(linkData->fd, buffer, length, MSG_NOSIGNAL,
                        (struct sockaddr *) &linkData->link.peerAddress, linkData->link.peerAddressLength);
#else
    writeCount = sendto(linkData->fd, buffer, length, 0,
                        (struct sockaddr *) &linkData->link.peerAddress, linkData->link.peerAddressLength);
#endif

    // on error close the link, else return to retry a zero write
    if (writeCount == -1) {
        if (errno == EPIPE) {
            athenaTransportLink_SetEvent(athenaTransportLink, AthenaTransportLinkEvent_Error);
        }
        parcLog_Error(athenaTransportLink_GetLogger(athenaTransportLink),
                      "send error (%s)", strerror(errno));
        parcBuffer_Release(&wireFormatBuffer);
        return -1;
    }

    // Short write
    if (writeCount != length) {
        linkData->_stats.receive_ShortWrite++;
        parcLog_Debug(athenaTransportLink_GetLogger(athenaTransportLink), "short write");
        parcBuffer_Release(&wireFormatBuffer);
        return -1;
    }

    parcBuffer_Release(&wireFormatBuffer);
    return 0;
}