Skip to content

fix(dcutr): add uvarint length-delimited framing to /libp2p/dcutr protocol messages #17

Description

@SilverFire

Summary

The current /libp2p/dcutr implementation in dart_libp2p (lib/p2p/protocol/holepunch/service.dart and holepuncher.dart) sends and expects raw Protobuf payload bytes without length-delimited message framing.

However, the libp2p DCUtR protocol specification and standard go-libp2p implementation (github.com/libp2p/go-libp2p/p2p/protocol/holepunch) frame stream messages using pbio (unsigned varint length prefix).

Problem Impact

When a dart_libp2p node attempts DCUtR hole punching with a go-libp2p peer over a circuit relay:

  1. go-libp2p sends a CONNECT message prefixed by a uvarint length byte (for example, 0x1e).
  2. dart_libp2p performs HolePunch.fromBuffer() on the unstripped stream, failing to parse the Protobuf tag.
  3. The stream is reset, breaking the NAT hole-punching upgrade.

Fix

  • Wrap outbound HolePunch Protobuf messages using encodeDelimitedMessage() to prepend the uvarint length.
  • Use BufferedP2PStreamReader in _incomingHolePunch and _initiateHolePunchImpl to read the uvarint length prefix followed by the exact payload bytes.
  • Cover single-byte and multi-byte uvarint prefixes and fragmented stream reads with unit tests.

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