Skip to content

c-v0.0.1 QUIC listener hang and crash with rust dialers #10

@dhuseby

Description

@dhuseby

Repo: Pier-Two/c-libp2p
Commit: 23a617223a3bbfb4b2af8f219f389e440b9c1ac2
Transport: quic-v1

Summary

c-v0.0.1 as a QUIC listener fails when rust implementations dial it. The QUIC handshake completes successfully and multistream-select begins, but the connection stalls and never progresses to the ping protocol. With rust-v0.53 and rust-v0.55, the test times out after 180 seconds. With rust-v0.56, the c listener crashes with a segmentation fault (exit code 139).

This is distinct from the existing c-v001-quic-stream-hang.md bug, which documents c-v0.0.1 as a QUIC dialer hanging during multistream-select against go. Here, c is the listener.

Failing tests (3)

  • rust-v0.53 x c-v0.0.1 (quic-v1) — timeout after 180s
  • rust-v0.55 x c-v0.0.1 (quic-v1) — timeout after 180s
  • rust-v0.56 x c-v0.0.1 (quic-v1) — SIGSEGV (exit code 139)

Passing test

  • rust-v0.54 x c-v0.0.1 (quic-v1) — passes

Error output

rust-v0.53 / rust-v0.55 (timeout): The QUIC handshake completes (Initial, Handshake, 1-RTT phases all succeed). The rust dialer sends multistream-select on streams 0 and 4. The c listener responds with multistream-select and identify data on stream 0, and ping negotiation on stream 4. However, the connection stalls after this exchange — no further progress until the 180s timeout.

stream 0, offset 0, length 20, fin = 0: 132f6d756c746973...   (multistream-select)
stream 4, offset 0, length 20, fin = 0: 132f6d756c746973...   (multistream-select)
stream 4, offset 20, length 18, fin = 0: 112f697066732f70... (ping protocol)

rust-v0.56 (crash): Same QUIC handshake and multistream-select exchange, but the c listener crashes mid-response:

listener exited with code 139

Exit code 139 = SIGSEGV. The crash occurs during QUIC packet construction (the log line is truncated mid-output at ack_ecn), suggesting a memory corruption or buffer overflow in c-libp2p's QUIC response handling.

Root cause analysis

The QUIC handshake works correctly in all cases (crypto, transport parameters, ALPN negotiation all succeed). The failure occurs at the application protocol layer after multistream-select begins. The c listener appears to stall after sending the initial protocol negotiation responses, never completing the ping stream handshake.

The segfault with rust-v0.56 may be related to rust-v0.56's use of additional QUIC extensions (min_ack_delay, immediate_ack, unknown extension type 854471258725259551) that rust-v0.53/v0.55 don't send. The c listener may mishandle these extensions, causing the memory corruption.

rust-v0.54 passes, suggesting a narrow compatibility window — possibly related to specific QUIC transport parameter differences between rust versions.

Notes

  • The existing c-v001-quic-stream-hang.md documents c as a QUIC dialer failing. This report documents c as a QUIC listener failing — different code paths.
  • All proxy hostnames use correct RFC 1123 format (proxy-<hash>). No framework issues detected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    cc-libp2p relatedquicquic transport related

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions