Files
lneto/x/xnet/xnet_bench_test.go
T
Pat Whittingslow a2970b923d add ipv6 to xnet.StackAsync (#107)
* add ipv6 to xnet.StackAsync

* dns improvements

* improve DNS workings of StackAsync

* add tentative ICMPv6

* work on prefixes and fix some small bugs, plan UDP/TCP6

* fix bugs in StackAsync and ipv4.Prefix.Contains

* update arpsubtable

* completely remove legacy internet.StackIP for StackIPv4/v6

* ipv4/ipv6 tcp/udp

* add TCP6/UDP6 dialing APIs

* add xnet.Stack6 interface

* more ipv6 integration into StackAsync; various tweaks to lneto and documentation+TODOs

* add stack6 tests

* replace netip.Prefix with ipv4.Prefix where it makes sense
2026-05-13 15:31:18 -03:00

177 lines
4.0 KiB
Go

package xnet
import (
"net/netip"
"testing"
"github.com/soypat/lneto/ethernet"
"github.com/soypat/lneto/tcp"
)
func BenchmarkARPExchange(b *testing.B) {
const MTU = ethernet.MaxMTU
const frameSize = ethernet.MaxFrameLength
c1, c2 := new(StackAsync), new(StackAsync)
queryAddr := netip.AddrFrom4([4]byte{192, 168, 1, 2})
err := c1.Reset(StackConfig{
Hostname: "C1",
RandSeed: 1,
StaticAddress4: [4]byte{192, 168, 1, 1},
HardwareAddress: [6]byte{0xde, 0xad, 0xbe, 0xef, 0x00, 0x00},
MTU: MTU,
})
if err != nil {
b.Fatal(err)
}
err = c2.Reset(StackConfig{
Hostname: "C2",
RandSeed: 2,
StaticAddress4: queryAddr.As4(),
HardwareAddress: [6]byte{0xc0, 0xff, 0xee, 0xc0, 0xff, 0xee},
MTU: MTU,
})
if err != nil {
b.Fatal(err)
}
// Set gateways so ethernet frames are properly addressed.
c1.SetGatewayHardwareAddr(c2.HardwareAddr())
c2.SetGatewayHardwareAddr(c1.HardwareAddr())
var buf [frameSize]byte
b.ResetTimer()
for i := 0; i < b.N; i++ {
err = c1.StartResolveHardwareAddress6(queryAddr)
if err != nil {
b.Fatal(err)
}
n, err := c1.EgressEthernet(buf[:]) // Send Request.
if err != nil {
b.Fatal(err)
} else if n == 0 {
b.Fatal("expected send of data after first query")
}
err = c2.IngressEthernet(buf[:n]) // Receive request.
if err != nil {
b.Fatal(err)
}
n, err = c2.EgressEthernet(buf[:]) // Send response.
if err != nil {
b.Fatal(err)
} else if n == 0 {
b.Fatal("got no response to request")
}
err = c1.IngressEthernet(buf[:n]) // Receive response.
if err != nil {
b.Fatal(err)
}
_, err = c1.ResultResolveHardwareAddress6(queryAddr)
if err != nil {
b.Fatal("expected query result:", err)
}
// Discard query for next iteration.
c1.DiscardResolveHardwareAddress6(queryAddr)
}
}
func BenchmarkTCPHandshake(b *testing.B) {
const MTU = ethernet.MaxMTU
const frameSize = ethernet.MaxFrameLength
const svPort = 8080
client, sv := new(StackAsync), new(StackAsync)
clconn, svconn := new(tcp.Conn), new(tcp.Conn)
err := sv.Reset(StackConfig{
Hostname: "Server",
RandSeed: 1,
StaticAddress4: [4]byte{10, 0, 0, 1},
MaxActiveTCPPorts: 1,
HardwareAddress: [6]byte{0xbe, 0xef, 0, 0, 0, 1},
MTU: MTU,
})
if err != nil {
b.Fatal(err)
}
err = client.Reset(StackConfig{
Hostname: "Client",
RandSeed: 2,
StaticAddress4: [4]byte{10, 0, 0, 2},
MaxActiveTCPPorts: 1,
HardwareAddress: [6]byte{0xbe, 0xef, 0, 0, 0, 2},
MTU: MTU,
})
if err != nil {
b.Fatal(err)
}
sv.SetGatewayHardwareAddr(client.HardwareAddr())
client.SetGatewayHardwareAddr(sv.HardwareAddr())
buf := make([]byte, MTU*4)
err = clconn.Configure(tcp.ConnConfig{
RxBuf: buf[:MTU],
TxBuf: buf[MTU : MTU*2],
TxPacketQueueSize: 4,
})
if err != nil {
b.Fatal(err)
}
err = svconn.Configure(tcp.ConnConfig{
RxBuf: buf[2*MTU : 3*MTU],
TxBuf: buf[3*MTU : 4*MTU],
TxPacketQueueSize: 4,
})
if err != nil {
b.Fatal(err)
}
var pktbuf [frameSize]byte
b.ResetTimer()
for i := 0; i < b.N; i++ {
// Setup connections.
err = sv.ListenTCP4(svconn, svPort)
if err != nil {
b.Fatal(err)
}
err = client.DialTCP(clconn, 1337, netip.AddrPortFrom(netip.AddrFrom4(sv.Addr4()), svPort))
if err != nil {
b.Fatal(err)
}
// SYN from client.
n, err := client.EgressEthernet(pktbuf[:])
if err != nil {
b.Fatal(err)
}
err = sv.IngressEthernet(pktbuf[:n])
if err != nil {
b.Fatal(err)
}
// SYN-ACK from server.
n, err = sv.EgressEthernet(pktbuf[:])
if err != nil {
b.Fatal(err)
}
err = client.IngressEthernet(pktbuf[:n])
if err != nil {
b.Fatal(err)
}
// ACK from client.
n, err = client.EgressEthernet(pktbuf[:])
if err != nil {
b.Fatal(err)
}
err = sv.IngressEthernet(pktbuf[:n])
if err != nil {
b.Fatal(err)
}
// Abort connections for next iteration.
clconn.Abort()
svconn.Abort()
}
}