Commit 8deee4dd authored by Greg Williams's avatar Greg Williams
Browse files

Added KineticEntry and dynamic allocation support allocating max length byte...

Added KineticEntry and dynamic allocation support allocating max length byte array for each of the metadata byte arrays, though this is desired to get reverted. Saving as a placeholder in case of re-instatement down the road.
parent e3f45eb0
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ KINETIC_LIB_NAME = $(PROJECT).$(VERSION)
KINETIC_LIB = $(BIN_DIR)/lib$(KINETIC_LIB_NAME).a
KINETIC_SO_DEV = $(BIN_DIR)/lib$(KINETIC_LIB_NAME).so
KINETIC_SO_RELEASE = $(PREFIX)/lib$(KINETIC_LIB_NAME).so

CC = gcc
OPTIMIZE = -O3
WARN = -Wall -Wextra -pedantic
@@ -36,7 +35,7 @@ LIB_DEPS = $(PUB_INC)/kinetic_client.h $(PUB_INC)/kinetic_types.h $(LIB_DIR)/kin
# LIB_OBJ = $(patsubst %,$(OUT_DIR)/%,$(LIB_OBJS))
LIB_OBJS = $(OUT_DIR)/kinetic_nbo.o $(OUT_DIR)/kinetic_operation.o $(OUT_DIR)/kinetic_pdu.o $(OUT_DIR)/kinetic_proto.o $(OUT_DIR)/kinetic_socket.o $(OUT_DIR)/kinetic_message.o $(OUT_DIR)/kinetic_logger.o $(OUT_DIR)/kinetic_hmac.o $(OUT_DIR)/kinetic_connection.o $(OUT_DIR)/kinetic_types.o $(OUT_DIR)/kinetic_client.o $(OUT_DIR)/socket99.o $(OUT_DIR)/protobuf-c.o

default: $(KINETIC_SO)
default: $(KINETIC_LIB)

test: Rakefile $(LIB_OBJS)
	@echo
+1 −1
Original line number Diff line number Diff line
#!/bin/sh
# Run astyle on all C files in all project source folders
astyle --style=kr --break-closing-brackets --pad-oper --pad-header --unpad-paren --convert-tabs --indent=spaces=4 --lineend=linux --recursive ./src/*.c ./src/*.h ./include/*.h
astyle --style=kr --break-closing-brackets --pad-oper --pad-header --unpad-paren --convert-tabs --indent=spaces=4 --lineend=linux --recursive src/*.* ./include/*.h
+16 −2
Original line number Diff line number Diff line
@@ -51,6 +51,20 @@ KineticStatus KineticClient_Connect(const KineticSession* config,
 */
KineticStatus KineticClient_Disconnect(KineticSessionHandle* const handle);

/**
 * @brief Creates a new key/value entry with preallocated ByteArrays for
 *        pertinent metadata fields. 'value' and its memory are owned by
 *        the caller.
 *
 * @param handle    KineticSessionHandle for a connected session.
 * @param value     Payload ByteArray w/ caller-allocated buffer to embed in
 *                  entry.
 *
 * @return          Returns the resulting KineticStatus
 */
KineticStatus KineticClient_CreateEntry(KineticSessionHandle handle,
    ByteArray value);

/**
 * @brief Executes a NOOP command to test whether the Kinetic Device is operational.
 *
@@ -70,7 +84,7 @@ KineticStatus KineticClient_NoOp(KineticSessionHandle handle);
 * @return              Returns the resulting KineticStatus
 */
KineticStatus KineticClient_Put(KineticSessionHandle handle,
    const KineticKeyValue* const metadata);
    KineticKeyValue* const metadata);

/**
 * @brief Executes a GET command to retrieve and entry from the Kinetic Device.
@@ -94,6 +108,6 @@ KineticStatus KineticClient_Get(KineticSessionHandle handle,
 * @return              Returns the resulting KineticStatus
 */
KineticStatus KineticClient_Delete(KineticSessionHandle handle,
    const KineticKeyValue* const metadata);
    KineticKeyValue* const metadata);

#endif // _KINETIC_CLIENT_H
+33 −1
Original line number Diff line number Diff line
@@ -42,7 +42,8 @@
#define KINETIC_TLS_PORT        (8443)
#define KINETIC_HMAC_SHA1_LEN   (SHA_DIGEST_LENGTH)
#define KINETIC_HMAC_MAX_LEN    (KINETIC_HMAC_SHA1_LEN)
#define KINETIC_MAX_KEY_LEN     (128)
#define KINETIC_MAX_KEY_LEN     (4096)
#define KINETIC_MAX_VERSION_LEN (256)
#define PDU_VALUE_MAX_LEN       (1024 * 1024)

// Define max host name length
@@ -222,6 +223,37 @@ typedef struct _KineticKeyValue
    KineticSynchronization synchronization;
    ByteArray value;
} KineticKeyValue;
#define KINETIC_KEY_VALUE_INIT(_keyValue) \
    memset((_keyValue), 0, sizeof(KineticKeyValue));

typedef struct _KineticEntry {
    KineticKeyValue keyValue;
    KineticSessionHandle sessionHandle;
    uint8_t keyData[KINETIC_MAX_KEY_LEN];
    uint8_t newVersionData[KINETIC_MAX_VERSION_LEN];
    uint8_t dbVersionData[KINETIC_MAX_VERSION_LEN];
    uint8_t tagData[KINETIC_MAX_VERSION_LEN];
    bool force;
    KineticAlgorithm algorithm;
    bool metadataOnly;
    KineticSynchronization synchronization;
    uint8_t valueData[PDU_VALUE_MAX_LEN];
} KineticEntry;
#define KINTEIC_ENTRY_INIT(_entry, _sessionHandle) \
{ \
    KINETIC_KEY_VALUE_INIT(&(_entry)->keyValue); \
    (_entry)->sessionHandle = (_sessionHandle); \
    (_entry)->keyValue.key = (ByteArray){ \
        .data = (_entry)->keyData, .len = sizeof((_entry)->keyData) }; \
    (_entry)->keyValue.newVersion = (ByteArray){ \
        .data = (_entry)->newVersionData, .len = sizeof((_entry)->newVersionData) }; \
    (_entry)->keyValue.dbVersion = (ByteArray){ \
        .data = (_entry)->dbVersionData, .len = sizeof((_entry)->dbVersionData) }; \
    (_entry)->keyValue.tag = (ByteArray){ \
        .data = (_entry)->tagData, .len = sizeof((_entry)->tagData) }; \
    (_entry)->keyValue.value = (ByteArray){ \
        .data = (_entry)->valueData, .len = sizeof((_entry)->valueData) }; \
}

// Expose normally private data for test builds to allow inspection
#ifdef TEST
+120 −53
Original line number Diff line number Diff line
@@ -22,69 +22,70 @@
#include "kinetic_logger.h"
#include <stdlib.h>

STATIC KineticPDUListItem* PDUList = NULL;
STATIC KineticPDUListItem* PDUListLast = NULL;
STATIC KineticList PDUList = {.start = NULL, .last = NULL};
STATIC KineticList EntryList = {.start = NULL, .last = NULL};

KineticPDU* KineticAllocator_NewPDU(void)
void* KineticAllocator_NewItem(KineticList* list, size_t size)
{
    KineticPDUListItem* newItem = (KineticPDUListItem*)malloc(sizeof(KineticPDUListItem));
    KineticListItem* newItem = (KineticListItem*)malloc(sizeof(KineticListItem));
    if (newItem == NULL) {
        LOG("Failed allocating new PDU!");
        LOG("Failed allocating new list item!");
        return NULL;
    }
    memset(newItem, 0, sizeof(KineticListItem));
    newItem->data = malloc(size);
    memset(newItem->data, 0, size);

    // Zero-out the new PDU and add it to the list
    memset(newItem, 0, sizeof(KineticPDUListItem));
    if (PDUList == NULL) {
        PDUList = newItem;
    // Add the new item to the list
    if (list->start == NULL) {
        list->start = newItem;
    }
    else {
        newItem->previous = PDUListLast;
        PDUListLast->next = newItem;
        newItem->previous = list->last;
        list->last->next = newItem;
    }
    PDUListLast = newItem;
    list->last = newItem;

    LOGF("Allocated new PDU list item @ 0x%0llX w/PDU @ 0x%0llX",
         (long long)newItem, (long long)&newItem->pdu);
    LOGF("Allocated new list item @ 0x%0llX w/data @ 0x%0llX",
         (long long)newItem, (long long)&newItem->data);

    return &newItem->pdu;
    return newItem->data;
}

void KineticAllocator_FreePDU(KineticPDU** pdu)
void KineticAllocator_FreeItem(KineticList* list, void** item)
{
    KineticPDUListItem* cur = PDUList;
    while (&cur->pdu != *pdu) {
    KineticListItem* cur = list->start;
    while (cur->data != *item) {
        if (cur->next == NULL) {
            LOG("  Reached end of list before finding PDU to free!");
            LOG("  Reached end of list before finding item to free!");
            return;
        }
        else {
            LOG("  next..");
            cur = cur->next;
        }
    }
    LOG("  Done searching for PDU list item");
    LOG("  Done searching for item list item");

    if ((cur != NULL) && (&cur->pdu == *pdu)) {
        LOG("  PDU found! freeing it.");
    if ((cur != NULL) && (cur->data == *item)) {
        LOG("  item found! freeing it.");

        // Handle PDU list emptied
        if (cur->previous == NULL) {
            LOG("  At start of list.");
            if (cur->next == NULL) {
                LOG("  Making it empty, since all deallocated!");
                PDUList = NULL;
                PDUListLast = NULL;
                list->start = NULL;
                list->last = NULL;
            }
            else {
                LOG("  Moving current item to head, since head deallocated!");
                PDUList = cur->next;
                PDUList->previous = NULL;
                list->start = cur->next;
                list->start->previous = NULL;
            }
        }
        else {
            // Relink from previous to next, if avaliable
            LOG("  Not at list start, so relinking list to free PDU.");
            LOG("  Not at list start, so relinking list to free item.");
            if (cur->previous->next != NULL) {
                LOG("  Relinking previous to next");
                if (cur->next != NULL) {
@@ -92,39 +93,35 @@ void KineticAllocator_FreePDU(KineticPDU** pdu)
                    cur->previous->next = cur->next;
                }
                else {
                    PDUListLast = cur->previous;
                    PDUListLast->next = NULL;
                    list->last = cur->previous;
                    list->last->next = NULL;
                    LOGF("    next is NULL. End of list now @ 0x%0llX",
                         (long long)PDUListLast);
                         (long long)list->last);
                }
            }
            else {
                LOG("  This shouldn't happen!");
                PDUListLast = cur->previous;
                list->last = cur->previous;
            }
        }

        if ((cur->pdu.proto != NULL) && cur->pdu.protobufDynamicallyExtracted) {
            KineticProto__free_unpacked(cur->pdu.proto, NULL);
            cur->pdu.proto = NULL;
            cur->pdu.protobufDynamicallyExtracted = false;
        };

        LOGF("  Freeing item @ 0x%0llX, pdu @ 0x%0llX",
             (long long)cur, (long long)&cur->pdu);
        LOGF("  Freeing item @ 0x%0llX, item @ 0x%0llX",
             (long long)cur, (long long)&cur->data);
        free(cur->data);
        cur->data = NULL;
        free(cur);
        cur = NULL;
    }

    *pdu = NULL;
    *item = NULL;
}

void KineticAllocator_FreeAllPDUs(void)
void KineticAllocator_FreeList(KineticList* list)
{
    LOG_LOCATION;
    if (PDUList != NULL) {
        LOG("Freeing list of PDUs...");
        KineticPDUListItem* current = PDUList;
    if (list != NULL) {
        LOG("Freeing list of all items...");
        KineticListItem* current = list->start;

        while (current->next != NULL) {
            LOG("Advancing to next list item...");
@@ -133,12 +130,15 @@ void KineticAllocator_FreeAllPDUs(void)

        while (current != NULL) {
            LOG("  Current item not freed!");
            LOGF("  DEALLOCATING item: 0x%0llX, pdu: 0x%llX, prev: 0x%0llX",
                 (long long)current, (long long)&current->pdu, (long long)current->previous);
            KineticPDUListItem* curItem = current;
            KineticPDUListItem* prevItem = current->previous;
            LOGF("  DEALLOCATING item: 0x%0llX, data: 0x%llX, prev: 0x%0llX",
                 (long long)current, (long long)&current->data, (long long)current->previous);
            KineticListItem* curItem = current;
            KineticListItem* prevItem = current->previous;
            if (curItem != NULL) {
                LOG("  Freeing list item");
                if (curItem->data != NULL) {
                    free(curItem->data);
                }
                free(curItem);
            }
            current = prevItem;
@@ -148,15 +148,82 @@ void KineticAllocator_FreeAllPDUs(void)
    else {
        LOG("  Nothing to free!");
    }
    PDUList = NULL;
    PDUListLast = NULL;

    *list = (KineticList){.start = NULL, .last = NULL};
}



KineticPDU* KineticAllocator_NewPDU(void)
{
    KineticPDU* newPDU = (KineticPDU*)KineticAllocator_NewItem(
        &PDUList, sizeof(KineticPDU));
    if (newPDU == NULL) {
        LOG("Failed allocating new PDU!");
        return NULL;
    }

    assert(newPDU->proto == NULL);

    LOGF("Allocated new PDU @ 0x%0llX", (long long)newPDU);

    return newPDU;
}

void KineticAllocator_FreePDU(KineticPDU** pdu)
{
    if (((*pdu)->proto != NULL) && (*pdu)->protobufDynamicallyExtracted) {
        LOG("Freeing dynamically allocated protobuf");
        KineticProto__free_unpacked((*pdu)->proto, NULL);
    };
    KineticAllocator_FreeItem(&PDUList, (void**)pdu);
}



void KineticAllocator_FreeAllPDUs(void)
{
    LOG_LOCATION;
    if (PDUList.start != NULL) {
        LOG("Freeing all PDUs...");
        KineticListItem* current = PDUList.start;
        while (current != NULL) {
            KineticPDU* pdu = (KineticPDU*)current->data;
            if (pdu != NULL && pdu->proto != NULL
                && pdu->protobufDynamicallyExtracted) {
                KineticProto__free_unpacked(pdu->proto, NULL);
            }
            current = current->next;
        }
        KineticAllocator_FreeList(&PDUList);
    }
    else {
        LOG("  Nothing to free!");
    }
}


KineticEntry* KineticAllocator_NewEntry(KineticConnection* connection)
{
    return NULL;
}

void KineticAllocator_FreeEntry(KineticConnection* connection, KineticEntry* entry)
{
}

void KineticAllocator_FreeAllEntries(KineticConnection* connection)
{
}




bool KineticAllocator_ValidateAllMemoryFreed(void)
{
    bool empty = (PDUList == NULL);
    bool empty = (PDUList.start == NULL);
    LOG_LOCATION;
    LOGF("  PDUList: 0x%0llX, empty=%s",
        (long long)PDUList, empty ? "true" : "false");
        (long long)PDUList.start, empty ? "true":"false");
    return empty;
}
Loading