Impact & TL;DR

Introduction

<aside> ⚠️ Throughout the text you will find Open Issue blocks. These are open questions and input there would be much appreciated 🙏

</aside>

NAT hole punching is a widely used technique for establishing peer-to-peer connections in networked systems, allowing communication between hosts that are behind Network Address Translation (NAT) devices. The concept of NAT hole punching was first introduced in [1] and later formally described in RFC 5128, which was released in 2008. In the years that followed, various NAT hole punching protocols have been proposed and implemented. Most notably WebRTC makes use of NAT hole punching techniques which was released in 2011. In 2021 and early 2022, the DCUtR protocol was specified and implemented by the libp2p team at Protocol Labs, with the goal of making centralized components in traditional protocols, like WebRTC, obsolete. The implementation was presented in a talk at FOSDEM 2022, where its potential was discussed, as well as in a research paper presented at DINPS 2022.

In December 2022, we conducted a NAT hole punching measurement campaign to evaluate the NAT hole punching success rate of the DCUtR protocol. The goal of this campaign was to not only measure the performance of the protocol, but also to identify its limitations and potential areas for optimization. The measurement was designed to provide insights into when and why the DCUtR protocol fails in NAT hole punching and to provide recommendations for improvement. In this report, we will present the results of our measurement campaign and provide an analysis of the data collected. The findings of this report will be valuable for researchers and practitioners in the field of network communication, particularly those interested in improving the performance of NAT hole punching protocols.

Measurement

Setup

Untitled

The measurement architecture for the NAT hole punching campaign consists of three components: the honeypot, a server, and a fleet of clients. The challenge is that we have no straightforward way of detecting peers that are behind NATs. A DHT crawler is not of much help in this case, as it only detects publicly reachable peers. The goal of the measurement architecture is to find peers that are behind NATs and not publicly reachable. For that, we use the honeypot component.

The honeypot is a DHT server peer that is designed to be very stable and announces itself to the network by slowly crawling it. This increases the chances that other peers add the honeypot to their routing tables. This, in turn, leads to increased traffic from client peers to the honeypot because other server peers increasingly redirect clients to it. The honeypot tracks all inbound connections from peers that satisfy both of the following conditions:

  1. Peer supports the DCUtR protocol
  2. Peer is only reachable through relay addresses → this indicates it’s behind a NAT

“Tracking all inbound connections” means that they are stored in the common database that’s then queried by the server component.

The server component exposes a gRPC API and can be queried for NAT'd + DCUtR capable peers. It is responsible for tracking the results of hole punching attempts and provides a centralized location for the clients to retrieve information about potential peers to hole punch.

The clients, which are implemented in both Rust and Go, periodically query the server for information about NAT'd DCUtR capable peers. They then use this information to perform hole punching attempts and report back the outcome to the server. This component provides the actual data for the measurement campaign and allows the server to collect the results. The Go client comes in two flavours, a CLI and a GUI version. The GUI version was developed to ease the onboarding of users to the measurement campaign.