summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.y42
-rw-r--r--src/fastd.c35
-rw-r--r--src/fastd.h2
-rw-r--r--src/peer.c134
-rw-r--r--src/peer.h47
-rw-r--r--src/protocol_ec25519_fhmqvc.c49
-rw-r--r--src/resolve.c14
-rw-r--r--src/types.h2
8 files changed, 214 insertions, 111 deletions
diff --git a/src/config.y b/src/config.y
index 97d2f97..fde2873 100644
--- a/src/config.y
+++ b/src/config.y
@@ -397,29 +397,39 @@ peer_statement: TOK_REMOTE peer_remote ';'
;
peer_remote: TOK_ADDR4 port {
- free(conf->peers->hostname);
- conf->peers->hostname = NULL;
+ fastd_remote_config_t **remote = &conf->peers->remotes;
+ while (*remote)
+ remote = &(*remote)->next;
- conf->peers->address.in.sin_family = AF_INET;
- conf->peers->address.in.sin_addr = $1;
- conf->peers->address.in.sin_port = htons($2);
- fastd_peer_address_simplify(&conf->peers->address);
+ *remote = calloc(1, sizeof(fastd_remote_config_t));
+
+ (*remote)->address.in.sin_family = AF_INET;
+ (*remote)->address.in.sin_addr = $1;
+ (*remote)->address.in.sin_port = htons($2);
+ fastd_peer_address_simplify(&(*remote)->address);
}
| TOK_ADDR6 port {
- free(conf->peers->hostname);
- conf->peers->hostname = NULL;
+ fastd_remote_config_t **remote = &conf->peers->remotes;
+ while (*remote)
+ remote = &(*remote)->next;
+
+ *remote = calloc(1, sizeof(fastd_remote_config_t));
- conf->peers->address.in6.sin6_family = AF_INET6;
- conf->peers->address.in6.sin6_addr = $1;
- conf->peers->address.in6.sin6_port = htons($2);
- fastd_peer_address_simplify(&conf->peers->address);
+ (*remote)->address.in6.sin6_family = AF_INET6;
+ (*remote)->address.in6.sin6_addr = $1;
+ (*remote)->address.in6.sin6_port = htons($2);
+ fastd_peer_address_simplify(&(*remote)->address);
}
| maybe_af TOK_STRING port maybe_float {
- free(conf->peers->hostname);
+ fastd_remote_config_t **remote = &conf->peers->remotes;
+ while (*remote)
+ remote = &(*remote)->next;
+
+ *remote = calloc(1, sizeof(fastd_remote_config_t));
- conf->peers->hostname = strdup($2->str);
- conf->peers->address.sa.sa_family = $1;
- conf->peers->address.in.sin_port = htons($3);
+ (*remote)->hostname = strdup($2->str);
+ (*remote)->address.sa.sa_family = $1;
+ (*remote)->address.in.sin_port = htons($3);
conf->peers->floating = conf->peers->dynamic_float_deprecated = $4;
}
;
diff --git a/src/fastd.c b/src/fastd.c
index fa6ea65..8ba4ea3 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -793,8 +793,13 @@ static inline void schedule_handshake(fastd_context_t *ctx, fastd_peer_t *peer)
}
static void send_handshake(fastd_context_t *ctx, fastd_peer_t *peer) {
- if (!fastd_peer_is_established(peer))
+ if (!peer->next_remote)
+ exit_bug(ctx, "send_handshake: no remote");
+
+ if (!fastd_peer_is_established(peer)) {
+ fastd_peer_claim_address(ctx, peer, NULL, NULL, &peer->next_remote->address);
fastd_peer_reset_socket(ctx, peer);
+ }
if (!peer->sock)
return;
@@ -823,14 +828,23 @@ static void handle_tasks(fastd_context_t *ctx) {
case TASK_HANDSHAKE:
schedule_handshake(ctx, task->peer);
- if(!fastd_peer_may_connect(ctx, task->peer))
+ if(!fastd_peer_may_connect(ctx, task->peer)) {
+ task->peer->next_remote = task->peer->remotes;
break;
-
- if (fastd_peer_is_dynamic(task->peer) && !fastd_peer_is_established(task->peer))
- fastd_resolve_peer(ctx, task->peer);
+ }
send_handshake(ctx, task->peer);
+ if (fastd_peer_is_established(task->peer))
+ break;
+
+ task->peer->next_remote = task->peer->next_remote->next;
+ if (!task->peer->next_remote)
+ task->peer->next_remote = task->peer->remotes;
+
+ if (fastd_peer_remote_is_dynamic(task->peer->next_remote))
+ fastd_resolve_peer(ctx, task->peer, task->peer->next_remote);
+
break;
case TASK_KEEPALIVE:
@@ -1069,13 +1083,16 @@ static void handle_resolve_returns(fastd_context_t *ctx) {
if (!peer->config)
continue;
- if (!strequal(peer->config->hostname, hostname))
- continue;
+ fastd_remote_t *remote;
+ for (remote = peer->remotes; remote; remote = remote->next) {
+ if (strequal(remote->config->hostname, hostname) && fastd_peer_remote_matches_dynamic(remote->config, &resolve_return.constraints))
+ break;
+ }
- if (!fastd_peer_config_matches_dynamic(peer->config, &resolve_return.constraints))
+ if (!remote)
continue;
- fastd_peer_handle_resolve(ctx, peer, &resolve_return.addr);
+ fastd_peer_handle_resolve(ctx, peer, remote, &resolve_return.addr);
break;
}
diff --git a/src/fastd.h b/src/fastd.h
index a155c80..e3aa76b 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -312,7 +312,7 @@ fastd_socket_t* fastd_socket_open(fastd_context_t *ctx, fastd_peer_t *peer, int
void fastd_setfd(const fastd_context_t *ctx, int fd, int set, int unset);
void fastd_setfl(const fastd_context_t *ctx, int fd, int set, int unset);
-void fastd_resolve_peer(fastd_context_t *ctx, fastd_peer_t *peer);
+void fastd_resolve_peer(fastd_context_t *ctx, fastd_peer_t *peer, fastd_remote_t *remote);
int fastd_vsnprintf(const fastd_context_t *ctx, char *buffer, size_t size, const char *format, va_list ap);
void fastd_logf(const fastd_context_t *ctx, int level, const char *format, ...);
diff --git a/src/peer.c b/src/peer.c
index 422cd2e..d50fdec 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -163,28 +163,27 @@ static void init_handshake(fastd_context_t *ctx, fastd_peer_t *peer) {
fastd_task_schedule_handshake(ctx, peer, delay);
}
-void fastd_peer_handle_resolve(fastd_context_t *ctx, fastd_peer_t *peer, const fastd_peer_address_t *address) {
- peer->last_resolve_return = ctx->now;
-
- if (!fastd_peer_claim_address(ctx, peer, NULL, NULL, address))
- pr_warn(ctx, "resolved address %I for peer %P which is used by a fixed peer", address, peer);
+void fastd_peer_handle_resolve(fastd_context_t *ctx, fastd_peer_t *peer, fastd_remote_t *remote, const fastd_peer_address_t *address) {
+ remote->last_resolve_return = ctx->now;
+ remote->address = *address;
if (peer->state == STATE_RESOLVING)
init_handshake(ctx, peer);
}
static void setup_peer(fastd_context_t *ctx, fastd_peer_t *peer) {
- if (!peer->config || peer->config->hostname)
- peer->address.sa.sa_family = AF_UNSPEC;
- else
- peer->address = peer->config->address;
-
- memset(&peer->local_address, 0, sizeof(peer->local_address));
+ peer->address.sa.sa_family = AF_UNSPEC;
+ peer->local_address.sa.sa_family = AF_UNSPEC;
peer->state = STATE_INIT;
- peer->last_resolve = (struct timespec){0, 0};
- peer->last_resolve_return = (struct timespec){0, 0};
+ fastd_remote_t *remote;
+ for (remote = peer->remotes; remote; remote = remote->next) {
+ remote->last_resolve = (struct timespec){0, 0};
+ remote->last_resolve_return = (struct timespec){0, 0};
+ }
+
+ peer->next_remote = peer->remotes;
peer->last_handshake = (struct timespec){0, 0};
peer->last_handshake_address.sa.sa_family = AF_UNSPEC;
@@ -195,12 +194,14 @@ static void setup_peer(fastd_context_t *ctx, fastd_peer_t *peer) {
if (!peer->protocol_state)
ctx->conf->protocol->init_peer_state(ctx, peer);
- if (fastd_peer_is_dynamic(peer)) {
- peer->state = STATE_RESOLVING;
- fastd_resolve_peer(ctx, peer);
- }
- else if(peer->address.sa.sa_family != AF_UNSPEC) {
- init_handshake(ctx, peer);
+ if(peer->next_remote) {
+ if (fastd_peer_remote_is_dynamic(peer->next_remote)) {
+ peer->state = STATE_RESOLVING;
+ fastd_resolve_peer(ctx, peer, peer->next_remote);
+ }
+ else {
+ init_handshake(ctx, peer);
+ }
}
}
@@ -245,8 +246,15 @@ fastd_peer_config_t* fastd_peer_config_new(fastd_context_t *ctx, fastd_config_t
}
void fastd_peer_config_free(fastd_peer_config_t *peer) {
+ while (peer->remotes) {
+ fastd_remote_config_t *remote = peer->remotes;
+ peer->remotes = remote->next;
+
+ free(remote->hostname);
+ free(remote);
+ }
+
free(peer->name);
- free(peer->hostname);
free(peer->key);
free(peer->protocol_config);
free(peer);
@@ -318,6 +326,35 @@ static inline void reset_peer_address(fastd_context_t *ctx, fastd_peer_t *peer)
memset(&peer->address, 0, sizeof(fastd_peer_address_t));
}
+bool fastd_peer_owns_address(fastd_context_t *ctx, const fastd_peer_t *peer, const fastd_peer_address_t *addr) {
+ if (fastd_peer_is_floating(peer))
+ return false;
+
+ fastd_remote_config_t *remote;
+ for (remote = peer->config->remotes; remote; remote = remote->next) {
+ if (remote->hostname)
+ continue;
+
+ if (fastd_peer_address_equal(&remote->address, addr))
+ return true;
+ }
+
+ return false;
+}
+
+bool fastd_peer_matches_address(fastd_context_t *ctx, const fastd_peer_t *peer, const fastd_peer_address_t *addr) {
+ if (fastd_peer_is_floating(peer))
+ return true;
+
+ fastd_remote_t *remote;
+ for (remote = peer->remotes; remote; remote = remote->next) {
+ if (fastd_peer_address_equal(&remote->address, addr))
+ return true;
+ }
+
+ return false;
+}
+
bool fastd_peer_claim_address(fastd_context_t *ctx, fastd_peer_t *new_peer, fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr) {
if (remote_addr->sa.sa_family == AF_UNSPEC) {
if (fastd_peer_is_established(new_peer))
@@ -354,17 +391,30 @@ bool fastd_peer_claim_address(fastd_context_t *ctx, fastd_peer_t *new_peer, fast
return true;
}
-bool fastd_peer_config_equal(const fastd_peer_config_t *peer1, const fastd_peer_config_t *peer2) {
- if (peer1->group != peer2->group)
+static bool fastd_remote_configs_equal(const fastd_remote_config_t *remote1, const fastd_remote_config_t *remote2) {
+ if (!remote1 && !remote2)
+ return true;
+
+ if (!remote1 || !remote2)
+ return false;
+
+ if (!fastd_peer_address_equal(&remote1->address, &remote2->address))
+ return false;
+
+ if (!strequal(remote1->hostname, remote2->hostname))
return false;
- if (!strequal(peer1->hostname, peer2->hostname))
+ return fastd_remote_configs_equal(remote1->next, remote2->next);
+}
+
+bool fastd_peer_config_equal(const fastd_peer_config_t *peer1, const fastd_peer_config_t *peer2) {
+ if (peer1->group != peer2->group)
return false;
if(peer1->floating != peer2->floating)
return false;
- if (!fastd_peer_address_equal(&peer1->address, &peer2->address))
+ if (!fastd_remote_configs_equal(peer1->remotes, peer2->remotes))
return false;
if (!strequal(peer1->key, peer2->key))
@@ -414,7 +464,7 @@ bool fastd_peer_may_connect(fastd_context_t *ctx, fastd_peer_t *peer) {
}
fastd_peer_t* fastd_peer_add(fastd_context_t *ctx, fastd_peer_config_t *peer_conf) {
- fastd_peer_t *peer = malloc(sizeof(fastd_peer_t));
+ fastd_peer_t *peer = calloc(1, sizeof(fastd_peer_t));
peer->next = ctx->peers;
ctx->peers = peer;
@@ -422,9 +472,20 @@ fastd_peer_t* fastd_peer_add(fastd_context_t *ctx, fastd_peer_config_t *peer_con
peer->config = peer_conf;
peer->group = find_peer_group(ctx->peer_group, peer_conf->group);
peer->protocol_config = peer_conf->protocol_config;
- peer->protocol_state = NULL;
- peer->sock = NULL;
- peer->seen = (struct timespec){0, 0};
+
+ fastd_remote_t **remote = &peer->remotes;
+ fastd_remote_config_t *remote_config = peer_conf->remotes;
+
+ while (remote_config) {
+ *remote = calloc(1, sizeof(fastd_remote_t));
+ (*remote)->config = remote_config;
+
+ if (!remote_config->hostname)
+ (*remote)->address = remote_config->address;
+
+ remote = &(*remote)->next;
+ remote_config = remote_config->next;
+ }
pr_verbose(ctx, "adding peer %P (group `%s')", peer, peer->group->conf->name);
@@ -439,15 +500,12 @@ fastd_peer_t* fastd_peer_add_temporary(fastd_context_t *ctx) {
if (!ctx->conf->on_verify)
exit_bug(ctx, "tried to add temporary peer without on-verify command");
- fastd_peer_t *peer = malloc(sizeof(fastd_peer_t));
+ fastd_peer_t *peer = calloc(1, sizeof(fastd_peer_t));
peer->next = ctx->peers_temp;
ctx->peers_temp = peer;
- peer->config = NULL;
peer->group = ctx->peer_group;
- peer->protocol_state = NULL;
- peer->sock = NULL;
peer->seen = ctx->now;
pr_debug(ctx, "adding temporary peer");
@@ -513,20 +571,20 @@ const fastd_eth_addr_t* fastd_get_dest_address(const fastd_context_t *ctx, fastd
}
}
-bool fastd_peer_config_matches_dynamic(const fastd_peer_config_t *config, const fastd_peer_address_t *addr) {
- if (!config->hostname)
+bool fastd_peer_remote_matches_dynamic(const fastd_remote_config_t *remote, const fastd_peer_address_t *addr) {
+ if (!remote->hostname)
return false;
- if (config->address.sa.sa_family != AF_UNSPEC &&
- config->address.sa.sa_family != addr->sa.sa_family)
+ if (remote->address.sa.sa_family != AF_UNSPEC &&
+ remote->address.sa.sa_family != addr->sa.sa_family)
return false;
if (addr->sa.sa_family == AF_INET6) {
- if (config->address.in.sin_port != addr->in6.sin6_port)
+ if (remote->address.in.sin_port != addr->in6.sin6_port)
return false;
}
else {
- if (config->address.in.sin_port != addr->in.sin_port)
+ if (remote->address.in.sin_port != addr->in.sin_port)
return false;
}
diff --git a/src/peer.h b/src/peer.h
index a363424..1b6303e 100644
--- a/src/peer.h
+++ b/src/peer.h
@@ -41,11 +41,11 @@ struct fastd_peer {
fastd_peer_address_t address;
fastd_peer_state_t state;
-
- struct timespec last_resolve;
- struct timespec last_resolve_return;
struct timespec seen;
+ fastd_remote_t *remotes;
+ fastd_remote_t *next_remote;
+
struct timespec last_handshake;
fastd_peer_address_t last_handshake_address;
@@ -64,11 +64,10 @@ struct fastd_peer_config {
bool enabled;
char *name;
- char *hostname;
- fastd_peer_address_t address;
+ fastd_remote_config_t *remotes;
+ char *key;
bool floating;
bool dynamic_float_deprecated;
- char *key;
const fastd_peer_group_config_t *group;
fastd_protocol_peer_config_t *protocol_config;
@@ -80,6 +79,22 @@ struct fastd_peer_eth_addr {
struct timespec seen;
};
+struct fastd_remote {
+ fastd_remote_t *next;
+
+ fastd_remote_config_t *config;
+ fastd_peer_address_t address;
+ struct timespec last_resolve;
+ struct timespec last_resolve_return;
+};
+
+struct fastd_remote_config {
+ fastd_remote_config_t *next;
+
+ char *hostname;
+ fastd_peer_address_t address;
+};
+
bool fastd_peer_address_equal(const fastd_peer_address_t *addr1, const fastd_peer_address_t *addr2);
void fastd_peer_address_simplify(fastd_peer_address_t *addr);
@@ -111,7 +126,9 @@ bool fastd_peer_verify_temporary(fastd_context_t *ctx, fastd_peer_t *peer, const
void fastd_peer_enable_temporary(fastd_context_t *ctx, fastd_peer_t *peer);
void fastd_peer_set_established(fastd_context_t *ctx, fastd_peer_t *peer);
bool fastd_peer_may_connect(fastd_context_t *ctx, fastd_peer_t *peer);
-void fastd_peer_handle_resolve(fastd_context_t *ctx, fastd_peer_t *peer, const fastd_peer_address_t *address);
+void fastd_peer_handle_resolve(fastd_context_t *ctx, fastd_peer_t *peer, fastd_remote_t *remote, const fastd_peer_address_t *address);
+bool fastd_peer_owns_address(fastd_context_t *ctx, const fastd_peer_t *peer, const fastd_peer_address_t *addr);
+bool fastd_peer_matches_address(fastd_context_t *ctx, const fastd_peer_t *peer, const fastd_peer_address_t *addr);
bool fastd_peer_claim_address(fastd_context_t *ctx, fastd_peer_t *peer, fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr);
void fastd_peer_reset_socket(fastd_context_t *ctx, fastd_peer_t *peer);
@@ -123,23 +140,15 @@ static inline bool fastd_peer_allow_unknown(fastd_context_t *ctx) {
}
static inline bool fastd_peer_config_is_floating(const fastd_peer_config_t *config) {
- return ((config->hostname == NULL && config->address.sa.sa_family == AF_UNSPEC) || config->floating);
+ return (!config->remotes || config->floating);
}
-static inline bool fastd_peer_config_is_dynamic(const fastd_peer_config_t *config) {
- return (config->hostname != NULL);
-}
-
-bool fastd_peer_config_matches_dynamic(const fastd_peer_config_t *config, const fastd_peer_address_t *addr);
+bool fastd_peer_remote_matches_dynamic(const fastd_remote_config_t *remote, const fastd_peer_address_t *addr);
static inline bool fastd_peer_is_floating(const fastd_peer_t *peer) {
return peer->config ? fastd_peer_config_is_floating(peer->config) : true;
}
-static inline bool fastd_peer_is_dynamic(const fastd_peer_t *peer) {
- return peer->config ? fastd_peer_config_is_dynamic(peer->config) : false;
-}
-
static inline bool fastd_peer_is_temporary(const fastd_peer_t *peer) {
return (!peer->config);
}
@@ -154,6 +163,10 @@ static inline bool fastd_peer_is_established(const fastd_peer_t *peer) {
}
}
+static inline bool fastd_peer_remote_is_dynamic(const fastd_remote_t *remote) {
+ return remote->config->hostname;
+}
+
static inline void fastd_peer_seen(fastd_context_t *ctx, fastd_peer_t *peer) {
peer->seen = ctx->now;
}
diff --git a/src/protocol_ec25519_fhmqvc.c b/src/protocol_ec25519_fhmqvc.c
index 487acdc..c9baba4 100644
--- a/src/protocol_ec25519_fhmqvc.c
+++ b/src/protocol_ec25519_fhmqvc.c
@@ -550,20 +550,31 @@ static void handle_finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock,
}
static fastd_peer_t* find_sender_key(fastd_context_t *ctx, const fastd_peer_address_t *address, const unsigned char key[32], fastd_peer_t *peers) {
- fastd_peer_t *peer;
+ errno = 0;
+
+ fastd_peer_t *ret = NULL, *peer;
+
for (peer = peers; peer; peer = peer->next) {
- if (memcmp(peer->protocol_config->public_key.p, key, PUBLICKEYBYTES) != 0)
- continue;
+ if (memcmp(peer->protocol_config->public_key.p, key, PUBLICKEYBYTES) == 0) {
+ if (!fastd_peer_matches_address(ctx, peer, address)) {
+ errno = EPERM;
+ return NULL;
+ }
- if (fastd_peer_is_floating(peer))
- return peer;
+ ret = peer;
+ continue;
+ }
- errno = EPERM;
- return NULL;
+ if (fastd_peer_owns_address(ctx, peer, address)) {
+ errno = EPERM;
+ return NULL;
+ }
}
- errno = ENOENT;
- return NULL;
+ if (!ret)
+ errno = ENOENT;
+
+ return ret;
}
static fastd_peer_t* match_sender_key(fastd_context_t *ctx, const fastd_socket_t *sock, const fastd_peer_address_t *address, fastd_peer_t *peer, const unsigned char key[32]) {
@@ -573,27 +584,19 @@ static fastd_peer_t* match_sender_key(fastd_context_t *ctx, const fastd_socket_t
exit_bug(ctx, "packet without correct peer set on dynamic socket");
if (peer) {
- if (memcmp(peer->protocol_config->public_key.p, key, PUBLICKEYBYTES) == 0) {
- if (sock->peer && sock->peer != peer) {
- errno = EPERM;
- return NULL;
- }
-
+ if (memcmp(peer->protocol_config->public_key.p, key, PUBLICKEYBYTES) == 0)
return peer;
- }
- }
- if (peer && !fastd_peer_is_floating(peer) && !fastd_peer_is_dynamic(peer)) {
- errno = EPERM;
- return NULL;
+ if (fastd_peer_owns_address(ctx, peer, address)) {
+ errno = EPERM;
+ return NULL;
+ }
}
peer = find_sender_key(ctx, address, key, ctx->peers);
- if (!peer && errno == ENOENT) {
- errno = 0;
+ if (!peer && errno == ENOENT)
peer = find_sender_key(ctx, address, key, ctx->peers_temp);
- }
return peer;
}
diff --git a/src/resolve.c b/src/resolve.c
index 103ba5f..5a18002 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -99,27 +99,27 @@ static void* resolve_peer(void *varg) {
return NULL;
}
-void fastd_resolve_peer(fastd_context_t *ctx, fastd_peer_t *peer) {
+void fastd_resolve_peer(fastd_context_t *ctx, fastd_peer_t *peer, fastd_remote_t *remote) {
if (!peer->config)
exit_bug(ctx, "trying to resolve temporary peer");
- if (timespec_after(&peer->last_resolve, &peer->last_resolve_return)) {
+ if (timespec_after(&remote->last_resolve, &remote->last_resolve_return)) {
pr_debug(ctx, "not resolving %P as there is already a resolve running", peer);
return;
}
- if (timespec_diff(&ctx->now, &peer->last_resolve) < ctx->conf->min_resolve_interval*1000) {
+ if (timespec_diff(&ctx->now, &remote->last_resolve) < ctx->conf->min_resolve_interval*1000) {
/* last resolve was just a few seconds ago */
return;
}
- pr_verbose(ctx, "resolving host `%s' for peer %P...", peer->config->hostname, peer);
+ pr_verbose(ctx, "resolving host `%s' for peer %P...", remote->config->hostname, peer);
resolv_arg_t *arg = malloc(sizeof(resolv_arg_t));
arg->ctx = ctx;
- arg->hostname = strdup(peer->config->hostname);
- arg->constraints = peer->config->address;
+ arg->hostname = strdup(remote->config->hostname);
+ arg->constraints = remote->config->address;
pthread_t thread;
if (pthread_create(&thread, NULL, resolve_peer, arg) != 0) {
@@ -132,5 +132,5 @@ void fastd_resolve_peer(fastd_context_t *ctx, fastd_peer_t *peer) {
}
pthread_detach(thread);
- peer->last_resolve = ctx->now;
+ remote->last_resolve = ctx->now;
}
diff --git a/src/types.h b/src/types.h
index 0425db7..7cec771 100644
--- a/src/types.h
+++ b/src/types.h
@@ -66,6 +66,8 @@ typedef struct fastd_peer_config fastd_peer_config_t;
typedef struct fastd_eth_addr fastd_eth_addr_t;
typedef struct fastd_peer fastd_peer_t;
typedef struct fastd_peer_eth_addr fastd_peer_eth_addr_t;
+typedef struct fastd_remote_config fastd_remote_config_t;
+typedef struct fastd_remote fastd_remote_t;
typedef struct fastd_log_file fastd_log_file_t;
typedef struct fastd_log_fd fastd_log_fd_t;