lossy: github.com/cevatbarisyilmaz/lossy Index | Examples | Files

package lossy

import "github.com/cevatbarisyilmaz/lossy"

Package lossy simulates bandwidth, latency and packet loss for net.PacketConn and net.Conn interfaces.

Its main usage is to test robustness of applications and network protocols run over unreliable transport protocols such as UDP or IP. As a side benefit, it can also be used as outbound bandwidth limiter.

lossy only alters the writing side of the connection, reading side is kept as it is.

Code:

packetConn, err := net.ListenUDP("udp", &net.UDPAddr{
    IP:   net.IPv4(127, 0, 0, 1),
    Port: 0,
})
if err != nil {
    log.Fatal(err)
}
conn, err := net.DialUDP("udp", nil, packetConn.LocalAddr().(*net.UDPAddr))
if err != nil {
    log.Fatal(err)
}
lossyConn := lossy.NewConn(conn, 1024, time.Second, time.Second*2, 0.25, lossy.UDPv4MinHeaderOverhead)
var bytesWritten int
const packetCount = 32
go func() {
    for i := 0; i < packetCount; i++ {
        packet := make([]byte, i*64)
        bytesWritten += len(packet) // Ignoring the packet headers
        rand.Read(packet)
        _, err := lossyConn.Write(packet)
        if err != nil {
            log.Fatal(err)
        }
    }
    fmt.Println("Sent", packetCount, "packets with total size of", bytesWritten, "bytes")
}()
const timeOut = time.Second * 5
var bytesRead int
var packetsReceived int
startTime := time.Now()
for {
    err = packetConn.SetReadDeadline(time.Now().Add(timeOut))
    if err != nil {
        log.Fatal(err)
    }
    buffer := make([]byte, 32*64)
    n, addr, err := packetConn.ReadFrom(buffer)
    if err != nil {
        if nerr, ok := err.(net.Error); ok {
            if nerr.Timeout() {
                break
            }
        }
        log.Fatal(err)
    }
    if addr.String() != conn.LocalAddr().String() {
        log.Fatal("hijacked by", addr.String())
    }
    packetsReceived++
    bytesRead += n // Ignoring the packet headers
}
dur := time.Now().Sub(startTime) - timeOut
fmt.Println("Received", packetsReceived, "packets with total size of", bytesRead, "bytes in", dur.Seconds(), "seconds")

Index

Examples

Package Files

conn.go lossy.go packet_conn.go

Constants

const IPv4MaxHeaderOverhead = 60

IPv4MaxHeaderOverhead is the maximum header overhead for IPv4 based connections.

const IPv4MinHeaderOverhead = 20

IPv4MinHeaderOverhead is the minimum header overhead for IPv4 based connections.

const IPv6HeaderOverhead = 40

IPv6HeaderOverhead is the header overhead for IPv6 based connections.

const UDPv4MaxHeaderOverhead = 68

UDPv4MaxHeaderOverhead is the maximum header overhead for UDP based connections over IPv4.

const UDPv4MinHeaderOverhead = 28

UDPv4MinHeaderOverhead is the minimum header overhead for UDP based connections over IPv4.

const UDPv6HeaderOverhead = 48

UDPv6HeaderOverhead is the header overhead for UDP based connections over IPv6.

func NewConn Uses

func NewConn(c net.Conn, bandwidth int, minLatency, maxLatency time.Duration, packetLossRate float64, headerOverhead int) net.Conn

NewConn wraps the given net.Conn with a lossy connection.

bandwidth is in bytes/second. i.e. enter 1024 * 1024 for a 8 Mbit/s connection. Enter 0 or a negative value for an unlimited bandwidth.

minLatency and maxLatency is used to create a random latency for each packet. maxLatency should be equal or greater than minLatency. If bandwidth is not unlimited and there's no other packets waiting to be delivered, time to deliver a packet is (len(packet) + headerOverhead) / bandwidth + randomDuration(minLatency, maxLatency)

packetLossRate is chance of a packet to be dropped. It should be less than 1 and equal or greater than 0.

headerOverhead is the header size of the underlying protocol of the connection. It is used to simulate bandwidth more realistically. If bandwidth is unlimited, headerOverhead is ignored.

func NewPacketConn Uses

func NewPacketConn(c net.PacketConn, bandwidth int, minLatency, maxLatency time.Duration, packetLossRate float64, headerOverhead int) net.PacketConn

NewPacketConn wraps the given net.PacketConn with a lossy packet connection.

bandwidth is in bytes/second. i.e. enter 1024 * 1024 for a 8 Mbit/s connection. Enter 0 or a negative value for an unlimited bandwidth.

minLatency and maxLatency is used to create a random latency for each packet. maxLatency should be equal or greater than minLatency. If bandwidth is not unlimited and there's no other packets waiting to be delivered, time to deliver a packet is (len(packet) + headerOverhead) / bandwidth + randomDuration(minLatency, maxLatency)

packetLossRate is chance of a packet to be dropped. It should be less than 1 and equal or greater than 0.

headerOverhead is the header size of the underlying protocol of the connection. It is used to simulate bandwidth more realistically. If bandwidth is unlimited, headerOverhead is ignored.

Package lossy imports 4 packages (graph) and is imported by 1 packages. Updated 2020-10-16. Refresh now. Tools for package owners.