Skip to content

Portal: entering control tears down the whole iroh endpoint, dropping the session #137

Description

@FelineStateMachine

Found during the v0.1.0 end-to-end test on a freshly installed host. View works; clicking to control always disconnects. Reproduced 4/4 times.

What happens

The host accepts everything correctly, then the entire QUIC session dies 8ms later.

Host (sigil 0.1.0, fresh install from the published release):

22:00:27.111  slot-0 focus state changed   action=Request  transition_reason=Requested
22:00:27.126  input v2 client accepted     session_id=2  focus_generation=2  authorization_revision=2
22:00:27.134  shared-generation media feedback contributor released
22:00:27.134  input v2 client released
22:00:27.134  input v2 connection ended    error=I/O error: connection lost
22:00:27.134  probe stream error           err=transport: session error
22:00:27.134  subscribed cancelled  video/h264 + audio/opus
22:00:27.134  multi-viewer session membership changed  active_viewers=0  reason="disconnected"

Portal (0.1.0, macOS arm64, run from a terminal to capture stderr):

[client] moq catalog: goq-v2-authenticated          <- view working
[client] adaptive decision read failed: I/O error: connection lost
[client] invalid control v2 message: I/O error: connection lost
[moq_net::lite::subscriber] subscribe error id=1 audio/opus err=transport: session error
[moq_net::lite::subscriber] subscribe error id=2 video/h264 err=transport: session error
[client] timed out waiting for endpoint shutdown after explicit connection close
[iroh::socket][ERROR] Endpoint dropped without calling `Endpoint::close`. Aborting ungracefully.

Why this is an endpoint bug, not a session bug

  • The host accepts the input v2 client. This is not a rejection or an authorization failure.
  • Portal does not crash; the process survives.
  • Control v2, media, audio, and media-feedback all report connection lost simultaneously. Those are separate connections, so the common factor is the iroh Endpoint itself.
  • Endpoint dropped without calling Endpoint::close fires when the last reference goes away.

The subsequent timed out waiting for endpoint shutdown after explicit connection close (media/connect.rs:574) is the aftermath — disconnect_client runs against an endpoint that is already gone, which is why it times out.

Hypothesis

start_focused_input_v2 (media/input_delivery.rs:512) takes context.endpoint from state.v2_input_context. Entering control also advances the roster/snapshot. If that path clears or replaces v2_input_context while its Endpoint clone is the last strong reference, dropping the context drops the endpoint, which kills every connection at once. That matches the timing and the "all at once" signature exactly.

Worth checking whether anything other than state.client_endpoint is expected to keep the endpoint alive.

Environment

  • Host: Bazzite 43 Kinoite, installed via curl -fsSL https://goq.sh/install-sigil | bash, activation guide followed end to end
  • Capture: gamescope-pipewire, 2560x1600@60, vah264enc on /dev/dri/renderD128, external-gst-launch backend
  • Portal: v0.1.0 macOS arm64 from the published release
  • Enrollment: fresh, grants view,pointer-keyboard,gamepad
  • Host preflight was clean: capture probe 300 frames, 0 post-encode drops, 58.2 fps

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions