netem

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 6, 2026 License: MIT Imports: 6 Imported by: 0

README

netem

Go Reference Go Report Card GitHub Release

netem is a lightweight Go network emulation package designed to wrap standard net.Conn and net.PacketConn interfaces. It allows developers to simulate real-world network conditions, like restricted bandwidth, high latency, jitter, and packet loss, directly within their Go tests.

Why netem?

While several tools exist for network emulation at the OS level (like tc-netem on Linux), netem brings this capability directly into the Go test suite. It allows you to wrap existing connections to simulate poor network conditions without requiring administrative privileges or external dependencies.

Key Improvements

This package iterates on the design of cevatbarisyilmaz/lossy, focusing on:

  • Idiomatic API: Designed to feel like a natural extension of the net package.

  • Resource Efficiency: Replaces "goroutine-per-packet" models with internal FIFO queues to prevent unbounded resource growth at high throughput.

  • Stream Integrity: Specifically addresses the "WorldHello" corruption bug. In stream-oriented protocols (TCP), high jitter should cause Head-of-Line Blocking, not out-of-order byte delivery.

Dynamic Configuration (Inspired by slog)

One of the standout features of netem is its thread-safe indirection system, inspired by the design of slog.LevelVar.

Instead of static values, netem uses Policies. By using types like policy.LatencyVar or policy.BandwidthVar, you can alter network conditions on the fly for an active connection without needing to reconnect or use complex synchronization in your application code.

Usage

import (
    "github.com/kasader/netem"
    "github.com/kasader/netem/policy"
)

func TestMyNetworkCode(t *testing.T) {
    // 1. Define a profile
    lat := &policy.LatencyVar{}
    lat.Set(100 * time.Millisecond)

    profile := netem.PacketProfile{
        Latency: lat,
        Jitter:  policy.RandomJitter(20 * time.Millisecond),
        Loss:    policy.RandomLoss(0.01), // 1% loss
    }

    // 2. Wrap an existing connection
    conn := netem.NewPacketConn(rawUDPConn, profile)

    // 3. Dynamically change conditions later
    lat.Set(500 * time.Millisecond) 
}

Core Features (v0.1.0)

1. Dynamic Policies (netem/policy)

Inspired by the design of slog.LevelVar, netem uses an indirection system for its metrics. By using Var types, you can change network conditions on-the-fly for active connections.

  • Bandwidth: Limit throughput (bits per second) via StaticBandwidth or the thread-safe BandwidthVar.

  • Latency: Add base propagation delay.

  • Jitter: Introduce variance in delivery time. RandomJitter provides amplitude-based variance.

  • Loss: Simulate packet drops with RandomLoss.

  • Fault: Manually trigger connection failures or closures.

2. Protocol-Specific Wrappers
  • Conn (Stream-Oriented): Designed for TCP-like behavior. Uses an internal FIFO queue to ensure that jitter manifests as Head-of-Line Blocking rather than byte-stream corruption.

  • PacketConn (Packet-Oriented): Designed for UDP-like behavior. Supports natural packet reordering, allowing later datagrams to overtake earlier ones if jitter is sufficiently high.

Documentation

Overview

Package netem provides network emulation wrappers for the net.PacketConn and net.Conn interfaces; it allows for dynamic thread-safe configuration of connection bandwidth, latency, jitter, and packet loss via indirection.

Index

Constants

View Source
const (
	// IPv4HeaderSize is the min size of an IPv4 header in bytes.
	IPv4HeaderSize = 20
	// IPv6HeaderSize is the fixed size of an IPv6 header in bytes.
	IPv6HeaderSize = 40
)
View Source
const (
	// EthernetDefaultMTU is the standard MTU for most WANs and Internet traffic (1500 bytes).
	EthernetDefaultMTU = 1_500
	// EthernetJumboFrameMTU is used in data center environments to reduce CPU overhead (9000 bytes).
	EthernetJumboFrameMTU = 9_000
	// IPMaximumMTU represents the maximum possible size of an IP packet.
	// This is commonly the default MTU for Linux loopback devices.
	IPMaximumMTU = 65_536
)

Variables

This section is empty.

Functions

func NewConn

func NewConn(c net.Conn, p StreamProfile) net.Conn

NewConn wraps an existing net.Conn to emulate network conditions for stream-oriented protocols like TCP. It ensures that data order is strictly preserved even when jitter or latency is applied.

func NewPacketConn

func NewPacketConn(c net.PacketConn, p PacketProfile) net.PacketConn

NewPacketConn wraps an existing net.PacketConn to emulate network conditions for packet-oriented protocols like UDP.

Types

type Bandwidth

type Bandwidth interface {
	// Limit returns the allowed throughput in bits per second.
	Limit() uint64
}

Bandwidth models the capacity of the link.

type Conn

type Conn struct {
	net.Conn
	// contains filtered or unexported fields
}

Conn wraps an existing net.Conn to emulate network conditions for stream-oriented protocols.

To prevent stream corruption, Conn uses an internal FIFO queue (writeCh) to ensure that data is written to the underlying socket in the exact order it was received from the application, even in the presence of latency and jitter.

func (*Conn) Close

func (c *Conn) Close() error

Close implements net.Conn.

func (*Conn) SetDeadline

func (c *Conn) SetDeadline(t time.Time) error

SetDeadline implements net.Conn.

func (*Conn) SetWriteDeadline

func (c *Conn) SetWriteDeadline(t time.Time) error

SetWriteDeadline implements net.Conn.

func (*Conn) Write

func (c *Conn) Write(b []byte) (n int, err error)

Write implements net.Conn.

type Fault

type Fault interface {
	// ShouldClose returns true if the connection should be severed abruptly.
	ShouldClose() bool
}

Fault models the stability of a connection.

type Jitter

type Jitter interface {
	// Duration returns the random variance to add to the latency.
	Duration() time.Duration
}

Jitter models the variance in transmission delay.

type Latency

type Latency interface {
	// Duration returns the delay for the current operation.
	Duration() time.Duration
}

Latency models the delay of a network transmission.

type LinkProfile

type LinkProfile struct {
	Latency   Latency
	Jitter    Jitter
	Bandwidth Bandwidth
}

LinkProfile defines the shared physical properties of a network link.

type Loss

type Loss interface {
	// Drop returns true if the current datagram should be discarded.
	Drop() bool
}

Loss models the unreliability of a datagram link.

type PacketConn

type PacketConn struct {
	net.PacketConn
	// contains filtered or unexported fields
}

PacketConn wraps an existing net.PacketConn to emulate network conditions for packet-oriented protocols.

Unlike Conn, PacketConn allows for natural packet reordering if jitter configurations cause a later packet to be scheduled for delivery earlier than a previous one.

func (*PacketConn) Close

func (c *PacketConn) Close() error

Close implements net.PacketConn.

func (*PacketConn) SetDeadline

func (c *PacketConn) SetDeadline(t time.Time) error

SetDeadline implements net.PacketConn.

func (*PacketConn) SetWriteDeadline

func (c *PacketConn) SetWriteDeadline(t time.Time) error

SetWriteDeadline implements net.PacketConn.

func (*PacketConn) WriteTo

func (c *PacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error)

WriteTo implements net.PacketConn.

type PacketProfile

type PacketProfile struct {
	// MTU (Maximum Transmission Unit) is the largest packet size allowed.
	// This value includes L3/L4 headers.
	//
	// Defaults to [EthernetDefaultMTU] if 0.
	MTU uint

	Latency   Latency
	Jitter    Jitter
	Bandwidth Bandwidth
	Loss      Loss
}

PacketProfile extends the link with datagram-specific behaviors.

type StreamProfile

type StreamProfile struct {
	// MTU (Maximum Transmission Unit) is the largest packet size allowed.
	// This value includes L3/L4 headers.
	//
	// Defaults to [EthernetDefaultMTU] if 0.
	MTU uint

	Latency   Latency
	Jitter    Jitter
	Bandwidth Bandwidth
	Fault     Fault
}

StreamProfile extends the link with stream-specific behaviors.

Directories

Path Synopsis
Package policy provides dynamic, thread-safe implementations for network emulation parameters such as bandwidth, latency, and loss.
Package policy provides dynamic, thread-safe implementations for network emulation parameters such as bandwidth, latency, and loss.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL