summaryrefslogtreecommitdiff
path: root/src/irmd/reg
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2025-08-09 13:57:56 +0200
committerSander Vrijders <sander@ouroboros.rocks>2025-08-11 10:06:59 +0200
commit10f70a0ab27c8b80b1dcb501147d64a851e7ad06 (patch)
treead382d41564301f86153c4f29b69385e6b85a7b7 /src/irmd/reg
parenta6f272544855941c2f8081e727c51ad49955a937 (diff)
downloadouroboros-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/reg')
-rw-r--r--src/irmd/reg/reg.c15
-rw-r--r--src/irmd/reg/tests/reg_test.c71
2 files changed, 80 insertions, 6 deletions
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, &reg.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;