Skip to content

fix(ec): stop prior Kad search when EC client starts any new search - #36

Merged
got3nks merged 1 commit into
amule-org:masterfrom
got3nks:fix/ec-search-stop-prior-kad-on-type-switch
Jun 9, 2026
Merged

fix(ec): stop prior Kad search when EC client starts any new search#36
got3nks merged 1 commit into
amule-org:masterfrom
got3nks:fix/ec-search-stop-prior-kad-on-type-switch

Conversation

@got3nks

@got3nks got3nks commented Jun 9, 2026

Copy link
Copy Markdown

Summary

When an EC client (amuleweb / amulegui / amulecmd) starts a new search via EC_OP_SEARCH_START, the daemon's previous Kad search wasn't being terminated unless the new search was also Kad — so late-arriving Kad reply packets continued feeding the shared m_results[0xffffffff] bucket while the new search was filling it. Switching from Kad → ed2k (Local or Global) via the web UI ends up showing Kad results mixed in with the ed2k server replies.

Root cause

EC clients pass 0xffffffff to CSearchList::StartNewSearch regardless of search type, per the partition agreed in 3008ada0f (native GUI uses bottom-half IDs, Kad-allocated uses top half, 0xffffffff reserved as the EC sentinel).

The daemon's Get_EC_Response_Search already calls RemoveResults(0xffffffff) to clear the bucket, but that path invokes CSearchManager::StopSearch(0xffffffff, /*delayDelete=*/true) which only marks the prior Kad search for cleanup via PrepareToStop() so it can still drain in-flight packets. Those drained packets call KademliaSearchKeyword(0xffffffff, ...) and AddToList puts them right back into the bucket the new search has just started using.

Inside CSearchList::StartNewSearch itself there's already a hard-delete (StopSearch(0xffffffff, false)) — but it's gated under if (type == KadSearch), so it only runs when the new search is also Kad. The cross-type case (Kad → ed2k) leaves the soft-stopped Kad search alive.

Fix

Hoist the hard-delete out of the if (type == KadSearch) block so it fires for any EC-driven new search, before either Kad's PrepareFindKeywords or ed2k's server packet starts feeding m_results[0xffffffff].

Why monolithic / native GUI is unaffected

CSearchDlg::StartNewSearch allocates bottom-half IDs (m_nSearchID & 0x7fffffff), so the new gate if (*searchID == 0xffffffff) is false for native-GUI calls. Their per-tab m_results[id] isolation is unchanged. Multiple parallel Kad searches + one ed2k search continue to work because each tab's Kad-allocated top-half ID and each ed2k search's bottom-half ID are distinct buckets, fed by codepaths that own those IDs.

Test plan

  • amuled with EC enabled.
  • amuleweb (or any EC client): run Kad search "ubuntu" → wait for results.
  • Start ed2k Local search "ubuntu" → click "Update results" after the server replies → result list contains only ed2k results, no Kad-flavored hits.
  • Native amule GUI: open multiple search tabs (multiple Kad + one ed2k) → each tab shows only its own search's results, no cross-contamination.

Discovered while triaging #31. PR #33 fixed the amuleweb-side rendering bug; this fixes the orthogonal daemon-side cross-type contamination.

When an EC client (amuleweb / amulegui) starts a new search, the
daemon's `Get_EC_Response_Search` invokes
`searchlist->RemoveResults(0xffffffff)` which calls
`CSearchManager::StopSearch(0xffffffff, /*delayDelete=*/true)`.
The delay-delete flag deliberately keeps the `CSearch` object in
`m_searches` so late-arriving Kad reply packets can still be
processed.

Post-3008ada0f, EC clients pass `0xffffffff` for any search type.
When an EC ed2k search starts immediately after a Kad search, the
still-alive prior Kad search continues firing
`KademliaSearchKeyword(0xffffffff, ...)` for late UDP replies, and
those results land in `m_results[0xffffffff]` -- the same bucket
the new ed2k search is filling via `m_currentSearch=0xffffffff` +
`ProcessSearchAnswer`. The user sees Kad-flavored hits mixed in
with their ed2k results.

The pre-existing hard-stop inside the Kad branch of
`CSearchList::StartNewSearch` already terminates the prior Kad
search when both old and new searches are Kad. Hoisting that hard-
stop out of the `if (type == KadSearch)` block makes it fire for
any EC-driven new search regardless of type, terminating the
stale Kad search before it can contaminate the new bucket.

Native-GUI searches are unaffected: `CSearchDlg::StartNewSearch`
allocates bottom-half IDs (`m_nSearchID & 0x7fffffff`), so the
`*searchID == 0xffffffff` gate skips them. They keep their per-
tab `m_results[id]` isolation.
@got3nks
got3nks marked this pull request as draft June 9, 2026 15:56
@got3nks
got3nks marked this pull request as ready for review June 9, 2026 16:09
@got3nks
got3nks merged commit 508bc83 into amule-org:master Jun 9, 2026
10 checks passed
@got3nks
got3nks deleted the fix/ec-search-stop-prior-kad-on-type-switch branch June 9, 2026 16:09
got3nks added a commit that referenced this pull request Jun 9, 2026
#37)

PR #36 hard-stops the previous Kad search when an EC client starts
any new search, blocking late KademliaSearchKeyword(0xffffffff, ...)
callbacks from contaminating the new search's m_results[0xffffffff]
bucket. The reverse direction was unfixed: late ed2k server replies
(TCP Local in ProcessSearchAnswer, UDP Global in
ProcessUDPSearchAnswer) keep arriving for seconds after the request
was sent and continue calling AddToList with searchID =
m_currentSearch. With the EC sentinel `0xffffffff` pinned across
all EC searches, those late results land in the new (Kad) search's
bucket -- ed2k contamination of a Kad result list, symmetric to
the Kad contamination of an ed2k list that PR #36 fixed.

Drop late ed2k replies when the active search type is no longer
ed2k. Same shape as PR #36's StopSearch hoist: cheap one-line gate
that closes the bucket on the protocol level.

Native-GUI parallel searches: a Kad tab updates m_searchType to
KadSearch, so this gate also drops late ed2k packets that would
otherwise misroute to the Kad tab's m_results[m_currentSearch].
Pre-existing GUI misrouting bug that wasn't visible because cross-
protocol hits in a Kad tab look like generic Kad noise; the right
fix there is per-search-object tracking on the ed2k side (mirroring
CSearch), out of scope for this hotfix.
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