diff options
author | Dimitri Staessens <dimitri@ouroboros.rocks> | 2025-08-09 13:57:56 +0200 |
---|---|---|
committer | Sander Vrijders <sander@ouroboros.rocks> | 2025-08-11 10:06:59 +0200 |
commit | 10f70a0ab27c8b80b1dcb501147d64a851e7ad06 (patch) | |
tree | ad382d41564301f86153c4f29b69385e6b85a7b7 /src/irmd | |
parent | a6f272544855941c2f8081e727c51ad49955a937 (diff) | |
download | ouroboros-10f70a0ab27c8b80b1dcb501147d64a851e7ad06.tar.gz ouroboros-10f70a0ab27c8b80b1dcb501147d64a851e7ad06.zip |
irmd: Fix IPCP order in registry and query timeout
Until we have a more elaborate strategy for figuring out in which
Layer a service is reachable, the IRMd queries the IPCPs for names.
It currently does this in the order they are stored in the registry,
and the idea was to do this ordered by IPCP type. That order got
messed up when the registry was rewritten. This is now fixed, with a
test.
The default query timeout is also lowered from 20s to 200ms. It's
better to let the IRMd fail and retry the flow allocation than spend
20s waiting for the link-state routing to converge on a layer that
doesn't hold the name. This does wonders for tests using Rumba...
Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks>
Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src/irmd')
-rw-r--r-- | src/irmd/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/irmd/reg/reg.c | 15 | ||||
-rw-r--r-- | src/irmd/reg/tests/reg_test.c | 71 |
3 files changed, 81 insertions, 7 deletions
diff --git a/src/irmd/CMakeLists.txt b/src/irmd/CMakeLists.txt index 420cda0f..965c4b3d 100644 --- a/src/irmd/CMakeLists.txt +++ b/src/irmd/CMakeLists.txt @@ -48,7 +48,7 @@ set(ENROLL_TIMEOUT 20000 CACHE STRING "Timeout for an IPCP to enroll (ms)") set(REG_TIMEOUT 20000 CACHE STRING "Timeout for registering a name (ms)") -set(QUERY_TIMEOUT 20000 CACHE STRING +set(QUERY_TIMEOUT 200 CACHE STRING "Timeout to query a name with an IPCP (ms)") set(CONNECT_TIMEOUT 20000 CACHE STRING "Timeout to connect an IPCP to another IPCP (ms)") diff --git a/src/irmd/reg/reg.c b/src/irmd/reg/reg.c index 41f8d9da..811019f6 100644 --- a/src/irmd/reg/reg.c +++ b/src/irmd/reg/reg.c @@ -151,16 +151,23 @@ static struct reg_ipcp * __reg_get_ipcp_by_layer(const char * layer) return NULL; } -static struct list_head * __reg_after_ipcp(pid_t pid) + +static struct list_head * __reg_after_ipcp(const struct ipcp_info * info) { struct list_head * p; - assert(pid > 0); + assert(info != NULL); list_for_each(p, ®.ipcps) { struct reg_ipcp * entry; entry = list_entry(p, struct reg_ipcp, next); - if (entry->info.pid > pid) + if (entry->info.type < info->type) + continue; + + if (entry->info.type > info->type) + break; + + if (entry->info.pid > info->pid) break; } @@ -780,7 +787,7 @@ int reg_create_ipcp(const struct ipcp_info * info) entry->pid = info->pid; - list_add(&ipcp->next, __reg_after_ipcp(info->pid)); + list_add_tail(&ipcp->next, __reg_after_ipcp(info)); list_add(&entry->next, __reg_after_spawned(info->pid)); reg.n_ipcps++; diff --git a/src/irmd/reg/tests/reg_test.c b/src/irmd/reg/tests/reg_test.c index fab5f364..6553f316 100644 --- a/src/irmd/reg/tests/reg_test.c +++ b/src/irmd/reg/tests/reg_test.c @@ -527,7 +527,7 @@ static int test_reg_create_ipcp(void) return TEST_RC_FAIL; } -static int test_rest_reg_list_ipcps(void) +static int test_reg_list_ipcps(void) { ipcp_list_msg_t ** ipcps; int i; @@ -574,6 +574,8 @@ static int test_rest_reg_list_ipcps(void) reg_fini(); + TEST_SUCCESS(); + return TEST_RC_SUCCESS; fail: @@ -581,6 +583,70 @@ static int test_rest_reg_list_ipcps(void) return TEST_RC_FAIL; } +static int test_insert_ipcps(void) +{ + ipcp_list_msg_t ** ipcps; + struct ipcp_info info; + size_t i; + size_t len; + + TEST_START(); + + if (reg_init() < 0) { + printf("Failed to init registry.\n"); + goto fail; + } + + for (i = 0; i < 100; i++) { + sprintf(info.name, "%s-%ld", TEST_IPCP, i); + info.pid = TEST_PID + rand() % 10000; + info.type = rand() % IPCP_INVALID; + info.state = IPCP_BOOT; /* set by spawn_ipcp */ + + if (reg_create_ipcp(&info) < 0) { + printf("Failed to create ipcp %s.\n", info.name); + goto fail; + } + } + + len = reg_list_ipcps(&ipcps); + if (len != 100) { + printf("Failed to list all ipcps.\n"); + goto fail; + } + + for (i = 1; i < len; i++) { + if (ipcps[i]->type < ipcps[i - 1]->type) { + printf("IPCPS not sorted by type.\n"); + goto fail; + } + + if (ipcps[i]->type != ipcps[i - 1]->type) + continue; + + /* allow occasional duplicate PID in test */ + if (ipcps[i]->pid < ipcps[i - 1]->pid) { + printf("IPCPS not sorted by pid.\n"); + goto fail; + } + } + + while (len-- > 0) + ipcp_list_msg__free_unpacked(ipcps[len], NULL); + free(ipcps); + + reg_clear(); + + reg_fini(); + + TEST_SUCCESS(); + + return TEST_RC_SUCCESS; +fail: + REG_TEST_FAIL(); + return TEST_RC_FAIL; +} + static int test_set_layer(void) { struct reg_ipcp * ipcp; @@ -648,7 +714,8 @@ static int test_reg_ipcp(void) int rc = 0; rc |= test_reg_create_ipcp(); - rc |= test_rest_reg_list_ipcps(); + rc |= test_reg_list_ipcps(); + rc |= test_insert_ipcps(); rc |= test_set_layer(); return rc; |