-Align definition of constants.
-csv.h and .c: add void param to 'csv_parse_vrps_file'.
-line_file.h: add missing param of 'lfile_close'.
-main.c: comment 'TODO This will be overriden [..]' was for developer, isn't valid since the conf will be loaded from the JSON file.
-notify.h and .c: add void param to 'notify_clients'.
-vrps.c: explain VRP meaning, how session ID is the existent solution to avoid serial desynchronization, and remove bad comment style.
errno = 0;
len = strtoul(text, NULL, 10);
if (errno) {
- err(errno, "Invalid prefix length '%s': %s", text, strerror(errno));
+ err(errno, "Invalid prefix length '%s': %s", text,
+ strerror(errno));
return -EINVAL;
}
/* An underflow or overflow will be considered here */
if ((prefix->addr.s_addr & be32_suffix_mask(prefix->len)) != 0) {
err(-EINVAL, "IPv4 prefix %s/%u has enabled suffix bits.",
- addr2str4(&prefix->addr, buffer), prefix->len);
+ addr2str4(&prefix->addr, buffer), prefix->len);
return -EINVAL;
}
return 0;
memset(&suffix, 0, sizeof(suffix));
ipv6_suffix_mask(prefix->len, &suffix);
- if ( (prefix->addr.s6_addr32[0] & suffix.s6_addr32[0])
- || (prefix->addr.s6_addr32[1] & suffix.s6_addr32[1])
- || (prefix->addr.s6_addr32[2] & suffix.s6_addr32[2])
- || (prefix->addr.s6_addr32[3] & suffix.s6_addr32[3])) {
+ if ((prefix->addr.s6_addr32[0] & suffix.s6_addr32[0])
+ || (prefix->addr.s6_addr32[1] & suffix.s6_addr32[1])
+ || (prefix->addr.s6_addr32[2] & suffix.s6_addr32[2])
+ || (prefix->addr.s6_addr32[3] & suffix.s6_addr32[3])) {
err(-EINVAL, "IPv6 prefix %s/%u has enabled suffix bits.",
- addr2str6(&prefix->addr, buffer), prefix->len);
+ addr2str6(&prefix->addr, buffer), prefix->len);
return -EINVAL;
}
return 0;
\
tmp = realloc(list->array, list->capacity \
* sizeof(elem_type)); \
- if (tmp == NULL) { \
- err(-ENOMEM, "Out of memory"); \
+ if (tmp == NULL) { \
+ err(-ENOMEM, "Out of memory"); \
return -ENOMEM; \
- } \
+ } \
list->array = tmp; \
} \
\
#include "common.h"
#include "csv.h"
-#define OPTNAME_LISTEN "listen"
-#define OPTNAME_LISTEN_ADDRESS "address"
-#define OPTNAME_LISTEN_PORT "port"
-#define OPTNAME_LISTEN_QUEUE "queue"
-#define OPTNAME_VRPS "vrps"
-#define OPTNAME_VRPS_LOCATION "location"
+#define OPTNAME_LISTEN "listen"
+#define OPTNAME_LISTEN_ADDRESS "address"
+#define OPTNAME_LISTEN_PORT "port"
+#define OPTNAME_LISTEN_QUEUE "queue"
+#define OPTNAME_VRPS "vrps"
+#define OPTNAME_VRPS_LOCATION "location"
#define OPTNAME_VRPS_CHECK_INTERVAL "checkInterval"
-#define OPTNAME_RTR_INTERVAL "rtrInterval"
+#define OPTNAME_RTR_INTERVAL "rtrInterval"
#define OPTNAME_RTR_INTERVAL_REFRESH "refresh"
#define OPTNAME_RTR_INTERVAL_RETRY "retry"
#define OPTNAME_RTR_INTERVAL_EXPIRE "expire"
-#define DEFAULT_ADDR NULL
-#define DEFAULT_PORT "323"
-#define DEFAULT_QUEUE 10
+#define DEFAULT_ADDR NULL
+#define DEFAULT_PORT "323"
+#define DEFAULT_QUEUE 10
#define DEFAULT_VRPS_LOCATION NULL
#define DEFAULT_VRPS_CHECK_INTERVAL 60
-#define DEFAULT_REFRESH_INTERVAL 3600
+#define DEFAULT_REFRESH_INTERVAL 3600
#define DEFAULT_RETRY_INTERVAL 600
#define DEFAULT_EXPIRE_INTERVAL 7200
/* Protocol timing parameters ranges in secs */
-#define MIN_VRPS_CHECK_INTERVAL 60
-#define MAX_VRPS_CHECK_INTERVAL 7200
-#define MIN_REFRESH_INTERVAL 1
-#define MAX_REFRESH_INTERVAL 86400
+#define MIN_VRPS_CHECK_INTERVAL 60
+#define MAX_VRPS_CHECK_INTERVAL 7200
+#define MIN_REFRESH_INTERVAL 1
+#define MAX_REFRESH_INTERVAL 86400
#define MIN_RETRY_INTERVAL 1
#define MAX_RETRY_INTERVAL 7200
#define MIN_EXPIRE_INTERVAL 600
/* An underflow or overflow will be considered here */
if (asn < 0 || UINT32_MAX < asn) {
err(-EINVAL, "Prefix length (%lu) is out of bounds (0-%u).",
- asn, UINT32_MAX);
+ asn, UINT32_MAX);
return -EINVAL;
}
*value = (unsigned int) asn;
/* Second column (second part): Prefix length in numeric format */
token = strtok(NULL, ",");
- error = parse_prefix_length(token, isv4 ? &prefixv4.len : &prefixv6.len,
+ error = parse_prefix_length(token,
+ isv4 ? &prefixv4.len : &prefixv6.len,
isv4 ? 32 : 128);
if (error)
goto error;
/* Third column: Prefix max length in numeric format */
token = strtok(NULL, ",");
- error = parse_prefix_length(token, &max_prefix_length, isv4 ? 32 : 128);
+ error = parse_prefix_length(token, &max_prefix_length,
+ isv4 ? 32 : 128);
if (error)
goto error;
}
if (isv4)
- vrp = create_vrp4(asn, prefixv4.addr, prefixv4.len, max_prefix_length);
+ vrp = create_vrp4(asn, prefixv4.addr, prefixv4.len,
+ max_prefix_length);
else
- vrp = create_vrp6(asn, prefixv6.addr, prefixv6.len, max_prefix_length);
+ vrp = create_vrp6(asn, prefixv6.addr, prefixv6.len,
+ max_prefix_length);
if (vrp == NULL) {
error = -ENOMEM;
++current_line;
error = lfile_read(lfile, &line);
if (error) {
- err(error, "Error reading line %d, stop processing file.", current_line);
+ err(error, "Error reading line %d, stop processing file.",
+ current_line);
delta_destroy(&delta);
goto end;
}
goto persist;
}
if (strcmp(line, "") == 0) {
- warn("There's nothing at line %d, ignoring.", current_line);
+ warn("There's nothing at line %d, ignoring.",
+ current_line);
continue;
}
if (error)
goto end1; /* Error msg already printed. */
- // Look for the last update date
+ /* Look for the last update date */
error = stat(location, &attr);
if (error) {
warn("Couldn't get last modified date of %s, skip update",
goto end2;
if (updated != NULL)
- *updated = check_update && last_update > get_vrps_last_modified_date();
+ *updated = check_update &&
+ last_update > get_vrps_last_modified_date();
set_vrps_last_modified_date(last_update);
- // TODO Double check of date
end2:
lfile_close(lfile);
return error;
}
-/* TODO (review) Should be `csv_parse_vrps_file(void)`. */
int
-csv_parse_vrps_file()
+csv_parse_vrps_file(void)
{
return load_vrps_file(false, NULL);
}
#include <stdbool.h>
-int csv_parse_vrps_file();
+int csv_parse_vrps_file(void);
int csv_check_vrps_file(bool *);
#endif /* SRC_CSV_H_ */
* - The string WILL be NULL-terminated, but the NULL chara will not be
* included in the returned length. BUT IT'S THERE. Don't worry about
* writing past the allocated space on the last line.
- * - Newline is `\n` according to POSIX, which is good, because RFC 7730
- * agrees. You will have to worry about `\r`, though.
+ * - Newline is `\n` according to POSIX, which is good, because
+ * RFC 7730 agrees. You will have to worry about `\r`, though.
*
* Also, the Linux man page claims the following:
*
free(string);
*result = NULL;
if (ferror(lfile->file)) {
- err(error, "Error while reading file: %s\n", strerror(error));
+ err(error, "Error while reading file: %s\n",
+ strerror(error));
return error;
}
if (feof(lfile->file))
return 0;
error = -EINVAL;
- err(error, "Supposedly unreachable code reached. ferror:%d feof:%d\n",
+ err(error,
+ "Supposedly unreachable code reached. ferror:%d feof:%d\n",
ferror(lfile->file), feof(lfile->file));
return error;
}
struct line_file;
int lfile_open(const char *, struct line_file **);
-void lfile_close();
+void lfile_close(struct line_file *lf);
int lfile_read(struct line_file *, char **);
* This program is an RTR server.
*
* RTR ("RPKI-to-Router") is a protocol (defined in RFCs 6810 and 8210) that
- * reports the work of an RPKI validator (cryptographcally-verified attestations
- * that define the ASN that owns a given routing prefix). It is normally served
- * to routers who wish to verify BGP claims.
+ * reports the work of an RPKI validator (cryptographcally-verified
+ * attestations that define the ASN that owns a given routing prefix). It is
+ * normally served to routers who wish to verify BGP claims.
*/
int
main(int argc, char *argv[])
}
}
- /* TODO (review) I don't understand this comment; please ellaborate. */
- /* TODO This will be overriden when reading from config file */
if (json_file == NULL) {
fprintf(stderr, "Missing flag '-f <file name>'\n");
return -EINVAL;
serial = get_last_serial_number();
session_id = get_current_session_id(rtr_version);
- init_sender_common(&common, fd, rtr_version, &session_id, &serial, NULL);
+ init_sender_common(&common, fd, rtr_version, &session_id, &serial,
+ NULL);
return send_serial_notify_pdu(&common);
}
void
-notify_clients()
+notify_clients(void)
{
struct client *clients, *ptr;
size_t clients_len;
#ifndef SRC_NOTIFY_H_
#define SRC_NOTIFY_H_
-void notify_clients();
+void notify_clients(void);
#endif /* SRC_NOTIFY_H_ */
#include <unistd.h>
#include "pdu_sender.h"
-int err_pdu_send(int fd, u_int8_t version, u_int16_t code,
- void *err_pdu_header, char *message)
+int
+err_pdu_send(int fd, u_int8_t version, u_int16_t code, void *err_pdu_header,
+ char *message)
{
int error;
- error = send_error_report_pdu(fd, version, code, err_pdu_header, message);
+ error = send_error_report_pdu(fd, version, code, err_pdu_header,
+ message);
if (err_pdu_is_fatal(code)) {
- warnx("Fatal error report PDU sent [code %u], closing socket.", code);
+ warnx("Fatal error report PDU sent [code %u], closing socket.",
+ code);
close(fd);
}
#define ERR_PDU_UNSUP_PDU_TYPE 5
#define ERR_PDU_WITHDRAWAL_UNKNOWN 6
#define ERR_PDU_DUPLICATE_ANNOUNCE 7
-#define ERR_PDU_UNEXPECTED_PROTO_VERSION 8
+#define ERR_PDU_UNEXPECTED_PROTO_VERSION 8
int err_pdu_send(int, u_int8_t, u_int16_t, void *, char *);
static int
pdu_header_from_stream(int fd, struct pdu_header *header)
{
- /* TODO if the first read yields no bytes, the connection was terminated. */
+ /* If the first read yields no bytes, the connection was terminated. */
return read_int8(fd, &header->protocol_version)
|| read_int8(fd, &header->pdu_type)
|| read_int16(fd, &header->session_id)
{
int error;
- // Send Cache response PDU
+ /* Send Cache response PDU */
error = send_cache_response_pdu(common);
if (error)
return error;
- // Send Payload PDUs
+ /* Send Payload PDUs */
error = send_payload_pdus(common);
if (error)
return error;
- // Send End of data PDU
+ /* Send End of data PDU */
return send_end_of_data_pdu(common);
}
/*
* RFC 6810 and 8210:
* "If [...] either the router or the cache finds that the value of the
- * Session ID is not the same as the other's, the party which detects the
- * mismatch MUST immediately terminate the session with an Error Report PDU
- * with code 0 ("Corrupt Data")"
+ * Session ID is not the same as the other's, the party which detects
+ * the mismatch MUST immediately terminate the session with an Error
+ * Report PDU with code 0 ("Corrupt Data")"
*/
version = received->header.protocol_version;
session_id = get_current_session_id(version);
if (received->header.session_id != session_id)
- return err_pdu_send(fd, version, ERR_PDU_CORRUPT_DATA, NULL, NULL);
+ return err_pdu_send(fd, version, ERR_PDU_CORRUPT_DATA, NULL,
+ NULL);
current_serial = get_last_serial_number();
init_sender_common(&common, fd, version, &session_id,
switch (updates) {
case NO_DATA_AVAILABLE:
/* https://tools.ietf.org/html/rfc8210#section-8.4 */
- return err_pdu_send(fd, version, ERR_PDU_NO_DATA_AVAILABLE, NULL,
- NULL);
+ return err_pdu_send(fd, version, ERR_PDU_NO_DATA_AVAILABLE,
+ NULL, NULL);
case DIFF_UNDETERMINED:
/* https://tools.ietf.org/html/rfc8210#section-8.3 */
return send_cache_reset_pdu(&common);
switch (updates) {
case NO_DATA_AVAILABLE:
/* https://tools.ietf.org/html/rfc8210#section-8.4 */
- return err_pdu_send(fd, version, ERR_PDU_NO_DATA_AVAILABLE, NULL,
- NULL);
+ return err_pdu_send(fd, version, ERR_PDU_NO_DATA_AVAILABLE,
+ NULL, NULL);
case DIFF_AVAILABLE:
/* https://tools.ietf.org/html/rfc8210#section-8.1 */
return send_commmon_exchange(&common);
#include "../common.h"
-__BEGIN_DECLS
+
int handle_serial_notify_pdu(int, void *);
int handle_serial_query_pdu(int, void *);
int handle_reset_query_pdu(int, void *);
int handle_end_of_data_pdu(int, void *);
int handle_cache_reset_pdu(int, void *);
int handle_error_report_pdu(int, void *);
-__END_DECLS
#endif /* RTR_PDU_HANDLER_H_ */
#include "pdu_serializer.h"
/* Header length field is always 64 bits long */
-#define HEADER_LENGTH 8
+#define HEADER_LENGTH 8
/* IPvN PDUs length without header */
-#define IPV4_PREFIX_LENGTH 12
-#define IPV6_PREFIX_LENGTH 24
+#define IPV4_PREFIX_LENGTH 12
+#define IPV6_PREFIX_LENGTH 24
void
init_sender_common(struct sender_common *common, int fd, u_int8_t version,
static u_int32_t
length_ipvx_prefix_pdu(bool isv4)
{
- return HEADER_LENGTH + (isv4 ? IPV4_PREFIX_LENGTH : IPV6_PREFIX_LENGTH);
+ return HEADER_LENGTH +
+ (isv4 ? IPV4_PREFIX_LENGTH : IPV6_PREFIX_LENGTH);
}
static u_int32_t
size_t len;
/* This PDU has only the header */
- set_header_values(&pdu.header, common->version, PDU_TYPE_CACHE_RESET, 0);
+ set_header_values(&pdu.header, common->version, PDU_TYPE_CACHE_RESET,
+ 0);
pdu.header.length = HEADER_LENGTH;
len = serialize_cache_reset_pdu(&pdu, data);
size_t len;
/* This PDU has only the header */
- set_header_values(&pdu.header, common->version, PDU_TYPE_CACHE_RESPONSE,
- *common->session_id);
+ set_header_values(&pdu.header, common->version,
+ PDU_TYPE_CACHE_RESPONSE, *common->session_id);
pdu.header.length = HEADER_LENGTH;
len = serialize_cache_response_pdu(&pdu, data);
char data[BUFFER_SIZE];
size_t len;
- set_header_values(&pdu.header, common->version, PDU_TYPE_IPV4_PREFIX, 0);
+ set_header_values(&pdu.header, common->version, PDU_TYPE_IPV4_PREFIX,
+ 0);
pdu.flags = vrp->flags;
pdu.prefix_length = vrp->prefix_length;
char data[BUFFER_SIZE];
size_t len;
- set_header_values(&pdu.header, common->version, PDU_TYPE_IPV6_PREFIX, 0);
+ set_header_values(&pdu.header, common->version, PDU_TYPE_IPV6_PREFIX,
+ 0);
pdu.flags = vrp->flags;
pdu.prefix_length = vrp->prefix_length;
size_t head_size;
char *ptr;
- head_size = serialize_pdu_header(&pdu->header, pdu->header.session_id, buf);
+ head_size = serialize_pdu_header(&pdu->header, pdu->header.session_id,
+ buf);
ptr = buf + head_size;
ptr = write_int32(ptr, pdu->serial_number);
size_t head_size;
char *ptr;
- head_size = serialize_pdu_header(&pdu->header, pdu->header.reserved, buf);
+ head_size = serialize_pdu_header(&pdu->header, pdu->header.reserved,
+ buf);
ptr = buf + head_size;
ptr = write_int8(ptr, pdu->flags);
size_t head_size;
char *ptr;
- head_size = serialize_pdu_header(&pdu->header, pdu->header.reserved, buf);
+ head_size = serialize_pdu_header(&pdu->header, pdu->header.reserved,
+ buf);
ptr = buf + head_size;
ptr = write_int8(ptr, pdu->flags);
size_t head_size;
char *ptr;
- head_size = serialize_pdu_header(&pdu->header, pdu->header.session_id, buf);
+ head_size = serialize_pdu_header(&pdu->header, pdu->header.session_id,
+ buf);
ptr = buf + head_size;
ptr = write_int32(ptr, pdu->serial_number);
char *ptr, *tmp_ptr;
int i;
- head_size = serialize_pdu_header(&pdu->header, pdu->header.error_code, buf);
+ head_size = serialize_pdu_header(&pdu->header, pdu->header.error_code,
+ buf);
ptr = buf + head_size;
#include "pdu.h"
-#define BUFFER_SIZE 128
+#define BUFFER_SIZE 128
struct data_buffer {
size_t len;
#define EINVALID_UTF8 -0xFFFF
/*
- * Returns the length (in octets) of the UTF-8 code point that starts with octet
- * @first_octet.
+ * Returns the length (in octets) of the UTF-8 code point that starts with
+ * octet @first_octet.
*/
static int
get_octets(unsigned char first_octet)
* Reads an RTR string from the file descriptor @fd. Returns the string as a
* normal UTF-8 C string (NULL-terminated).
*
- * Will consume the entire string from the stream, but @result can be truncated.
- * This is because RTR strings are technically allowed to be 4 GBs long.
+ * Will consume the entire string from the stream, but @result can be
+ * truncated. This is because RTR strings are technically allowed to be 4 GBs
+ * long.
*
* The result is allocated in the heap. It will length 4096 characters at most.
* (Including the NULL chara.)
* This exists because there might be value in truncating the string;
* full_length is a fucking 32-bit integer for some reason.
* Note that, because this is UTF-8 we're dealing with, this might not
- * necessarily end up being the actual octet length of the final string;
- * since our truncation can land in the middle of a code point, the null
- * character might need to be shifted left slightly.
+ * necessarily end up being the actual octet length of the final
+ * string; since our truncation can land in the middle of a code point,
+ * the null character might need to be shifted left slightly.
*/
size_t alloc_length; /* Includes the null chara */
rtr_char *str;
/*
* The client socket threads' entry routine.
*
- * Please remember that this function needs to always release @param_void before
- * returning.
+ * Please remember that this function needs to always release @param_void
+ * before returning.
*/
static void *
client_thread_cb(void *param_void)
if (err)
return NULL;
- /* Protocol Version Negotiation, accept only what's supported */
+ /* Protocol Version Negotiation */
if (rtr_version != RTR_VERSION_SUPPORTED) {
err_pdu_send(param.client_fd, RTR_VERSION_SUPPORTED,
ERR_PDU_UNSUP_PROTO_VERSION,
return NULL;
}
/* RTR Version ready, now update client */
- err = update_client(param.client_fd, ¶m.client_addr, rtr_version);
+ err = update_client(param.client_fd, ¶m.client_addr,
+ rtr_version);
if (err) {
if (err == -EINVAL) {
err_pdu_send(param.client_fd, rtr_version,
- (rtr_version == RTR_V0 ? ERR_PDU_UNSUP_PROTO_VERSION :
- ERR_PDU_UNEXPECTED_PROTO_VERSION),
+ (rtr_version == RTR_V0
+ ? ERR_PDU_UNSUP_PROTO_VERSION
+ : ERR_PDU_UNEXPECTED_PROTO_VERSION),
(struct pdu_header *) pdu, NULL);
}
return NULL;
#include "vrps.h"
-/* TODO (review) Can't find the meaning of "VRP" and "VRPS". Please explain. */
-
#include <stdbool.h>
#include <string.h>
#include "array_list.h"
+/*
+ * Storage of VRPs (term taken from RFC 6811 "Validated ROA Payload") and
+ * Serials that contain such VRPs
+ */
+
#define FLAG_WITHDRAWAL 0
#define FLAG_ANNOUNCEMENT 1
-#define START_SERIAL 0
+#define START_SERIAL 0
ARRAY_LIST(vrps, struct vrp)
}
/*
- * TODO (review) This looks dangerous.
- *
- * 1. RTR server starts with serial 0
- * 2. Router wants serial
- * 3. RTR Server provides serial 0
- * 4. RTR Server dies
- * 5. RTR Server starts with serial 0, but the repository has changed
- * by this point
- *
- * Can they realize that they are out of sync?
- *
- * Can't you use the current date as serial?
+ * Use the same start serial, the session ID will avoid
+ * "desynchronization" (more at RFC 6810 'Glossary' and
+ * 'Fields of a PDU')
*/
state.current_serial = START_SERIAL;
/* The downcast takes the LSBs */
static bool
vrp_equal(struct vrp *left, struct vrp *right)
{
- return left->asn == right->asn && left->in_addr_len == right->in_addr_len
+ return left->asn == right->asn
+ && left->in_addr_len == right->in_addr_len
&& left->prefix_length == right->prefix_length
&& left->max_prefix_length == right->max_prefix_length
&& ((left->in_addr_len == INET_ADDRSTRLEN
* NO_DATA_AVAILABLE -> There's no data at the DB
* DIFF_UNDETERMINED -> The diff can't be determined
* NO_DIFF -> There's no difference
- * DIFF_AVAILABLE -> There are differences between SERIAL and the last DB serial
+ * DIFF_AVAILABLE -> There are diffs between SERIAL and the last DB serial
*/
int
deltas_db_status(u_int32_t *serial)
if (state.base_db->vrps.len == 0)
return NO_DATA_AVAILABLE;
- /*
- * TODO (review) `//`-style comments are somewhat controversial in that
- * they weren't added until some late standard. From my reading of it,
- * the OpenBSD style does not approve of them either.
- *
- * If you're using Eclipse, go to `Window > Preferences > C/C++ > Code
- * Analysis`, and set `Coding Style > Line Comments` to `Error`.
- *
- * Then patch all the emerging red underlines.
- */
- // No serial to match, and there's data at DB
+ /* No serial to match, and there's data at DB */
if (serial == NULL)
return DIFF_AVAILABLE;
/* NULL start? Send the last version, there's no need to iterate DB */
if (start_serial == NULL) {
- copy_vrps(result, state.base_db->vrps.array, state.base_db->vrps.len);
+ copy_vrps(result, state.base_db->vrps.array,
+ state.base_db->vrps.len);
return state.base_db->vrps.len;
}
#define NO_DATA_AVAILABLE -2
#define DIFF_UNDETERMINED -1
-#define NO_DIFF 0
+#define NO_DIFF 0
#define DIFF_AVAILABLE 1
struct vrp {