Skip to content

Only intercept ENet disconnects addressed to our peer - #162

Merged
cgutman merged 1 commit into
moonlight-stream:masterfrom
ccowan93:fix/validate-disconnect-intercept
Oct 24, 2026
Merged

cgutman merged 1 commit into
moonlight-stream:masterfrom
ccowan93:fix/validate-disconnect-intercept

Conversation

@ccowan93

Copy link
Copy Markdown
Contributor

ignoreDisconnectIntercept() is installed as the control stream's ENet intercept callback, so it sees every datagram on the control socket before ENet validates it. It only checked the datagram length and the command, so any 12-byte DISCONNECT from any source set disconnectPending. The receive thread then ends the session about a second later.

This PR acts on the disconnect only if the header's peer ID and session ID match our peer and the datagram came from the peer's current address. Anything else returns 0 and goes through ENet's normal processing unchanged. So a real disconnect that doesn't match (for example from another address of a multi-homed host) is still handled, just without the grace period this intercept adds.

Note: this makes the intercept no looser than ENet itself. ENet's own peer-address check is still disabled in the fork for multi-homed hosts (cgutman/enet@cf38f85), so this narrows the problem but doesn't fully close it. That part probably needs a separate design discussion.

Tested: builds without warnings into moonlight-qt (macOS, Qt 6.12, release) and the app runs. Not tested against a live host.

🤖 Generated with Claude Code

ignoreDisconnectIntercept() runs on every datagram the control stream
socket receives, before ENet has validated the packet. It only checked
the length and command, so any 12-byte DISCONNECT from any source set
disconnectPending, which tears down the session about a second later.

Check that the header's peer ID and session ID match our peer and that
the packet came from the peer's current address before acting on it.
Anything else is passed to ENet unchanged, so a genuine disconnect that
does not match (for example from another address of a multi-homed
host) is still handled, just without the grace period.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cgutman
cgutman merged commit 41cedb8 into moonlight-stream:master Oct 24, 2026
11 checks passed
MrOz59 pushed a commit to MrOz59/moonlight-common-c that referenced this pull request Oct 26, 2026
…am#162)

ignoreDisconnectIntercept() runs on every datagram the control stream
socket receives, before ENet has validated the packet. It only checked
the length and command, so any 12-byte DISCONNECT from any source set
disconnectPending, which tears down the session about a second later.

Check that the header's peer ID and session ID match our peer and that
the packet came from the peer's current address before acting on it.
Anything else is passed to ENet unchanged, so a genuine disconnect that
does not match (for example from another address of a multi-homed
host) is still handled, just without the grace period.

(cherry picked from commit 41cedb8)
MrOz59 pushed a commit to MrOz59/moonlight-common-c that referenced this pull request Oct 26, 2026
…am#162)

ignoreDisconnectIntercept() runs on every datagram the control stream
socket receives, before ENet has validated the packet. It only checked
the length and command, so any 12-byte DISCONNECT from any source set
disconnectPending, which tears down the session about a second later.

Check that the header's peer ID and session ID match our peer and that
the packet came from the peer's current address before acting on it.
Anything else is passed to ENet unchanged, so a genuine disconnect that
does not match (for example from another address of a multi-homed
host) is still handled, just without the grace period.

(cherry picked from commit 41cedb8)
MrOz59 pushed a commit to MrOz59/moonlight-common-c that referenced this pull request Oct 26, 2026
…am#162)

ignoreDisconnectIntercept() runs on every datagram the control stream
socket receives, before ENet has validated the packet. It only checked
the length and command, so any 12-byte DISCONNECT from any source set
disconnectPending, which tears down the session about a second later.

Check that the header's peer ID and session ID match our peer and that
the packet came from the peer's current address before acting on it.
Anything else is passed to ENet unchanged, so a genuine disconnect that
does not match (for example from another address of a multi-homed
host) is still handled, just without the grace period.

(cherry picked from commit 41cedb8)
pabragin pushed a commit to pabragin/moonlight-common-c that referenced this pull request Oct 27, 2026
…am#162)

ignoreDisconnectIntercept() runs on every datagram the control stream
socket receives, before ENet has validated the packet. It only checked
the length and command, so any 12-byte DISCONNECT from any source set
disconnectPending, which tears down the session about a second later.

Check that the header's peer ID and session ID match our peer and that
the packet came from the peer's current address before acting on it.
Anything else is passed to ENet unchanged, so a genuine disconnect that
does not match (for example from another address of a multi-homed
host) is still handled, just without the grace period.

(cherry picked from commit 41cedb8)
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.

2 participants