LONGBOW_TEST_CASE(Object, parcRandomAccessFile_Read)
{
    char *fname = "tmpfile";

    PARCFile *file = parcFile_Create(fname);

    parcFile_CreateNewFile(file);
    FILE *fp = fopen(fname, "w");
    fseek(fp, 0, SEEK_SET);

    uint8_t data[128];
    for (int i = 0; i < 128; i++) {
        data[i] = i;
    }
    fwrite(data, 1, 128, fp);
    fclose(fp);

    PARCRandomAccessFile *instance = parcRandomAccessFile_Open(file);
    parcFile_Release(&file);

    PARCBuffer *buffer = parcBuffer_Allocate(128);
    size_t numBytes = parcRandomAccessFile_Read(instance, buffer);
    assertTrue(numBytes == 128, "Expected 128 bytes to be read, but got %zu", numBytes);

    parcBuffer_Flip(buffer);
    uint8_t *bytes = parcBuffer_Overlay(buffer, parcBuffer_Remaining(buffer));
    assertTrue(memcmp(data, bytes, 128) == 0, "Expected buffers to be equal");

    parcBuffer_Release(&buffer);
    parcRandomAccessFile_Close(instance);
    parcRandomAccessFile_Release(&instance);
}
LONGBOW_TEST_CASE(Global, parc_Chunker_ReverseIterator_Buffer)
{
    PARCBuffer *buffer = parcBuffer_Allocate(1024);

    for (size_t i = 0; i < 32; i++) {
        for (size_t j = 0; j < 32; j++) {
            parcBuffer_PutUint8(buffer, i);
        }
    }
    parcBuffer_Flip(buffer);

    PARCBufferChunker *chunker = parcBufferChunker_Create(buffer, 32); // each chunk is 32 bytes
    assertNotNull(chunker, "Expected non-NULL Chunker");

    PARCIterator *itr = parcBufferChunker_ReverseIterator(chunker);
    size_t count = 0;
    while (parcIterator_HasNext(itr)) {
        PARCBuffer *payload = (PARCBuffer *) parcIterator_Next(itr);

        uint8_t *contents = parcBuffer_Overlay(payload, 0);
        for (size_t i = 0; i < 32; i++) {
            assertTrue(contents[i] == (31 - count), "Expected %zu at index %zu, got %d", (31 - count), i, contents[i]);
        }
        count++;

        parcBuffer_Release(&payload);
    }
    assertTrue(count == 32, "Expected to iterate over 32 content objects from the chunker, but for %zu", count);
    parcIterator_Release(&itr);

    parcBufferChunker_Release(&chunker);
    parcBuffer_Release(&buffer);
}
LONGBOW_TEST_CASE(Global, parc_Chunker_ReverseIterator_BufferSmall)
{
    PARCBuffer *buffer = parcBuffer_Allocate(16);

    // Special 0xFF to mark the start
    for (int i = 0; i < 16; i++) {
        parcBuffer_PutUint8(buffer, 0xFF);
    }
    parcBuffer_Flip(buffer);

    PARCBufferChunker *chunker = parcBufferChunker_Create(buffer, 32); // each chunk is 32 bytes
    assertNotNull(chunker, "Expected non-NULL Chunker");

    PARCIterator *itr = parcBufferChunker_ReverseIterator(chunker);
    size_t count = 0;
    while (parcIterator_HasNext(itr)) {
        PARCBuffer *payload = (PARCBuffer *) parcIterator_Next(itr);

        uint8_t *contents = parcBuffer_Overlay(payload, 0);
        for (size_t i = 0; i < 16; i++) {
            assertTrue(contents[i] == 0xFF, "Expected %zu at index %zu, got %d", (size_t) 0xFF, i, contents[i]);
        }
        count++;

        parcBuffer_Release(&payload);
    }
    assertTrue(count == 1, "Expected to iterate over 1 content objects from the chunker, but for %zu", count);
    parcIterator_Release(&itr);

    parcBufferChunker_Release(&chunker);
    parcBuffer_Release(&buffer);
}
示例#4
0
LONGBOW_TEST_CASE(JSON, parcJSON_AddValue)
{
    PARCJSON *json = parcJSON_Create();

    char *expectedName = "value";

    PARCJSONValue *value = parcJSONValue_CreateFromCString("Some Pig");

    parcJSON_AddValue(json, expectedName, value);

    const PARCJSONPair *pair = parcJSON_GetPairByName(json, expectedName);

    PARCBuffer *actualName = parcJSONPair_GetName(pair);
    PARCJSONValue *actualValue = parcJSONPair_GetValue(pair);
    assertTrue(strcmp(expectedName, parcBuffer_Overlay(actualName, 0)) == 0,
               "Expected name %s, actual %s", expectedName, (char *) parcBuffer_ToString(actualName));
    assertTrue(parcJSONValue_IsString(actualValue), "Expect value to be type PARCJSONArray");
    assertTrue(parcBuffer_Equals(parcJSONValue_GetString(actualValue), parcJSONValue_GetString(value)),
               "Expected %s actual %s",
               parcJSONValue_ToString(value),
               parcJSONValue_ToString(actualValue));

    parcJSONValue_Release(&value);

    parcJSON_Release(&json);
}
示例#5
0
PARCBuffer *
athenaEthernet_Receive(AthenaEthernet *athenaEthernet, int timeout, AthenaTransportLinkEvent *events)
{
    // Allocate, and read, a new BPF buffer if no packets are currently pending in an old one
    if (athenaEthernet->bpfBuffer == NULL) {
        athenaEthernet->bpfBuffer = parcBuffer_Allocate(athenaEthernet->etherBufferLength);
        uint8_t *buffer = parcBuffer_Overlay(athenaEthernet->bpfBuffer, 0);

        athenaEthernet->readCount = read(athenaEthernet->fd, buffer, athenaEthernet->etherBufferLength);
        if (athenaEthernet->readCount == -1) {
            if ((errno == EAGAIN) || (errno == EINTR)) {
                parcLog_Info(athenaEthernet->log, "Ethernet read retry");
                return NULL;
            }
            parcLog_Error(athenaEthernet->log, "recv: %s", strerror(errno));
            *events = AthenaTransportLinkEvent_Error;
            parcBuffer_Release(&athenaEthernet->bpfBuffer);
            return NULL;
        }
        parcLog_Debug(athenaEthernet->log, "received bpf packet (size=%d)", athenaEthernet->readCount);
    }

    // Obtain the current position in the BPF buffer to return a message from
    size_t position = parcBuffer_Position(athenaEthernet->bpfBuffer);

    // Read the BPF header and seek past it
    struct bpf_hdr *bpfhdr = parcBuffer_Overlay(athenaEthernet->bpfBuffer, sizeof(struct bpf_hdr));
    parcBuffer_SetLimit(athenaEthernet->bpfBuffer, position + bpfhdr->bh_hdrlen + bpfhdr->bh_datalen);
    parcBuffer_SetPosition(athenaEthernet->bpfBuffer, position + bpfhdr->bh_hdrlen);
    parcLog_Debug(athenaEthernet->log, "received message (size=%d)", bpfhdr->bh_datalen);

    // Slice a new PARCBuffer with the message to send up.
    PARCBuffer *wireFormatBuffer = parcBuffer_Slice(athenaEthernet->bpfBuffer);

    // If there's another packet in the buffer, position it and flag a receive event
    if ((athenaEthernet->readCount - (position + bpfhdr->bh_hdrlen + bpfhdr->bh_datalen)) != 0) {
        parcBuffer_SetLimit(athenaEthernet->bpfBuffer, athenaEthernet->readCount);
        parcBuffer_SetPosition(athenaEthernet->bpfBuffer,
                               BPF_WORDALIGN(position + bpfhdr->bh_hdrlen + bpfhdr->bh_datalen));
        // Mark a receive event for this packet
        *events = AthenaTransportLinkEvent_Receive;
    } else {
        parcBuffer_Release(&athenaEthernet->bpfBuffer);
    }

    return wireFormatBuffer;
}
示例#6
0
static PARCSignature *
_SignDigest(PARCPublicKeySigner *signer, const PARCCryptoHash *digestToSign)
{
    parcSecurity_AssertIsInitialized();

    assertNotNull(signer, "Parameter must be non-null CCNxFileKeystore");
    assertNotNull(digestToSign, "Buffer to sign must not be null");

    // TODO: what is the best way to expose this?
    PARCKeyStore *keyStore = signer->keyStore;
    PARCBuffer *privateKeyBuffer = parcKeyStore_GetDEREncodedPrivateKey(keyStore);
    EVP_PKEY *privateKey = NULL;
    size_t keySize = parcBuffer_Remaining(privateKeyBuffer);
    uint8_t *bytes = parcBuffer_Overlay(privateKeyBuffer, keySize);
    privateKey = d2i_PrivateKey(EVP_PKEY_RSA, &privateKey, (const unsigned char **) &bytes, keySize);
    parcBuffer_Release(&privateKeyBuffer);

    RSA *rsa = EVP_PKEY_get1_RSA(privateKey);

    int opensslDigestType;

    switch (parcCryptoHash_GetDigestType(digestToSign)) {
        case PARCCryptoHashType_SHA256:
            opensslDigestType = NID_sha256;
            break;
        case PARCCryptoHashType_SHA512:
            opensslDigestType = NID_sha512;
            break;
        default:
            trapUnexpectedState("Unknown digest type: %s",
                                parcCryptoHashType_ToString(parcCryptoHash_GetDigestType(digestToSign)));
    }

    uint8_t *sig = parcMemory_Allocate(RSA_size(rsa));
    assertNotNull(sig, "parcMemory_Allocate(%u) returned NULL", RSA_size(rsa));

    unsigned sigLength = 0;
    PARCBuffer *bb_digest = parcCryptoHash_GetDigest(digestToSign);
    int result = RSA_sign(opensslDigestType,
                          (unsigned char *) parcByteArray_Array(parcBuffer_Array(bb_digest)),
                          (int) parcBuffer_Remaining(bb_digest),
                          sig,
                          &sigLength,
                          rsa);
    assertTrue(result == 1, "Got error from RSA_sign: %d", result);
    RSA_free(rsa);

    PARCBuffer *bbSign = parcBuffer_Allocate(sigLength);
    parcBuffer_Flip(parcBuffer_PutArray(bbSign, sigLength, sig));
    parcMemory_Deallocate((void **) &sig);

    PARCSignature *signature =
    parcSignature_Create(_GetSigningAlgorithm(signer),
                         parcCryptoHash_GetDigestType(digestToSign),
                         bbSign
                         );
    parcBuffer_Release(&bbSign);
    return signature;
}
//
// Peek at the header and derive our total message length
//
static size_t
_messageLengthFromHeader(AthenaTransportLink *athenaTransportLink, _UDPLinkData *linkData)
{
    // Peek at our message header to determine the total length of buffer we need to allocate.
    size_t fixedHeaderLength = ccnxCodecTlvPacket_MinimalHeaderLength();
    PARCBuffer *wireFormatBuffer = parcBuffer_Allocate(fixedHeaderLength);
    const uint8_t *peekBuffer = parcBuffer_Overlay(wireFormatBuffer, 0);

    ssize_t readCount = recv(linkData->fd, (void *) peekBuffer, fixedHeaderLength, MSG_PEEK);

    if (readCount == -1) {
        parcBuffer_Release(&wireFormatBuffer);
        if ((errno == EAGAIN) || (errno == EINTR)) {
            parcLog_Debug(athenaTransportLink_GetLogger(athenaTransportLink), "recv retry (%s)", strerror(errno));
            linkData->_stats.receive_ReadRetry++;
        } else {
            linkData->_stats.receive_ReadError++;
            parcLog_Debug(athenaTransportLink_GetLogger(athenaTransportLink), "recv error (%s)", strerror(errno));
            athenaTransportLink_SetEvent(athenaTransportLink, AthenaTransportLinkEvent_Error);
        }
        return -1;
    }

    // A zero read means no data
    if (readCount == 0) {
        parcBuffer_Release(&wireFormatBuffer);
        return -1;
    }

    // Check for a short header read, since we're only peeking here we just return and retry later
    if (readCount != fixedHeaderLength) {
        linkData->_stats.receive_ReadHeaderFailure++;
        parcBuffer_Release(&wireFormatBuffer);
        return -1;
    }

    // Obtain the total size of the message from the header
    size_t messageLength = ccnxCodecTlvPacket_GetPacketLength(wireFormatBuffer);
    parcBuffer_Release(&wireFormatBuffer);

    // Could do more to check the integrity of the message and framing.
    // If length is greater than our MTU we will find out in the read.
    if (messageLength < fixedHeaderLength) {
        linkData->_stats.receive_BadMessageLength++;
        parcLog_Error(athenaTransportLink_GetLogger(athenaTransportLink), "Framing error, flushing link.");
        char trash[MAXPATHLEN];
        // Flush link to attempt to resync our framing
        while (read(linkData->fd, trash, sizeof(trash)) == sizeof(trash)) {
            parcLog_Error(athenaTransportLink_GetLogger(athenaTransportLink), "... flushing link.");
        }
        return -1;
    }

    return messageLength;
}
示例#8
0
PARCHashCode
parcBuffer_HashCode(const PARCBuffer *buffer)
{
    PARCHashCode result = 0;

    size_t remaining = parcBuffer_Remaining(buffer);
    if (remaining > 0) {
        result = parcHashCode_Hash(parcBuffer_Overlay((PARCBuffer *) buffer, 0), parcBuffer_Remaining(buffer));
    }
    return result;
}
示例#9
0
static void *
_ccnxChunker_NextFromBuffer(PARCBufferChunker *chunker, _ChunkerState *state)
{
    size_t chunkSize = state->nextChunkSize;

    parcBuffer_SetPosition(chunker->data, state->position);
    PARCBuffer *slice = parcBuffer_CreateFromArray(parcBuffer_Overlay(chunker->data, chunkSize), chunkSize);
    slice = parcBuffer_Flip(slice);

    _advanceState(chunker, state);

    return slice;
}
示例#10
0
int
parcBuffer_Compare(const PARCBuffer *x, const PARCBuffer *y)
{
    if (x == y) {
        return 0;
    }

    if (x == NULL) {
        return -1;
    }

    if (y == NULL) {
        return +1;
    }

    size_t count = parcBuffer_Remaining(x);
    if (count > parcBuffer_Remaining(y)) {
        count = parcBuffer_Remaining(y);
    }

    int result = 0;

    if (count > 0) {
        result = memcmp(parcBuffer_Overlay((PARCBuffer *) x, 0), parcBuffer_Overlay((PARCBuffer *) y, 0), count);
    }

    if (result == 0) {
        // This is when one buffer is longer than the other, and they are equivalent thus far.
        ssize_t difference = parcBuffer_Remaining(x) - parcBuffer_Remaining(y);
        if (difference > 0) {
            result = +1;
        } else if (difference < 0) {
            result = -1;
        }
    }

    return result;
}
示例#11
0
CCNxPortalAnchor *
ccnxPortalAnchor_CreateFromJSON(const PARCJSON *json)
{
    CCNxPortalAnchor *result = parcObject_CreateInstance(CCNxPortalAnchor);

    if (result != NULL) {
        result->prefix = ccnxName_CreateFromURI(parcBuffer_Overlay(parcJSONValue_GetString(parcJSON_GetByPath(json, "/namePrefix")), 0));
        result->expireTime = parcJSONValue_GetInteger(parcJSON_GetByPath(json, "/expireTime"));

       ccnxPortalAnchor_OptionalAssertValid(result);
    }

    return result;
}
/**
 * If successful, return true and fill in the parameters in the output argument
 */
bool
publicKeySignerPkcs12Store_GetConnectionParams(PARCJSON *connectionJson, struct publickeysigner_params *output)
{
    assertNotNull(connectionJson, "Parameter connectionJson must be non-null");
    assertNotNull(output, "Parameter output must be non-null");

    PARCJSONValue *value = parcJSON_GetValueByName(connectionJson, publicKeySignerPkcs12Store_GetName());
    assertNotNull(value, "JSON key %s missing", publicKeySignerPkcs12Store_GetName());
    PARCJSON *keystoreJson = parcJSONValue_GetJSON(value);

    value = parcJSON_GetValueByName(keystoreJson, param_KEYSTORE_NAME);
    assertNotNull(value, "JSON key %s missing inside %s", param_KEYSTORE_NAME, publicKeySignerPkcs12Store_GetName());
    PARCBuffer *sBuf = parcJSONValue_GetString(value);
    output->filename = parcBuffer_Overlay(sBuf, 0);

    value = parcJSON_GetValueByName(keystoreJson, param_KEYSTORE_PASSWD);
    assertNotNull(value, "JSON key %s missing inside %s", param_KEYSTORE_PASSWD, publicKeySignerPkcs12Store_GetName());
    sBuf = parcJSONValue_GetString(value);
    output->password = parcBuffer_Overlay(sBuf, 0);


    return true;
}
//
// Receive a message from the specified link.
//
static CCNxMetaMessage *
_ETHReceiveMessage(AthenaTransportLink *athenaTransportLink, struct ether_addr *peerAddress, socklen_t *peerAddressLength)
{
    struct _ETHLinkData *linkData = athenaTransportLink_GetPrivateData(athenaTransportLink);
    CCNxMetaMessage *ccnxMetaMessage = NULL;
    AthenaTransportLinkEvent events = 0;

    PARCBuffer *message = athenaEthernet_Receive(linkData->athenaEthernet, -1, &events);
    if (message == NULL) {
        return NULL;
    }
    // Mark any pending events
    if (events) {
        athenaTransportLink_SetEvent(athenaTransportLink, events);
    }

    // Map the header
    struct ether_header *header = parcBuffer_Overlay(message, sizeof(struct ether_header));

    // If the destination does not match my address, drop the message
    if (memcmp(&linkData->link.myAddress, header->ether_dhost, ETHER_ADDR_LEN * sizeof(uint8_t)) != 0) {
        linkData->_stats.receive_NoLinkDestination++;
        parcBuffer_Release(&message);
        return NULL;
    }
    assertTrue(header->ether_type == htons(CCNX_ETHERTYPE), "Unexpected ether type %x", header->ether_type);

    // Set peerAddress from header source address
    *peerAddressLength = ETHER_ADDR_LEN * sizeof(uint8_t);
    memcpy(peerAddress, header->ether_shost, *peerAddressLength);

    parcBuffer_SetPosition(message, sizeof(struct ether_header));
    PARCBuffer *wireFormatBuffer = parcBuffer_Slice(message);
    parcBuffer_Release(&message);
    parcBuffer_SetPosition(wireFormatBuffer, 0);

    // Construct, and return a ccnxMetaMessage from the wire format buffer.
    ccnxMetaMessage = ccnxMetaMessage_CreateFromWireFormatBuffer(wireFormatBuffer);
    if (ccnxMetaMessage == NULL) {
        linkData->_stats.receive_DecodeFailed++;
        parcLog_Error(athenaTransportLink_GetLogger(athenaTransportLink), "Failed to decode message from received packet.");
    } else if (ccnxTlvDictionary_GetSchemaVersion(ccnxMetaMessage) == CCNxTlvDictionary_SchemaVersion_V0) {
        parcLog_Debug(athenaTransportLink_GetLogger(athenaTransportLink),
                      "received deprecated version %d message\n", ccnxTlvDictionary_GetSchemaVersion(ccnxMetaMessage));
    }
    parcBuffer_Release(&wireFormatBuffer);

    return ccnxMetaMessage;
}
示例#14
0
char *
parcBuffer_ToString(const PARCBuffer *buffer)
{
    size_t remaining = parcBuffer_Remaining(buffer);

    char *result = parcMemory_Allocate(remaining + 1);
    if (remaining > 0) {
        assertNotNull(result, "parcMemory_Allocate returned NULL");
        if (result != NULL) {
            memcpy(result, parcBuffer_Overlay((PARCBuffer *) buffer, 0), remaining);
        }
    }
    result[remaining] = 0;
    return result;
}
示例#15
0
LONGBOW_TEST_CASE(JSON, parcJSON_AddString)
{
    PARCJSON *json = parcJSON_Create();

    char *expectedName = "string";
    char *expectedValue = "value";

    parcJSON_AddString(json, expectedName, expectedValue);

    const PARCJSONPair *pair = parcJSON_GetPairByName(json, "string");
    PARCBuffer *actualName = parcJSONPair_GetName(pair);
    PARCJSONValue *actualValue = parcJSONPair_GetValue(pair);

    assertTrue(strcmp(expectedName, parcBuffer_Overlay(actualName, 0)) == 0,
               "Expected name %s, actual %s",
               expectedName,
               parcBuffer_ToString(actualName));
    assertTrue(strcmp(expectedValue, parcBuffer_Overlay(parcJSONValue_GetString(actualValue), 0)) == 0,
               "Expected value %s, actual %s",
               expectedValue,
               parcJSONValue_ToString(actualValue));

    parcJSON_Release(&json);
}
示例#16
0
uint64_t
parcBuffer_ParseNumeric(PARCBuffer *buffer)
{
    uint64_t result = 0;

    char *bytes = parcBuffer_Overlay(buffer, 0);

    if (parcBuffer_Remaining(buffer) > 2 && bytes[0] == '0' && bytes[1] == 'x') {
        result = parcBuffer_ParseHexNumber(buffer);
    } else {
        result = parcBuffer_ParseDecimalNumber(buffer);
    }

    return result;
}
示例#17
0
LONGBOW_TEST_CASE(parcURISegment, parcURISegment_GetBuffer)
{
    const char *pointer;
    PARCURISegment *segment = parcURISegment_Parse(URI_PATH_SEGMENT, &pointer);
    assertNotNull(segment, "Expected non-null result.");
    assertTrue(*pointer == 0, "Expected pointer to point to the null terminating byte.");

    PARCBuffer *buffer = parcURISegment_GetBuffer(segment);

    char *expected = URI_PATH_SEGMENT;
    char *actual = (char *) parcBuffer_Overlay(buffer, 0);
    size_t compareLength = strlen(URI_PATH_SEGMENT);
    assertTrue(strncmp(expected, actual, compareLength), "Buffer does not contain original data.");

    parcURISegment_Release(&segment);
}
示例#18
0
LONGBOW_TEST_CASE(Global, parc_Chunker_ForwardIterator_BufferPartial)
{
    // Allocate something that's not divisible by the chunk size
    PARCBuffer *buffer = parcBuffer_Allocate(1030);

    for (size_t i = 0; i < 32; i++) {
        for (size_t j = 0; j < 32; j++) {
            parcBuffer_PutUint8(buffer, i);
        }
    }

    // Special 0xFF to mark the end...
    for (int i = 0; i < 6; i++) {
        parcBuffer_PutUint8(buffer, 0xFF);
    }

    parcBuffer_Flip(buffer);

    PARCBufferChunker *chunker = parcBufferChunker_Create(buffer, 32); // each chunk is 32 bytes
    assertNotNull(chunker, "Expected non-NULL Chunker");

    PARCIterator *itr = parcBufferChunker_ForwardIterator(chunker);
    size_t count = 0;
    while (parcIterator_HasNext(itr)) {
        PARCBuffer *payload = (PARCBuffer *) parcIterator_Next(itr);

        uint8_t *contents = parcBuffer_Overlay(payload, 0);
        if (count < 32) {
            for (size_t i = 0; i < 32; i++) {
                assertTrue(contents[i] == count, "Expected %zu at index %zu, got %d", count, i, contents[i]);
            }
        } else {
            for (size_t i = 0; i < 6; i++) {
                assertTrue(contents[i] == 0xFF, "Expected %zu at index %zu, got %d", (size_t) 0xFF, i, contents[i]);
            }
        }
        count++;

        parcBuffer_Release(&payload);
    }
    assertTrue(count == 33, "Expected to iterate over 33 content objects from the chunker, but for %zu", count);
    parcIterator_Release(&itr);

    parcBufferChunker_Release(&chunker);
    parcBuffer_Release(&buffer);
}
示例#19
0
MetisTlvName *
metisTlvName_CreateFromCCNxName(const CCNxName *ccnxName)
{
    // to avoid reallocs, calculate the exact size we need
    size_t memoryLength = 0;
    for (size_t i = 0; i < ccnxName_GetSegmentCount(ccnxName); i++) {
        CCNxNameSegment *segment = ccnxName_GetSegment(ccnxName, i);
        memoryLength += 4 + ccnxNameSegment_Length(segment);
    }

    MetisTlvName *name = parcMemory_AllocateAndClear(sizeof(MetisTlvName));
    assertNotNull(name, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(MetisTlvName));

    name->memoryLength = memoryLength;
    name->memory = parcMemory_Allocate(memoryLength);
    assertNotNull(name->memory, "parcMemory_Allocate(%zu) returned NULL", memoryLength);

    uint8_t *p = name->memory;
    uint8_t *end = p + memoryLength;
    for (size_t i = 0; i < ccnxName_GetSegmentCount(ccnxName); i++) {
        CCNxNameSegment *segment = ccnxName_GetSegment(ccnxName, i);
        uint16_t type = ccnxNameSegment_GetType(segment);
        uint16_t length = ccnxNameSegment_Length(segment);

        *(uint16_t *) p = htons(type);
        p += 2;

        *(uint16_t *) p = htons(length);
        p += 2;

        if (length >0) {
            PARCBuffer *buffer = ccnxNameSegment_GetValue(segment);
            uint8_t *overlay = parcBuffer_Overlay(buffer, 0);
            memcpy(p, overlay, length);

            p += length;
        }

        // sanity check
        assertTrue(p <= end, "Wrote past the end of buffer, now at %p end at %p", p, end);
    }

    _setup(name);
    return name;
}
示例#20
0
uint64_t
parcBuffer_ParseDecimalNumber(PARCBuffer *buffer)
{
    char *bytes = parcBuffer_Overlay(buffer, 0);

    int start = 0;

    unsigned count = 0;
    uint64_t result = 0;
    for (int i = start; i < parcBuffer_Remaining(buffer) && isdigit(bytes[i]); i++) {
        result = (result * 10) + _digittoint(bytes[i]);
        count++;
    }

    parcBuffer_SetPosition(buffer, parcBuffer_Position(buffer) + count);

    return result;
}
示例#21
0
LONGBOW_TEST_CASE(Global, parcNetwork_LinkAddress_BuildString_colons)
{
    char *expected = "link://01-23-45-67-89-ab";

    PARCBuffer *address = parcNetwork_ParseLinkAddress("link://01:23:45:67:89:ab");

    PARCBufferComposer *composer = parcBufferComposer_Create();
    parcNetwork_LinkAddress_BuildString((unsigned char *) parcBuffer_Overlay(address, 0), parcBuffer_Remaining(address), composer);

    PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer);
    char *actual = parcBuffer_ToString(tempBuffer);
    parcBuffer_Release(&tempBuffer);

    assertTrue(strcmp(expected, actual) == 0, "Expected '%s', actual '%s'", expected, actual);

    parcMemory_Deallocate((void **) &actual);
    parcBufferComposer_Release(&composer);
    parcBuffer_Release(&address);
}
示例#22
0
size_t
tutorialFileIO_AppendFileChunk(const char *fileName, const PARCBuffer *chunk)
{
    size_t numBytesWritten = 0;

    FILE *file = fopen(fileName, "a"); // Open for appending. Create if it doesn't exist.

    assertNotNull(file, "Could not open file '%s' - stopping.", fileName);

    const void *buffer = parcBuffer_Overlay((PARCBuffer *) chunk, 0); // We're un-const'ing for parcBuffer_Overlay, but we do not change the buffer state.

    numBytesWritten = fwrite(buffer, 1, parcBuffer_Remaining(chunk), file);

    assertTrue(numBytesWritten == parcBuffer_Remaining(chunk),
               "Couldn't write requested chunk to file: %s", fileName);

    fclose(file);

    return numBytesWritten;
}
示例#23
0
int
ccnGet(PARCIdentity *identity, CCNxName *name)
{
    CCNxPortalFactory *factory = ccnxPortalFactory_Create(identity);

    CCNxPortal *portal = ccnxPortalFactory_CreatePortal(factory, ccnxPortalRTA_Message);

    assertNotNull(portal, "Expected a non-null CCNxPortal pointer.");

    CCNxInterest *interest = ccnxInterest_CreateSimple(name);
    ccnxName_Release(&name);

    CCNxMetaMessage *message = ccnxMetaMessage_CreateFromInterest(interest);

    if (ccnxPortal_Send(portal, message, CCNxStackTimeout_Never)) {
        while (ccnxPortal_IsError(portal) == false) {
            CCNxMetaMessage *response = ccnxPortal_Receive(portal, CCNxStackTimeout_Never);
            if (response != NULL) {
                if (ccnxMetaMessage_IsContentObject(response)) {
                    CCNxContentObject *contentObject = ccnxMetaMessage_GetContentObject(response);

                    PARCBuffer *payload = ccnxContentObject_GetPayload(contentObject);

                    size_t length = parcBuffer_Remaining(payload);
                    ssize_t nwritten = write(1, parcBuffer_Overlay(payload, length), length);
                    assertTrue(nwritten == length, "Did not write whole buffer, got %zd expected %zu", nwritten, length);

                    break;
                }
                ccnxMetaMessage_Release(&response);
            }
        }
    }

    ccnxPortal_Release(&portal);

    ccnxPortalFactory_Release(&factory);

    return 0;
}
示例#24
0
LONGBOW_TEST_CASE(JSON, parcJSON_AddInteger)
{
    PARCJSON *json = parcJSON_Create();

    char *expectedName = "integer";
    uint64_t expectedValue = 12345;

    parcJSON_AddInteger(json, expectedName, expectedValue);

    const PARCJSONPair *pair = parcJSON_GetPairByName(json, expectedName);

    PARCBuffer *actualName = parcJSONPair_GetName(pair);
    PARCJSONValue *actualValue = parcJSONPair_GetValue(pair);

    assertTrue(strcmp(expectedName, parcBuffer_Overlay(actualName, 0)) == 0,
               "Expected name %s, actual %s", expectedName, (char *) parcBuffer_ToString(actualName));

    assertTrue(expectedValue == parcJSONValue_GetInteger(actualValue),
               "Expected %" PRIi64 "d actual %" PRIi64 "d", expectedValue, parcJSONValue_GetInteger(actualValue));

    parcJSON_Release(&json);
}
示例#25
0
LONGBOW_TEST_CASE(JSON, parcJSON_AddBoolean)
{
    PARCJSON *json = parcJSON_Create();

    char *expectedName = "boolean";
    bool expectedValue = true;

    parcJSON_AddBoolean(json, expectedName, expectedValue);

    const PARCJSONPair *pair = parcJSON_GetPairByName(json, expectedName);

    PARCBuffer *actualName = parcJSONPair_GetName(pair);
    PARCJSONValue *actualValue = parcJSONPair_GetValue(pair);

    assertTrue(strcmp(expectedName, parcBuffer_Overlay(actualName, 0)) == 0,
               "Expected name %s, actual %s", expectedName, (char *) parcBuffer_ToString(actualName));

    assertTrue(expectedValue == parcJSONValue_GetBoolean(actualValue),
               "Expected %d actual %d", expectedValue, parcJSONValue_GetBoolean(actualValue));

    parcJSON_Release(&json);
}
示例#26
0
LONGBOW_TEST_CASE(JSON, parcJSON_AddObject)
{
    PARCJSON *json = parcJSON_Create();

    PARCJSON *expectedValue = parcJSON_ParseString("{ \"string\" : \"xyzzy\" }");
    parcJSON_AddObject(json, "object", expectedValue);

    char *expectedName = "object";
    const PARCJSONPair *pair = parcJSON_GetPairByName(json, expectedName);

    PARCBuffer *actualName = parcJSONPair_GetName(pair);
    PARCJSONValue *actualValue = parcJSONPair_GetValue(pair);

    assertTrue(strcmp(expectedName, parcBuffer_Overlay(actualName, 0)) == 0,
               "Expected name %s, actual %s", expectedName, (char *) parcBuffer_ToString(actualName));

    assertTrue(parcJSON_Equals(expectedValue, parcJSONValue_GetJSON(actualValue)),
               "Expected value did not match the actual value.");

    parcJSON_Release(&expectedValue);
    parcJSON_Release(&json);
}
示例#27
0
uint64_t
parcBuffer_ParseHexNumber(PARCBuffer *buffer)
{
    char *bytes = parcBuffer_Overlay(buffer, 0);

    int start = 0;
    if (parcBuffer_Remaining(buffer) > 2) {
        if (bytes[0] == '0' && bytes[1] == 'x') {
            start = 2;
        }
    }

    unsigned count = 0;
    uint64_t result = 0;
    for (int i = start; i < parcBuffer_Remaining(buffer) && isxdigit(bytes[i]); i++) {
        result = (result * 16) + _digittoint(bytes[i]);
        count++;
    }

    parcBuffer_SetPosition(buffer, parcBuffer_Position(buffer) + start + count);

    return result;
}
示例#28
0
PARCBuffer *
tutorialFileIO_GetFileChunk(const char *fileName, size_t chunkSize, uint64_t chunkNum)
{
    FILE *file = fopen(fileName, "r");

    assertNotNull(file, "Could not open file '%s' - stopping.", fileName);

    // When PARCFileInputStream has a Seek() function, consider using it instead of
    // the following approach.

    // Seek to the location of the desired chunk in the file.
    assertTrue(fseek(file, chunkSize * chunkNum, SEEK_SET) == 0, "Could not seek to desired chunk");

    // If we're here, we were able to seek to the start of the desired chunk

    PARCBuffer *result = parcBuffer_Allocate(chunkSize);

    size_t numberOfBytesNeeded = chunkSize;
    size_t numberOfBytesRead = 0;       // # bytes read in each read.
    size_t totalNumberOfBytesRead = 0;  // Overall # of bytes read

    // Read until we get the required number of bytes.
    while (numberOfBytesNeeded > 0
           && (numberOfBytesRead = fread(parcBuffer_Overlay(result, 0), 1, numberOfBytesNeeded, file)) > 0) {
        numberOfBytesNeeded -= numberOfBytesRead;
        parcBuffer_SetPosition(result, parcBuffer_Position(result) + numberOfBytesRead);

        totalNumberOfBytesRead += numberOfBytesRead;
    }

    parcBuffer_SetLimit(result, totalNumberOfBytesRead);
    parcBuffer_Flip(result);

    fclose(file);

    return result;
}
//
// Receive a message from the specified link.
//
static CCNxMetaMessage *
_UDPReceiveMessage(AthenaTransportLink *athenaTransportLink, struct sockaddr_in *peerAddress, socklen_t *peerAddressLength)
{
    struct _UDPLinkData *linkData = athenaTransportLink_GetPrivateData(athenaTransportLink);
    CCNxMetaMessage *ccnxMetaMessage = NULL;
    size_t messageLength;

    // If an MTU has been set, allocate a buffer of that size to avoid having to peek at the message,
    // othersize derive the link from the header and allocate a buffer based on the message size.

    if ((messageLength = linkData->link.mtu) == 0) {
        messageLength = _messageLengthFromHeader(athenaTransportLink, linkData);
        if (messageLength <= 0) {
            return NULL;
        }
    }

    PARCBuffer *wireFormatBuffer = parcBuffer_Allocate(messageLength);

    char *buffer = parcBuffer_Overlay(wireFormatBuffer, 0);
    *peerAddressLength = (socklen_t) sizeof(struct sockaddr_in);
    ssize_t readCount = recvfrom(linkData->fd, buffer, messageLength, 0, (struct sockaddr *) peerAddress, peerAddressLength);

    // On error, just return and retry.
    if (readCount == -1) {
        linkData->_stats.receive_ReadError++;
        parcLog_Debug(athenaTransportLink_GetLogger(athenaTransportLink), "read error (%s)", strerror(errno));
        parcBuffer_Release(&wireFormatBuffer);
        return NULL;
    }

    // A zero read means either no more data is currently available or our peer hungup.
    // Just return to retry as we'll detect EOF when we come back at the top of UDPReceive
    if (readCount == 0) {
        parcBuffer_Release(&wireFormatBuffer);
        return NULL;
    }

    // If it was it a short read just return to retry later.
    while (readCount < messageLength) {
        linkData->_stats.receive_ShortRead++;
        parcLog_Debug(athenaTransportLink_GetLogger(athenaTransportLink), "short read error (%s)", strerror(errno));
        parcBuffer_Release(&wireFormatBuffer);
        return NULL;
    }

    parcLog_Debug(athenaTransportLink_GetLogger(athenaTransportLink), "received message (size=%d)", readCount);
    parcBuffer_SetPosition(wireFormatBuffer, parcBuffer_Position(wireFormatBuffer) + readCount);
    parcBuffer_Flip(wireFormatBuffer);

    // Construct, and return a ccnxMetaMessage from the wire format buffer.
    ccnxMetaMessage = ccnxMetaMessage_CreateFromWireFormatBuffer(wireFormatBuffer);
    if (ccnxTlvDictionary_GetSchemaVersion(ccnxMetaMessage) == CCNxTlvDictionary_SchemaVersion_V0) {
        parcLog_Debug(athenaTransportLink_GetLogger(athenaTransportLink),
                      "received deprecated version %d message\n", ccnxTlvDictionary_GetSchemaVersion(ccnxMetaMessage));
    }
    if (ccnxMetaMessage == NULL) {
        linkData->_stats.receive_DecodeFailed++;
        parcLog_Error(athenaTransportLink_GetLogger(athenaTransportLink), "Failed to decode message from received packet.");
    }
    parcBuffer_Release(&wireFormatBuffer);

    return ccnxMetaMessage;
}
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;
}