error = vrps_init();
if (error)
- goto end1;
-
- return error;
++ goto just_quit;
error = clients_db_init();
if (error)
- goto end2;
-
+ goto revert_vrps;
+ error = slurm_load();
+ if (error)
- goto end3;
++ goto revert_clients;
error = rtr_listen();
rtr_cleanup(); /* TODO shouldn't this only happen on !error? */
- end3:
- clients_db_destroy();
+ slurm_cleanup();
- end2: vrps_destroy();
- end1: return error;
++revert_clients:
+ clients_db_destroy();
+ revert_vrps:
+ vrps_destroy();
++just_quit:
+ return error;
}
int
#include "rtr/db/vrps.h"
static int
- send_notify(int fd, uint8_t rtr_version)
+ send_notify(struct client const *client, void *arg)
{
struct sender_common common;
- uint32_t serial;
+ uint32_t *serial = arg;
uint16_t session_id;
+ int error;
+
+ /* Send Serial Notify PDU */
+ session_id = get_current_session_id(client->rtr_version);
+ init_sender_common(&common, client->fd, client->rtr_version,
+ &session_id, serial, NULL);
+ error = send_serial_notify_pdu(&common);
- serial = get_last_serial_number();
- session_id = get_current_session_id(rtr_version);
- init_sender_common(&common, fd, rtr_version, &session_id, &serial,
- NULL);
- return send_serial_notify_pdu(&common);
+ /* Error? Log it */
+ if (error)
- warnx("Error sending notify PDU to client");
++ pr_warn("Error sending notify PDU to client");
+
+ return 0; /* Do not interrupt notify to other clients */
}
- void
+ int
notify_clients(void)
{
- struct client *clients, *ptr;
- size_t clients_len;
+ uint32_t serial;
int error;
- clients_len = client_list(&clients);
- for (ptr = clients; (ptr - clients) < clients_len; ptr++) {
- /* Send Serial Notify PDU */
- error = send_notify(ptr->fd, ptr->rtr_version);
- /* Error? Log it */
- if (error)
- pr_warn("Error sending notify PDU to client");
- }
+ error = get_last_serial_number(&serial);
+ if (error)
+ return error;
+
+ return clients_foreach(send_notify, &serial);
}
DEFINE_ARRAY_LIST_FUNCTIONS(v4_addresses, struct v4_address)
DEFINE_ARRAY_LIST_FUNCTIONS(v6_addresses, struct v6_address)
- static void
- v4_address_destroy(struct v4_address *addr)
- {
- free(addr);
- }
-
- static void
- v6_address_destroy(struct v6_address *addr)
- {
- free(addr);
- }
-
int
-roa_create(u_int32_t as, struct roa **_result)
+roa_create(uint32_t as, struct roa **_result)
{
struct roa *result;
- int error;
result = malloc(sizeof(struct roa));
if (result == NULL)
DEFINE_ARRAY_LIST_FUNCTIONS(nodes, struct node)
- node->children.array = NULL;
+static void
+node_init(struct node *node, struct rfc5280_name *subject_name,
+ struct node *parent)
+{
+ node->subject_name = subject_name;
+ x509_name_get(subject_name);
+ node->parent = parent;
++ nodes_init(&node->children);
+ node->roa = NULL;
+}
+
static struct node *
node_create(struct rfc5280_name *subject_name, struct node *parent)
{
}
static void
-node_destroy(struct node *node)
+node_cleanup(struct node *node)
{
- x509_name_put(node->subject_name);
- nodes_cleanup(&node->children, node_destroy);
+ if (node->subject_name != NULL)
+ x509_name_put(node->subject_name);
-
- if (node->children.array != NULL)
- nodes_cleanup(&node->children, node_cleanup);
-
++ nodes_cleanup(&node->children, node_cleanup);
if (node->roa != NULL)
roa_destroy(node->roa);
- free(node);
}
static int
node_add_child(struct node *parent, struct rfc5280_name *subject_name)
{
- struct node *child;
+ struct node child;
int error;
- if (parent->children.array == NULL) {
- error = nodes_init(&parent->children);
- if (error)
- return error;
- }
-
- child = node_create(subject_name, parent);
- if (child == NULL)
- return pr_enomem();
+ node_init(&child, subject_name, parent);
- error = nodes_add(&parent->children, child);
+ error = nodes_add(&parent->children, &child);
if (error)
- node_destroy(child);
+ node_cleanup(&child);
return error;
}
struct node *child;
int error;
- if (node->children.array != NULL)
- ARRAYLIST_FOREACH(&node->children, child) {
- error = __foreach(child, cb, arg);
- if (error)
- return error;
- }
+ ARRAYLIST_FOREACH(&node->children, child) {
+ error = __foreach(child, cb, arg);
+ if (error)
+ return error;
+ }
- if (child->roa != NULL) {
- error = __foreach_v4(child->roa, cb, arg);
+ if (node->roa != NULL) {
+ error = __foreach_v4(node->roa, cb, arg);
if (error)
return error;
- error = __foreach_v6(child->roa, cb, arg);
+ error = __foreach_v6(node->roa, cb, arg);
if (error)
return error;
}
return send_end_of_data_pdu(&common);
}
- warnx("Reached 'unreachable' code");
+ pr_warn("Reached 'unreachable' code");
return -EINVAL;
+
+ critical:
+ return err_pdu_send(fd, version, ERR_PDU_INTERNAL_ERROR,
+ &received->header, NULL);
}
int
break;
}
- warnx("Reached 'unreachable' code");
+ pr_warn("Reached 'unreachable' code");
return -EINVAL;
+
+ critical:
+ return err_pdu_send(fd, version, ERR_PDU_INTERNAL_ERROR,
+ &received->header, NULL);
}
int
service = config_get_server_port();
error = getaddrinfo(hostname, service, &hints, result);
- if (error)
- return pr_err("Could not infer a bindable address out of address '%s' and port '%s': %s",
+ if (error) {
- warnx("Could not infer a bindable address out of address '%s' and port '%s': %s",
++ pr_err("Could not infer a bindable address out of address '%s' and port '%s': %s",
(hostname != NULL) ? hostname : "any", service,
gai_strerror(error));
+ return error;
+ }
return 0;
}
int fd; /* "file descriptor" */
int error;
++ *result = 0; /* Shuts up gcc */
++
error = init_addrinfo(&addrs);
if (error)
return error;
continue;
}
- arg.client_fd = client_fd;
- arg.client_addr = client_addr;
+ arg = malloc(sizeof(struct thread_param));
+ if (arg == NULL) {
- warnx("Couldn't create thread_param struct");
++ pr_err("Couldn't create thread_param struct");
+ free(new_thread);
+ close(client_fd);
+ continue;
+ }
+ arg->client_fd = client_fd;
+ arg->client_addr = client_addr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
errno = pthread_create(&new_thread->tid, &attr,
- client_thread_cb, &arg);
+ client_thread_cb, arg);
pthread_attr_destroy(&attr);
if (errno) {
- warn("Could not spawn the client's thread");
+ pr_errno(errno, "Could not spawn the client's thread");
+ /*
+ * It is not clear to me whether @arg should be freed
+ * here. We're supposed to have transferred its
+ * ownership to the thread.
+ * Maybe we should store it in @new_thread instead.
+ */
free(new_thread);
close(client_fd);
continue;