Skip to content

Migration from vnet.Net to transport.Net

Steffen Vogel edited this page Jan 31, 2023 · 2 revisions

This page summarized changes to Pion's virtual network test facility which have been introduced by v2 of the pion/transport module.

The old vnet.Net type

The vnet (Virtual NETwork) package was introduced to facilitate integration tests by emulating a network stack in user-space to build. This allowed Pion to be tested against complex network topologies / NAT setups to ensure its correct operation.

It does so my providing alternative implementations of many functions provided by Go's standard net package. These alternative functions are implemented as methods for a new vnet.Net type:

package vnet

type Net struct {
	[...]

	v   *vNet // internal type to represent the virtual network
}

func (n *Net) ListenUDP(network string, locAddr *net.UDPAddr) (UDPPacketConn, error) {
	if n.v == nil {
		return net.ListenUDP(network, locAddr)
	}

	return n.v.listenUDP(network, locAddr)
}

[...]

Whether the original net functions or alternative implementation of vnet.Net where used was decided by vnet.Net the presence of the vnet.vNet member.

As the use of Go's standard net functions is widespread throughout the Pion code base, the respective vnet.Net instance needs to be passed to various network-related Pion modules like pion/stun, pion/turn and pion/ice. Ultimately, the Net type is also surfaced by pion/webrtc's SettingEngine.

The initial implementation implemented Net as a struct type whose methods where not an exact mapping of standard net functions.

The new transport.Net interface

In v2 of pion/transport introduced a new transport.Net interface to further abstract Pions use of the network stack:

package transport

interface Net {
	ListenUDP(network string, locAddr *net.UDPAddr) (UDPPacketConn, error)

	[.. All functions of Go's standard net package follow here ..]
}

Initially, two implementations are provided for this interface:

  • stdnet.Net a direct mapping to the standard net package, used for production
  • vnet.Net the virtual network used for testing

In many places, Pion will automatically use a stdnet.Net if a nil pointer is provided for transport.Net (e.g. the webrtc SettingEngine).

The new transport.Net interface will allow users to provide their own network stack in the future. E.g. a virtual network implementation based on stv0g/gont which uses Linux kernel network namespaces rather than a userspace implementation. In its current state vnet.Net only supports UDP sockets. Hence a virtual network implementation based on stv0g/gont could lift this limitation.

In addition, the new new interface is more closely aligned with the function signatures of the net package. This will allow use to eliminate any remaining direct calls to standard net functions which currently can still be found in some places of the Pion codespace (mainly for name resolution and TCP sockets in pion/ice, pion/turn and pion/dtls).

Migration path

The Pion developers currently exclude the vnet.Net API from the semantic versioning guarantees as they are considered to be used mainly for debugging and testing and as such not part of the Pion's core API.

⚠️ Note: Please be aware that if you use those interfaces, your code might break also for minor version updates

Updating your project to the new transport.Net interface is relatively straight forward:

  1. Upgrade your imports of pion/transport to pion/transport/v2.
  2. Change all occurrences of the * vnet.Net type to the new interface transport.Net.

In the long run, all Pion developers are encouraged to fully eliminate any remaining direct calls to the standard net functions. We can expect to add those functions to the global list of disallowed functions for the Pion project at some point in time.

Clone this wiki locally