Skip to content

proto-p10: BX P merge case + silent variant for probe lookups#56

Open
MrLenin wants to merge 2 commits into
evilnet:masterfrom
MrLenin:fix/bx-p-merge-and-silent-probes
Open

proto-p10: BX P merge case + silent variant for probe lookups#56
MrLenin wants to merge 2 commits into
evilnet:masterfrom
MrLenin:fix/bx-p-merge-and-silent-probes

Conversation

@MrLenin

@MrLenin MrLenin commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Two related fixes for cmd_bouncer_transfer's BX P handler in src/proto-p10.c.

1. GetUserN_silent() variant — stop spamming "couldn't find user!" snotices from BX P probes

Factor the existing GetUserN lookup into a private GetUserN_impl(numeric, quiet) helper. Expose two variants:

  • GetUserN — original behaviour, every failure mode (numeric too long/short, server not found, user not found at valid slot) logs LOG_WARNING.
  • GetUserN_silent — same lookup, all warnings suppressed on miss.

Flip only the two probe lookups in cmd_bouncer_transfer (old_primary and new_node) to the silent variant — the BX P handler is the probe path, so a lookup miss is expected, not bug-worthy. Everything else (mod-snoop / mod-track / opserv command targets / FAKEHOST / MARK / channel-mode victims) keeps the noisy GetUserN.

Symptom this addresses: networks running the IRCv3 fork's bouncer subsystem were seeing repeated

x3 warning: GetUserN(GkAAp) couldn't find user!

snotices to oper channels for every BX P probe miss.

2. BX P merge case for in-place conversion

The original handler logged a warning and bailed when both old_primary and new_node existed locally. Modern fork peers can emit BX P in exactly that shape when an N-introduced client is being absorbed into an existing primary on the same account — typically because burst ordering caused us to receive the would-be-alias's N before its BX C, so both userNodes landed in our tables.

Add a merge branch gated on same-handle:

if (new_node) {
    if (old_primary->handle_info
        && old_primary->handle_info == new_node->handle_info) {
        DelUser(old_primary, NULL, 0, "Bouncer transfer");
        return 1;
    }
    /* mismatched/no handle → keep original "log and ignore" */
}

DelUser(announce=0) suppresses both QUIT and KILL emission — this is internal cleanup, the network shouldn't see the alias's identity leave. The surviving identity is new_node.

The mismatched-handle case keeps the existing "log and ignore" guard — we don't silently merge across unrelated accounts.

Test plan

  • X3 rebuilds clean, links to nefarious without warnings
  • Silent variant verified: BX P probe path no longer emits GetUserN(...) couldn't find user! for the alias/primary lookups
  • Mismatched-handle guard preserved: the genuinely-unexpected case still warns

Real-world burst-ordering scenario (modern fork peer sending BX P in merge shape) needs network-level verification on the fork side once both halves of the patch are in.

🤖 Generated with Claude Code

MrLenin and others added 2 commits June 6, 2026 03:11
Factor the GetUserN numeric-to-userNode lookup into a static
GetUserN_impl(numeric, quiet) helper, expose both the original
GetUserN (noisy — keeps WARNING for every failure mode) and a new
GetUserN_silent (suppresses all warnings on lookup miss).

Flip the BX P handler's two probe lookups (cmd_bouncer_transfer:
both old_primary and new_node) to the silent variant.  Probing is
the whole point — the old client may already be gone, and new_node
is normally absent in the swap-path case.

Command handlers and protocol parsers (opserv command targets,
FAKEHOST/MARK/etc. dispatchers, channel-mode victims) keep using
the noisy GetUserN — a miss there is a real protocol bug or
config issue worth surfacing.  mod-snoop / mod-track stay on the
noisy variant too (those modules are off by default and operators
who enable them want the misses).

Symptom this addresses: noisy networks running the fork's bouncer
subsystem were seeing repeated

  x3 warning: GetUserN(GkAAp) couldn't find user!

snotices to O3 channels from the BX P probe path.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The original cmd_bouncer_transfer BX P handler logged a warning
and bailed when both old_primary and new_node existed locally.
Modern fork peers can emit BX P in that exact shape when an
N-introduced client is being absorbed into an existing primary
on the same account — typically because we received the
would-be-alias's N before its BX C in a burst, so both userNodes
landed in our tables.

Add a merge branch gated on same-handle: if both nodes exist AND
share handle_info, delete old_primary's userNode via
DelUser(announce=0) — channels, dict entry, oper list, etc. all
get cleaned up by the standard DelUser path without a network
QUIT/KILL.  The surviving identity is new_node.

The mismatched-handle case keeps the original "log and ignore"
behaviour — we don't silently merge across unrelated accounts.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant