From: Alberto Leiva Popper Date: Thu, 28 May 2026 18:31:15 +0000 (-0600) Subject: Delete old RTR serials over time X-Git-Tag: 1.7.0.experimental~19 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f1c3b56a299c177a1ed894d73ec10c8fb1b057a5;p=thirdparty%2FFORT-validator.git Delete old RTR serials over time Was missing from the previous refactor. --- diff --git a/docs/usage.md b/docs/usage.md index 84223472..9899ce74 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -456,12 +456,14 @@ See [RFC 8210, section 6](https://tools.ietf.org/html/rfc8210#section-6). - **Type:** Integer - **Availability:** `argv` and JSON -- **Default:** 2 -- **Range:** [0, [`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)] +- **Default:** 21600 (6 hours) +- **Range:** [1, [`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)] + +RTR delta lifetime, measured in validation cycles. -When routers first connect to Fort, they request a _snapshot_ of the validation results. (ROAs and Router Keys.) Because they need to keep their validated objects updated, and snapshots tend to be relatively large amounts of information, they request _deltas_ afterwards over configurable intervals. ("Deltas" being the differences between snapshots.) +When routers first connect to Fort, they request a _snapshot_ of the validation results. (ROAs, Router Keys and ASPAs.) Because they need to keep their validated objects updated, and snapshots tend to be relatively large amounts of information, they request _deltas_ afterwards over configurable intervals. ("Deltas" being the differences between snapshots.) -During each validation cycle, Fort generates a new snapshot, as well as the deltas needed to build the new snapshot from the previous one. These are all stored in RAM. `--server.deltas.lifetime` is the number of iterations a set of deltas will be kept before being deallocated. (Recall that every iteration lasts [`--server.interval.validation`](#--serverintervalvalidation) seconds, plus however long the validation takes.) +Fort stores the information necessary to serve these deltas in the cache. `--server.deltas.lifetime` is the number of validation cycles a delta will be preserved before being expired. If a router lags behind, to the point Fort has already deleted the deltas it needs to update the router's snapshot, Fort will have to fall back to fetch the entire latest snapshot instead. diff --git a/src/config.c b/src/config.c index 83be8f99..b36c71d0 100644 --- a/src/config.c +++ b/src/config.c @@ -370,7 +370,11 @@ static const struct option_field options[] = { * minute. */ .min = 60, - .max = UINT_MAX, + /* + * 7 days. + * Must not overflow when multiplied by deltas.lifetime. + */ + .max = 604800, }, { .id = 5004, .name = "server.interval.refresh", @@ -432,6 +436,7 @@ static const struct option_field options[] = { /* * It's a serial, which means the technical maximum is about * 2^31 - 1. But that's too much. + * Must not overflow when multiplied by interval.validation. */ .max = 1000, }, @@ -1012,7 +1017,7 @@ set_default_values(void) rpki_config.server.interval.refresh = 3600; rpki_config.server.interval.retry = 600; rpki_config.server.interval.expire = 7200; - rpki_config.server.deltas_lifetime = 2; + rpki_config.server.deltas_lifetime = 6; rpki_config.prometheus.port = 0; diff --git a/src/file.c b/src/file.c index 58f59edb..dbcccb1d 100644 --- a/src/file.c +++ b/src/file.c @@ -127,7 +127,7 @@ file_exists(char const *path) static int rm(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) { - pr_op_debug("Deleting %s.", fpath); + pr_op_debug("Deleting %s", fpath); return (remove(fpath) != 0) ? errno : 0; } @@ -135,6 +135,7 @@ rm(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) int file_rm_rf(char const *path) { + pr_op_debug("rm -rf %s", path); /* TODO (performance) optimize that 32 */ return nftw(path, rm, 32, FTW_DEPTH | FTW_PHYS); } diff --git a/src/rtr/db/db_table.c b/src/rtr/db/db_table.c index 782f05f0..5b51983a 100644 --- a/src/rtr/db/db_table.c +++ b/src/rtr/db/db_table.c @@ -36,7 +36,7 @@ struct db_table { unsigned int total_roas_v4; unsigned int total_roas_v6; - struct rtr_metadata rtr; + struct rtr_index rtr; }; struct db_table * @@ -71,6 +71,8 @@ db_table_destroy(struct db_table *table) free(aspa); } + rtridx_cleanup(&table->rtr); + free(table); } @@ -361,7 +363,7 @@ write_addr(FILE *file, struct vrp *vrp) } static int -cache_vrps(struct db_table *table) +cache_vrps(struct db_table *table, serial_t serial) { FILE *f4 = NULL; FILE *f6 = NULL; @@ -370,10 +372,10 @@ cache_vrps(struct db_table *table) struct vrp *vrp; int err; - err = rtr_open_file(table->rtr.serial, "vrp4", "w", &f4); + err = rtr_open_file(serial, "vrp4", "w", &f4); if (err) return err; - err = rtr_open_file(table->rtr.serial, "vrp6", "w", &f6); + err = rtr_open_file(serial, "vrp6", "w", &f6); if (err) goto end; @@ -402,13 +404,13 @@ end: if (f4) fclose(f4); } static int -cache_rks(struct db_table *table) +cache_rks(struct db_table *table, serial_t serial) { FILE *file = NULL; struct hashable_key *rk, *tmpr; int err; - err = rtr_open_file(table->rtr.serial, "rk", "w", &file); + err = rtr_open_file(serial, "rk", "w", &file); if (err) return err; @@ -426,14 +428,14 @@ cache_rks(struct db_table *table) } static int -cache_aspas(struct db_table *table) +cache_aspas(struct db_table *table, serial_t serial) { FILE *file = NULL; struct hashable_aspa *aspa, *tmpa; array_index i; int err; - err = rtr_open_file(table->rtr.serial, "aspa", "w", &file); + err = rtr_open_file(serial, "aspa", "w", &file); if (err) return err; @@ -457,7 +459,7 @@ cache_metadata(struct db_table *table) char *dir; int error; - error = rtr_save_metadata(&table->rtr); + error = rtridx_save(&table->rtr); if (error) { pr_op_err("Could not save RTR metadata; RTR can no longer be served."); dir = rtr_filename(NULL, NULL); @@ -468,117 +470,52 @@ cache_metadata(struct db_table *table) return error; } -static bool -is_number(char const *str) -{ - if (*str == 0) - return false; - - for (; *str != 0; str++) - if (*str < '0' || '9' < *str) - return false; - - return true; -} - -static void -delete_old_serials(serial_t current) -{ - char *path; - serial_t lowest; - DIR *dir; - struct dirent *file; - unsigned long serial; - int ret; - - lowest = current - ((serial_t)config_get_deltas_lifetime()); - - path = rtr_filename(NULL, NULL); - dir = opendir(path); - free(path); - if (!dir) { - if (errno != ENOENT) - pr_op_warn("Cannot clean rtr directory: %s", - strerror(errno)); - return; - } - - FOREACH_DIR_FILE(dir, file) { - if (!is_number(file->d_name)) - continue; - - errno = 0; - serial = strtoul(file->d_name, NULL, 10); - if (errno) { - pr_op_warn("Cannot delete rtr/%s: %s", - file->d_name, strerror(errno)); - continue; - } - if (serial > UINT32_MAX) { - pr_op_warn("Cannot delete rtr/%s: Serial too big", - file->d_name); - continue; - } - - if (!serial_lt(serial, lowest)) - continue; - - path = rtr_filename2(serial, NULL); - ret = file_rm_rf(path); - free(path); - if (ret < 0) - pr_op_warn("Cannot delete rtr/%s: nftw returned %d", - file->d_name, ret); - else if (ret) - pr_op_warn("Cannot delete rtr/%s: %s", - file->d_name, strerror(ret)); - } - if (errno) - pr_op_warn("Cleanup rtr directory traversal interrupted: %s", - strerror(errno)); - - closedir(dir); -} - int db_table_cache(struct db_table *table) { char *path; + serial_t serial; int ret; - if (rtr_load_metadata(&table->rtr) != 0) - rtr_new_metadata(&table->rtr); - table->rtr.serial++; + ret = rtridx_load(&table->rtr, true); + if (ret == ENOENT) + rtridx_init(&table->rtr); + else if (ret) { + pr_op_err("Cannot access RTR index file: %s", strerror(ret)); + return ret; + } + + serial = rtridx_add_serial(&table->rtr); - path = rtr_filename(NULL, NULL); + path = rtr_filename(NULL, NULL); /* cache/rtr */ ret = mkdir_f(path); free(path); if (ret) return ret; - path = rtr_filename2(table->rtr.serial, NULL); + path = rtr_filename2(serial, NULL); /* cache/rtr/1234 */ ret = mkdir_f(path); free(path); if (ret) return ret; - ret = cache_vrps(table); + ret = cache_vrps(table, serial); if (ret) goto fail; - ret = cache_rks(table); + ret = cache_rks(table, serial); if (ret) goto fail; - ret = cache_aspas(table); + ret = cache_aspas(table, serial); if (ret) goto fail; ret = cache_metadata(table); if (ret) goto fail; - delete_old_serials(table->rtr.serial); + rtridx_clean(&table->rtr); return 0; -fail: path = rtr_filename2(table->rtr.serial, NULL); +fail: path = rtr_filename2(serial, NULL); file_rm_rf(path); free(path); return ret; @@ -670,7 +607,7 @@ db_table_session(struct db_table *table) serial_t db_table_serial(struct db_table *table) { - return table ? table->rtr.serial : 0; + return (table && table->rtr.serials) ? table->rtr.serials->serial : 0; } void diff --git a/src/rtr/meta.c b/src/rtr/meta.c index 6e7d8115..d26d8989 100644 --- a/src/rtr/meta.c +++ b/src/rtr/meta.c @@ -8,6 +8,7 @@ #include "alloc.h" #include "common.h" #include "config.h" +#include "data_structure/common.h" #include "log.h" #include "file.h" @@ -78,69 +79,372 @@ rtr_filename2(serial_t serial, char const *b) } void -rtr_new_metadata(struct rtr_metadata *rtr) +rtridx_init(struct rtr_index *idx) { - time_t now = 0x1234u; - get_current_time(&now); - rtr->session = now & 0xFFFFu; - rtr->serial = 0; + time_t now; + + now = time(NULL); + if (now == (time_t)-1) + pr_crit("time(NULL) returned (time_t) -1."); + + idx->session = now & 0xFFFF; + idx->serials = NULL; } int -rtr_save_metadata(struct rtr_metadata *rtr) +rtridx_save(struct rtr_index *idx) { - char *filepath; + char *path; FILE *file; - int error = 0; + struct rtr_serial *srl; + int error; - filepath = rtr_filename("metadata", NULL); + path = rtr_filename("index", NULL); - file = fopen(filepath, "w"); + file = fopen(path, "w"); if (!file) { error = errno; pr_op_err("Cannot open '%s' for writing: %s", - filepath, strerror(error)); - free(filepath); + path, strerror(error)); + free(path); return error; } - free(filepath); + free(path); + + if (fprintf(file, "session:%u\n", idx->session) < 0) { + error = pr_op_err("fprintf(session) failed."); + goto end; + } - if (fprintf(file, "session:%u serial:%u", rtr->session, rtr->serial) < 0) - error = pr_op_err("fprintf(serial) failed."); + for (srl = idx->serials; srl; srl = srl->next) { + if (fprintf(file, "serial:%u date:%04d-%02d-%02dT%02d:%02d:%02dZ\n", + srl->serial, srl->date.tm_year + 1900, srl->date.tm_mon + 1, + srl->date.tm_mday, srl->date.tm_hour, srl->date.tm_min, + srl->date.tm_sec) < 0) { + error = pr_op_err("fprintf(serial) failed."); + goto end; + } + } - fclose(file); + error = 0; + +end: fclose(file); return error; } +/* + * If @all is true, loads all the serials from the index. + * Otherwise loads only the most recent one. + */ int -rtr_load_metadata(struct rtr_metadata *rtr) +rtridx_load(struct rtr_index *idx, bool all) { char *filepath; FILE *file; - unsigned int session; - unsigned int serial; - int error = 0; + char buf[64]; + unsigned int se; + struct rtr_serial *srl, *prev; + int error; + + idx->serials = NULL; - filepath = rtr_filename("metadata", NULL); + filepath = rtr_filename("index", NULL); /* cache/rtr/index */ file = fopen(filepath, "r"); if (!file) { + error = errno; + if (error != ENOENT) + pr_op_warn("Cannot open RTR index: %s", strerror(error)); free(filepath); - return errno; + return error; } free(filepath); - if (fscanf(file, "session:%u serial:%u", &session, &serial) >= 2) { - rtr->session = session; - rtr->serial = serial; - } else { - error = EINVAL; + if (!fgets(buf, sizeof(buf), file)) { + pr_op_debug("RTR index seems empty."); + goto fail; + } + if (sscanf(buf, "session:%u", &se) < 1 || se > UINT16_MAX) { + pr_op_debug("First line of RTR index is not a session."); + goto fail; + } + + idx->session = se; + prev = NULL; + + while (fgets(buf, sizeof(buf), file) != NULL) { + srl = pzalloc(sizeof(struct rtr_serial)); + + if (sscanf(buf, "serial:%u date:%d-%d-%dT%d:%d:%dZ", + &se, &srl->date.tm_year, &srl->date.tm_mon, + &srl->date.tm_mday, &srl->date.tm_hour, &srl->date.tm_min, + &srl->date.tm_sec) < 1 || se > UINT32_MAX) { + pr_op_debug("Malformed serial in RTR index."); + goto fail; + } + srl->serial = se; + + if (idx->serials) { + if (serial_le(idx->serials->serial, srl->serial)) { + pr_op_debug("RTR index serials are not sorted."); + goto fail; + } + } + + srl->date.tm_year -= 1900; + srl->date.tm_mon -= 1; + if (prev) + prev->next = srl; + else + idx->serials = srl; + prev = srl; + + if (!all) + break; } fclose(file); - return error; + return 0; + +fail: fclose(file); + rtridx_cleanup(idx); + return ENOENT; +} + +serial_t +rtridx_add_serial(struct rtr_index *idx) +{ + struct rtr_serial *srl; + time_t now; + + srl = pmalloc(sizeof(struct rtr_serial)); + + srl->serial = idx->serials ? (idx->serials->serial + 1) : 1; + + now = time(NULL); + if (now == (time_t)-1) + pr_crit("time(NULL) returned (time_t) -1."); + if (gmtime_r(&now, &srl->date) == NULL) + pr_crit("gmtime_r(now) failed: %s", strerror(errno)); + + srl->next = idx->serials; + idx->serials = srl; + + return srl->serial; +} + +void +rtridx_cleanup(struct rtr_index *idx) +{ + struct rtr_serial *srl; + + while (idx->serials) { + srl = idx->serials; + idx->serials = srl->next; + free(srl); + } +} + +void +rtridx_print(struct rtr_index *idx) +{ + struct rtr_serial *srl; + + printf("==== RTR index ====\n"); + + if (!idx) { + printf("\n"); + return; + } + + printf("session:%u\n", idx->session); + printf("serials:\n"); + + for (srl = idx->serials; srl; srl = srl->next) + printf(" serial:%u date:%04d-%02d-%02dT%02d:%02d:%02dZ\n", + srl->serial, + srl->date.tm_year + 1900, srl->date.tm_mon + 1, srl->date.tm_mday, + srl->date.tm_hour, srl->date.tm_min + 1, srl->date.tm_sec); +} + +static bool +is_number(char const *str) +{ + if (*str == 0) + return false; + + for (; *str != 0; str++) + if (*str < '0' || '9' < *str) + return false; + + return true; +} + +static void +rm_rf(char *path) +{ + int error; + + error = file_rm_rf(path); + if (error < 0) + pr_op_warn("Cannot delete %s: nftw returned %d", path, error); + else if (error) + pr_op_warn("Cannot delete %s: %s", path, strerror(error)); + + free(path); +} + +static void +delete_unindexed_serials(serial_t min, serial_t max) +{ + char *path; + DIR *dir; + struct dirent *file; + serial_t serial; + + path = rtr_filename(NULL, NULL); + dir = opendir(path); + free(path); + if (!dir) { + if (errno != ENOENT) + pr_op_warn("Cannot clean rtr directory: %s", + strerror(errno)); + return; + } + + FOREACH_DIR_FILE(dir, file) { + if (S_ISDOTS(file) || strcmp(file->d_name, "index") == 0) + continue; + if (!is_number(file->d_name)) + goto rm; + + errno = 0; + serial = strtoul(file->d_name, NULL, 10); + if (errno || serial > UINT32_MAX) + goto rm; + + if (serial_le(min, serial) && serial_le(serial, max)) + continue; + +rm: pr_op_warn("Deleting stray filesystem entry rtr/%s", file->d_name); + rm_rf(rtr_filename(file->d_name, NULL)); + } + if (errno) + pr_op_warn("Cleanup rtr directory traversal interrupted: %s", + strerror(errno)); + + closedir(dir); +} + +/* + * Cleans cache/rtr. + * This means dropping serials that exceed the threshold + * (config_get_deltas_lifetime()) and unknown files or directories + * directly in cache/rtr. + */ +void +rtridx_clean(struct rtr_index *idx) +{ + struct rtr_serial *srl, **prev; + serial_t min, max; + + max = idx->serials[0].serial; + min = max - config_get_deltas_lifetime(); + + for (srl = idx->serials, prev = &idx->serials; srl; srl = *prev) { + if (serial_lt(srl->serial, min) || serial_lt(max, srl->serial)) { + pr_op_debug("Dropping serial by FIFO: %u", srl->serial); + rm_rf(rtr_filename2(srl->serial, NULL)); + *prev = srl->next; + free(srl); + } else { + prev = &srl->next; + } + } + + if (!idx->serials) { + /* The session died; we'll create a new one later. */ + pr_op_debug("All serials expired; clearing RTR cache."); + rm_rf(rtr_filename(NULL, NULL)); + return; + } + + rtridx_save(idx); + + /* Clean up unindexed serials for paranoia */ + delete_unindexed_serials(min, max); +} + +static bool +too_old(struct rtr_serial *srl, time_t now) +{ + time_t serial_date; + double diff; + unsigned int lifetime; + + serial_date = timegm(&srl->date); + if (serial_date == (time_t)-1) + return true; /* Dunno; delete it */ + + diff = difftime(serial_date, now); + if (diff > 0) + return true; /* Dunno; delete it */ + + /* + * This is an estimate. In reality, I'd like deltas_lifetime to be the + * timestamp, but I can't because of historical reasons, and also + * because it's a lot easier to test as a cycle count. + */ + lifetime = config_get_deltas_lifetime() * config_get_validation_interval(); + + return (-diff) > lifetime; +} + +/* Deletes serials that are too old, based on time. */ +void +rtridx_expire(void) +{ + time_t now; + struct rtr_index idx; + struct rtr_serial *srl, **prev; + int error; + + now = time(NULL); + if (now == (time_t)-1) { + pr_op_warn("Can't ditch old RTR: time() returned -1."); + return; + } + + error = rtridx_load(&idx, true); + if (error == ENOENT) + return; + if (error) { + pr_op_warn("Can't ditch old RTR: %s", strerror(error)); + return; + } + + for (srl = idx.serials, prev = &idx.serials; srl; srl = *prev) { + if (too_old(srl, now)) { + pr_op_debug("Dropping expired serial: %u", srl->serial); + rm_rf(rtr_filename2(srl->serial, NULL)); + *prev = srl->next; + free(srl); + } else { + prev = &srl->next; + } + } + + if (!idx.serials) { + /* The session died; we'll create a new one later. */ + pr_op_debug("All serials expired; clearing RTR cache."); + rm_rf(rtr_filename(NULL, NULL)); + goto end; + } + + rtridx_save(&idx); +end: rtridx_cleanup(&idx); } int diff --git a/src/rtr/meta.h b/src/rtr/meta.h index 67af12af..73822148 100644 --- a/src/rtr/meta.h +++ b/src/rtr/meta.h @@ -2,6 +2,8 @@ #define SRC_RTR_META_H_ #include +#include +#include #include "types/serial.h" struct rtr_metadata { @@ -21,12 +23,35 @@ struct rtr_metadata { serial_t serial; }; +struct rtr_serial { + serial_t serial; + struct tm date; + struct rtr_serial *next; +}; + +struct rtr_index { + uint16_t session; + /* + * Linked list; sorted from newest to oldest. + * + * Can't use SLIST because clean() and expire() want safe traversal + * with cursor removals. + */ + struct rtr_serial *serials; +}; + char *rtr_filename(char const *, char const *); char *rtr_filename2(serial_t, char const *); -void rtr_new_metadata(struct rtr_metadata *); -int rtr_save_metadata(struct rtr_metadata *); -int rtr_load_metadata(struct rtr_metadata *); +void rtridx_init(struct rtr_index *); +int rtridx_save(struct rtr_index *); +int rtridx_load(struct rtr_index *, bool); +serial_t rtridx_add_serial(struct rtr_index *); +void rtridx_cleanup(struct rtr_index *); +void rtridx_print(struct rtr_index *); + +void rtridx_clean(struct rtr_index *); +void rtridx_expire(void); int rtr_serial_stat(serial_t serial); diff --git a/src/rtr/pdu_handler.c b/src/rtr/pdu_handler.c index 98f63ece..a02b077a 100644 --- a/src/rtr/pdu_handler.c +++ b/src/rtr/pdu_handler.c @@ -229,6 +229,27 @@ send_aspas(int fd, uint8_t ver, serial_t serial) return error; } +static int +load_rtr_metadata(struct rtr_metadata *rtr) +{ + struct rtr_index idx; + int error; + + error = rtridx_load(&idx, false); + if (error) + return error; + if (idx.serials == NULL) { + error = ENOENT; + goto end; + } + + rtr->session = idx.session; + rtr->serial = idx.serials->serial; + +end: rtridx_cleanup(&idx); + return error; +} + int handle_reset_query_pdu(struct rtr_request *request) { @@ -242,7 +263,7 @@ handle_reset_query_pdu(struct rtr_request *request) stream.fd = request->fd; stream.ver = request->pdu.rtr_version; - error = rtr_load_metadata(&rtr); + error = load_rtr_metadata(&rtr); switch (error) { case 0: break; @@ -493,7 +514,7 @@ handle_serial_query_pdu(struct rtr_request *request) stream.fd = request->fd; stream.ver = request->pdu.rtr_version; - error = rtr_load_metadata(&rtr); + error = load_rtr_metadata(&rtr); switch (error) { case 0: break; case ENOENT: return err_pdu_send_no_data_available(stream.fd, stream.ver); @@ -520,6 +541,8 @@ handle_serial_query_pdu(struct rtr_request *request) default: goto internal_error; } + pr_op_debug("Sending RTR delta: %u-%u", oserial, nserial); + error = send_cache_response_pdu(stream.fd, stream.ver, rtr.session); if (error) return error; diff --git a/src/rtr/pdu_sender.c b/src/rtr/pdu_sender.c index 1d3ac771..baf7d610 100644 --- a/src/rtr/pdu_sender.c +++ b/src/rtr/pdu_sender.c @@ -92,6 +92,8 @@ send_serial_notify_pdu(int fd, uint8_t version, struct rtr_metadata *meta) unsigned char data[RTRPDU_SERIAL_NOTIFY_LEN]; unsigned char *buf; + pr_op_debug("Sending Serial Notify PDU."); + buf = serialize_hdr(data, version, type, meta->session, len); buf = write_uint32(buf, meta->serial); @@ -105,8 +107,8 @@ send_cache_reset_pdu(int fd, uint8_t version) static const uint32_t len = RTRPDU_CACHE_RESET_LEN; unsigned char data[RTRPDU_CACHE_RESET_LEN]; + pr_op_debug("Sending Cache Reset PDU."); serialize_hdr(data, version, type, 0, len); - return send_response(fd, type, data, len); } @@ -117,8 +119,8 @@ send_cache_response_pdu(int fd, uint8_t version, uint16_t session) static const uint32_t len = RTRPDU_CACHE_RESPONSE_LEN; unsigned char data[RTRPDU_CACHE_RESPONSE_LEN]; + pr_op_debug("Sending Cache Response PDU."); serialize_hdr(data, version, type, session, len); - return send_response(fd, type, data, len); } @@ -165,6 +167,8 @@ send_ipv6_prefix_pdu(int fd, uint8_t version, struct vrp const *vrp, int send_prefix_pdu(int fd, uint8_t version, struct vrp const *vrp, uint8_t flags) { + pr_op_debug("Sending Prefix PDU."); + switch (vrp->addr_fam) { case AF_INET: return send_ipv4_prefix_pdu(fd, version, vrp, flags); @@ -187,6 +191,8 @@ send_router_key_pdu(int fd, uint8_t version, if (version < RTR_V1) return 0; + pr_op_debug("Sending RK PDU."); + buf = serialize_hdr(data, version, type, flags << 8, len); memcpy(buf, router_key->ski, sizeof(router_key->ski)); buf += sizeof(router_key->ski); @@ -209,6 +215,8 @@ send_aspa_announce_pdu(int fd, uint8_t version, struct aspa const *aspa) if (version < RTR_V2) return 0; + pr_op_debug("Sending ASPA announcement PDU."); + bufsize = 12 + 4 * aspa->providers.count; if (bufsize > 1024) bufsize = 1024; @@ -246,6 +254,8 @@ send_aspa_withdraw_pdu(int fd, uint8_t version, uint32_t customer) unsigned char data[12]; unsigned char *buf; + pr_op_debug("Sending ASPA withdraw PDU."); + buf = serialize_hdr(data, version, type, FLAG_WITHDRAWAL << 8, 12); write_uint32(buf, customer); @@ -264,6 +274,8 @@ send_end_of_data_pdu(int fd, uint8_t version, uint16_t session, serial_t serial) unsigned char *buf; uint32_t len; + pr_op_debug("Sending End of Data PDU."); + switch (version) { case RTR_V0: len = RTRPDU_END_OF_DATA_V0_LEN; @@ -314,6 +326,8 @@ send_error_report_pdu(int fd, uint8_t version, uint16_t code, size_t len; int error; + pr_op_debug("Sending error PDU: %s", message); + error_pdu_len = compute_error_pdu_len(request); error_msg_len = (message != NULL) ? strlen(message) : 0; len = rtrpdu_error_report_len(error_pdu_len, error_msg_len); diff --git a/src/rtr/rtr.c b/src/rtr/rtr.c index e3fedaed..2e7d4da7 100644 --- a/src/rtr/rtr.c +++ b/src/rtr/rtr.c @@ -682,6 +682,8 @@ rtr_start(void) { int error; + rtridx_expire(); + server_arraylist_init(&servers); client_arraylist_init(&clients); diff --git a/src/types/serial.c b/src/types/serial.c index 9fbe6558..ad80da1c 100644 --- a/src/types/serial.c +++ b/src/types/serial.c @@ -12,3 +12,9 @@ serial_lt(serial_t s1, serial_t s2) return ((s1 < s2) && ((s2 - s1) < 0x80000000u)) || ((s1 > s2) && ((s1 - s2) > 0x80000000u)); } + +bool +serial_le(serial_t s1, serial_t s2) +{ + return (s1 == s2) ? true : serial_lt(s1, s2); +} diff --git a/src/types/serial.h b/src/types/serial.h index a9b1683d..72af8bfc 100644 --- a/src/types/serial.h +++ b/src/types/serial.h @@ -7,5 +7,6 @@ typedef uint32_t serial_t; bool serial_lt(serial_t s1, serial_t s2); +bool serial_le(serial_t s1, serial_t s2); #endif /* SRC_TYPES_SERIAL_H_ */ diff --git a/test/rtr/db/db_table_test.c b/test/rtr/db/db_table_test.c index 3bcd9388..31c6a9b1 100644 --- a/test/rtr/db/db_table_test.c +++ b/test/rtr/db/db_table_test.c @@ -23,9 +23,9 @@ static unsigned int total_found; __MOCK_ABORT(config_get_deltas_lifetime, unsigned int, 0, void) __MOCK_ABORT(config_get_local_repository, char const *, "tmp/dbt", void) MOCK_UINT(config_get_max_aspa_providers, 10, void) -MOCK_ABORT_VOID(rtr_new_metadata, struct rtr_metadata *m) -MOCK_ABORT_INT(rtr_save_metadata, struct rtr_metadata *m) -MOCK_ABORT_INT(rtr_load_metadata, struct rtr_metadata *m) +MOCK_ABORT_VOID(rtridx_init, struct rtr_index *i) +MOCK_ABORT_INT(rtridx_save, struct rtr_index *i) +MOCK_ABORT_INT(rtridx_load, struct rtr_index *i, bool b) MOCK_ABORT_INT(rtr_open_file, serial_t serial, char const *basename, char const *mode, FILE **result) __MOCK_ABORT(rtr_filename, char *, NULL, char const *a, char const *b)