*/
struct serial_numbers serials;
- /*
- * Certificate repository "level". This aims to identify if the
- * certificate is located at a distinct server than its father (common
- * case when the RIRs delegate RPKI repositories).
- */
- unsigned int level;
-
/** Used by certstack. Points to the next stacked certificate. */
SLIST_ENTRY(metadata_node) next;
};
return error;
}
-static int
-init_level(struct cert_stack *stack, unsigned int *_result)
-{
- struct metadata_node *head_meta;
- unsigned int work_repo_level;
- unsigned int result;
-
- /*
- * Bruh, I don't understand the point of this block.
- * Why can't it just be `result = working_repo_peek_level();`?
- */
-
- result = 0;
- work_repo_level = working_repo_peek_level();
- head_meta = SLIST_FIRST(&stack->metas);
- if (head_meta != NULL && work_repo_level > head_meta->level)
- result = work_repo_level;
-
- *_result = result;
- return 0;
-}
-
static struct defer_node *
create_separator(void)
{
if (error)
goto cleanup_serial;
- error = init_level(stack, &meta->level); /* Does not need a revert */
- if (error)
- goto destroy_resources;
-
defer_separator = create_separator();
ok = sk_X509_push(stack->x509s, x509);
destroy_separator:
free(defer_separator);
-destroy_resources:
resources_destroy(meta->resources);
cleanup_serial:
serial_numbers_cleanup(&meta->serials, serial_cleanup);
return (meta != NULL) ? meta->resources : NULL;
}
-unsigned int
-x509stack_peek_level(struct cert_stack *stack)
-{
- struct metadata_node *meta = SLIST_FIRST(&stack->metas);
- return (meta != NULL) ? meta->level : 0;
-}
-
static char *
get_current_file_name(void)
{
X509 *x509stack_peek(struct cert_stack *);
struct rpki_uri *x509stack_peek_uri(struct cert_stack *);
struct resources *x509stack_peek_resources(struct cert_stack *);
-unsigned int x509stack_peek_level(struct cert_stack *);
void x509stack_store_serial(struct cert_stack *, BIGNUM *);
typedef int (*subject_pk_check_cb)(bool *, char const *, void *);
int x509stack_store_subject(struct cert_stack *, struct rfc5280_name *,
* Returns 0 on success, otherwise an error code.
*/
char *
-map_uri_to_local(char const *uri, char const *uri_prefix, char const *workspace)
+map_uri_to_local(char const *uri, char const *uri_prefix)
{
char const *repository;
char *local;
size_t repository_len;
size_t uri_prefix_len;
size_t uri_len;
- size_t workspace_len;
size_t extra_slash;
size_t offset;
uri_len -= uri_prefix_len;
extra_slash = (repository[repository_len - 1] == '/') ? 0 : 1;
- workspace_len = 0;
- if (workspace != NULL)
- workspace_len = strlen(workspace);
-
- local = pmalloc(repository_len + extra_slash + workspace_len + uri_len + 1);
+ local = pmalloc(repository_len + extra_slash + uri_len + 1);
offset = 0;
strcpy(local + offset, repository);
strcpy(local + offset, "/");
offset += extra_slash;
}
- if (workspace_len > 0) {
- strcpy(local + offset, workspace);
- offset += workspace_len;
- }
strncpy(local + offset, uri, uri_len);
offset += uri_len;
local[offset] = '\0';
int get_current_time(time_t *);
-char *map_uri_to_local(char const *, char const*, char const *);
+char *map_uri_to_local(char const *, char const *);
#endif /* SRC_RTR_COMMON_H_ */
/* ASN1 decoder max stack size allowed */
unsigned int asn1_decode_max_stack;
- /* Time period that must lapse to warn about a stale repository */
+ /* Deprecated; does nothing. */
unsigned int stale_repository_period;
/* Download the normal TALs into --tal? */
.name = "stale-repository-period",
.type = >_uint,
.offset = offsetof(struct rpki_config, stale_repository_period),
- .doc = "Time period that must lapse to warn about stale repositories",
+ .doc = "Deprecated; does nothing.",
.min = 0,
.max = UINT_MAX,
},
rpki_config.output.format = OFM_CSV;
rpki_config.asn1_decode_max_stack = 4096; /* 4kB */
- rpki_config.stale_repository_period = 43200; /* 12 hours */
rpki_config.init_tals = false;
rpki_config.init_tal_locations = 0;
return rpki_config.asn1_decode_max_stack;
}
-unsigned int
-config_get_stale_repository_period(void)
-{
- return rpki_config.stale_repository_period;
-}
-
unsigned int
config_get_thread_pool_server_max(void)
{
char const *config_get_output_bgpsec(void);
enum output_format config_get_output_format(void);
unsigned int config_get_asn1_decode_max_stack(void);
-unsigned int config_get_stale_repository_period(void);
unsigned int config_get_thread_pool_server_max(void);
unsigned int config_get_thread_pool_validation_max(void);
* - '= 0' no error
*/
static int
-get_local_path(char const *rcvd, char const *workspace, char **result)
+get_local_path(char const *rcvd, char **result)
{
struct stat attr;
char *tmp, *local_path;
int error;
/* Currently, only rsync URIs are utilized */
- local_path = map_uri_to_local(rcvd, "rsync://", workspace);
+ local_path = map_uri_to_local(rcvd, "rsync://");
error = stat(local_path, &attr);
if (error) {
}
static int
-rename_all_roots(struct rem_dirs *rem_dirs, char **src, char const *workspace)
+rename_all_roots(struct rem_dirs *rem_dirs, char **src)
{
char *local_path, *delete_path;
size_t i;
for (i = 0; i < rem_dirs->arr_len; i++) {
local_path = NULL;
error = get_local_path(src[(rem_dirs->arr_len - 1) - i],
- workspace, &local_path);
+ &local_path);
if (error < 0)
return error;
if (error > 0)
* considers the relations (parent-child) at dirs.
*/
int
-delete_dir_daemon_start(char **roots, size_t roots_len, char const *workspace)
+delete_dir_daemon_start(char **roots, size_t roots_len)
{
struct rem_dirs *arg;
int error;
arg = rem_dirs_create(roots_len);
- error = rename_all_roots(arg, roots, workspace);
+ error = rename_all_roots(arg, roots);
if (error) {
rem_dirs_destroy(arg);
return error;
#include <stddef.h>
-int delete_dir_daemon_start(char **, size_t, char const *);
+int delete_dir_daemon_start(char **, size_t);
#endif /* SRC_DELETE_DIR_DAEMON_H_ */
*/
static int
http_fetch(struct http_handler *handler, char const *uri, long *response_code,
- long *cond_met, bool log_operation, FILE *file)
+ FILE *file)
{
struct write_callback_arg args;
CURLcode res;
long http_code;
- long unmet = 0;
handler->errbuf[0] = 0;
setopt_str(handler->curl, CURLOPT_URL, uri);
if (res != CURLE_OK) {
pr_val_err("Error requesting URL: %s. (HTTP code: %ld)",
curl_err_string(handler, res), http_code);
- if (log_operation)
- pr_op_err("Error requesting URL: %s. (HTTP code: %ld)",
- curl_err_string(handler, res), http_code);
switch (res) {
case CURLE_FILESIZE_EXCEEDED:
}
pr_val_debug("HTTP result code: %ld", http_code);
-
- /*
- * Scenario: Received an OK code, but the time condition
- * (if-modified-since) wasn't actually met (ie. the document
- * has not been modified since we last requested it), so handle
- * this as a "Not Modified" code.
- *
- * This check is due to old libcurl versions, where the impl
- * doesn't let us get the response content since the library
- * does the time validation, resulting in "The requested
- * document is not new enough".
- *
- * Update 2021-05-25: I just tested libcurl in my old CentOS 7.7
- * VM (which is from October 2019, ie. older than the comments
- * above), and it behaves normally.
- * Also, the changelog doesn't mention anything about
- * If-Modified-Since.
- * This glue code is suspicious to me.
- *
- * For the record, this is how it behaves in my today's Ubuntu,
- * as well as my Centos 7.7.1908:
- *
- * if if-modified-since is included:
- * if page was modified:
- * HTTP 200
- * unmet: 0
- * writefunction called
- * else:
- * HTTP 304
- * unmet: 1
- * writefunction not called
- * else:
- * HTTP OK
- * unmet: 0
- * writefunction called
- */
- res = curl_easy_getinfo(handler->curl, CURLINFO_CONDITION_UNMET, &unmet);
- if (res == CURLE_OK && unmet == 1)
- *cond_met = 0;
-
return 0;
}
}
static int
-__http_download_file(struct rpki_uri *uri, long *response_code, long ims_value,
- long *cond_met, bool log_operation)
+__http_download_file(struct rpki_uri *uri, long *response_code, long ims_value)
{
char const *tmp_suffix = "_tmp";
struct http_handler handler;
int error;
retries = 0;
- *cond_met = 1;
if (!config_get_http_enabled()) {
*response_code = 0; /* Not 200 code, but also not an error */
return 0;
CURL_TIMECOND_IFMODSINCE);
}
error = http_fetch(&handler, uri_get_global(uri), response_code,
- cond_met, log_operation, out);
+ out);
if (error != EREQFAILED)
break; /* Note: Usually happy path */
* request to the server failed.
*/
int
-http_download_file(struct rpki_uri *uri, bool log_operation)
+http_download_file(struct rpki_uri *uri)
{
long response;
- long cond_met;
- return __http_download_file(uri, &response, 0, &cond_met,
- log_operation);
+ return __http_download_file(uri, &response, 0);
}
/*
* < 0 an actual error happened.
*/
int
-http_download_file_with_ims(struct rpki_uri *uri, long value,
- bool log_operation)
+http_download_file_with_ims(struct rpki_uri *uri, long value)
{
long response;
- long cond_met;
int error;
- error = __http_download_file(uri, &response, value, &cond_met,
- log_operation);
+ error = __http_download_file(uri, &response, value);
if (error)
return error;
if (response == 304)
return 1;
- /*
- * Got another HTTP response code (OK or error).
- *
- * Check if the time condition was met (in case of error is set as
- * 'true'), if it wasn't, then do a regular request (no time condition).
- */
- if (cond_met)
- return 0;
-
- /*
- * Situation:
- *
- * - old libcurl (because libcurl returned HTTP 200 and cond_met == 0,
- * which is a contradiction)
- * - the download was successful (error == 0)
- * - the page WAS modified since the last update
- *
- * libcurl wrote an empty file, so we have to redownload.
- */
-
- return __http_download_file(uri, &response, 0, &cond_met,
- log_operation);
-
+ return 0;
}
/*
struct http_handler handler;
FILE *out;
long response_code;
- long cond_met;
char *tmp_file;
int error;
goto end;
http_easy_init(&handler);
- error = http_fetch(&handler, remote, &response_code, &cond_met, true,
- out);
+ error = http_fetch(&handler, remote, &response_code, out);
http_easy_cleanup(&handler);
file_close(out);
#ifndef SRC_HTTP_HTTP_H_
#define SRC_HTTP_HTTP_H_
-#include <stdbool.h>
#include <stddef.h>
#include "types/uri.h"
int http_init(void);
void http_cleanup(void);
-int http_download_file(struct rpki_uri *, bool);
-int http_download_file_with_ims(struct rpki_uri *, long, bool);
+int http_download_file(struct rpki_uri *);
+int http_download_file_with_ims(struct rpki_uri *, long);
int http_direct_download(char const *, char const *);
/* HTTPS RRDP */
error = handle_ad("SIA", sia, "rpkiNotify", nid_rpkiNotify(),
- URI_VALID_HTTPS | URI_USE_RRDP_WORKSPACE, false, handle_rpkiNotify,
- &uris->rpkiNotify);
+ URI_VALID_HTTPS, false, handle_rpkiNotify, &uris->rpkiNotify);
if (error)
goto end;
struct rpki_uri *tmp;
int error;
- if (db_rrdp_uris_workspace_get() == NULL)
- return -ENOENT;
-
tmp = NULL;
error = uri_create_rsync_str_rrdp(&tmp, uri_get_global(mft_uri),
uri_get_global_len(mft_uri));
bool data_updated;
int error;
- /* Start working on the RRDP local workspace */
- db_rrdp_uris_workspace_enable();
-
data_updated = false;
error = rrdp_load(sia_uris->rpkiNotify.uri, &data_updated);
if (error)
- goto err;
+ return error;
error = verify_rrdp_mft_loc(sia_uris->mft.uri);
switch(error) {
case -ENOENT:
/* Doesn't exist and the RRDP data was updated: error */
if (data_updated)
- goto err;
+ return error;
/* Otherwise, force the snapshot processing and check again */
error = rrdp_reload_snapshot(sia_uris->rpkiNotify.uri);
if (error)
- goto err;
+ return error;
error = verify_rrdp_mft_loc(sia_uris->mft.uri);
if (error)
- goto err;
+ return error;
break;
default:
- goto err;
+ return error;
}
/* Successfully loaded (or no updates yet), update MFT local URI */
- error = replace_rrdp_mft_uri(&sia_uris->mft);
- if (error)
- goto err;
-
- return 0;
-err:
- db_rrdp_uris_workspace_disable();
- return error;
+ return replace_rrdp_mft_uri(&sia_uris->mft);
}
static int
{
int error;
- /* Stop working on the RRDP local workspace */
- db_rrdp_uris_workspace_disable();
error = rsync_download_files(sia_uris->caRepository.uri, false, false);
if (error)
return error;
* Both access method callbacks must verify the manifest existence.
*/
static int
-use_access_method(struct sia_ca_uris *sia_uris,
- access_method_exec rsync_cb, access_method_exec rrdp_cb, bool new_level,
- bool *retry_repo_sync)
+use_access_method(struct sia_ca_uris *sia_uris, access_method_exec rsync_cb,
+ access_method_exec rrdp_cb, bool *retry_repo_sync)
{
access_method_exec *cb_primary;
access_method_exec *cb_secondary;
primary_rrdp = true;
(*retry_repo_sync) = true;
- /*
- * Very specific scenario, yet possible:
- * - Still working at the same repository level
- * - The previous object was working on an RRDP repository
- * - This certificate doesn't have an update notification URI
- *
- * Probably the object does exist at the RRDP repository, so check if
- * that's the case. Otherwise, just keep going.
- *
- * The main reason, is a (possible) hole at RFC 8182. Apparently, the
- * CA childs aren't obligated to have the same RRDP accessMethod than
- * their parent, so there's no problem if they don't use it at all; not
- * even if such childs (and even the grandchilds or anyone below that
- * level) "reside" at the RRDP repository.
- */
- if (!new_level && db_rrdp_uris_workspace_get() != NULL &&
- sia_uris->rpkiNotify.uri == NULL &&
- verify_rrdp_mft_loc(sia_uris->mft.uri) == 0) {
- (*retry_repo_sync) = false;
- return replace_rrdp_mft_uri(&sia_uris->mft);
- }
-
/*
* RSYNC will always be present (at least for now, see
* rfc6487#section-4.8.8.1). If rsync is disabled, the cb will take
error = db_rrdp_uris_get_request_status(
uri_get_global(sia_uris->rpkiNotify.uri), &rrdp_req_status);
if (error == 0 && rrdp_req_status == RRDP_URI_REQ_VISITED) {
- db_rrdp_uris_workspace_enable();
(*retry_repo_sync) = false;
return replace_rrdp_mft_uri(&sia_uris->mft);
}
/* Error and the primary access method was RRDP? Use its workspace */
if (error && primary_rrdp) {
- db_rrdp_uris_workspace_enable();
upd_error = replace_rrdp_mft_uri(&sia_uris->mft);
if (upd_error)
return upd_error;
return verify_mft_loc(sia_uris->mft.uri);
}
-/*
- * Get the rsync server part from an rsync URI.
- *
- * If the URI is:
- * rsync://<server>/<service/<file path>
- * This will return:
- * rsync://<server>
- */
-static void
-get_rsync_server_uri(struct rpki_uri *src, char **result, size_t *result_len)
-{
- char const *global;
- char *tmp;
- size_t global_len;
- unsigned int slashes;
- size_t i;
-
- global = uri_get_global(src);
- global_len = uri_get_global_len(src);
- slashes = 0;
-
- for (i = 0; i < global_len; i++) {
- if (global[i] == '/') {
- slashes++;
- if (slashes == 3)
- break;
- }
- }
-
- tmp = pmalloc(i + 1);
- strncpy(tmp, global, i);
- tmp[i] = '\0';
-
- *result_len = i;
- *result = tmp;
-}
-
-static void
-set_repository_level(bool is_ta, struct validation *state,
- struct rpki_uri *cert_uri, struct sia_ca_uris *sia_uris, bool *updated)
-{
- char *parent_server, *current_server;
- size_t parent_server_len, current_server_len;
- unsigned int new_level;
- bool update;
-
- new_level = 0;
- if (is_ta || cert_uri == NULL) {
- working_repo_push_level(new_level);
- return;
- }
-
- /* Warning killer */
- parent_server = NULL;
- current_server = NULL;
- parent_server_len = 0;
- current_server_len = 0;
-
- /* Both are rsync URIs, check the server part */
- get_rsync_server_uri(cert_uri, &parent_server, &parent_server_len);
- get_rsync_server_uri(sia_uris->caRepository.uri, ¤t_server,
- ¤t_server_len);
-
- if (parent_server_len != current_server_len) {
- update = true;
- goto end;
- }
-
- update = (strcmp(parent_server, current_server) != 0);
-end:
- new_level = x509stack_peek_level(validation_certstack(state));
- if (update)
- new_level++;
-
- working_repo_push_level(new_level);
-
- free(parent_server);
- free(current_server);
-
- (*updated) = update;
-}
-
/** Boilerplate code for CA certificate validation and recursive traversal. */
int
certificate_traverse(struct rpp *rpp_parent, struct rpki_uri *cert_uri)
enum cert_type type;
struct rpp *pp;
bool repo_retry;
- bool new_level;
int error;
state = state_retrieve();
if (error)
goto revert_uris;
- /* Identify if this is a new repository before fetching it */
- new_level = false;
- set_repository_level(IS_TA, state, cert_uri, &sia_uris, &new_level);
-
/*
* RFC 6481 section 5: "when the repository publication point contents
* are updated, a repository operator cannot assure RPs that the
*/
repo_retry = true;
error = use_access_method(&sia_uris, exec_rsync_method,
- exec_rrdp_method, new_level, &repo_retry);
+ exec_rrdp_method, &repo_retry);
if (error)
goto revert_uris;
cert = NULL; /* Ownership stolen */
- error = handle_manifest(sia_uris.mft.uri, !repo_retry, &pp);
+ error = handle_manifest(sia_uris.mft.uri, &pp);
if (error == 0 || !repo_retry)
break;
}
static int
-build_rpp(struct Manifest *mft, struct rpki_uri *mft_uri, bool rrdp_workspace,
- struct rpp **pp)
+build_rpp(struct Manifest *mft, struct rpki_uri *mft_uri, struct rpp **pp)
{
int i;
struct FileAndHash *fah;
for (i = 0; i < mft->fileList.list.count; i++) {
fah = mft->fileList.list.array[i];
- error = uri_create_mft(&uri, mft_uri, &fah->file,
- rrdp_workspace);
+ error = uri_create_mft(&uri, mft_uri, &fah->file);
if (error == ESKIP)
continue;
/*
* @pp. If @rrdp_workspace is true, use the local RRDP repository.
*/
int
-handle_manifest(struct rpki_uri *uri, bool rrdp_workspace, struct rpp **pp)
+handle_manifest(struct rpki_uri *uri, struct rpp **pp)
{
static OID oid = OID_MANIFEST;
struct oid_arcs arcs = OID2ARCS("manifest", oid);
goto revert_sobj;
/* Initialize out parameter (@pp) */
- error = build_rpp(mft, uri, rrdp_workspace, pp);
+ error = build_rpp(mft, uri, pp);
if (error)
goto revert_manifest;
#ifndef SRC_OBJECT_MANIFEST_H_
#define SRC_OBJECT_MANIFEST_H_
-#include <stdbool.h>
#include "rpp.h"
-int handle_manifest(struct rpki_uri *, bool, struct rpp **);
+int handle_manifest(struct rpki_uri *, struct rpp **);
#endif /* SRC_OBJECT_MANIFEST_H_ */
validation_destroy(state);
return 0; /* Try some other TAL URI */
}
- error = http_download_file(uri,
- reqs_errors_log_uri(uri_get_global(uri)));
+ error = http_download_file(uri);
}
/* Reminder: there's a positive error: EREQFAILED */
{
struct tal_param *t_param = arg;
struct validation_thread *thread;
- int error;
- error = db_rrdp_add_tal(tal_file);
- if (error)
- return error;
+ db_rrdp_add_tal(tal_file);
thread = pmalloc(sizeof(struct validation_thread));
thread_pool_push(t_param->pool, thread->tal_file, do_file_validation,
thread);
-
SLIST_INSERT_HEAD(&t_param->threads, thread, next);
+
return 0;
}
thread_destroy(thread);
}
- /* Log the error'd URIs summary */
- reqs_errors_log_summary();
-
/* One thread has errors, validation can't keep the resulting table */
if (error)
return error;
#include "log.h"
#include "thread_var.h"
-/*
- * Only log messages of repositories whose level is less than or equal to this.
- *
- * Level 0 is "top level", mostly used by the root CAs (trust anchors) and RIRs
- * before RPKI servers delegation.
- *
- * Eg. The URIs will have this level (data according to current RPKI state):
- * rsync://repository.lacnic.net/ [level 0]
- * rsync://rpki-repo.registro.br/ [level 1]
- *
- * rsync://rpki.ripe.net/ [level 0]
- * rsync://ca.rg.net/ [level 1]
- * rsync://cc.rg.net/ [level 2]
- */
-#define LOG_REPO_LEVEL 0
+/* TODO (#78) Is any of this still useful? */
struct error_uri {
/* Key */
char *uri_related;
/* Refered by (where this.uri == that.uri_related) */
char *ref_by;
- /* Log the summary */
- bool log_summary;
UT_hash_handle hh;
};
error = get_current_time(&tmp->first_attempt);
if (error)
goto release_uri;
- tmp->log_summary = false;
tmp->uri_related = NULL;
tmp->ref_by = NULL;
set_working_repo(new_uri);
- /*
- * Check if this will always be logged, in that case the summary will
- * be logged also if the level must be logged.
- */
- if (config_get_stale_repository_period() == 0)
- new_uri->log_summary =
- (working_repo_peek_level() <= LOG_REPO_LEVEL);
-
rwlock_write_lock(&db_lock);
HASH_ADD_STR(err_uris_db, uri, new_uri);
rwlock_unlock(&db_lock);
return 0;
}
-
-bool
-reqs_errors_log_uri(char const *uri)
-{
- struct error_uri *node;
- time_t now;
- unsigned int config_period;
- int error;
-
- if (log_op_enabled(LOG_DEBUG))
- return true;
-
- if (working_repo_peek_level() > LOG_REPO_LEVEL)
- return false;
-
- /* Log always? Don't care if the URI exists yet or not */
- config_period = config_get_stale_repository_period();
- if (config_period == 0)
- return true;
-
- node = find_error_uri(uri, true);
- if (node == NULL)
- return false;
-
- now = 0;
- error = get_current_time(&now);
- if (error)
- return false;
-
- node->log_summary = (difftime(now, node->first_attempt) >=
- (double)config_period);
-
- return node->log_summary;
-}
-
-/*
- * Log a summary of the error'd servers.
- */
-void
-reqs_errors_log_summary(void)
-{
- /* Remove all the uris */
- struct error_uri *node, *tmp;
- time_t now;
- char *str_time;
- bool first;
- int error;
-
- first = true;
- now = 0;
- error = get_current_time(&now);
- if (error)
- return;
-
- rwlock_read_lock(&db_lock);
- HASH_ITER(hh, err_uris_db, node, tmp) {
- if (!node->log_summary)
- continue;
- if (first) {
- pr_op_warn("The following repositories URIs couldn't be fetched (it can be a local issue or a server issue), please review previous log messages related to such URIs/servers:");
- first = false;
- }
- str_time = asctime(localtime(&node->first_attempt));
- if (strrchr(str_time, '\n') != NULL) {
- *(str_time + strlen(str_time) - 1) = ' ';
- }
- pr_op_warn("- '%s': can't be downloaded since %s", node->uri,
- str_time);
- }
-
- rwlock_unlock(&db_lock);
-}
#include <stdbool.h>
+/* TODO (#78) removable? */
+
int reqs_errors_init(void);
void reqs_errors_cleanup(void);
int reqs_errors_add_uri(char const *);
void reqs_errors_rem_uri(char const *);
-bool reqs_errors_log_uri(char const *);
-
typedef int (reqs_errors_cb)(char const *, void *);
int reqs_errors_foreach(reqs_errors_cb, void *);
-void reqs_errors_log_summary(void);
-
#endif /* SRC_REQS_ERRORS_H_ */
struct tal_elem {
char *file_name;
struct db_rrdp_uri *uris;
- char *workspace;
bool visited;
SLIST_ENTRY(tal_elem) next;
};
* (later) facilitate the concatenation of the ID at --local-repository.
*
* The ID is allocated at @result.
+ *
+ * TODO (#78) Improve and use this.
*/
static int
get_workspace_path(char const *base, char **result)
return 0;
}
-static int
-tal_elem_create(struct tal_elem **elem, char const *name)
+static struct tal_elem *
+tal_elem_create(char const *name)
{
- struct tal_elem *tmp;
- int error;
+ struct tal_elem *result;
- tmp = pmalloc(sizeof(struct tal_elem));
+ result = pmalloc(sizeof(struct tal_elem));
- tmp->uris = db_rrdp_uris_create();
- tmp->visited = true;
- tmp->file_name = pstrdup(name);
+ result->uris = db_rrdp_uris_create();
+ result->visited = true;
+ result->file_name = pstrdup(name);
- error = get_workspace_path(name, &tmp->workspace);
- if (error) {
- free(tmp->file_name);
- db_rrdp_uris_destroy(tmp->uris);
- free(tmp);
- return error;
- }
-
- *elem = tmp;
- return 0;
+ return result;
}
static void
tal_elem_destroy(struct tal_elem *elem, bool remove_local)
{
- if (remove_local)
- db_rrdp_uris_remove_all_local(elem->uris, elem->workspace);
db_rrdp_uris_destroy(elem->uris);
free(elem->file_name);
- free(elem->workspace);
free(elem);
}
return NULL;
}
-int
+void
db_rrdp_add_tal(char const *tal_name)
{
struct tal_elem *elem, *found;
- int error;
/* Element exists, no need to create it again */
found = db_rrdp_find_tal(tal_name);
if (found != NULL) {
found->visited = true;
- return 0;
+ return;
}
- error = tal_elem_create(&elem, tal_name);
- if (error)
- return error;
+ elem = tal_elem_create(tal_name);
rwlock_write_lock(&lock);
SLIST_INSERT_HEAD(&db.tals, elem, next);
rwlock_unlock(&lock);
-
- return 0;
}
void
return found->uris;
}
-char const *
-db_rrdp_get_workspace(char const *tal_name)
-{
- struct tal_elem *found;
-
- found = db_rrdp_find_tal(tal_name);
- if (found == NULL)
- pr_crit("db_rrdp_find_tal() returned NULL, means it hasn't been initialized");
-
- return found->workspace;
-}
-
/* Set all tals to non-visited */
void
db_rrdp_reset_visited_tals(void)
int db_rrdp_init(void);
void db_rrdp_cleanup(void);
-int db_rrdp_add_tal(char const *);
+void db_rrdp_add_tal(char const *);
void db_rrdp_rem_tal(char const *);
struct db_rrdp_uri *db_rrdp_get_uris(char const *);
-char const *db_rrdp_get_workspace(char const *);
void db_rrdp_reset_visited_tals(void);
void db_rrdp_rem_nonvisited_tals(void);
struct db_rrdp_uri {
struct uris_table *table;
- char const *current_workspace;
};
static struct uris_table *
return validation_get_rrdp_uris(state_retrieve());
}
-static char const *
-get_thread_rrdp_workspace(void)
-{
- return validation_get_rrdp_workspace(state_retrieve());
-}
-
struct db_rrdp_uri *
db_rrdp_uris_create(void)
{
tmp = pmalloc(sizeof(struct db_rrdp_uri));
tmp->table = NULL;
- tmp->current_workspace = NULL;
return tmp;
}
if (error)
return error;
- /* TODO (#78) why are we casting */
found->last_update = (long)now;
return 0;
}
return found->visited_uris;
}
-
-int
-db_rrdp_uris_remove_all_local(struct db_rrdp_uri *uris, char const *workspace)
-{
- struct uris_table *uri_node, *uri_tmp;
- int error;
-
- /* Remove each 'visited_uris' from all the table */
- HASH_ITER(hh, uris->table, uri_node, uri_tmp) {
- error = visited_uris_delete_local(uri_node->visited_uris,
- workspace);
- if (error)
- return error;
- }
-
- return 0;
-}
-
-char const *
-db_rrdp_uris_workspace_get(void)
-{
- return get_thread_rrdp_uris()->current_workspace;
-}
-
-void
-db_rrdp_uris_workspace_enable(void)
-{
- get_thread_rrdp_uris()->current_workspace = get_thread_rrdp_workspace();
-}
-
-void
-db_rrdp_uris_workspace_disable(void)
-{
- get_thread_rrdp_uris()->current_workspace = NULL;
-}
struct visited_uris *db_rrdp_uris_get_visited_uris(char const *);
-int db_rrdp_uris_remove_all_local(struct db_rrdp_uri *, char const *);
-
char const *db_rrdp_uris_workspace_get(void);
-void db_rrdp_uris_workspace_enable(void);
-void db_rrdp_uris_workspace_disable(void);
#endif /* SRC_RRDP_DB_DB_RRDP_URIS_H_ */
/* Fetch and process the deltas from the @notification */
static int
process_diff_serial(struct update_notification *notification,
- bool log_operation, struct visited_uris **visited)
+ struct visited_uris **visited)
{
unsigned long serial;
int error;
if ((*visited) == NULL)
return -ENOENT;
- return rrdp_process_deltas(notification, serial, *visited,
- log_operation);
+ return rrdp_process_deltas(notification, serial, *visited);
}
/* Fetch and process the snapshot from the @notification */
static int
-process_snapshot(struct update_notification *notification, bool log_operation,
+process_snapshot(struct update_notification *notification,
struct visited_uris **visited)
{
struct visited_uris *tmp;
/* Use a new allocated visited_uris struct */
tmp = visited_uris_create();
- error = rrdp_parse_snapshot(notification, tmp, log_operation);
+ error = rrdp_parse_snapshot(notification, tmp);
if (error) {
visited_uris_refput(tmp);
return error;
if (tmp == NULL)
return -ENOENT;
- return visited_uris_delete_local(tmp, db_rrdp_uris_workspace_get());
+ return visited_uris_delete_local(tmp);
}
/* Mark the URI as errored with dummy data, so it won't be requested again */
static int
process_diff_session(struct update_notification *notification,
- bool log_operation, struct visited_uris **visited)
+ struct visited_uris **visited)
{
int error;
if (error)
return error;
- return process_snapshot(notification, log_operation, visited);
+ return process_snapshot(notification, visited);
}
/*
struct visited_uris *visited;
rrdp_req_status_t requested;
rrdp_uri_cmp_result_t res;
- bool log_operation;
int error, upd_error;
(*data_updated) = false;
}
pr_val_debug("Downloading RRDP Update Notification...");
- log_operation = reqs_errors_log_uri(uri_get_global(uri));
- error = rrdp_parse_notification(uri, log_operation, force_snapshot,
- &upd_notification);
+ error = rrdp_parse_notification(uri, force_snapshot, &upd_notification);
if (error)
goto upd_end;
/* Same flow as a session update */
if (force_snapshot) {
error = process_diff_session(upd_notification,
- log_operation, &visited);
+ &visited);
if (error)
goto upd_destroy;
(*data_updated) = true;
case RRDP_URI_DIFF_SESSION:
/* Delete the old session files */
error = process_diff_session(upd_notification,
- log_operation, &visited);
+ &visited);
if (error)
goto upd_destroy;
(*data_updated) = true;
break;
case RRDP_URI_DIFF_SERIAL:
- error = process_diff_serial(upd_notification,
- log_operation, &visited);
+ error = process_diff_serial(upd_notification, &visited);
if (!error) {
visited_uris_refget(visited);
(*data_updated) = true;
/* Something went wrong, use snapshot */
pr_val_info("There was an error processing RRDP deltas, using the snapshot instead.");
case RRDP_URI_NOTFOUND:
- error = process_snapshot(upd_notification, log_operation,
- &visited);
+ error = process_snapshot(upd_notification, &visited);
if (error)
goto upd_destroy;
(*data_updated) = true;
struct proc_upd_args {
struct update_notification *parent;
struct visited_uris *visited_uris;
- bool log_operation;
};
static void
}
static int
-download_file(struct rpki_uri *uri, long last_update, bool log_operation)
+download_file(struct rpki_uri *uri, long last_update)
{
int error;
if (last_update > 0)
- error = http_download_file_with_ims(uri, last_update,
- log_operation);
+ error = http_download_file_with_ims(uri, last_update);
else
- error = http_download_file(uri, log_operation);
+ error = http_download_file(uri);
/*
* Since distinct files can be downloaded (notification, snapshot,
fnstack_push_uri(uri);
- error = download_file(uri, 0, args->log_operation);
+ error = download_file(uri, 0);
if (error)
goto release_uri;
* Set @force to true to omit 'If-Modified-Since' header.
*/
int
-rrdp_parse_notification(struct rpki_uri *uri, bool log_operation, bool force,
+rrdp_parse_notification(struct rpki_uri *uri, bool force,
struct update_notification **result)
{
long last_update;
goto end;
}
- error = download_file(uri, last_update, log_operation);
+ error = download_file(uri, last_update);
if (error < 0)
goto end;
int
rrdp_parse_snapshot(struct update_notification *parent,
- struct visited_uris *visited_uris, bool log_operation)
+ struct visited_uris *visited_uris)
{
struct proc_upd_args args;
struct rpki_uri *uri;
fnstack_push_uri(uri);
- error = download_file(uri, 0, log_operation);
+ error = download_file(uri, 0);
if (error)
goto release_uri;
int
rrdp_process_deltas(struct update_notification *parent,
- unsigned long cur_serial, struct visited_uris *visited_uris,
- bool log_operation)
+ unsigned long cur_serial, struct visited_uris *visited_uris)
{
struct proc_upd_args args;
args.parent = parent;
args.visited_uris = visited_uris;
- args.log_operation = log_operation;
return deltas_head_for_each(&parent->deltas_list,
parent->global_data.serial, cur_serial, process_delta, &args);
#include "rrdp/rrdp_objects.h"
#include "visited_uris.h"
-int rrdp_parse_notification(struct rpki_uri *, bool, bool,
+int rrdp_parse_notification(struct rpki_uri *, bool,
struct update_notification **);
-int rrdp_parse_snapshot(struct update_notification *, struct visited_uris *,
- bool);
+int rrdp_parse_snapshot(struct update_notification *, struct visited_uris *);
-int rrdp_process_deltas(struct update_notification *,
- unsigned long serial, struct visited_uris *, bool);
+int rrdp_process_deltas(struct update_notification *, unsigned long,
+ struct visited_uris *);
#endif /* SRC_RRDP_RRDP_PARSER_H_ */
}
static void
-log_buffer(char const *buffer, ssize_t read, int type, bool log_operation)
+log_buffer(char const *buffer, ssize_t read, int type)
{
#define PRE_RSYNC "[RSYNC exec]: "
char *cpy, *cur, *tmp;
continue;
}
if (type == 0) {
- if (log_operation)
- pr_op_err_st(PRE_RSYNC "%s", cur);
pr_val_err(PRE_RSYNC "%s", cur);
} else {
pr_val_info(PRE_RSYNC "%s", cur);
}
static int
-read_pipe(int fd_pipe[2][2], int type, bool log_operation)
+read_pipe(int fd_pipe[2][2], int type)
{
char buffer[4096];
ssize_t count;
if (count == 0)
break;
- log_buffer(buffer, count, type, log_operation);
+ log_buffer(buffer, count, type);
}
close(fd_pipe[type][0]); /* Close read end */
* success and on error.
*/
static int
-read_pipes(int fds[2][2], bool log_operation)
+read_pipes(int fds[2][2])
{
int error;
close(fds[1][1]);
/* stderr pipe */
- error = read_pipe(fds, 0, log_operation);
+ error = read_pipe(fds, 0);
if (error) {
/* Close the other pipe pending to read */
close(fds[1][0]);
}
/* stdout pipe, always logs to info */
- return read_pipe(fds, 1, true);
+ return read_pipe(fds, 1);
}
/*
* Downloads the @uri->global file into the @uri->local path.
*/
static int
-do_rsync(struct rpki_uri *uri, bool is_ta, bool log_operation)
+do_rsync(struct rpki_uri *uri, bool is_ta)
{
/* Descriptors to pipe stderr (first element) and stdout (second) */
char **args;
}
/* This code is run by us. */
- error = read_pipes(fork_fds, log_operation);
+ error = read_pipes(fork_fds);
if (error)
kill(child_pid, SIGCHLD); /* Stop the child */
struct validation *state;
struct uri_list *visited_uris;
struct rpki_uri *rsync_uri;
- bool to_op_log;
int error;
if (!config_get_rsync_enabled())
pr_val_debug("Going to RSYNC '%s'.", uri_val_get_printable(rsync_uri));
- to_op_log = reqs_errors_log_uri(uri_get_global(rsync_uri));
- error = do_rsync(rsync_uri, is_ta, to_op_log);
+ error = do_rsync(rsync_uri, is_ta);
switch(error) {
case 0:
/* Don't store when "force" and if its already downloaded */
struct uri_list *rsync_visited_uris;
- /* Local RRDP workspace path */
- char const *rrdp_workspace;
-
/* Shallow copy of RRDP URIs and its corresponding visited uris */
struct db_rrdp_uri *rrdp_uris;
result->rsync_visited_uris = rsync_create();
result->rrdp_uris = db_rrdp_get_uris(tal_get_file_name(tal));
- result->rrdp_workspace = db_rrdp_get_workspace(tal_get_file_name(tal));
result->pubkey_state = PKS_UNTESTED;
result->validation_handler = *validation_handler;
result->x509_data.params = params; /* Ownership transfered */
{
return state->rrdp_uris;
}
-
-char const *
-validation_get_rrdp_workspace(struct validation *state)
-{
- return state->rrdp_workspace;
-}
validation_get_validation_handler(struct validation *);
struct db_rrdp_uri *validation_get_rrdp_uris(struct validation *);
-char const *validation_get_rrdp_workspace(struct validation *);
#endif /* SRC_STATE_H_ */
struct working_repo {
char const *uri;
- unsigned int level;
};
static void
repo = pmalloc(sizeof(struct working_repo));
repo->uri = NULL;
- repo->level = 0;
error = pthread_setspecific(repository_key, repo);
if (error)
repo->uri = location;
}
-/*
- * Set the current repository level, must be called before trying to fetch the
- * repository.
- *
- * The level "calculation" must be done by the caller.
- */
-void
-working_repo_push_level(unsigned int level)
-{
- struct working_repo *repo;
-
- repo = pthread_getspecific(repository_key);
- if (repo == NULL)
- return;
-
- repo->level = level;
-}
-
char const *
working_repo_peek(void)
{
return repo == NULL ? NULL : repo->uri;
}
-unsigned int
-working_repo_peek_level(void)
-{
- struct working_repo *repo;
-
- repo = pthread_getspecific(repository_key);
-
- return repo->level;
-}
-
/*
* Call once the certificate's repositories were downloaded (either successful
* or erroneously).
return;
repo->uri = NULL;
- repo->level = 0;
}
static char const *
void working_repo_init(void);
void working_repo_cleanup(void);
+/* TODO (#78) remove? */
void working_repo_push(char const *);
-void working_repo_push_level(unsigned int);
char const *working_repo_peek(void);
-unsigned int working_repo_peek_level(void);
void working_repo_pop(void);
/* Please remember that these functions can only be used during validations. */
{
size_t const PFX_RSYNC_LEN = strlen(PFX_RSYNC);
size_t const PFX_HTTPS_LEN = strlen(PFX_HTTPS);
- uint8_t l_flags;
int error;
- /* Exclude RSYNC RRDP flag, isn't relevant here */
- l_flags = flags & ~URI_USE_RRDP_WORKSPACE;
-
- if (l_flags == URI_VALID_RSYNC) {
+ if (flags == URI_VALID_RSYNC) {
(*type) = URI_RSYNC;
return validate_uri_begin(PFX_RSYNC, PFX_RSYNC_LEN, global,
global_len, ENOTRSYNC);
}
- if (l_flags == URI_VALID_HTTPS) {
+ if (flags == URI_VALID_HTTPS) {
(*type) = URI_HTTPS;
return validate_uri_begin(PFX_HTTPS, PFX_HTTPS_LEN, global,
global_len, ENOTHTTPS);
}
- if (l_flags != (URI_VALID_RSYNC | URI_VALID_HTTPS))
+ if (flags != (URI_VALID_RSYNC | URI_VALID_HTTPS))
pr_crit("Unknown URI flag");
/* It has both flags */
return 0;
}
-static char *
-get_local_workspace(void)
-{
- char const *workspace;
-
- workspace = db_rrdp_uris_workspace_get();
- if (workspace == NULL)
- return NULL;
-
- return pstrdup(workspace);
-}
-
/**
* Initializes @uri->local by converting @uri->global.
*
g2l(char const *global, size_t global_len, uint8_t flags, char **result,
enum rpki_uri_type *result_type)
{
- char *local;
- char *workspace;
enum rpki_uri_type type;
int error;
if (error)
return error;
- workspace = ((flags & URI_USE_RRDP_WORKSPACE) != 0)
- ? get_local_workspace()
- : NULL;
-
- local = map_uri_to_local(global,
- type == URI_RSYNC ? PFX_RSYNC : PFX_HTTPS,
- workspace);
-
- free(workspace);
- *result = local;
+ *result = map_uri_to_local(global,
+ type == URI_RSYNC ? PFX_RSYNC : PFX_HTTPS);
(*result_type) = type;
return 0;
}
uri_create_rsync_str_rrdp(struct rpki_uri **uri, char const *guri,
size_t guri_len)
{
- return uri_create(uri, URI_VALID_RSYNC | URI_USE_RRDP_WORKSPACE, guri,
- guri_len);
+ return uri_create(uri, URI_VALID_RSYNC, guri, guri_len);
}
int
uri_create_https_str_rrdp(struct rpki_uri **uri, char const *guri,
size_t guri_len)
{
- return uri_create(uri, URI_VALID_HTTPS | URI_USE_RRDP_WORKSPACE, guri,
- guri_len);
+ return uri_create(uri, URI_VALID_HTTPS, guri, guri_len);
}
int
* names. This function will infer the rest of the URL.
*/
int
-uri_create_mft(struct rpki_uri **result, struct rpki_uri *mft, IA5String_t *ia5,
- bool use_rrdp_workspace)
+uri_create_mft(struct rpki_uri **result, struct rpki_uri *mft, IA5String_t *ia5)
{
struct rpki_uri *uri;
- uint8_t flags;
int error;
uri = pmalloc(sizeof(struct rpki_uri));
return error;
}
- flags = URI_VALID_RSYNC;
- if (use_rrdp_workspace)
- flags |= URI_USE_RRDP_WORKSPACE;
-
- error = autocomplete_local(uri, flags);
+ error = autocomplete_local(uri, URI_VALID_RSYNC);
if (error) {
free(uri->global);
free(uri);
/* Flags to indicate expected uri type */
#define URI_VALID_RSYNC 0x01
#define URI_VALID_HTTPS 0x02
-/* Work with a local workspace (eg. map rsync RRPD uri's) */
-#define URI_USE_RRDP_WORKSPACE 0x10
#define ESKIP 85830
int uri_create_rsync_str(struct rpki_uri **, char const *, size_t);
int uri_create_mixed_str(struct rpki_uri **, char const *, size_t);
-int uri_create_mft(struct rpki_uri **, struct rpki_uri *, IA5String_t *, bool);
+int uri_create_mft(struct rpki_uri **, struct rpki_uri *, IA5String_t *);
int uri_create_ad(struct rpki_uri **, ACCESS_DESCRIPTION *, int);
void uri_refget(struct rpki_uri *);
* Delete all the corresponding local files of @uris located at @workspace
*/
int
-visited_uris_delete_local(struct visited_uris *uris, char const *workspace)
+visited_uris_delete_local(struct visited_uris *uris)
{
struct uris_roots roots;
int error;
if (roots.len == 0)
goto success;
- error = delete_dir_daemon_start(roots.array, roots.len, workspace);
+ error = delete_dir_daemon_start(roots.array, roots.len);
if (error) {
uris_roots_cleanup(&roots, uris_root_destroy);
return error;
void visited_uris_add(struct visited_uris *, char const *);
int visited_uris_remove(struct visited_uris *, char const *);
-int visited_uris_delete_local(struct visited_uris *, char const *);
+int visited_uris_delete_local(struct visited_uris *);
#endif /* SRC_VISITED_URIS_H_ */
/* Nothing here */
}
-char const *
-db_rrdp_uris_workspace_get(void)
-{
- return NULL;
-}
-
char const *
config_get_tal(void)
{