From 2ddcad3989cd8d2314453ed31ff43e122118663f Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Fri, 1 May 2026 23:41:49 +0200 Subject: irmd: Drop replayed flow alloc requests A duplicating link could deliver the same alloc request twice. OAP detected the replay but still replied over the wire, so the requester saw a second flow_alloc_reply on an already-allocated flow and reg_respond_alloc tripped its PENDING-state assertion. Add EREPLAY so the OAP server can signal replays distinctly; flow_accept drops them silently. As a safety net, reg_respond_alloc warn-drops late replies instead of asserting. Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- src/irmd/oap/auth.c | 1 + src/irmd/oap/srv.c | 15 +++++++++++++-- src/irmd/oap/tests/oap_test.c | 7 ++++--- 3 files changed, 18 insertions(+), 5 deletions(-) (limited to 'src/irmd/oap') diff --git a/src/irmd/oap/auth.c b/src/irmd/oap/auth.c index 4b86f055..d165de73 100644 --- a/src/irmd/oap/auth.c +++ b/src/irmd/oap/auth.c @@ -174,6 +174,7 @@ int oap_check_hdr(const struct oap_hdr * hdr) fail_replay: pthread_mutex_unlock(&oap_auth.replay.mtx); free(new); + return -EREPLAY; fail_stamp: return -EAUTH; } diff --git a/src/irmd/oap/srv.c b/src/irmd/oap/srv.c index afc54acc..ce97654f 100644 --- a/src/irmd/oap/srv.c +++ b/src/irmd/oap/srv.c @@ -393,6 +393,7 @@ int oap_srv_process(const struct name_info * info, void * pkp = NULL; void * crt = NULL; int req_md_nid; + int ret; assert(info != NULL); assert(rsp_buf != NULL); @@ -427,8 +428,13 @@ int oap_srv_process(const struct name_info * info, id = peer_hdr.id.data; /* Logging */ - if (oap_check_hdr(&peer_hdr) < 0) { - log_err_id(id, "OAP header failed replay check."); + ret = oap_check_hdr(&peer_hdr); + if (ret == -EREPLAY) { + log_warn_id(id, "OAP header failed replay check."); + goto fail_replay; + } + if (ret < 0) { + log_err_id(id, "OAP header check failed."); goto fail_auth; } @@ -491,6 +497,11 @@ int oap_srv_process(const struct name_info * info, fail_cred: return -EAUTH; + fail_replay: + crypt_free_crt(crt); + crypt_free_key(pkp); + return -EREPLAY; + fail_kex: crypt_free_crt(crt); crypt_free_key(pkp); diff --git a/src/irmd/oap/tests/oap_test.c b/src/irmd/oap/tests/oap_test.c index a324b586..a525d988 100644 --- a/src/irmd/oap/tests/oap_test.c +++ b/src/irmd/oap/tests/oap_test.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -1053,9 +1054,9 @@ static int test_oap_replay_packet(void) freebuf(ctx.req_hdr); ctx.req_hdr = saved_req; - /* Replayed request should fail */ - if (oap_srv_process_ctx(&ctx) == 0) { - printf("Server should reject replayed packet.\n"); + /* Replay must return -EREPLAY so callers can drop silently. */ + if (oap_srv_process_ctx(&ctx) != -EREPLAY) { + printf("Replayed packet rejection != -EREPLAY.\n"); goto fail_cleanup; } -- cgit v1.2.3