From: pcarana Date: Fri, 22 Feb 2019 01:12:39 +0000 (-0600) Subject: Send VRPs payloads, data buffer is now used from one place X-Git-Tag: v0.0.2~52^2~58 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0d6cc2ccbcaf61372ea75a35d0c63fde16cc70fa;p=thirdparty%2FFORT-validator.git Send VRPs payloads, data buffer is now used from one place --- diff --git a/src/rtr/pdu_handler.c b/src/rtr/pdu_handler.c index 38476382..c82d764e 100644 --- a/src/rtr/pdu_handler.c +++ b/src/rtr/pdu_handler.c @@ -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; diff --git a/src/rtr/pdu_sender.c b/src/rtr/pdu_sender.c index 31aef7ef..ecb8dcf3 100644 --- a/src/rtr/pdu_sender.c +++ b/src/rtr/pdu_sender.c @@ -1,36 +1,21 @@ #include "pdu_sender.h" #include -#include #include +#include +#include -#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); } diff --git a/src/rtr/pdu_sender.h b/src/rtr/pdu_sender.h index ba7815ef..47559abd 100644 --- a/src/rtr/pdu_sender.h +++ b/src/rtr/pdu_sender.h @@ -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); diff --git a/src/vrps.c b/src/vrps.c index e181db58..111484fc 100644 --- a/src/vrps.c +++ b/src/vrps.c @@ -1,19 +1,7 @@ #include "vrps.h" -#include -#include #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; +} diff --git a/src/vrps.h b/src/vrps.h index 70c5abf9..91ab1d61 100644 --- a/src/vrps.h +++ b/src/vrps.h @@ -3,7 +3,17 @@ #include -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_ */