summaryrefslogtreecommitdiffstats
path: root/include/tlv.h
diff options
context:
space:
mode:
authorGravatar Gediminas Jakutis <gediminas@varciai.lt> 2019-06-07 17:13:13 +0300
committerGravatar Gediminas Jakutis <gediminas@varciai.lt> 2019-06-07 17:13:13 +0300
commit30513e7a89cc2f9283458100dea298770c7d18de (patch)
tree244ce464f2f8a363418c4e9f256f7958f771a979 /include/tlv.h
parent75c92f6776a69c1dddee3ee63af5d59e89184828 (diff)
downloadusurpation-30513e7a89cc2f9283458100dea298770c7d18de.tar.gz
usurpation-30513e7a89cc2f9283458100dea298770c7d18de.tar.bz2
usurpation-30513e7a89cc2f9283458100dea298770c7d18de.zip
refactor server/client discovery to use TLVs.
Signed-off-by: Gediminas Jakutis <gediminas@varciai.lt>
Diffstat (limited to 'include/tlv.h')
-rw-r--r--include/tlv.h153
1 files changed, 39 insertions, 114 deletions
diff --git a/include/tlv.h b/include/tlv.h
index 75aa133..43b7a11 100644
--- a/include/tlv.h
+++ b/include/tlv.h
@@ -1,7 +1,8 @@
/*
- * Usurpataion --- client-server protocol interface.
+ * Usurpation – clinet-server protocol implementation.
*
* Copyright (C) 2019 Ramūnas Mažeikis
+ * Copyright (C) 2019 Gediminas Jakutis
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,55 +22,12 @@
#ifndef USURPATION_PROTOCOL_H_INCLUDED
#define USURPATION_PROTOCOL_H_INCLUDED
-#if 0
-
-How do we use this API(?), I hear you say. Well, here is a self-contained
-example complete with tedious comments, allocation of buffers and cleanup:
-
--------------------------------------------------------------------------------
- 1 | void functy_the_function(void)
- 2 | {
- 3 | struct tlv tlv_packet; /* A packet made of tlv's */
- 4 | struct tlv text; /* Actually useful data */
- 5 | char *packet; /* Raw bytes to be pushed via UDP */
- 6 | size_t packet_size; /* Raw packet size */
- 7 | char message[] = "Get jacked!"; /* Duh! */
- 9 |
- 10 | tlv_init(&tlv_packet, REGURAL); /* Initialise tlv_packet to regular */
- 11 | tlv_init(&text, TEXT); /* Initialise text packet */
- 12 | tlv_push_data(&text, message, sizeof(message)); /* Push text to appropriate tlv */
- 13 | tlv_push_tlv(&tlv_packet, &text); /* Push the tlv into tlv packet */
- 14 |
- 15 | packet_size = tlv_raw_size(&tlv_packet); /* Get raw size required to push entire tlv_packet as bytes */
- 16 | packet = (char *)malloc(packet_size); /* Allocate buffer for outgoing packet */
- 17 | tlv_get_raw(&tlv_packet, packet); /* Flash tlv_packet to buffer */
- 19 | udp_push(packet, packet_size); /* Push packet via UDP */
- 20 | udp_flush(); /* Flush to the other side*/
- 21 |
- 22 | tlv_destroy(&tlv_packet); /* Free tlv_packet */
- 23 | free(packet); /* Free packet itself */
- 24 | return; /* GTFO and save stack space */
- 25 | }
--------------------------------------------------------------------------------
-
-A few things to note:
- * Calling tlv_destroy() on a tlv of type REGURAL or HEARTBEAT destorys
- all sub-tlv's too.
- * Tlv's get copies of data, which means the original buffer can be
- freed immediately.
-
-#endif
-
-
#include <errno.h>
#include <stdint.h>
+#include <stddef.h>
#include <limits.h>
-#define E_TLV_OVERFLOW (1 << 0)
-#define E_UNKNOWN_TYPE (1 << 1)
-#define END_OF_PACKET (1 << 2)
-
-#define TLV_SZ_MAX_RAW (MTU - 64)
+#define TLV_SZ_MAX (MTU - 64)
#ifdef __cplusplus
extern "C" {
@@ -81,12 +39,6 @@ extern "C" {
*/
typedef unsigned int msg_idx_t;
-#if INT32_MAX == INT_MAX
-#define READ_ENUM(data) htonl((data))
-#else INT_MAX == INT16_MAX
-#define READ_ENUM(data) htons((data))
-#endif
-
enum tlv_type {
/**
* Explicitly states that this tlv is no longer valid for reading.
@@ -122,93 +74,66 @@ enum tlv_type {
*/
UUID,
-/* Data of the following types are other tlv's! */
-
- /**
- * Just a TLV container.
- */
- REGURAL,
-
/**
* Says "I'm not dead yet.".
*/
HEARTBEAT,
+};
- /**
- * Says "Bring out yer dead!".
- */
- DISCOVERY
+struct tlv_header {
+ int32_t type;
+ uint32_t size;
};
-/**
- * Literally type-length-value
- * */
struct tlv {
- enum tlv_type type;
- uint16_t length;
- const void *data;
+ struct tlv_header head;
+ char *data;
};
-/**
- * Keeps state of the parsing process.
- *
- * Related functions return one tlv at a time.
- */
-struct tlv_parser {
- const char *data;
- uint16_t offset;
+/* for tlv to "raw" conversion */
+struct tlv_packet {
+ size_t size;
+ ptrdiff_t cursor;
+ char *data;
};
-/**
- * Initialises parser to begin parsing the data.
- *
- * Returns the first tlv which should be a meta-tlv. If it is not --- you got
- * problems.
- */
-int tlv_parser_init(struct tlv_parser *parser, char *data, struct tlv *ret);
+/* used as a termninator */
+#define tlv_none ((struct tlv) {{INVALID, 0}, NULL})
/**
* Fills tlv structure to represent the next tlv in the packet.
+ * If saveptr is non-NULL, saves the offset to the next field in saveptr.
+ * Returns NONEWDATA if once all tlvs were read.
*
- * Returns END_OF_PACKET if all tlv's were read or E_TLV_OVERFLOW, if the last
- * tlv, according to its declared size should not fit in a packet.
+ * tlv data fields obtained through this function MUST NOT be given
+ * to free(), as they point to the offsets in the "in" buffer.
*/
-int tlv_get(struct tlv_parser *parser, struct tlv *ret);
+int tlv_get(char *in, struct tlv *tlv, char **saveptr);
-/**
- * Initialises tlv to sane values.
- */
-void tlv_init(struct tlv *t, enum tlv_type type);
+/* host<->network endianess conversion for the header */
+struct tlv_header ntoh_tlvh(const struct tlv_header * const in);
+struct tlv_header hton_tlvh(const struct tlv_header * const in);
/**
- * Frees data held in the tlv structure. The structure itself shall be freed as
- * needed by calling code.
+ * Forms (packs up) a raw data packet from the given tlv by appending it to the
+ * packet. Returns E_TLV_OVERFLOW if pushing data would cause the final size
+ * (including the terminator tlv) to be greater than TLV_SZ_MAX_RAW. In case of
+ * such error the data is left untouched.
*/
-void tlv_destroy(struct tlv *t);
+int tlv_pack(struct tlv_packet *pack, struct tlv *tlv);
-/**
- * Tells amount of bytes needed to push tlv to a buffer
- */
-size_t tlv_raw_size(const struct tlv *t);
+/* finalized the packet by placing tlv_none at the end */
+int tlv_packet_finalize(struct tlv_packet *pack);
-/**
- * Pushes tlv to buffer as contiguous data. Check tlv size with tlv_raw_size
- * beforehand. If you don't do that and overflow --- tough tiddy.
- */
-int tlv_get_raw(const struct tlv *t, char *buf);
+struct tlv *tlv_init(struct tlv *in, enum tlv_type type);
+void tlv_destroy(struct tlv *in);
-/**
- * Pushes data to tlv. Returns E_TLV_OVERFLOW if pushing data would cause the
- * final size to be greater than TLV_SZ_MAX_RAW. In case of such error the data is left
- * untouched.
- */
-int tlv_push_data(struct tlv *t, const char *data, uint16_t size);
+struct tlv_packet *tlv_packet_init(struct tlv_packet *in);
+void tlv_packet_destroy(struct tlv_packet *in);
+
+/* resets the packet to form a new one, without deallocating buffers */
+struct tlv_packet *tlv_packet_reset(struct tlv_packet *in);
-/**
- * Pushes a sub-tlv into the packet. 't' can only be REGURAL, HEARTBEAT or
- * DISCOVERY.
- */
-int tlv_push_tlv(struct tlv *t, const struct tlv *other);
#ifdef __cplusplus
}