Fixes the new issue reported in #103.
max: maximum
min: minimum
msg: message
-notif: Notification
+notif: (RRDP) Notification
pdu: Protocol Data Unit (RFC 6810)
pp: Publication Point
pr: print
#define TAGNAME_ATTEMPT_TS "attempt-timestamp"
#define TAGNAME_ATTEMPT_ERR "attempt-result"
#define TAGNAME_SUCCESS_TS "success-timestamp"
+#define TAGNAME_IS_NOTIF "is-rrdp-notification"
static char *
get_json_filename(struct rpki_cache *cache)
{
struct cache_node *node;
char const *url;
+ bool is_notif;
enum uri_type type;
int error;
pr_op_err("Unknown protocol: %s", url);
goto fail;
}
- error = uri_create(&node->url, cache->tal, type, NULL, url);
+
+ error = json_get_bool(json, TAGNAME_IS_NOTIF, &is_notif);
+ if (error < 0)
+ goto fail;
+
+ error = uri_create(&node->url, cache->tal, type, is_notif, NULL, url);
+ if (error) {
+ pr_op_err("Cannot parse '%s' into a URI.", url);
+ goto fail;
+ }
error = json_get_ts(json, TAGNAME_ATTEMPT_TS, &node->attempt.ts);
if (error) {
if (json_add_str(json, TAGNAME_URL, uri_get_global(node->url)))
goto cancel;
+ if (uri_is_notif(node->url))
+ if (json_add_bool(json, TAGNAME_IS_NOTIF, true))
+ goto cancel;
if (json_add_date(json, TAGNAME_ATTEMPT_TS, node->attempt.ts))
goto cancel;
if (json_add_int(json, TAGNAME_ATTEMPT_ERR, node->attempt.result))
if (*c == '/') {
slashes++;
if (slashes == 4)
- return __uri_create(url, tal, UT_RSYNC, NULL,
- guri, c - guri + 1);
+ return __uri_create(url, tal, UT_RSYNC, false,
+ NULL, guri, c - guri + 1);
}
}
if (slashes == 3 && *(c - 1) != '/') {
guri2 = pstrdup(guri); /* Remove const */
guri2[c - guri] = '/';
- error = __uri_create(url, tal, UT_RSYNC, NULL, guri2,
+ error = __uri_create(url, tal, UT_RSYNC, false, NULL, guri2,
c - guri + 1);
free(guri2);
return error;
delete_node_and_cage(struct rpki_cache *cache, struct cache_node *node)
{
struct rpki_uri *cage;
- int error;
- if (uri_get_type(node->url) == UT_HTTPS) {
- error = __uri_create(&cage, cache->tal, UT_CAGED, node->url,
- "", 0);
- if (!error) {
+ if (uri_is_notif(node->url)) {
+ if (uri_create_cage(&cage, cache->tal, node->url) == 0) {
pr_op_debug("Deleting cage %s.", uri_get_local(cage));
file_rm_rf(uri_get_local(cage));
uri_refput(cage);
break;
case ENOENT:
/* Node exists but file doesn't: Delete node */
+ pr_op_debug("Node exists but file doesn't: %s", path);
delete_node_and_cage(cache, node);
return;
default:
uri_refget(node->url);
uris_add(&dnc, node->url);
- error = __uri_create(&cage, cache->tal, UT_CAGED, node->url,
- "", 0);
- if (error) {
+ if (!uri_is_notif(node->url))
+ continue;
+
+ if (uri_create_cage(&cage, cache->tal, node->url) != 0) {
pr_op_err("Cannot generate %s's cage. I'm probably going to end up deleting it from the cache.",
uri_op_get_printable(node->url));
continue;
struct cache_node *node, *tmp;
time_t last_week;
+ pr_op_debug("Cleaning up old abandoned cache files.");
last_week = get_days_ago(7);
HASH_ITER(hh, cache->ht, node, tmp)
cleanup_node(cache, node, last_week);
+ pr_op_debug("Cleaning up unknown cache files.");
delete_unknown_files(cache);
}
* Create @uri from the @ad
*/
static int
-uri_create_ad(struct rpki_uri **uri, ACCESS_DESCRIPTION *ad, enum uri_type type)
+uri_create_ad(struct rpki_uri **uri, ACCESS_DESCRIPTION *ad, enum uri_type type,
+ bool is_notif)
{
- ASN1_STRING *asn1_string;
+ ASN1_STRING *asn1str;
int ptype;
- asn1_string = GENERAL_NAME_get0_value(ad->location, &ptype);
+ asn1str = GENERAL_NAME_get0_value(ad->location, &ptype);
/*
* RFC 6487: "This extension MUST have an instance of an
* But ask the testers to keep an eye on it anyway.
*/
return __uri_create(uri,
- tal_get_file_name(validation_tal(state_retrieve())), type, NULL,
- ASN1_STRING_get0_data(asn1_string),
- ASN1_STRING_length(asn1_string));
+ tal_get_file_name(validation_tal(state_retrieve())), type,
+ is_notif, NULL,
+ ASN1_STRING_get0_data(asn1str), ASN1_STRING_length(asn1str));
}
/**
for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ia); i++) {
ad = sk_ACCESS_DESCRIPTION_value(ia, i);
if (OBJ_obj2nid(ad->method) == nid) {
- error = uri_create_ad(&uri, ad, meta->type);
+ error = uri_create_ad(&uri, ad, meta->type,
+ meta == &RPKI_NOTIFY);
switch (error) {
case 0:
break;
return 0;
}
- return __uri_create(uri,
- tal_get_file_name(validation_tal(state_retrieve())),
- UT_CAGED, notif, uri_get_global(*uri),
- uri_get_global_len(*uri));
+ return uri_create_caged(uri,
+ tal_get_file_name(validation_tal(state_retrieve())), notif,
+ uri_get_global(*uri), uri_get_global_len(*uri));
}
static int
int error;
if (str_starts_with(uri, "rsync://"))
- error = uri_create(&new, tal, UT_RSYNC, NULL, uri);
+ error = uri_create(&new, tal, UT_RSYNC, false, NULL, uri);
else if (str_starts_with(uri, "https://"))
- error = uri_create(&new, tal, UT_HTTPS, NULL, uri);
+ error = uri_create(&new, tal, UT_HTTPS, false, NULL, uri);
else
return pr_op_err("TAL has non-RSYNC/HTTPS URI: %s", uri);
if (error)
error = uri_create(&meta->uri,
tal_get_file_name(validation_tal(state_retrieve())),
(notif != NULL) ? UT_CAGED : UT_HTTPS,
- notif, (char const *)uri);
+ false, notif, (char const *)uri);
xmlFree(uri);
if (error)
return error;
#include "types/uri.h"
-
#include "alloc.h"
#include "common.h"
#include "config.h"
/* "local_len" is never needed right now. */
enum uri_type type;
+ bool is_notif; /* Does it point to an RRDP Notification? */
unsigned int references;
};
*/
int
__uri_create(struct rpki_uri **result, char const *tal, enum uri_type type,
- struct rpki_uri *notif, void const *guri, size_t guri_len)
+ bool is_notif, struct rpki_uri *notif, void const *guri, size_t guri_len)
{
struct rpki_uri *uri;
int error;
}
uri->type = type;
+ uri->is_notif = is_notif;
error = autocomplete_local(uri, tal, notif);
if (error) {
return 0;
}
-int
-uri_create(struct rpki_uri **result, char const *tal, enum uri_type type,
- struct rpki_uri *notif, char const *guri)
-{
- return __uri_create(result, tal, type, notif, guri, strlen(guri));
-}
-
/*
* Manifest fileList entries are a little special in that they're just file
* names. This function will infer the rest of the URL.
return uri_has_extension(uri, ".cer");
}
+bool
+uri_is_notif(struct rpki_uri *uri)
+{
+ return uri->is_notif;
+}
+
enum uri_type
uri_get_type(struct rpki_uri *uri)
{
#ifndef SRC_TYPES_URI_H_
#define SRC_TYPES_URI_H_
+#include <stdbool.h>
#include "asn1/asn1c/IA5String.h"
#include "data_structure/array_list.h"
struct rpki_uri;
int __uri_create(struct rpki_uri **, char const *, enum uri_type,
- struct rpki_uri *, void const *, size_t);
-int uri_create(struct rpki_uri **, char const *, enum uri_type,
- struct rpki_uri *, char const *);
+ bool, struct rpki_uri *, void const *, size_t);
int uri_create_mft(struct rpki_uri **, char const *, struct rpki_uri *,
struct rpki_uri *, IA5String_t *);
struct rpki_uri *uri_create_cache(char const *);
+#define uri_create(uri, tal, type, is_notif, notif, guri) \
+ __uri_create(uri, tal, type, is_notif, notif, guri, strlen(guri))
+#define uri_create_caged(uri, tal, notif, guri, guri_len) \
+ __uri_create(uri, tal, UT_CAGED, false, notif, guri, guri_len)
+#define uri_create_cage(uri, tal, notif) \
+ uri_create_caged(uri, tal, notif, "", 0)
+
struct rpki_uri *uri_refget(struct rpki_uri *);
void uri_refput(struct rpki_uri *);
bool uri_equals(struct rpki_uri *, struct rpki_uri *);
bool uri_has_extension(struct rpki_uri *, char const *);
bool uri_is_certificate(struct rpki_uri *);
+bool uri_is_notif(struct rpki_uri *);
enum uri_type uri_get_type(struct rpki_uri *);
bool uri_is_rsync(struct rpki_uri *);
rsync_counter = 0;
https_counter = 0;
- ck_assert_int_eq(0, uri_create(&uri, TAL_FILE, type, NULL, url));
+ ck_assert_int_eq(0, uri_create(&uri, TAL_FILE, type, false, NULL, url));
ck_assert_int_eq(expected_error, cache_download(cache, uri, NULL));
ck_assert_uint_eq(rsync_calls, rsync_counter);
ck_assert_uint_eq(https_calls, https_counter);
}
static struct cache_node *
-node(char const *url, time_t attempt, int err, bool succeeded, time_t success)
+node(char const *url, time_t attempt, int err, bool succeeded, time_t success,
+ bool is_notif)
{
enum uri_type type;
struct cache_node *result;
ck_abort_msg("Bad protocol: %s", url);
result = pzalloc(sizeof(struct cache_node));
- ck_assert_int_eq(0, uri_create(&result->url, TAL_FILE, type, NULL, url));
+ ck_assert_int_eq(0, uri_create(&result->url, TAL_FILE, type, is_notif,
+ NULL, url));
result->attempt.ts = attempt;
result->attempt.result = err;
result->success.happened = succeeded;
}
#define NODE(url, err, succeeded, has_file) \
- node(url, has_file, err, succeeded, 0)
+ node(url, has_file, err, succeeded, 0, 0)
static void
reset_visiteds(void)
add_node(cache, NODE("rsync://a.b.c/e", 1, 0, 0));
add_node(cache, NODE("rsync://x.y.z/e", 0, 1, 0));
add_node(cache, NODE("https://a/b", 1, 1, 0));
- add_node(cache, NODE("https://a/c", 0, 1, 0));
+ add_node(cache, node("https://a/c", 0, 0, 1, 0, 1));
json = build_metadata_json(cache);
ck_assert_int_eq(0, json_dump_file(json, "tmp/" TAL_FILE "/metadata.json", JSON_COMPACT));
str = json_dumps(json, /* JSON_INDENT(4) */ JSON_COMPACT);
- /* printf("%s\n", str); */
json_decref(json);
ck_assert_str_eq(
"{\"url\":\"rsync://a.b.c/e\",\"attempt-timestamp\":\"1970-01-01T00:00:00Z\",\"attempt-result\":1},"
"{\"url\":\"rsync://x.y.z/e\",\"attempt-timestamp\":\"1970-01-01T00:00:00Z\",\"attempt-result\":0,\"success-timestamp\":\"1970-01-01T00:00:00Z\"},"
"{\"url\":\"https://a/b\",\"attempt-timestamp\":\"1970-01-01T00:00:00Z\",\"attempt-result\":1,\"success-timestamp\":\"1970-01-01T00:00:00Z\"},"
- "{\"url\":\"https://a/c\",\"attempt-timestamp\":\"1970-01-01T00:00:00Z\",\"attempt-result\":0,\"success-timestamp\":\"1970-01-01T00:00:00Z\"}]",
+ "{\"url\":\"https://a/c\",\"is-rrdp-notification\":true,\"attempt-timestamp\":\"1970-01-01T00:00:00Z\",\"attempt-result\":0,\"success-timestamp\":\"1970-01-01T00:00:00Z\"}]",
str);
- printf("%s", str);
free(str);
cache_reset(cache);
type = UT_RSYNC;
else
ck_abort_msg("Bad protocol: %s", str);
- ck_assert_int_eq(0, uri_create(&uri, TAL_FILE, type, NULL, str));
+ ck_assert_int_eq(0, uri_create(&uri, TAL_FILE, type, false,
+ NULL, str));
uris_add(uris, uri);
}
va_end(args);
*/
cache_reset(cache);
- add_node(cache, node("rsync://a/1", 100, 0, 1, 100));
- add_node(cache, node("rsync://a/2", 100, 1, 1, 100));
- add_node(cache, node("rsync://a/3", 200, 0, 1, 100));
- add_node(cache, node("rsync://a/4", 200, 1, 1, 100));
- add_node(cache, node("rsync://a/5", 100, 0, 1, 200));
- add_node(cache, node("rsync://a/6", 100, 1, 1, 200));
- add_node(cache, node("rsync://b/1", 100, 0, 0, 100));
- add_node(cache, node("rsync://b/2", 100, 1, 0, 100));
- add_node(cache, node("rsync://b/3", 200, 0, 0, 100));
- add_node(cache, node("rsync://b/4", 200, 1, 0, 100));
- add_node(cache, node("rsync://b/5", 100, 0, 0, 200));
- add_node(cache, node("rsync://b/6", 100, 1, 0, 200));
+ add_node(cache, node("rsync://a/1", 100, 0, 1, 100, 0));
+ add_node(cache, node("rsync://a/2", 100, 1, 1, 100, 0));
+ add_node(cache, node("rsync://a/3", 200, 0, 1, 100, 0));
+ add_node(cache, node("rsync://a/4", 200, 1, 1, 100, 0));
+ add_node(cache, node("rsync://a/5", 100, 0, 1, 200, 0));
+ add_node(cache, node("rsync://a/6", 100, 1, 1, 200, 0));
+ add_node(cache, node("rsync://b/1", 100, 0, 0, 100, 0));
+ add_node(cache, node("rsync://b/2", 100, 1, 0, 100, 0));
+ add_node(cache, node("rsync://b/3", 200, 0, 0, 100, 0));
+ add_node(cache, node("rsync://b/4", 200, 1, 0, 100, 0));
+ add_node(cache, node("rsync://b/5", 100, 0, 0, 200, 0));
+ add_node(cache, node("rsync://b/6", 100, 1, 0, 200, 0));
/* Multiple successful caches: Prioritize the most recent one */
PREPARE_URI_LIST(&uris, "rsync://a/1", "rsync://a/3", "rsync://a/5");
MOCK_ABORT_INT(relax_ng_parse, const char *path, xml_read_cb cb, void *arg)
MOCK_ABORT_PTR(state_retrieve, validation, void)
__MOCK_ABORT(tal_get_file_name, char const *, NULL, struct tal *tal)
-MOCK_ABORT_INT(uri_create, struct rpki_uri **result, char const *tal,
- enum uri_type type, struct rpki_uri *notif, char const *guri)
__MOCK_ABORT(uri_get_global, char const *, NULL, struct rpki_uri *uri)
__MOCK_ABORT(uri_get_local, char const *, NULL, struct rpki_uri *uri)
__MOCK_ABORT(uri_get_rrdp_workspace, char *, NULL, char const *tal,
/* Tests */
-#define URI_CREATE_HTTP(uri, str) uri_create(&uri, "test.tal", UT_HTTPS, NULL, str)
-#define URI_CREATE_RSYNC(uri, str) uri_create(&uri, "test.tal", UT_RSYNC, NULL, str)
+#define URI_CREATE_HTTP(uri, str) uri_create(&uri, "test.tal", UT_HTTPS, false, NULL, str)
+#define URI_CREATE_RSYNC(uri, str) uri_create(&uri, "test.tal", UT_RSYNC, false, NULL, str)
START_TEST(test_constructor)
{
{
struct rpki_uri *uri;
- ck_assert_int_eq(0, uri_create(¬if, "test.tal", UT_HTTPS, NULL, "https://a.b.c/d/e.xml"));
- ck_assert_int_eq(0, uri_create(&uri, "test.tal", UT_CAGED, notif, "rsync://x.y.z/v/w.cer"));
+ ck_assert_int_eq(0, uri_create(¬if, "test.tal", UT_HTTPS, true, NULL, "https://a.b.c/d/e.xml"));
+ ck_assert_int_eq(0, uri_create(&uri, "test.tal", UT_CAGED, false, notif, "rsync://x.y.z/v/w.cer"));
ck_assert_str_eq("tmp/test.tal/rrdp/a.b.c/d/e.xml/x.y.z/v/w.cer", uri_get_local(uri));
uri_refput(uri);
uri_refput(notif);
- ck_assert_int_eq(0, uri_create(¬if, "test.tal", UT_HTTPS, NULL, "https://a.b.c"));
- ck_assert_int_eq(0, uri_create(&uri, "test.tal", UT_CAGED, notif, "rsync://w"));
+ ck_assert_int_eq(0, uri_create(¬if, "test.tal", UT_HTTPS, true, NULL, "https://a.b.c"));
+ ck_assert_int_eq(0, uri_create(&uri, "test.tal", UT_CAGED, false, notif, "rsync://w"));
ck_assert_str_eq("tmp/test.tal/rrdp/a.b.c/w", uri_get_local(uri));
uri_refput(uri);
uri_refput(notif);