コード例 #1
0
/**
 * Given a CCNxName, a directory path, and a requested chunk number, create a directory listing and return the specified
 * chunk of the directory listing as the payload of a newly created CCNxContentObject.
 * The new CCnxContentObject must eventually be released by calling ccnxContentObject_Release().
 *
 * @param [in] name The CCNxName to use when creating the new CCNxContentObject.
 * @param [in] directoryPath The directory whose contents are being listed.
 * @param [in] requestedChunkNumber The number of the requested chunk from the complete directory listing.
 *
 * @return A new CCNxContentObject instance containing the request chunk of the directory listing.
 */
static CCNxContentObject *
_createListResponse(CCNxName *name, const char *directoryPath, uint64_t requestedChunkNumber)
{
    CCNxContentObject *result = NULL;

    PARCBuffer *directoryList = tutorialFileIO_CreateDirectoryListing(directoryPath);

    uint64_t totalChunksInDirList = _getNumberOfChunksRequired(parcBuffer_Limit(directoryList), tutorialCommon_ChunkSize);
    if (requestedChunkNumber < totalChunksInDirList) {
        // Set the buffer's position to the start of the desired chunk.
        parcBuffer_SetPosition(directoryList, (requestedChunkNumber * tutorialCommon_ChunkSize));

        // See if we have more than 1 chunk's worth of data to in the buffer. If so, set the buffer's limit
        // to the end of the chunk.
        size_t chunkLen = parcBuffer_Remaining(directoryList);

        if (chunkLen > tutorialCommon_ChunkSize) {
            parcBuffer_SetLimit(directoryList, parcBuffer_Position(directoryList) + tutorialCommon_ChunkSize);
        }

        printf("tutorialServer: Responding to 'list' command with chunk %ld/%ld\n", (unsigned long) requestedChunkNumber, (unsigned long) totalChunksInDirList);

        // Calculate the final chunk number
        uint64_t finalChunkNumber = (totalChunksInDirList > 0) ? totalChunksInDirList - 1 : 0; // the final chunk, 0-based

        // At this point, dirListBuf has its position and limit set to the beginning and end of the
        // specified chunk.
        result = _createContentObject(name, directoryList, finalChunkNumber);
    }

    parcBuffer_Release(&directoryList);

    return result;
}
コード例 #2
0
ファイル: parc_JSONParser.c プロジェクト: isolis/Libparc
void
parcJSONParser_Advance(PARCJSONParser *parser, long bytes)
{
    parcJSONParser_OptionalAssertValid(parser);

    parcBuffer_SetPosition(parser->buffer, parcBuffer_Position(parser->buffer) + bytes);
}
コード例 #3
0
CCNxNameSegment *
ccnxNameSegment_ParseURISegment(const PARCURISegment *uriSegment)
{
    CCNxNameSegment *result = NULL;

    PARCBuffer *buffer = parcURISegment_GetBuffer(uriSegment);

    size_t originalPosition = parcBuffer_Position(buffer);
    CCNxNameLabel *label = ccnxNameLabel_Parse(buffer);

    if (ccnxNameLabel_IsValid(label)) {
        PARCBuffer *value = parcBuffer_Slice(buffer);

        CCNxNameLabelType nameType = ccnxNameLabel_GetType(label);
        if (nameType != CCNxNameLabelType_Unknown) {
            result = ccnxNameSegment_CreateLabelValue(label, value);
        }

        ccnxNameLabel_Release(&label);
        parcBuffer_Release(&value);

        parcBuffer_SetPosition(buffer, originalPosition);
    }

    return result;
}
コード例 #4
0
ファイル: parc_Buffer.c プロジェクト: isolis/Libparc
PARCBuffer *
parcBuffer_Slice(const PARCBuffer *original)
{
    PARCBuffer *result = _parcBuffer_getInstance();
    if (result != NULL) {
        _parcBuffer_Init(result,
                         parcByteArray_Acquire(original->array),
                         original->arrayOffset + parcBuffer_Position(original),
                         0,
                         parcBuffer_Limit(original) - parcBuffer_Position(original),
                         parcBuffer_Limit(original) - parcBuffer_Position(original));

        _optionalAssertInvariants(result);
    }
    return result;
}
コード例 #5
0
LONGBOW_TEST_CASE(Specialization, test_hmac_sha512)
{
    HMAC_CTX ctx;
    char key[] = "apple_pie_is_good";
    int fd;
    uint8_t to_digest_buffer[MAXPATHLEN];
    ssize_t to_digest_length;

    uint8_t true_hmac_buffer[MAXPATHLEN];
    ssize_t true_hmac_length;

LONGBOW_STOP_DEPRECATED_WARNINGS
    HMAC_CTX_init(&ctx);
    HMAC_Init_ex(&ctx, key, sizeof(key), EVP_sha512(), NULL);
LONGBOW_START_DEPRECATED_WARNINGS

    fd = open("test_random_bytes", O_RDONLY);
    assertTrue(fd > 0, "Could not open input file: %s", strerror(errno));
    to_digest_length = read(fd, to_digest_buffer, sizeof(to_digest_buffer));
    assertTrue(to_digest_length > 0, "Could not read input file: %s", strerror(errno));
    close(fd);

    fd = open("test_random_bytes.hmac_sha512", O_RDONLY);
    assertTrue(fd > 0, "Could not open input file: %s", strerror(errno));
    true_hmac_length = read(fd, true_hmac_buffer, sizeof(true_hmac_buffer));
    assertTrue(true_hmac_length > 0, "Could not read input file: %s", strerror(errno));
    close(fd);

    _hmacInit(&ctx);
    _hmacUpdate(&ctx, to_digest_buffer, to_digest_length);
    PARCBuffer *output = _hmacFinalize(&ctx);

    assertTrue(parcBuffer_Position(output) == true_hmac_length,
               "hmac wrong length, expected %zu got %zu",
               true_hmac_length,
               parcBuffer_Position(output));

    assertTrue(memcmp(parcByteArray_Array(parcBuffer_Array(output)), true_hmac_buffer, true_hmac_length) == 0,
               "hmac values did not match");

LONGBOW_STOP_DEPRECATED_WARNINGS
    HMAC_cleanup(&ctx);
LONGBOW_START_DEPRECATED_WARNINGS

    parcBuffer_Release(&output);
}
コード例 #6
0
ファイル: parc_Buffer.c プロジェクト: isolis/Libparc
size_t
parcBuffer_FindUint8(const PARCBuffer *buffer, uint8_t byte)
{
    for (size_t i = parcBuffer_Position(buffer); i < parcBuffer_Limit(buffer); i++) {
        if (parcBuffer_GetAtIndex(buffer, i) == byte) {
            return i;
        }
    }
    return SIZE_MAX;
}
コード例 #7
0
ファイル: parc_Buffer.c プロジェクト: isolis/Libparc
PARCBuffer *
parcBuffer_PutArray(PARCBuffer *buffer, size_t arrayLength, const uint8_t array[arrayLength])
{
    parcBuffer_OptionalAssertValid(buffer);
    assertTrue(parcBuffer_Remaining(buffer) >= arrayLength,
               "Buffer overflow");

    parcByteArray_PutBytes(buffer->array, _effectivePosition(buffer), arrayLength, array);
    return parcBuffer_SetPosition(buffer, parcBuffer_Position(buffer) + arrayLength);
}
コード例 #8
0
ファイル: parc_Buffer.c プロジェクト: isolis/Libparc
PARCBuffer *
parcBuffer_PutBuffer(PARCBuffer *result, const PARCBuffer *buffer)
{
    parcBuffer_OptionalAssertValid(buffer);
    assertTrue(parcBuffer_Remaining(result) >= parcBuffer_Remaining(buffer),
               "Buffer overflow. %zd bytes remaining, %zd required.", parcBuffer_Remaining(result), parcBuffer_Remaining(buffer));

    size_t length = parcBuffer_Remaining(buffer);
    parcByteArray_ArrayCopy(result->array, _effectivePosition(result), buffer->array, _effectivePosition(buffer), length);
    parcBuffer_SetPosition(result, parcBuffer_Position(result) + length);
    return result;
}
コード例 #9
0
ファイル: parc_Buffer.c プロジェクト: isolis/Libparc
bool
parcBuffer_SkipOver(PARCBuffer *buffer, size_t length, const uint8_t bytesToSkipOver[length])
{
    while (parcBuffer_Remaining(buffer) > 0) {
        uint8_t character = parcBuffer_GetUint8(buffer);
        if (memchr(bytesToSkipOver, character, length) == NULL) {
            parcBuffer_SetPosition(buffer, parcBuffer_Position(buffer) - 1);
            return true;
        }
    }
    return false;
}
コード例 #10
0
ファイル: parc_Buffer.c プロジェクト: isolis/Libparc
bool
parcBuffer_SkipTo(PARCBuffer *buffer, size_t length, const uint8_t bytesToSkipTo[length])
{
    bool result = false;

    while (parcBuffer_Remaining(buffer) > 0) {
        uint8_t character = parcBuffer_GetUint8(buffer);
        if (memchr(bytesToSkipTo, character, length) != NULL) {
            parcBuffer_SetPosition(buffer, parcBuffer_Position(buffer) - 1);
            result = true;
            break;
        }
    }
    return result;
}
コード例 #11
0
ファイル: athena_Ethernet.c プロジェクト: chris-wood/ghost
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;
}
コード例 #12
0
ファイル: parc_Buffer.c プロジェクト: isolis/Libparc
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;
}
コード例 #13
0
ファイル: parc_LogEntry.c プロジェクト: PARC/Libparc
static char *
_toString(const PARCLogEntry *entry)
{
    PARCBufferComposer *composer = parcBufferComposer_Create();

    parcBufferComposer_Format(composer, "%ld.%06d %d ",
                              (long) entry->timeStamp.tv_sec, (int) entry->timeStamp.tv_usec, entry->level);

    size_t position = parcBuffer_Position(entry->payload);
    parcBufferComposer_PutBuffer(composer, entry->payload);
    parcBuffer_SetPosition(entry->payload, position);

    PARCBuffer *buffer = parcBufferComposer_GetBuffer(composer);
    parcBuffer_Rewind(buffer);

    char *result = parcBuffer_ToString(buffer);
    parcBufferComposer_Release(&composer);

    return result;
}
コード例 #14
0
ファイル: parc_Buffer.c プロジェクト: isolis/Libparc
PARCBuffer *
parcBuffer_Copy(const PARCBuffer *original)
{
    parcBuffer_OptionalAssertValid(original);

    PARCBuffer *result = _parcBuffer_getInstance();

    if (result != NULL) {
        PARCByteArray *array = parcByteArray_Copy(original->array);
        if (array != NULL) {
            _parcBuffer_Init(result,
                             array,
                             parcBuffer_ArrayOffset(original),
                             parcBuffer_Position(original),
                             parcBuffer_Limit(original),
                             parcBuffer_Capacity(original));
        } else {
            parcBuffer_Release(&result);
        }
    }

    return result;
}
コード例 #15
0
ファイル: parc_Buffer.c プロジェクト: isolis/Libparc
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;
}
コード例 #16
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;
}
コード例 #17
0
ファイル: parc_Buffer.c プロジェクト: isolis/Libparc
void *
parcBuffer_Overlay(PARCBuffer *buffer, size_t length)
{
    parcBuffer_OptionalAssertValid(buffer);
    _trapIfBufferUnderflow(buffer, length);

    uint8_t *result = parcByteArray_AddressOfIndex(buffer->array, _effectiveIndex(buffer, parcBuffer_Position(buffer)));
    buffer->position += length;
    return result;
}
コード例 #18
0
ファイル: parc_Buffer.c プロジェクト: isolis/Libparc
uint8_t
parcBuffer_PeekByte(const PARCBuffer *buffer)
{
    return parcBuffer_GetAtIndex(buffer, parcBuffer_Position(buffer));
}
コード例 #19
0
//
// 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;
}
コード例 #20
0
ファイル: parc_Buffer.c プロジェクト: isolis/Libparc
static inline size_t
_effectivePosition(const PARCBuffer *buffer)
{
    return buffer->arrayOffset + parcBuffer_Position(buffer);
}