]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Add multiple changes at PDU and buffers:
authorpcarana <pc.moreno2099@gmail.com>
Wed, 10 Apr 2019 22:16:41 +0000 (17:16 -0500)
committerpcarana <pc.moreno2099@gmail.com>
Wed, 10 Apr 2019 22:16:41 +0000 (17:16 -0500)
-Add Router Key PDU (structs, serializer, sender function with pending work to do).
-Set buffers as unsigned char buffers.
-Prepare to send large PDUs (beta).
-Increment default buffer size to 512.

src/rtr/pdu.c
src/rtr/pdu.h
src/rtr/pdu_handler.c
src/rtr/pdu_handler.h
src/rtr/pdu_sender.c
src/rtr/pdu_serializer.c
src/rtr/pdu_serializer.h
src/rtr/primitive_writer.c
src/rtr/primitive_writer.h
src/vrps.c
src/vrps.h

index 770e52a8be78da2458372d1b392467616c275bb9..9b7f3d255ccfa90ae0cdf45011886184b12ff139 100644 (file)
@@ -17,6 +17,7 @@ static int    ipv4_prefix_from_stream(struct pdu_header *, int, void *);
 static int     ipv6_prefix_from_stream(struct pdu_header *, int, void *);
 static int     end_of_data_from_stream(struct pdu_header *, int, void *);
 static int     cache_reset_from_stream(struct pdu_header *, int, void *);
+static int     router_key_from_stream(struct pdu_header *, int, void *);
 static int     error_report_from_stream(struct pdu_header *, int, void *);
 static void    error_report_destroy(void *);
 
@@ -136,6 +137,14 @@ cache_reset_from_stream(struct pdu_header *header, int fd, void *pdu_void)
        return 0;
 }
 
+static int
+router_key_from_stream(struct pdu_header *header, int fd, void *pdu_void)
+{
+       struct router_key_pdu *pdu = pdu_void;
+       memcpy(&pdu->header, header, sizeof(*header));
+       return 0;
+}
+
 static int
 error_report_from_stream(struct pdu_header *header, int fd, void *pdu_void)
 {
@@ -197,6 +206,7 @@ DEFINE_METADATA(ipv4_prefix, free);
 DEFINE_METADATA(ipv6_prefix, free);
 DEFINE_METADATA(end_of_data, free);
 DEFINE_METADATA(cache_reset, free);
+DEFINE_METADATA(router_key, free);
 DEFINE_METADATA(error_report, error_report_destroy);
 
 struct pdu_metadata const *const pdu_metadatas[] = {
@@ -209,7 +219,7 @@ struct pdu_metadata const *const pdu_metadatas[] = {
        /* 6 */  &ipv6_prefix_meta,
        /* 7 */  &end_of_data_meta,
        /* 8 */  &cache_reset_meta,
-       /* 9 */  NULL,
+       /* 9 */  &router_key_meta,
        /* 10 */ &error_report_meta,
 };
 
index 3fd761644024533d66d2c4f7e145c96be77fed53..8e61646308cc9440edf27e56008794fd4d611cf5 100644 (file)
@@ -15,6 +15,7 @@
 #define PDU_TYPE_IPV6_PREFIX           6
 #define PDU_TYPE_END_OF_DATA           7
 #define PDU_TYPE_CACHE_RESET           8
+#define PDU_TYPE_ROUTER_KEY            9
 #define PDU_TYPE_ERROR_REPORT          10
 
 struct pdu_header {
@@ -78,6 +79,15 @@ struct cache_reset_pdu {
        struct  pdu_header header;
 };
 
+struct router_key_pdu {
+       struct  pdu_header header;
+       unsigned char   *ski;
+       size_t          ski_len;
+       u_int32_t       asn;
+       unsigned char   *spki;
+       size_t          spki_len;
+};
+
 struct error_report_pdu {
        struct  pdu_header header;
        u_int32_t       error_pdu_length;
index 0ec9c4bf9d49b01d109de222017d3842f3b0fd63..1ded4de87407479e703bf8445ff555170e9c4d75 100644 (file)
@@ -157,6 +157,12 @@ handle_cache_reset_pdu(int fd, void *pdu)
        return warn_unexpected_pdu(fd, pdu, "Cache Reset");
 }
 
+int
+handle_router_key_pdu(int fd, void *pdu)
+{
+       return warn_unexpected_pdu(fd, pdu, "Router Key");
+}
+
 int
 handle_error_report_pdu(int fd, void *pdu)
 {
index c98f260a3166ee60a128ba6b402774b9c89ced01..d53c7103b47b9d1b0efaff38cc4496bd45afcd63 100644 (file)
@@ -12,6 +12,7 @@ int handle_ipv4_prefix_pdu(int, void *);
 int handle_ipv6_prefix_pdu(int, void *);
 int handle_end_of_data_pdu(int, void *);
 int handle_cache_reset_pdu(int, void *);
+int handle_router_key_pdu(int, void *);
 int handle_error_report_pdu(int, void *);
 
 #endif /* RTR_PDU_HANDLER_H_ */
index a7bf2e1a8c6b9d54d2ce1178ff6eff0c5c1ea932..b700545ea8fff3d49c93e8410e3087593a63bc85 100644 (file)
@@ -68,6 +68,13 @@ length_end_of_data_pdu(struct end_of_data_pdu *pdu)
        return len;
 }
 
+static u_int32_t
+length_router_key_pdu(struct router_key_pdu *pdu)
+{
+       return HEADER_LENGTH +
+           pdu->ski_len + sizeof(pdu->asn) + pdu->spki_len;
+}
+
 static u_int32_t
 length_error_report_pdu(struct error_report_pdu *pdu)
 {
@@ -76,28 +83,68 @@ length_error_report_pdu(struct error_report_pdu *pdu)
            pdu->error_message_length + sizeof(pdu->error_message_length);
 }
 
+/*
+ * TODO Needs some testing, this is just a beta version
+ */
+static int
+send_large_response(int fd, struct data_buffer *buffer)
+{
+       unsigned char *tmp_buffer, *ptr;
+       size_t buf_size, pending;
+       int written;
+
+       buf_size = buffer->capacity;
+       pending = buffer->len;
+       ptr = buffer->data;
+       while (pending > 0) {
+               tmp_buffer = calloc(pending, sizeof(unsigned char));
+               if (tmp_buffer == NULL) {
+                       warnx("Couldn't allocate temp buffer");
+                       return -ENOMEM;
+               }
+               memcpy(tmp_buffer, ptr, buf_size);
+
+               written = write(fd, tmp_buffer, buf_size);
+               free(tmp_buffer);
+               if (written < 0) {
+                       warnx("Error sending response");
+                       return -EINVAL;
+               }
+               pending -= buf_size;
+               ptr += buf_size;
+               buf_size = pending > buffer->capacity ? buffer->capacity :
+                   pending;
+       }
+
+       return 0;
+}
+
 static int
-send_response(int fd, char *data, size_t data_len)
+send_response(int fd, unsigned char *data, size_t data_len)
 {
        struct data_buffer buffer;
        int error;
 
        init_buffer(&buffer);
-       /* Check for buffer overflow */
-       if (data_len > buffer.capacity) {
-               warnx("Response buffer out of capacity");
-               return -EINVAL;
-       }
        memcpy(buffer.data, data, data_len);
        buffer.len = data_len;
 
-       error = write(fd, buffer.data, buffer.len);
-       free_buffer(&buffer);
-       if (error < 0) {
-               warnx("Error sending response");
-               return -EINVAL;
+       /* Check for buffer overflow */
+       if (data_len <= buffer.capacity) {
+               error = write(fd, buffer.data, buffer.len);
+               free_buffer(&buffer);
+               if (error < 0) {
+                       warnx("Error sending response");
+                       return -EINVAL;
+               }
+               return 0;
        }
 
+       error = send_large_response(fd, &buffer);
+       free_buffer(&buffer);
+       if (error)
+               return error;
+
        return 0;
 }
 
@@ -105,7 +152,7 @@ int
 send_serial_notify_pdu(struct sender_common *common)
 {
        struct serial_notify_pdu pdu;
-       char data[BUFFER_SIZE];
+       unsigned char data[BUFFER_SIZE];
        size_t len;
 
        set_header_values(&pdu.header, common->version, PDU_TYPE_SERIAL_NOTIFY,
@@ -123,7 +170,7 @@ int
 send_cache_reset_pdu(struct sender_common *common)
 {
        struct cache_reset_pdu pdu;
-       char data[BUFFER_SIZE];
+       unsigned char data[BUFFER_SIZE];
        size_t len;
 
        /* This PDU has only the header */
@@ -139,7 +186,7 @@ int
 send_cache_response_pdu(struct sender_common *common)
 {
        struct cache_response_pdu pdu;
-       char data[BUFFER_SIZE];
+       unsigned char data[BUFFER_SIZE];
        size_t len;
 
        /* This PDU has only the header */
@@ -156,7 +203,7 @@ static int
 send_ipv4_prefix_pdu(struct sender_common *common, struct vrp *vrp)
 {
        struct ipv4_prefix_pdu pdu;
-       char data[BUFFER_SIZE];
+       unsigned char data[BUFFER_SIZE];
        size_t len;
 
        set_header_values(&pdu.header, common->version, PDU_TYPE_IPV4_PREFIX,
@@ -179,7 +226,7 @@ static int
 send_ipv6_prefix_pdu(struct sender_common *common, struct vrp *vrp)
 {
        struct ipv6_prefix_pdu pdu;
-       char data[BUFFER_SIZE];
+       unsigned char data[BUFFER_SIZE];
        size_t len;
 
        set_header_values(&pdu.header, common->version, PDU_TYPE_IPV6_PREFIX,
@@ -198,8 +245,8 @@ send_ipv6_prefix_pdu(struct sender_common *common, struct vrp *vrp)
        return send_response(common->fd, data, len);
 }
 
-int
-send_payload_pdus(struct sender_common *common)
+static int
+send_vrps_payload(struct sender_common *common)
 {
        struct vrp *vrps, *ptr;
        unsigned int len;
@@ -232,11 +279,86 @@ end:
        return 0;
 }
 
+static int
+send_router_key_pdu(struct sender_common *common,
+    struct router_key *router_key)
+{
+       struct router_key_pdu pdu;
+       unsigned char data[BUFFER_SIZE];
+       size_t len;
+       u_int16_t reserved;
+
+       if (common->version == RTR_V0)
+               return 0;
+
+       reserved = 0;
+       /* Set the flags at the first 8 bits of reserved field */
+       reserved += (router_key->flags << 8);
+       set_header_values(&pdu.header, common->version, PDU_TYPE_ROUTER_KEY,
+           reserved);
+
+       pdu.ski = router_key->ski;
+       pdu.ski_len = router_key->ski_len;
+       pdu.asn = router_key->asn;
+       pdu.spki = router_key->spki;
+       pdu.spki_len = router_key->spki_len;
+       pdu.header.length = length_router_key_pdu(&pdu);
+
+       len = serialize_router_key_pdu(&pdu, data);
+
+       return send_response(common->fd, data, len);
+}
+
+static int
+send_keys_payload(struct sender_common *common)
+{
+       struct router_key *router_keys, *ptr;
+       unsigned int len;
+       int error;
+
+       router_keys = malloc(sizeof(struct router_key));
+       if (router_keys == NULL) {
+               warn("Couldn't allocate Router Keys to send PDUs");
+               return -ENOMEM;
+       }
+       len = get_router_keys_delta(common->start_serial, common->end_serial,
+           &router_keys);
+       if (len == 0)
+               goto end;
+
+       for (ptr = router_keys; (ptr - router_keys) < len; ptr++) {
+               error = send_router_key_pdu(common, ptr);
+               if (error) {
+                       free(router_keys);
+                       return error;
+               }
+       }
+end:
+       free(router_keys);
+       return 0;
+}
+
+int
+send_payload_pdus(struct sender_common *common)
+{
+       int error;
+
+       error = send_vrps_payload(common);
+       if (error)
+               return error;
+
+       error = send_keys_payload(common);
+       if (error)
+               return error;
+
+       return 0;
+}
+
 int
 send_end_of_data_pdu(struct sender_common *common)
 {
        struct end_of_data_pdu pdu;
-       char data[BUFFER_SIZE];
+       unsigned char data[BUFFER_SIZE];
        size_t len;
 
        set_header_values(&pdu.header, common->version, PDU_TYPE_END_OF_DATA,
@@ -259,7 +381,7 @@ send_error_report_pdu(int fd, u_int8_t version, u_int16_t code,
 struct pdu_header *err_pdu_header, char *message)
 {
        struct error_report_pdu pdu;
-       char data[BUFFER_SIZE];
+       unsigned char data[BUFFER_SIZE];
        size_t len;
 
        set_header_values(&pdu.header, version, PDU_TYPE_ERROR_REPORT,
index 3e6220d457730c215dba0cbd713080d27319860f..5de4ba8212ee741af2c952a7fd1d24dc4c71f3d5 100644 (file)
@@ -19,9 +19,9 @@ free_buffer(struct data_buffer *buffer)
 
 static size_t
 serialize_pdu_header(struct pdu_header *header, u_int16_t union_value,
-    char *buf)
+    unsigned char *buf)
 {
-       char *ptr;
+       unsigned char *ptr;
 
        ptr = buf;
        ptr = write_int8(ptr, header->protocol_version);
@@ -33,10 +33,10 @@ serialize_pdu_header(struct pdu_header *header, u_int16_t union_value,
 }
 
 size_t
-serialize_serial_notify_pdu(struct serial_notify_pdu *pdu, char *buf)
+serialize_serial_notify_pdu(struct serial_notify_pdu *pdu, unsigned char *buf)
 {
        size_t head_size;
-       char *ptr;
+       unsigned char *ptr;
 
        head_size = serialize_pdu_header(&pdu->header, pdu->header.session_id,
            buf);
@@ -48,17 +48,18 @@ serialize_serial_notify_pdu(struct serial_notify_pdu *pdu, char *buf)
 }
 
 size_t
-serialize_cache_response_pdu(struct cache_response_pdu *pdu, char *buf)
+serialize_cache_response_pdu(struct cache_response_pdu *pdu,
+    unsigned char *buf)
 {
        /* No payload to serialize */
        return serialize_pdu_header(&pdu->header, pdu->header.session_id, buf);
 }
 
 size_t
-serialize_ipv4_prefix_pdu(struct ipv4_prefix_pdu *pdu, char *buf)
+serialize_ipv4_prefix_pdu(struct ipv4_prefix_pdu *pdu, unsigned char *buf)
 {
        size_t head_size;
-       char *ptr;
+       unsigned char *ptr;
 
        head_size = serialize_pdu_header(&pdu->header, pdu->header.reserved,
            buf);
@@ -75,10 +76,10 @@ serialize_ipv4_prefix_pdu(struct ipv4_prefix_pdu *pdu, char *buf)
 }
 
 size_t
-serialize_ipv6_prefix_pdu(struct ipv6_prefix_pdu *pdu, char *buf)
+serialize_ipv6_prefix_pdu(struct ipv6_prefix_pdu *pdu, unsigned char *buf)
 {
        size_t head_size;
-       char *ptr;
+       unsigned char *ptr;
 
        head_size = serialize_pdu_header(&pdu->header, pdu->header.reserved,
            buf);
@@ -95,10 +96,10 @@ serialize_ipv6_prefix_pdu(struct ipv6_prefix_pdu *pdu, char *buf)
 }
 
 size_t
-serialize_end_of_data_pdu(struct end_of_data_pdu *pdu, char *buf)
+serialize_end_of_data_pdu(struct end_of_data_pdu *pdu, unsigned char *buf)
 {
        size_t head_size;
-       char *ptr;
+       unsigned char *ptr;
 
        head_size = serialize_pdu_header(&pdu->header, pdu->header.session_id,
            buf);
@@ -115,18 +116,48 @@ serialize_end_of_data_pdu(struct end_of_data_pdu *pdu, char *buf)
 }
 
 size_t
-serialize_cache_reset_pdu(struct cache_reset_pdu *pdu, char *buf)
+serialize_cache_reset_pdu(struct cache_reset_pdu *pdu, unsigned char *buf)
 {
        /* No payload to serialize */
        return serialize_pdu_header(&pdu->header, pdu->header.reserved, buf);
 }
 
+/*
+ * Don't forget to use 'header->reserved' to set flags
+ */
 size_t
-serialize_error_report_pdu(struct error_report_pdu *pdu, char *buf)
+serialize_router_key_pdu(struct router_key_pdu *pdu, unsigned char *buf)
+{
+       size_t head_size;
+       unsigned char *ptr;
+       int i;
+
+       if (pdu->header.protocol_version == RTR_V0)
+               return 0;
+
+       head_size = serialize_pdu_header(&pdu->header, pdu->header.reserved,
+           buf);
+
+       ptr = buf + head_size;
+
+       for (i = 0; i < pdu->ski_len; i++)
+               ptr = write_int8(ptr, pdu->ski[i]);
+
+       ptr = write_int32(ptr, pdu->asn);
+
+       for (i = 0; i < pdu->spki_len; i++)
+               ptr = write_int8(ptr, pdu->spki[i]);
+
+       return ptr - buf;
+}
+
+size_t
+serialize_error_report_pdu(struct error_report_pdu *pdu, unsigned char *buf)
 {
        struct pdu_header *err_pdu_header;
        size_t head_size;
-       char *ptr, *tmp_ptr;
+       unsigned char *ptr;
+       char *tmp_ptr;
        int i;
 
        head_size = serialize_pdu_header(&pdu->header, pdu->header.error_code,
index e536ac5d2e126a576e32f57fb2981b4f1e5e3045..2c490be56526ba84bd27901078934870f9c4e68a 100644 (file)
@@ -3,25 +3,28 @@
 
 #include "pdu.h"
 
-#define BUFFER_SIZE    128
+#define BUFFER_SIZE    512
 
 struct data_buffer {
        size_t len;
        size_t capacity;
-       char *data;
+       unsigned char *data;
 };
 
 __BEGIN_DECLS
 void init_buffer(struct data_buffer *);
 void free_buffer(struct data_buffer *);
 
-size_t serialize_serial_notify_pdu(struct serial_notify_pdu *, char *);
-size_t serialize_cache_response_pdu(struct cache_response_pdu *, char *);
-size_t serialize_ipv4_prefix_pdu(struct ipv4_prefix_pdu *, char *);
-size_t serialize_ipv6_prefix_pdu(struct ipv6_prefix_pdu *, char *);
-size_t serialize_end_of_data_pdu(struct end_of_data_pdu *, char *);
-size_t serialize_cache_reset_pdu(struct cache_reset_pdu *, char *);
-size_t serialize_error_report_pdu(struct error_report_pdu *, char *);
+size_t serialize_serial_notify_pdu(struct serial_notify_pdu *,
+    unsigned char *);
+size_t serialize_cache_response_pdu(struct cache_response_pdu *,
+    unsigned char *);
+size_t serialize_ipv4_prefix_pdu(struct ipv4_prefix_pdu *, unsigned char *);
+size_t serialize_ipv6_prefix_pdu(struct ipv6_prefix_pdu *, unsigned char *);
+size_t serialize_end_of_data_pdu(struct end_of_data_pdu *, unsigned char *);
+size_t serialize_cache_reset_pdu(struct cache_reset_pdu *, unsigned char *);
+size_t serialize_router_key_pdu(struct router_key_pdu *, unsigned char *);
+size_t serialize_error_report_pdu(struct error_report_pdu *, unsigned char *);
 __END_DECLS
 
 #endif /* SRC_RTR_PDU_SERIALIZER_H_ */
index c2635eafe89a7edb171354a25d282e189cbdc721..bb1a9be4ba8e4384c2a9899fc08dde0d14a73345 100644 (file)
@@ -1,15 +1,15 @@
 #include "primitive_writer.h"
 
-char *
-write_int8(char *buf, u_int8_t value)
+unsigned char *
+write_int8(unsigned char *buf, u_int8_t value)
 {
        buf[0] = value;
        return buf + 1;
 }
 
 /** Big Endian. */
-char *
-write_int16(char *buf, u_int16_t value)
+unsigned char *
+write_int16(unsigned char *buf, u_int16_t value)
 {
        buf[0] = value >> 8;
        buf[1] = value;
@@ -17,8 +17,8 @@ write_int16(char *buf, u_int16_t value)
 }
 
 /** Big Endian. */
-char *
-write_int32(char *buf, u_int32_t value)
+unsigned char *
+write_int32(unsigned char *buf, u_int32_t value)
 {
        buf[0] = value >> 24;
        buf[1] = value >> 16;
@@ -27,14 +27,14 @@ write_int32(char *buf, u_int32_t value)
        return buf + 4;
 }
 
-char *
-write_in_addr(char *buf, struct in_addr value)
+unsigned char *
+write_in_addr(unsigned char *buf, struct in_addr value)
 {
        return write_int32(buf, ntohl(value.s_addr));
 }
 
-char *
-write_in6_addr(char *buf, struct in6_addr value)
+unsigned char *
+write_in6_addr(unsigned char *buf, struct in6_addr value)
 {
        int i;
        for (i = 0; i < 16; i++)
index 1ecb1c7c3741549a55f59c176a7b4671a2890091..7bed5a71c65bd35ac5b4b2395e699d168276a78a 100644 (file)
@@ -4,11 +4,11 @@
 #include <netinet/in.h>
 
 __BEGIN_DECLS
-char *write_int8(char *, u_int8_t);
-char *write_int16(char *, u_int16_t);
-char *write_int32(char *, u_int32_t);
-char *write_in_addr(char *, struct in_addr);
-char *write_in6_addr(char *, struct in6_addr);
+unsigned char *write_int8(unsigned char *, u_int8_t);
+unsigned char *write_int16(unsigned char *, u_int16_t);
+unsigned char *write_int32(unsigned char *, u_int32_t);
+unsigned char *write_in_addr(unsigned char *, struct in_addr);
+unsigned char *write_in6_addr(unsigned char *, struct in6_addr);
 __END_DECLS
 
 #endif /* RTR_PRIMITIVE_WRITER_H_ */
index ff3ae7ccfb6e68a7c04818be7ccffd5ff4e90399..29933f0a62c93152283d094b68c886bd53fab84b 100644 (file)
@@ -424,6 +424,21 @@ get_vrps_delta(u_int32_t *start_serial, u_int32_t *end_serial,
        return summary.len;
 }
 
+/*
+ * Get the number of updates from serial START_SERIAL to END_SERIAL, set them
+ * at RESULT.
+ *
+ * Return 0 if no updates are available or couldn't be calculated with the
+ * received values.
+ */
+unsigned int
+get_router_keys_delta(u_int32_t *start_serial, u_int32_t *end_serial,
+    struct router_key **result)
+{
+       /* TODO Get deltas diff */
+       return 0;
+}
+
 void
 set_vrps_last_modified_date(time_t new_date)
 {
index f6d4c208f5ef152c77b9a039dd85a069dd6fc02a..df8c87e2b5820980a9d69bf7b4f974b19e0c0ad9 100644 (file)
@@ -21,6 +21,15 @@ struct vrp {
        u_int8_t        flags;
 };
 
+struct router_key {
+       u_int8_t        flags;
+       unsigned char   *ski;
+       size_t          ski_len;
+       u_int32_t       asn;
+       unsigned char   *spki;
+       size_t          spki_len;
+};
+
 int deltas_db_init(void);
 
 struct vrp create_vrp4(u_int32_t, struct in_addr, u_int8_t, u_int8_t);
@@ -30,6 +39,8 @@ int deltas_db_create_delta(struct vrp *, unsigned int);
 int deltas_db_status(u_int32_t *);
 
 unsigned int get_vrps_delta(u_int32_t *, u_int32_t *, struct vrp **);
+unsigned int get_router_keys_delta(u_int32_t *, u_int32_t *,
+    struct router_key **);
 
 void deltas_db_destroy(void);
 void set_vrps_last_modified_date(time_t);