Skip to content

QUIC/WebTransport Transport sometimes uses the wrong socket to dial out. #2913

@2color

Description

@2color

Context

Given the following scenario:

  • Two peers:
    • Peer A: with a public IP and a firewall blocking arbitrary remote connections. Running latest Vole
    • Peer B (Kubo Node) behind NAT with a circuit relay reservation
  • Peer A is running go-libp2p 0.36.1 as part of Vole
  • Peer A is constructed with h, err := libp2p.New(libp2p.DefaultMuxers, libp2p.EnableHolePunching())
  • Peer A is bound to a public IP
  • The machine with Peer A has a firewall configured that blocks incoming connections on public interfaces, so even though h.Addrs() contains public IPs:
    /ip4/127.0.0.1/tcp/35689 
    /ip4/127.0.0.1/udp/39191/webrtc-direct/certhash/uEiB5brq0KqYrJLT8O1Iq2Eo8E3gx8kThAJLs_pyncP74aA 
    /ip4/127.0.0.1/udp/39779/quic-v1/webtransport/certhash/uEiAvszmD8ETmRbFNmM1ZNPe1NDqJEGUSQku9xBhVR-n_MQ/certhash/uEiC9XsVxwVbJabPvDfAeooM4rrurb94qShBeDqmiS30Nfw 
    /ip4/127.0.0.1/udp/42886/quic-v1 
    /ip4/139.178.82.19/tcp/35689 
    /ip4/139.178.82.19/udp/39191/webrtc-direct/certhash/uEiB5brq0KqYrJLT8O1Iq2Eo8E3gx8kThAJLs_pyncP74aA 
    /ip4/139.178.82.19/udp/39779/quic-v1/webtransport/certhash/uEiAvszmD8ETmRbFNmM1ZNPe1NDqJEGUSQku9xBhVR-n_MQ/certhash/uEiC9XsVxwVbJabPvDfAeooM4rrurb94qShBeDqmiS30Nfw 
    /ip4/139.178.82.19/udp/42886/quic-v1 
    /ip6/::1/tcp/39833 
    /ip6/::1/udp/42162/quic-v1 
    /ip6/::1/udp/46915/quic-v1/webtransport/certhash/uEiAvszmD8ETmRbFNmM1ZNPe1NDqJEGUSQku9xBhVR-n_MQ/certhash/uEiC9XsVxwVbJabPvDfAeooM4rrurb94qShBeDqmiS30Nfw 
    /ip6/::1/udp/59420/webrtc-direct/certhash/uEiB5brq0KqYrJLT8O1Iq2Eo8E3gx8kThAJLs_pyncP74aA 
    /ip6/2604:1380:4642:6600::1/tcp/39833 
    /ip6/2604:1380:4642:6600::1/udp/42162/quic-v1 
    /ip6/2604:1380:4642:6600::1/udp/46915/quic-v1/webtransport/certhash/uEiAvszmD8ETmRbFNmM1ZNPe1NDqJEGUSQku9xBhVR-n_MQ/certhash/uEiC9XsVxwVbJabPvDfAeooM4rrurb94qShBeDqmiS30Nfw 
    /ip6/2604:1380:4642:6600::1/udp/59420/webrtc-direct/certhash/uEiB5brq0KqYrJLT8O1Iq2Eo8E3gx8kThAJLs_pyncP74aA]
    
    they are not dialable

Problem

  • Hole punching between the will fail consistently, because Peer A will not have the /libp2p/dcutr protocol enabled.
  • This causes a stream reset (logged by Peer A) and the "error": "failed to open hole-punching stream: failed to negotiate protocol: protocols not supported: [/libp2p/dcutr]"} error (logged by Peer B).

Source of the problem

Based on debugging with @sukunrt, it appears to be related to the following lines:

We were able to work around this problem and successfully hole punch by replacing s.ids.OwnObservedAddrs() with s.host.Addrs()). This was a temporary measure, as we may just want to add the listen addrs to the observed addrs.

Related issue

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions