]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Send VRPs payloads, data buffer is now used from one place
authorpcarana <pc.moreno2099@gmail.com>
Fri, 22 Feb 2019 01:12:39 +0000 (19:12 -0600)
committerpcarana <pc.moreno2099@gmail.com>
Fri, 22 Feb 2019 01:12:39 +0000 (19:12 -0600)
src/rtr/pdu_handler.c
src/rtr/pdu_sender.c
src/rtr/pdu_sender.h
src/vrps.c
src/vrps.h

index 38476382047d4feba2446c72ed31b6d2418f7b55..c82d764eefb4cf27a1836b774e6339b499c700ca 100644 (file)
@@ -55,7 +55,8 @@ handle_reset_query_pdu(int fd, void *pdu)
                return error;
 
        // Send Payload PDUs
-       error = send_payload_pdus(fd, version);
+       // TODO ..and handle Serial Number
+       error = send_payload_pdus(fd, version, 1);
        if (error)
                return error;
 
index 31aef7ef32e36b97580c3c9f6e095702dd2f851c..ecb8dcf3d1e5cfed6a8f66c9507da16de0aa0871 100644 (file)
@@ -1,36 +1,21 @@
 #include "pdu_sender.h"
 
 #include <err.h>
-#include <stdlib.h>
 #include <unistd.h>
+#include <stdbool.h>
+#include <string.h>
 
-#include "configuration.h"
+#include "../array_list.h"
+#include "../configuration.h"
+#include "../vrps.h"
 #include "pdu.h"
 #include "pdu_serializer.h"
 
 /* Header without length field is always 32 bits long */
 #define HEADER_LENGTH 4
-
-#define BUFFER_SIZE 32
-
-struct buffer {
-       size_t len;
-       size_t capacity;
-       char *data;
-};
-
-static void
-init_buffer(struct buffer *buffer)
-{
-       buffer->capacity = BUFFER_SIZE;
-       buffer->data = malloc(BUFFER_SIZE);
-}
-
-static void
-free_buffer(struct buffer *buffer)
-{
-       free(buffer->data);
-}
+/* IPvN PDUs length without header */
+#define IPV4_PREFIX_LENGTH 12
+#define IPV6_PREFIX_LENGTH 24
 
 /*
  * Set all the header values, EXCEPT length field.
@@ -51,6 +36,14 @@ length_cache_response_pdu(struct cache_response_pdu *pdu)
        return HEADER_LENGTH + sizeof(u_int32_t);
 }
 
+static u_int32_t
+length_ipvx_prefix_pdu(bool isv4)
+{
+       /* Consider 32 bits of the length field */
+       return HEADER_LENGTH + sizeof(u_int32_t) +
+           (isv4 ? IPV4_PREFIX_LENGTH : IPV6_PREFIX_LENGTH);
+}
+
 static u_int32_t
 length_end_of_data_pdu(struct end_of_data_pdu *pdu)
 {
@@ -69,15 +62,21 @@ length_end_of_data_pdu(struct end_of_data_pdu *pdu)
 }
 
 static int
-send_response(int fd, struct buffer *buffer)
+send_response(int fd, char *data, size_t data_len)
 {
+       struct data_buffer buffer;
        int error;
 
+       init_buffer(&buffer);
+       memcpy(buffer.data, data, data_len);
+       buffer.len = data_len;
+
        /*
         * FIXME Check for buffer overflow
         */
 
-       error = write(fd, buffer->data, buffer->len);
+       error = write(fd, buffer.data, buffer.len);
+       free_buffer(&buffer);
        if (error < 0) {
                err(error, "Error sending response");
                /*
@@ -93,27 +92,84 @@ int
 send_cache_response_pdu(int fd, u_int8_t version, u_int16_t session_id)
 {
        struct cache_response_pdu pdu;
-       struct buffer buffer;
-       int error;
+       char data[BUFFER_SIZE];
+       size_t len;
 
-       init_buffer(&buffer);
        set_header_values(&pdu.header, version,
            CACHE_RESPONSE_PDU_TYPE, session_id);
        pdu.header.length = length_cache_response_pdu(&pdu);
 
-       buffer.len = serialize_cache_response_pdu(&pdu, buffer.data);
-       error = send_response(fd, &buffer);
-       free_buffer(&buffer);
-       if (error)
-               return error;
+       len = serialize_cache_response_pdu(&pdu, data);
+       /* TODO wait for the ACK? */
+       return send_response(fd, data, len);
+}
 
-       return 0;
+static int
+send_ipv4_prefix_pdu(int fd, u_int8_t version, u_int32_t serial,
+    struct vrp *vrp)
+{
+       struct ipv4_prefix_pdu pdu;
+       char data[BUFFER_SIZE];
+       size_t len;
+
+       set_header_values(&pdu.header, version, IPV4_PREFIX_PDU_TYPE, 0);
+       /* TODO FLAGS!! Hardcoded 1 to send announcement */
+       pdu.flags = 1;
+       pdu.prefix_length = vrp->prefix_length;
+       pdu.max_length = vrp->max_prefix_length;
+       pdu.zero = 0;
+       pdu.ipv4_prefix = vrp->ipv4_prefix;
+       pdu.asn = vrp->asn;
+       pdu.header.length = length_ipvx_prefix_pdu(true);
+
+       len = serialize_ipv4_prefix_pdu(&pdu, data);
+       /* TODO wait for the ACK? */
+       return send_response(fd, data, len);
+}
+
+static int
+send_ipv6_prefix_pdu(int fd, u_int8_t version, u_int32_t serial,
+    struct vrp *vrp)
+{
+       struct ipv6_prefix_pdu pdu;
+       char data[BUFFER_SIZE];
+       size_t len;
+
+       set_header_values(&pdu.header, version, IPV6_PREFIX_PDU_TYPE, 0);
+       /* TODO FLAGS!! Hardcoded 1 to send announcement */
+       pdu.flags = 1;
+       pdu.prefix_length = vrp->prefix_length;
+       pdu.max_length = vrp->max_prefix_length;
+       pdu.zero = 0;
+       pdu.ipv6_prefix = vrp->ipv6_prefix;
+       pdu.asn = vrp->asn;
+       pdu.header.length = length_ipvx_prefix_pdu(false);
+
+       len = serialize_ipv6_prefix_pdu(&pdu, data);
+       /* TODO wait for the ACK? */
+       return send_response(fd, data, len);
 }
 
 int
-send_payload_pdus(int fd, u_int8_t version)
+send_payload_pdus(int fd, u_int8_t version, u_int32_t serial)
 {
-       // FIXME Complete me!!
+       struct vrp **vrps, **ptr;
+       unsigned int len, i;
+       int error;
+
+       vrps = get_vrps_delta(serial, &len);
+       ptr = vrps;
+       for (i = 0; i < len; i++) {
+               if ((*ptr)->in_addr_len == INET_ADDRSTRLEN)
+                       error = send_ipv4_prefix_pdu(fd, version, serial, *ptr);
+               else
+                       error = send_ipv6_prefix_pdu(fd, version, serial, *ptr);
+
+               if (error)
+                       return error;
+               ptr++;
+       }
+
        return 0;
 }
 
@@ -121,12 +177,11 @@ int
 send_end_of_data_pdu(int fd, u_int8_t version, u_int16_t session_id)
 {
        struct end_of_data_pdu pdu;
-       struct buffer buffer;
-       int error;
+       char data[BUFFER_SIZE];
+       size_t len;
 
-       init_buffer(&buffer);
        set_header_values(&pdu.header, version, END_OF_DATA_PDU_TYPE, session_id);
-       pdu.serial_number = 16;
+       pdu.serial_number = last_serial_number();
        if (version == RTR_V1) {
                pdu.refresh_interval = config_get_refresh_interval();
                pdu.retry_interval = config_get_retry_interval();
@@ -134,11 +189,7 @@ send_end_of_data_pdu(int fd, u_int8_t version, u_int16_t session_id)
        }
        pdu.header.length = length_end_of_data_pdu(&pdu);
 
-       buffer.len = serialize_end_of_data_pdu(&pdu, buffer.data);
-       error = send_response(fd, &buffer);
-       free_buffer(&buffer);
-       if (error)
-               return error;
-
-       return 0;
+       len = serialize_end_of_data_pdu(&pdu, data);
+       /* TODO wait for the ACK? */
+       return send_response(fd, data, len);
 }
index ba7815efdefdd09709524af4ac70b9082e55822b..47559abdcf2d7d40528bc21a21b26cba7bb8aa0f 100644 (file)
@@ -5,7 +5,7 @@
 
 
 int send_cache_response_pdu(int, u_int8_t, u_int16_t);
-int send_payload_pdus(int, u_int8_t);
+int send_payload_pdus(int, u_int8_t, u_int32_t);
 int send_end_of_data_pdu(int, u_int8_t, u_int16_t);
 
 
index e181db58abedc3711e72e435fdd55d8f160327d2..111484fc2476f3fb3d3b8b2f8ca928eb20999b46 100644 (file)
@@ -1,19 +1,7 @@
 #include "vrps.h"
 
-#include <netinet/in.h>
-#include <stdlib.h>
 #include "array_list.h"
 
-struct vrp {
-       u_int32_t       asn;
-       union {
-               struct  in_addr ipv4_prefix;
-               struct  in6_addr ipv6_prefix;
-       };
-       u_int8_t        prefix_length;
-       u_int8_t        max_prefix_length;
-};
-
 ARRAY_LIST(delta, struct vrp *)
 ARRAY_LIST(deltasdb, struct delta)
 
@@ -78,6 +66,7 @@ create_vrp4(u_int32_t asn, struct in_addr ipv4_prefix, u_int8_t prefix_length,
                return NULL;
 
        result->ipv4_prefix = ipv4_prefix;
+       result->in_addr_len = INET_ADDRSTRLEN;
 
        return result;
 }
@@ -93,6 +82,7 @@ create_vrp6(u_int32_t asn, struct in6_addr ipv6_prefix, u_int8_t prefix_length,
                return NULL;
 
        result->ipv6_prefix = ipv6_prefix;
+       result->in_addr_len = INET6_ADDRSTRLEN;
 
        return result;
 }
@@ -123,7 +113,26 @@ delta_destroy(struct delta *delta)
 }
 
 void
-deltas_db_destroy()
+deltas_db_destroy(void)
 {
        deltasdb_cleanup(&db, delta_destroy);
 }
+
+struct vrp **
+get_vrps_delta(u_int32_t serial, unsigned int *len)
+{
+       /*
+        * TODO Return the VRPs according to delta
+        */
+       *len = db.array[0].len;
+       return db.array[0].array;
+}
+
+u_int32_t
+last_serial_number(void)
+{
+       /*
+        * TODO Return the last serial number of the DB
+        */
+       return 1;
+}
index 70c5abf9a7459879ae6eb09b23c968ed95b59b1f..91ab1d61ad6b047126d0f296bf308e56f547e83e 100644 (file)
@@ -3,7 +3,17 @@
 
 #include <netinet/ip.h>
 
-struct vrp;
+struct vrp {
+       u_int32_t       asn;
+       union {
+               struct  in_addr ipv4_prefix;
+               struct  in6_addr ipv6_prefix;
+       };
+       u_int8_t        prefix_length;
+       u_int8_t        max_prefix_length;
+       u_int8_t        in_addr_len;
+};
+
 struct delta;
 
 int deltas_db_init(void);
@@ -11,12 +21,15 @@ int deltas_db_init(void);
 struct delta *create_delta(void);
 struct vrp *create_vrp4(u_int32_t, struct in_addr, u_int8_t, u_int8_t);
 struct vrp *create_vrp6(u_int32_t, struct in6_addr, u_int8_t, u_int8_t);
+struct vrp **get_vrps_delta(u_int32_t, unsigned int *);
 
 int delta_add_vrp(struct delta *, struct vrp *);
 int deltas_db_add_delta(struct delta *);
 
 void vrp_destroy(struct vrp **);
 void delta_destroy(struct delta *);
-void deltas_db_destroy();
+void deltas_db_destroy(void);
+
+u_int32_t last_serial_number(void);
 
 #endif /* SRC_VRPS_H_ */