Skip to content

Feature Request: Option to Block QUIC (UDP Port 443) to Prevent UDP-over-TCP Degradation #213

Closed

Description

@w0l4i

Description:

Is your feature request related to a problem? Please describe.
When QUIC (UDP port 443) traffic is forced through a TCP-based relay/tunnel, it often results in the "TCP meltdown" effect. Tunneling UDP inside TCP causes severe performance degradation, packet drop issues, and high latency because the two protocols' reliability mechanisms interfere with each other.

Describe the solution you'd like
I request a feature/toggle to explicitly block or drop QUIC (UDP port 443) traffic.

Benefits:

By blocking QUIC, modern browsers and applications will automatically fall back to standard TCP (HTTP/2 or HTTP/1.1).

TCP traffic proxies much more smoothly and efficiently through an HTTP relay.

This will lead to increased page load speeds and significantly reduced delay/latency on both the client and server sides.

Activity

  1. w0l4i commented on Apr 25, 2026

    @w0l4i
    Author
  2. therealaleph commented on Apr 25, 2026

    @therealaleph
    Owner

    This is a fair feature request and the analysis is correct — UDP-over-TCP via tunnel-node DOES suffer from TCP meltdown for QUIC. v1.6.0 added native UDP support via SOCKS5 UDP ASSOCIATE, but for users who can't use that path (e.g. apps that don't speak SOCKS5 UDP), QUIC traffic falls back to TCP encapsulation and gets the meltdown.

    A "block QUIC" option is the right shape for apps_script mode:

    For apps_script mode (no tunnel-node, just relay), QUIC packets to UDP/443 don't have a path through the relay anyway — Apps Script is HTTP-only. So the option to prevent QUIC and force browsers to fall back to TCP/443 (HTTPS) makes the user's experience more consistent. Common knob: an iptables/nftables rule on outbound UDP/443, or in our case a return-RST/no-route response in the SOCKS5 listener.

    Implementation options I'd consider:

    1. Black-hole UDP/443 in the SOCKS5 listener — when block_quic: true in config, the SOCKS5 UDP ASSOCIATE handler refuses to associate for destination port 443. Browsers see the QUIC attempt fail and fall back to TCP/HTTPS within ~1 second.
    2. Drop UDP packets to port 443 in the Android TUN bridge — for full-tunnel/proxy_only Android users, intercept at tun2proxy level. Cleaner but requires touching tun2proxy config.

    Path 1 is straightforward and ~50 lines in proxy_server.rs's SOCKS5 handler. Path 2 requires a tun2proxy feature flag or runtime config we don't currently expose.

    Compatibility with v1.6.0 UDP support:

    If the user has a working tunnel-node and UDP support, blocking QUIC isn't necessary — QUIC traverses cleanly. The block_quic option is for the UDP-can't-tunnel case (apps_script mode, or full-mode with broken UDP path), not for the working case.

    Queueing as enhancement. Probably ships in v1.7.0 or v1.8.0 alongside the broader "UDP behavior config" surface (block_quic, max_udp_sessions, udp_idle_timeout — all related knobs that should land together).

    If you have a strong use-case where this is blocking you today (specific app/site that breaks), reply with the details and I'll fast-track it. Otherwise leaving open as a feature tracker.


    [reply via Anthropic Claude | reviewed by @therealaleph]

  3. w0l4i commented on Apr 26, 2026

    @w0l4i
    Author

    please add block quic (udp 443) option on client side
    @dazzling-no-more @amirabbas117 @therealaleph @claude @vahidlazio @hamed256

  4. therealaleph commented on Apr 26, 2026

    @therealaleph
    Owner

    @w0l4i — block_quic config option implemented in 124d0c3. Will ship in v1.7.5.

    What it does:

    When block_quic = true in config.json, the SOCKS5 UDP relay drops any datagram destined for port 443 (UDP/443 = HTTP/3). The client's QUIC stack retries a couple of times then falls back to TCP/HTTPS, which goes through the regular CONNECT path (and the relay).

    Why client-side (not server-side udpgw):

    The udpgw block in #222 was bound to Full mode + Android tun2proxy. This block_quic flag covers everyone — apps_script users, desktop, Full mode, all the same path. It also avoids paying the 200–500 ms tunnel-node round-trip per dropped QUIC datagram, which would otherwise compound during the 1–3 retries before browsers fall back.

    Default off:

    Opt-in. udpgw partly mitigates QUIC TCP-meltdown via persistent socket reuse (your case in Full mode), and a tiny minority of sites only support HTTP/3. Users who want QUIC's failure modes off the table set "block_quic": true in config.json.

    Usage:

    {
      "block_quic": true,
      ...
    }

    Restart mhrv-rs after editing.

    In v1.7.5 changelog. Closing.


    [reply via Anthropic Claude | reviewed by @therealaleph]

  5. added a commit that references this issue on Apr 26, 2026
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