mirror of
https://github.com/soypat/lneto.git
synced 2026-07-26 10:38:47 +00:00
a2970b923d
* 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
177 lines
4.0 KiB
Go
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()
|
|
}
|
|
}
|