diff options
author | Dimitri Staessens <dimitri@ouroboros.rocks> | 2025-08-06 12:29:02 +0200 |
---|---|---|
committer | Sander Vrijders <sander@ouroboros.rocks> | 2025-08-06 12:34:15 +0200 |
commit | fa1af6aaed6a46acd0af1600f4c63e79fcf9ff84 (patch) | |
tree | 6c386340dab2af965f9ccfc9b5b6f6e97326a586 /src/lib | |
parent | a5f6ab5af03d9be6f3412d4dff67748908799e21 (diff) | |
download | ouroboros-fa1af6aaed6a46acd0af1600f4c63e79fcf9ff84.tar.gz ouroboros-fa1af6aaed6a46acd0af1600f4c63e79fcf9ff84.zip |
ipcpd: Update DHT for unicast layer
This is a rewrite of the DHT for name-to-address resolution in the
unicast layer. It is now integrated as a proper directory policy. The
dir_wait_running function is removed, instead the a DHT peer is passed
on during IPCP enrolment.
Each DHT request/response gets a random 64-bit ID ('cookie'). DHT
messages to the same peer are deduped, except in the case when the DHT
is low on contacts. In that case, it will contact the per it received
at enrolment for more contacts. To combat packet loss, these messages
are not deduped by means of a 'magic cookie', chosen at random when
the DHT starts.
The DHT parameters (Kademlia) can be set using the configfile or the
IRM command line tools:
if DIRECTORY_POLICY == DHT
[dht_alpha <search factor> (default: 3)]
[dht_k <replication factor> (default: 8)]
[dht_t_expire <expiration (s)> (default: 86400)]
[dht_t_refresh <contact refresh (s)> (default: 900)]
[dht_t_replicate <replication (s)> (default: 900)]
This commit also adds support for a protocol debug level (PP).
Protocol debugging for the DHT can be enabled using the
DEBUG_PROTO_DHT build flag.
The DHT has the following message types:
DHT_STORE, sent to k peers. Not acknowledged.
DHT_STORE --> [2861814146dbf9b5|ed:d9:e2:c4].
key: bcc236ab6ec69e65 [32 bytes]
val: 00000000c4e2d9ed [8 bytes]
exp: 2025-08-03 17:29:44 (UTC).
DHT_FIND_NODE_REQ, sent to 'alpha' peers, with a corresponding
response. This is used to update the peer routing table to iteratively
look for the nodes with IDs closest to the requested key.
DHT_FIND_NODE_REQ --> [a62f92abffb451c4|ed:d9:e2:c4].
cookie: 2d4b7acef8308210
key: a62f92abffb451c4 [32 bytes]
DHT_FIND_NODE_RSP <-- [2861814146dbf9b5|ed:d9:e2:c4].
cookie: 2d4b7acef8308210
key: a62f92abffb451c4 [32 bytes]
contacts: [1]
[a62f92abffb451c4|9f:0d:c1:fb]
DHT_FIND_VALUE_REQ, sent to 'k' peers, with a corresponding
response. Used to find a value for a key. Will also send its closest
known peers in the response.
DHT_FIND_VALUE_REQ --> [2861814146dbf9b5|ed:d9:e2:c4].
cookie: 80a1adcb09a2ff0a
key: 42dee3b0415b4f69 [32 bytes]
DHT_FIND_VALUE_RSP <-- [2861814146dbf9b5|ed:d9:e2:c4].
cookie: 80a1adcb09a2ff0a
key: 42dee3b0415b4f69 [32 bytes]
values: [1]
00000000c4e2d9ed [8 bytes]
contacts: [1]
[a62f92abffb451c4|9f:0d:c1:fb]
Also removes ubuntu 20 from appveyor config as it is not supported anymore.
Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks>
Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/config.h.in | 1 | ||||
-rw-r--r-- | src/lib/frct.c | 4 | ||||
-rw-r--r-- | src/lib/notifier.c | 18 | ||||
-rw-r--r-- | src/lib/pb/enroll.proto | 1 | ||||
-rw-r--r-- | src/lib/pb/ipcp_config.proto | 19 | ||||
-rw-r--r-- | src/lib/protobuf.c | 97 | ||||
-rw-r--r-- | src/lib/utils.c | 22 |
7 files changed, 141 insertions, 21 deletions
diff --git a/src/lib/config.h.in b/src/lib/config.h.in index 3fcac7b8..8326a332 100644 --- a/src/lib/config.h.in +++ b/src/lib/config.h.in @@ -23,7 +23,6 @@ #cmakedefine HAVE_SYS_RANDOM #cmakedefine HAVE_LIBGCRYPT #cmakedefine HAVE_OPENSSL -#cmakedefine OPENSS_VERSION_MAJOR @OPENSSL_VERSION_MAJOR@ #ifdef HAVE_OPENSSL #define HAVE_ENCRYPTION diff --git a/src/lib/frct.c b/src/lib/frct.c index 4d871efe..08c5ea80 100644 --- a/src/lib/frct.c +++ b/src/lib/frct.c @@ -137,11 +137,11 @@ static int frct_rib_read(const char * path, "Retransmit timeout RTO (ns): %20ld\n" "Sender left window edge: %20u\n" "Sender right window edge: %20u\n" - "Sender inactive (ns): %20ld\n" + "Sender inactive (ns): %20lld\n" "Sender current sequence number: %20u\n" "Receiver left window edge: %20u\n" "Receiver right window edge: %20u\n" - "Receiver inactive (ns): %20ld\n" + "Receiver inactive (ns): %20lld\n" "Receiver last ack: %20u\n" "Number of pkt retransmissions: %20zu\n" "Number of rtt probes: %20zu\n" diff --git a/src/lib/notifier.c b/src/lib/notifier.c index 45745b9a..4fccd371 100644 --- a/src/lib/notifier.c +++ b/src/lib/notifier.c @@ -95,18 +95,14 @@ int notifier_reg(notifier_fn_t callback, pthread_rwlock_wrlock(¬ifier.lock); list_for_each(p, ¬ifier.listeners) { - struct listener * l = list_entry(p, struct listener, next); - if (l->callback == callback) { - pthread_rwlock_unlock(¬ifier.lock); - return -EPERM; - } + l = list_entry(p, struct listener, next); + if (l->callback == callback) + goto fail; } l = malloc(sizeof(*l)); - if (l == NULL) { - pthread_rwlock_unlock(¬ifier.lock); - return -ENOMEM; - } + if (l == NULL) + goto fail; l->callback = callback; l->obj = obj; @@ -116,6 +112,10 @@ int notifier_reg(notifier_fn_t callback, pthread_rwlock_unlock(¬ifier.lock); return 0; + fail: + pthread_rwlock_unlock(¬ifier.lock); + return -1; + } void notifier_unreg(notifier_fn_t callback) diff --git a/src/lib/pb/enroll.proto b/src/lib/pb/enroll.proto index 7fe612a8..60e964c6 100644 --- a/src/lib/pb/enroll.proto +++ b/src/lib/pb/enroll.proto @@ -24,7 +24,6 @@ syntax = "proto2"; import "ipcp_config.proto"; message enroll_req_msg { - /* TODO authentication */ required bytes id = 1; } diff --git a/src/lib/pb/ipcp_config.proto b/src/lib/pb/ipcp_config.proto index 28528b0c..aaff599e 100644 --- a/src/lib/pb/ipcp_config.proto +++ b/src/lib/pb/ipcp_config.proto @@ -31,10 +31,25 @@ message dt_config_msg { required uint32 routing_type = 4; } +message dir_dht_config_msg { + required uint32 alpha = 1; + required uint32 k = 2; + required uint32 t_expire = 3; + required uint32 t_refresh = 4; + required uint32 t_replicate = 5; + required uint64 peer = 6; +} + +message dir_config_msg { + required uint32 pol = 1; + optional dir_dht_config_msg dht = 2; +} + message uni_config_msg { required dt_config_msg dt = 1; - required uint32 addr_auth_type = 2; - required uint32 cong_avoid = 3; + required dir_config_msg dir = 2; + required uint32 addr_auth_type = 3; + required uint32 cong_avoid = 4; } message eth_config_msg { diff --git a/src/lib/protobuf.c b/src/lib/protobuf.c index b586168c..70c1bc90 100644 --- a/src/lib/protobuf.c +++ b/src/lib/protobuf.c @@ -222,6 +222,97 @@ struct dt_config dt_config_msg_to_s(const dt_config_msg_t * msg) return s; } +struct dir_dht_config dir_dht_config_msg_to_s(const dir_dht_config_msg_t * msg) +{ + struct dir_dht_config s; + + assert(msg != NULL); + + s.params.alpha = msg->alpha; + s.params.k = msg->k; + s.params.t_expire = msg->t_expire; + s.params.t_refresh = msg->t_refresh; + s.params.t_replicate = msg->t_replicate; + s.peer = msg->peer; + + return s; +} + +dir_dht_config_msg_t * dir_dht_config_s_to_msg(const struct dir_dht_config * s) +{ + dir_dht_config_msg_t * msg; + + assert(s != NULL); + + msg = malloc(sizeof(*msg)); + if (msg == NULL) + return NULL; + + dir_dht_config_msg__init(msg); + + msg->alpha = s->params.alpha; + msg->k = s->params.k; + msg->t_expire = s->params.t_expire; + msg->t_refresh = s->params.t_refresh; + msg->t_replicate = s->params.t_replicate; + msg->peer = s->peer; + + return msg; +} + +struct dir_config dir_config_msg_to_s(const dir_config_msg_t * msg) +{ + struct dir_config s; + + assert(msg != NULL); + + switch (msg->pol) { + case DIR_DHT: + s.dht = dir_dht_config_msg_to_s(msg->dht); + break; + default: + /* No checks here */ + break; + } + + s.pol = msg->pol; + + return s; +} + +dir_config_msg_t * dir_config_s_to_msg(const struct dir_config * s) +{ + dir_config_msg_t * msg; + + assert(s != NULL); + + msg = malloc(sizeof(*msg)); + if (msg == NULL) + return NULL; + + dir_config_msg__init(msg); + + switch (s->pol) { + case DIR_DHT: + msg->dht = dir_dht_config_s_to_msg(&s->dht); + if (msg->dht == NULL) + goto fail_msg; + break; + default: + /* No checks here */ + break; + } + + msg->pol = s->pol; + + return msg; + + fail_msg: + dir_config_msg__free_unpacked(msg, NULL); + return NULL; +} + + uni_config_msg_t * uni_config_s_to_msg(const struct uni_config * s) { uni_config_msg_t * msg; @@ -238,6 +329,11 @@ uni_config_msg_t * uni_config_s_to_msg(const struct uni_config * s) if (msg->dt == NULL) goto fail_msg; + msg->dir = dir_config_s_to_msg(&s->dir); + if (msg->dir == NULL) + goto fail_msg; + + msg->addr_auth_type = s->addr_auth_type; msg->cong_avoid = s->cong_avoid; @@ -254,6 +350,7 @@ struct uni_config uni_config_msg_to_s(const uni_config_msg_t * msg) struct uni_config s; s.dt = dt_config_msg_to_s(msg->dt); + s.dir = dir_config_msg_to_s(msg->dir); s.addr_auth_type = msg->addr_auth_type; s.cong_avoid = msg->cong_avoid; diff --git a/src/lib/utils.c b/src/lib/utils.c index fdbcd9d9..fd275f63 100644 --- a/src/lib/utils.c +++ b/src/lib/utils.c @@ -27,16 +27,26 @@ #include <stdlib.h> #include <string.h> +int bufcmp(const buffer_t * a, + const buffer_t * b) +{ + if (a->len != b->len) + return a->len < b->len ? -1 : 1; + + return memcmp(a->data, b->data, a->len); +} + + int n_digits(unsigned i) { - int n = 1; + int n = 1; - while (i > 9) { - ++n; - i /= 10; - } + while (i > 9) { + ++n; + i /= 10; + } - return n; + return n; } char * path_strip(const char * src) |