ipv6: StackIP and StackAsync.Addr refactor (#105)

* apply StackIP changes and internet package test passing

* fix tests and examples

* remove old Reset method on StackIP

* use encapsulate for ipv6

* add TCP over IPv6 tests
This commit is contained in:
Pat Whittingslow
2026-05-09 16:11:31 -03:00
committed by GitHub
parent a430f6c40a
commit bdbd38ab44
22 changed files with 609 additions and 357 deletions
+30 -41
View File
@@ -36,6 +36,8 @@ type StackAsync struct {
udps internet.StackPortsMACFiltered
tcps internet.StackPortsMACFiltered
defaultValidator lneto.Validator
dhcpUDP internet.StackUDPPort
dhcp dhcpv4.Client
dhcpResults DHCPResults
@@ -63,11 +65,13 @@ type StackAsync struct {
}
type StackConfig struct {
StaticAddress netip.Addr
DNSServer netip.Addr
NTPServer netip.Addr
RandSeed int64
Hostname string
// StaticAddress6 [16]byte
StaticAddress4 [4]byte
DNSServer netip.Addr
NTPServer netip.Addr
RandSeed int64
Hostname string
// MaxActiveTCPPorts and MaxActiveUDPPorts are a memory guardrail to limit
// number of simultaneous open TCP/UDP ports. The memory impact at the stack level
@@ -148,16 +152,11 @@ func (s *StackAsync) Reset(cfg StackConfig) error {
return lneto.ErrInvalidConfig
}
mac := cfg.HardwareAddress
addr := cfg.StaticAddress
s.mu.Lock()
defer s.mu.Unlock()
s.prng = uint32(cfg.RandSeed)
s.hostname = cfg.Hostname
if !addr.IsValid() {
addr = netip.AddrFrom4([4]byte{}) // If static not set DHCP will be performed and address will be zero.
} else if addr.Is6() {
return lneto.ErrUnsupported
}
const linkNodes = 2 // ARP and IP nodes
ecfg := internet.StackEthernetConfig{
MTU: int(cfg.MTU),
@@ -178,11 +177,12 @@ func (s *StackAsync) Reset(cfg StackConfig) error {
s.link.OnEncapsulate(s.arpt.patchEgressMAC)
}
const ipNodes = 3 // 3 IP protocols possible: UDP, TCP, ICMP.
err = s.ip.Reset(addr, ipNodes)
err = s.ip.Reset(&s.defaultValidator, ipNodes, 0)
if err != nil {
return err
}
s.ip.SetAcceptMulticast(cfg.AcceptMulticast)
s.ip.SetAddr4(cfg.StaticAddress4)
s.ip.SetAcceptMulticast4(cfg.AcceptMulticast)
s.arpt.passivePeers = uint8(cfg.PassivePeers)
err = s.resetARP()
if err != nil {
@@ -201,7 +201,7 @@ func (s *StackAsync) Reset(cfg StackConfig) error {
if err != nil {
return err
}
err = s.ip.Register(&s.tcps)
err = s.ip.Register4(&s.tcps)
if err != nil {
return err
}
@@ -213,7 +213,7 @@ func (s *StackAsync) Reset(cfg StackConfig) error {
if err != nil {
return err
}
err = s.ip.Register(&s.udps)
err = s.ip.Register4(&s.udps)
if err != nil {
return err
}
@@ -243,17 +243,11 @@ func (s *StackAsync) Reset(cfg StackConfig) error {
func (s *StackAsync) resetARP() error {
mac := s.link.HardwareAddr6()
addr := s.ip.Addr()
if !addr.IsValid() {
return lneto.ErrInvalidAddr
}
addr := s.ip.Addr4()
proto := ethernet.TypeIPv4
if addr.Is6() {
proto = ethernet.TypeIPv6
}
err := s.arp.Reset(arp.HandlerConfig{
HardwareAddr: mac[:],
ProtocolAddr: addr.AsSlice(),
ProtocolAddr: addr[:],
MaxQueries: 5,
MaxPending: 5,
HardwareType: 1,
@@ -298,26 +292,21 @@ func (s *StackAsync) prand32() uint32 {
return seed
}
func (s *StackAsync) SetIPAddr(addr netip.Addr) error {
func (s *StackAsync) SetAddr4(addr [4]byte) error {
s.mu.Lock()
defer s.mu.Unlock()
return s.setIPAddr(addr)
return s.setIPAddr4(addr)
}
func (s *StackAsync) setIPAddr(addr netip.Addr) error {
err := s.ip.SetAddr(addr)
if err != nil {
return err
}
ip := addr.As4()
err = s.arp.UpdateProtoAddr(ip[:])
return err
func (s *StackAsync) setIPAddr4(addr [4]byte) error {
s.ip.SetAddr4(addr)
return s.arp.UpdateProtoAddr(addr[:])
}
func (s *StackAsync) Addr() netip.Addr {
func (s *StackAsync) Addr4() [4]byte {
s.mu.Lock()
defer s.mu.Unlock()
return s.ip.Addr()
return s.ip.Addr4()
}
func (s *StackAsync) SetSubnet(subnetMask netip.Prefix) {
@@ -359,10 +348,10 @@ func (s *StackAsync) EnableICMP(enabled bool) (err error) {
enabled = false // ensure aborted.
}
if enabled {
if s.ip.IsRegistered(lneto.IPProtoICMP) {
if s.ip.IsRegistered4(lneto.IPProtoICMP) {
return nil
}
err = s.ip.Register(&s.icmp)
err = s.ip.Register4(&s.icmp)
} else {
s.icmp.Abort()
}
@@ -625,7 +614,7 @@ func (s *StackAsync) DiscardResolveHardwareAddress6(ip netip.Addr) error {
type DHCPResults struct {
DNSServers []netip.Addr
Router netip.Addr
AssignedAddr netip.Addr
AssignedAddr4 [4]byte
ServerAddr netip.Addr
BroadcastAddr netip.Addr
Gateway netip.Addr
@@ -665,8 +654,8 @@ func (stack *StackAsync) AssimilateDHCPResults(results *DHCPResults) error {
if results.Subnet.IsValid() {
stack.arpt.subnet = results.Subnet
}
if results.AssignedAddr.IsValid() {
err := stack.setIPAddr(results.AssignedAddr)
if !internal.IsZeroed(results.AssignedAddr4) {
err := stack.setIPAddr4(results.AssignedAddr4)
if err != nil {
return err
}
@@ -696,7 +685,7 @@ func (s *StackAsync) populateDHCPResults() error {
s.dhcpResults = DHCPResults{
Router: router,
Subnet: s.dhcp.SubnetPrefix(),
AssignedAddr: netip.AddrFrom4(assigned4),
AssignedAddr4: assigned4,
ServerAddr: addr4(s.dhcp.ServerAddr()),
BroadcastAddr: addr4(s.dhcp.BroadcastAddr()),
Gateway: addr4(s.dhcp.GatewayAddr()),
+1 -1
View File
@@ -76,7 +76,7 @@ func (s StackGo) SocketNetip(ctx context.Context, network string, family, sotype
}
if laddr.Addr() == netip.IPv4Unspecified() {
// Specify address.
laddr = netip.AddrPortFrom(s.blk.async.ip.Addr(), laddr.Port())
laddr = netip.AddrPortFrom(netip.AddrFrom4(s.blk.async.ip.Addr4()), laddr.Port())
} else if laddr.Addr().Is6() {
return nil, lneto.ErrUnsupported
}
+4 -4
View File
@@ -16,13 +16,13 @@ func TestARPLocal(t *testing.T) {
// Most common case: we have a router in between computers.
s1.SetGateway6(routerHw)
s2.SetGateway6(routerHw)
addr1 := netip.AddrPortFrom(s1.Addr(), 1024) // dialer, client.
addr2 := netip.AddrPortFrom(s2.Addr(), 80) // listener, server.
addr1 := netip.AddrPortFrom(netip.AddrFrom4(s1.Addr4()), 1024) // dialer, client.
addr2 := netip.AddrPortFrom(netip.AddrFrom4(s2.Addr4()), 80) // listener, server.
err := s1.AssimilateDHCPResults(&DHCPResults{
Router: netip.AddrFrom4([4]byte{10, 0, 0, 255}),
BroadcastAddr: netip.AddrFrom4([4]byte{255, 255, 255, 255}),
AssignedAddr: s1.Addr(),
Subnet: netip.PrefixFrom(s2.Addr(), 24), // Subnet containing s2 will force an ARP on s1.
AssignedAddr4: s1.Addr4(),
Subnet: netip.PrefixFrom(netip.AddrFrom4(s2.Addr4()), 24), // Subnet containing s2 will force an ARP on s1.
TRenewal: 1000,
TRebind: 1000,
TLease: 1000,
+5 -5
View File
@@ -17,7 +17,7 @@ func BenchmarkARPExchange(b *testing.B) {
err := c1.Reset(StackConfig{
Hostname: "C1",
RandSeed: 1,
StaticAddress: netip.AddrFrom4([4]byte{192, 168, 1, 1}),
StaticAddress4: [4]byte{192, 168, 1, 1},
HardwareAddress: [6]byte{0xde, 0xad, 0xbe, 0xef, 0x00, 0x00},
MTU: MTU,
})
@@ -27,7 +27,7 @@ func BenchmarkARPExchange(b *testing.B) {
err = c2.Reset(StackConfig{
Hostname: "C2",
RandSeed: 2,
StaticAddress: queryAddr,
StaticAddress4: queryAddr.As4(),
HardwareAddress: [6]byte{0xc0, 0xff, 0xee, 0xc0, 0xff, 0xee},
MTU: MTU,
})
@@ -85,7 +85,7 @@ func BenchmarkTCPHandshake(b *testing.B) {
err := sv.Reset(StackConfig{
Hostname: "Server",
RandSeed: 1,
StaticAddress: netip.AddrFrom4([4]byte{10, 0, 0, 1}),
StaticAddress4: [4]byte{10, 0, 0, 1},
MaxActiveTCPPorts: 1,
HardwareAddress: [6]byte{0xbe, 0xef, 0, 0, 0, 1},
MTU: MTU,
@@ -96,7 +96,7 @@ func BenchmarkTCPHandshake(b *testing.B) {
err = client.Reset(StackConfig{
Hostname: "Client",
RandSeed: 2,
StaticAddress: netip.AddrFrom4([4]byte{10, 0, 0, 2}),
StaticAddress4: [4]byte{10, 0, 0, 2},
MaxActiveTCPPorts: 1,
HardwareAddress: [6]byte{0xbe, 0xef, 0, 0, 0, 2},
MTU: MTU,
@@ -134,7 +134,7 @@ func BenchmarkTCPHandshake(b *testing.B) {
if err != nil {
b.Fatal(err)
}
err = client.DialTCP(clconn, 1337, netip.AddrPortFrom(sv.Addr(), svPort))
err = client.DialTCP(clconn, 1337, netip.AddrPortFrom(netip.AddrFrom4(sv.Addr4()), svPort))
if err != nil {
b.Fatal(err)
}
+5 -5
View File
@@ -37,7 +37,7 @@ func TestTCPListener_ConcurrentEcho(t *testing.T) {
err := serverStack.Reset(StackConfig{
Hostname: "Server",
RandSeed: seed,
StaticAddress: serverIP,
StaticAddress4: serverIP.As4(),
MaxActiveTCPPorts: numClients,
HardwareAddress: serverMAC,
MTU: MTU,
@@ -75,11 +75,11 @@ func TestTCPListener_ConcurrentEcho(t *testing.T) {
for i := range clientStacks {
clientMAC := [6]byte{0xaa, 0xbb, 0xcc, 0x00, 0x01, byte(i + 1)}
clientIP := netip.AddrFrom4([4]byte{10, 0, 0, byte(i + 10)})
clientIP := [4]byte{10, 0, 0, byte(i + 10)}
err := clientStacks[i].Reset(StackConfig{
Hostname: fmt.Sprintf("Client%d", i),
RandSeed: int64(seed + i + 1),
StaticAddress: clientIP,
StaticAddress4: clientIP,
MaxActiveTCPPorts: 1,
HardwareAddress: clientMAC,
MTU: MTU,
@@ -185,10 +185,10 @@ func routePacketToClient(pkt []byte, clients []StackAsync) {
if len(pkt) < 20+ethernet.MaxOverheadSize { // 20 min IP header
return
}
dstIP := netip.AddrFrom4([4]byte{pkt[30], pkt[31], pkt[32], pkt[33]})
dstIP := [4]byte{pkt[30], pkt[31], pkt[32], pkt[33]}
for i := range clients {
if clients[i].Addr() == dstIP {
if clients[i].Addr4() == dstIP {
clients[i].IngressEthernet(pkt)
return
}
+1 -1
View File
@@ -27,7 +27,7 @@ func TestDNS_QueryReceivesAnswer(t *testing.T) {
err := client.Reset(StackConfig{
Hostname: "DNSClient",
RandSeed: seed,
StaticAddress: clientAddr,
StaticAddress4: clientAddr.As4(),
DNSServer: dnsServerAddr,
HardwareAddress: clientMAC,
MTU: uint16(MTU),
+15 -15
View File
@@ -26,7 +26,7 @@ func FuzzStackPacketHTTP(f *testing.F) {
if err != nil {
f.Fatal(err)
}
err = s2.DialTCP(c2, 1337, netip.AddrPortFrom(s1.Addr(), c1.LocalPort()))
err = s2.DialTCP(c2, 1337, netip.AddrPortFrom(netip.AddrFrom4(s1.Addr4()), c1.LocalPort()))
if err != nil {
f.Fatal(err)
}
@@ -92,7 +92,7 @@ func FuzzStackPacketHTTP(f *testing.F) {
if err != nil {
t.Fatal(err)
}
err = s2.DialTCP(c2, 1337, netip.AddrPortFrom(s1.Addr(), c1.LocalPort()))
err = s2.DialTCP(c2, 1337, netip.AddrPortFrom(netip.AddrFrom4(s1.Addr4()), c1.LocalPort()))
if err != nil {
t.Fatal(err)
}
@@ -275,7 +275,7 @@ func testStackSeeded(t *testing.T, seed1, seed2 int64) {
v1, v2 := byte(seed1), byte(seed2)
cfg1 := StackConfig{
Hostname: "s1",
StaticAddress: netip.AddrFrom4([4]byte{1, 0, 0, v1}),
StaticAddress4: [4]byte{1, 0, 0, v1},
RandSeed: seed1,
MaxActiveTCPPorts: 1,
MaxActiveUDPPorts: 1,
@@ -291,7 +291,7 @@ func testStackSeeded(t *testing.T, seed1, seed2 int64) {
}
cfg2 := StackConfig{
Hostname: "s2",
StaticAddress: netip.AddrFrom4([4]byte{1, 0, 0, v2}),
StaticAddress4: [4]byte{1, 0, 0, v2},
RandSeed: seed2,
MaxActiveTCPPorts: 1,
MaxActiveUDPPorts: 1,
@@ -360,7 +360,7 @@ func testStackSeeded(t *testing.T, seed1, seed2 int64) {
if verbose {
fmt.Fprintln(fzoutput, "TCP dial")
}
err = s1.DialTCP(&tcp1, port1, netip.AddrPortFrom(s2.Addr(), port2))
err = s1.DialTCP(&tcp1, port1, netip.AddrPortFrom(netip.AddrFrom4(s2.Addr4()), port2))
if err != nil {
t.Fatal(i, err)
}
@@ -387,7 +387,7 @@ func testStackSeeded(t *testing.T, seed1, seed2 int64) {
if verbose {
fmt.Fprintln(fzoutput, "UDP dial 1")
}
err = s1.DialUDP(&udp1, port1, netip.AddrPortFrom(s2.Addr(), port2))
err = s1.DialUDP(&udp1, port1, netip.AddrPortFrom(netip.AddrFrom4(s2.Addr4()), port2))
if err != nil {
t.Fatal(i, err)
}
@@ -396,7 +396,7 @@ func testStackSeeded(t *testing.T, seed1, seed2 int64) {
if verbose {
fmt.Fprintln(fzoutput, "UDP dial 2")
}
err = s2.DialUDP(&udp2, port2, netip.AddrPortFrom(s1.Addr(), port1))
err = s2.DialUDP(&udp2, port2, netip.AddrPortFrom(netip.AddrFrom4(s1.Addr4()), port1))
if err != nil {
t.Fatal(i, err)
}
@@ -447,13 +447,13 @@ func testStackSeeded(t *testing.T, seed1, seed2 int64) {
switch icmpaction {
case 0:
s1.icmp.Reset()
_, err = s1.icmp.PingStart(s2.Addr().As4(), buf[:pingMinPayload], pingMinPayload+uint16(action.Rand)%pingMinPayload)
_, err = s1.icmp.PingStart(s2.Addr4(), buf[:pingMinPayload], pingMinPayload+uint16(action.Rand)%pingMinPayload)
if err != nil {
t.Fatal(i, err)
}
case 1:
s2.icmp.Reset()
_, err = s2.icmp.PingStart(s1.Addr().As4(), buf[:pingMinPayload], pingMinPayload+uint16(action.Rand)%pingMinPayload)
_, err = s2.icmp.PingStart(s1.Addr4(), buf[:pingMinPayload], pingMinPayload+uint16(action.Rand)%pingMinPayload)
if err != nil {
t.Fatal(i, err)
}
@@ -466,17 +466,17 @@ func testStackSeeded(t *testing.T, seed1, seed2 int64) {
}
switch action {
case 0: // s1 queries s2 address.
s1.StartResolveHardwareAddress6(s2.Addr())
s1.StartResolveHardwareAddress6(netip.AddrFrom4(s2.Addr4()))
case 1: // s2 queries s1 address.
s2.StartResolveHardwareAddress6(s1.Addr())
s2.StartResolveHardwareAddress6(netip.AddrFrom4(s1.Addr4()))
case 2: // s1 checks query result for s2.
s1.ResultResolveHardwareAddress6(s2.Addr())
s1.ResultResolveHardwareAddress6(netip.AddrFrom4(s2.Addr4()))
case 3: // s2 checks query result for s1.
s2.ResultResolveHardwareAddress6(s1.Addr())
s2.ResultResolveHardwareAddress6(netip.AddrFrom4(s1.Addr4()))
case 4: // s1 discards pending query.
s1.DiscardResolveHardwareAddress6(s2.Addr())
s1.DiscardResolveHardwareAddress6(netip.AddrFrom4(s2.Addr4()))
case 5: // s2 discards pending query.
s2.DiscardResolveHardwareAddress6(s1.Addr())
s2.DiscardResolveHardwareAddress6(netip.AddrFrom4(s1.Addr4()))
}
}
// Exchange data while checking stack does not enter runaway infinite frame send loop.
+5 -6
View File
@@ -1,7 +1,6 @@
package xnet
import (
"net/netip"
"testing"
)
@@ -37,7 +36,7 @@ func TestStackAsync_ICMPEcho(t *testing.T) {
sender.SetGateway6(receiver.HardwareAddress())
receiver.SetGateway6(sender.HardwareAddress())
key, err := sender.icmp.PingStart(receiver.Addr().As4(), tt.pattern, tt.size)
key, err := sender.icmp.PingStart(receiver.Addr4(), tt.pattern, tt.size)
if err != nil {
t.Fatal(err)
}
@@ -92,15 +91,15 @@ func newICMPStacks(t testing.TB, randSeed int64, mtu int) (*StackAsync, *StackAs
// Use the seed to generate two adjacent IPs (10.0.0.x) and MACs.
base := byte(randSeed & 0x7F) // keep in safe range 0..127
addr1 := netip.AddrFrom4([4]byte{10, 0, 0, base})
addr2 := netip.AddrFrom4([4]byte{10, 0, 0, base + 1})
addr1 := [4]byte{10, 0, 0, base}
addr2 := [4]byte{10, 0, 0, base + 1}
mac1 := [6]byte{0xbe, 0xef, 0, 0, 0, base}
mac2 := [6]byte{0xbe, 0xef, 0, 0, 0, base + 1}
if err := s1.Reset(StackConfig{
Hostname: "icmp-stack-1",
RandSeed: randSeed,
StaticAddress: addr1,
StaticAddress4: addr1,
HardwareAddress: mac1,
MTU: uint16(mtu),
ICMPQueueLimit: icmpQueue,
@@ -111,7 +110,7 @@ func newICMPStacks(t testing.TB, randSeed int64, mtu int) (*StackAsync, *StackAs
if err := s2.Reset(StackConfig{
Hostname: "icmp-stack-2",
RandSeed: ^randSeed,
StaticAddress: addr2,
StaticAddress4: addr2,
HardwareAddress: mac2,
MTU: uint16(mtu),
ICMPQueueLimit: icmpQueue,
+7 -7
View File
@@ -21,7 +21,7 @@ func TestStackAsyncListener_SingleConnection(t *testing.T) {
err := client.Reset(StackConfig{
Hostname: "Client",
RandSeed: seed,
StaticAddress: netip.AddrFrom4([4]byte{10, 0, 0, 1}),
StaticAddress4: [4]byte{10, 0, 0, 1},
MaxActiveTCPPorts: 1,
HardwareAddress: [6]byte{0xbe, 0xef, 0, 0, 0, 1},
MTU: MTU,
@@ -32,7 +32,7 @@ func TestStackAsyncListener_SingleConnection(t *testing.T) {
err = sv.Reset(StackConfig{
Hostname: "Server",
RandSeed: ^seed,
StaticAddress: netip.AddrFrom4([4]byte{10, 0, 0, 2}),
StaticAddress4: [4]byte{10, 0, 0, 2},
MaxActiveTCPPorts: 1, // Note: We use listener, not direct TCP conn registration.
HardwareAddress: [6]byte{0xbe, 0xef, 0, 0, 0, 2},
MTU: MTU,
@@ -78,7 +78,7 @@ func TestStackAsyncListener_SingleConnection(t *testing.T) {
}
// Client dials server.
err = client.DialTCP(&clConn, clPort, netip.AddrPortFrom(sv.Addr(), svPort))
err = client.DialTCP(&clConn, clPort, netip.AddrPortFrom(netip.AddrFrom4(sv.Addr4()), svPort))
if err != nil {
t.Fatal(err)
}
@@ -133,7 +133,7 @@ func TestStackAsyncListener_MultiSequentialConn(t *testing.T) {
err := sv.Reset(StackConfig{
Hostname: "Server",
RandSeed: ^seed,
StaticAddress: netip.AddrFrom4([4]byte{10, 0, 0, 2}),
StaticAddress4: [4]byte{10, 0, 0, 2},
MaxActiveTCPPorts: 1, // Note: We use listener, not direct TCP conn registration.
HardwareAddress: [6]byte{0xbe, 0xef, 0, 0, 0, 2},
MTU: MTU,
@@ -173,7 +173,7 @@ func TestStackAsyncListener_MultiSequentialConn(t *testing.T) {
err := client.Reset(StackConfig{
Hostname: "Client",
RandSeed: seed,
StaticAddress: caddrp.Addr(),
StaticAddress4: caddrp.Addr().As4(),
MaxActiveTCPPorts: 1,
HardwareAddress: chw,
MTU: MTU,
@@ -193,7 +193,7 @@ func TestStackAsyncListener_MultiSequentialConn(t *testing.T) {
t.Fatal(err)
}
// Client dials server.
err = client.DialTCP(&clConn, caddrp.Port(), netip.AddrPortFrom(sv.Addr(), svPort))
err = client.DialTCP(&clConn, caddrp.Port(), netip.AddrPortFrom(netip.AddrFrom4(sv.Addr4()), svPort))
if err != nil {
t.Fatal(err)
}
@@ -207,7 +207,7 @@ func TestStackAsyncListener_MultiSequentialConn(t *testing.T) {
if err != nil {
t.Fatal(err)
} else if svconn.RemotePort() != clConn.LocalPort() ||
[4]byte(svconn.RemoteAddr()) != client.Addr().As4() {
[4]byte(svconn.RemoteAddr()) != client.Addr4() {
t.Fatal("race condition to listener acquisition")
}
// Verify both connections are established.
+5 -5
View File
@@ -34,9 +34,9 @@ func TestMDNS_QueryResponse(t *testing.T) {
Port: 80,
}
responderAddr := netip.AddrFrom4([4]byte{192, 168, 1, 50})
responderAddr := [4]byte{192, 168, 1, 50}
responderMAC := [6]byte{0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x01}
querierAddr := netip.AddrFrom4([4]byte{192, 168, 1, 100})
querierAddr := [4]byte{192, 168, 1, 100}
querierMAC := [6]byte{0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0x02}
mcastAddr := []byte{224, 0, 0, 251}
@@ -45,7 +45,7 @@ func TestMDNS_QueryResponse(t *testing.T) {
err = responderStack.Reset(StackConfig{
Hostname: "responder",
RandSeed: 1234,
StaticAddress: responderAddr,
StaticAddress4: responderAddr,
HardwareAddress: responderMAC,
MTU: MTU,
MaxActiveUDPPorts: 1,
@@ -75,7 +75,7 @@ func TestMDNS_QueryResponse(t *testing.T) {
err = querierStack.Reset(StackConfig{
Hostname: "querier",
RandSeed: 5678,
StaticAddress: querierAddr,
StaticAddress4: querierAddr,
HardwareAddress: querierMAC,
MTU: MTU,
MaxActiveUDPPorts: 1,
@@ -280,7 +280,7 @@ func newMDNSStack(t *testing.T, hostname string, seed int64,
err := stack.Reset(StackConfig{
Hostname: hostname,
RandSeed: seed,
StaticAddress: addr,
StaticAddress4: addr.As4(),
HardwareAddress: mac,
MTU: MTU,
MaxActiveUDPPorts: 1,
+3 -3
View File
@@ -53,7 +53,7 @@ func TestStackAsync_ListenerSynAckAddressedToClient(t *testing.T) {
err := sv.Reset(StackConfig{
Hostname: "Server1",
RandSeed: 1234,
StaticAddress: netip.AddrFrom4([4]byte{10, 0, 0, 2}),
StaticAddress4: [4]byte{10, 0, 0, 2},
MaxActiveTCPPorts: 1,
HardwareAddress: serverMAC,
MTU: mtu,
@@ -89,7 +89,7 @@ func TestStackAsync_ListenerSynAckAddressedToClient(t *testing.T) {
err = client.Reset(StackConfig{
Hostname: "Client1",
RandSeed: 5678,
StaticAddress: netip.AddrFrom4([4]byte{10, 0, 0, 1}),
StaticAddress4: [4]byte{10, 0, 0, 1},
MaxActiveTCPPorts: 1,
HardwareAddress: clientMAC,
MTU: mtu,
@@ -106,7 +106,7 @@ func TestStackAsync_ListenerSynAckAddressedToClient(t *testing.T) {
}); err != nil {
t.Fatal(err)
}
if err = client.DialTCP(&clConn, 54321, netip.AddrPortFrom(sv.Addr(), svPort)); err != nil {
if err = client.DialTCP(&clConn, 54321, netip.AddrPortFrom(netip.AddrFrom4(sv.Addr4()), svPort)); err != nil {
t.Fatal(err)
}
+17 -17
View File
@@ -178,7 +178,7 @@ func newTCPStacks(t testing.TB, randSeed int64, mtu int) (s1, s2 *StackAsync, c1
err := s1.Reset(StackConfig{
Hostname: "Stack1",
RandSeed: randSeed,
StaticAddress: netip.AddrFrom4([4]byte{10, 0, 0, byte1}),
StaticAddress4: [4]byte{10, 0, 0, byte1},
MaxActiveTCPPorts: 1,
HardwareAddress: [6]byte{0xbe, 0xef, 0, 0, 0, byte1},
MTU: uint16(mtu),
@@ -192,7 +192,7 @@ func newTCPStacks(t testing.TB, randSeed int64, mtu int) (s1, s2 *StackAsync, c1
err = s2.Reset(StackConfig{
Hostname: "Stack2",
RandSeed: ^randSeed,
StaticAddress: netip.AddrFrom4([4]byte{10, 0, 0, byte2}),
StaticAddress4: [4]byte{10, 0, 0, byte2},
MaxActiveTCPPorts: 1,
HardwareAddress: [6]byte{0xbe, 0xef, 0, 0, 0, byte2},
MTU: uint16(mtu),
@@ -257,7 +257,7 @@ func (tst *tester) TestTCPSetupAndEstablish(svStack, clStack *StackAsync, svConn
if err != nil {
t.Fatal(err)
}
err = clStack.DialTCP(clConn, clPort, netip.AddrPortFrom(svStack.Addr(), svPort))
err = clStack.DialTCP(clConn, clPort, netip.AddrPortFrom(netip.AddrFrom4(svStack.Addr4()), svPort))
if err != nil {
t.Fatal(err)
}
@@ -464,12 +464,12 @@ func (tst *tester) TCPExchange(expect tcpExpectExchange, stack1, stack2 *StackAs
if tst.getInt(protoIPv4, pcap.FieldClassVersion) != 4 {
t.Errorf("did not get IP version=4, got=%d", tst.getInt(protoIPv4, pcap.FieldClassVersion))
}
srcAddr := src.Addr()
dstAddr := dst.Addr()
if !bytes.Equal(srcAddr.AsSlice(), tst.getData(protoIPv4, pcap.FieldClassSrc)) {
srcAddr := src.Addr4()
dstAddr := dst.Addr4()
if !bytes.Equal(srcAddr[:], tst.getData(protoIPv4, pcap.FieldClassSrc)) {
t.Errorf("mismatched ip src addr %d", tst.getData(protoIPv4, pcap.FieldClassSrc))
}
if !bytes.Equal(dstAddr.AsSlice(), tst.getData(protoIPv4, pcap.FieldClassDst)) {
if !bytes.Equal(dstAddr[:], tst.getData(protoIPv4, pcap.FieldClassDst)) {
t.Errorf("mismatched ip dst addr %d", tst.getData(protoIPv4, pcap.FieldClassDst))
}
tfrm := tst.getTCPFrame()
@@ -514,8 +514,8 @@ func (tst *tester) ARPExchangeOnly(querying, target *StackAsync) {
qHw := querying.HardwareAddress()
tgtHw := target.HardwareAddress()
broadcast := ethernet.BroadcastAddr()
qIP := querying.Addr()
tgtIP := target.Addr()
qIP := querying.Addr4()
tgtIP := target.Addr4()
// Validate Ethernet layer (request is broadcast)
if !bytes.Equal(qHw[:], tst.getData(protoEthernet, pcap.FieldClassSrc)) {
@@ -534,10 +534,10 @@ func (tst *tester) ARPExchangeOnly(querying, target *StackAsync) {
if !bytes.Equal(qHw[:], tst.getFieldByClassLen(protoARP, pcap.FieldClassSrc, 6, 0)) {
t.Errorf("request: mismatched ARP sender HW")
}
if !bytes.Equal(qIP.AsSlice(), tst.getFieldByClassLen(protoARP, pcap.FieldClassSrc, 4, 0)) {
if !bytes.Equal(qIP[:], tst.getFieldByClassLen(protoARP, pcap.FieldClassSrc, 4, 0)) {
t.Errorf("request: mismatched ARP sender proto")
}
if !bytes.Equal(tgtIP.AsSlice(), tst.getFieldByClassLen(protoARP, pcap.FieldClassSrc, 4, 1)) {
if !bytes.Equal(tgtIP[:], tst.getFieldByClassLen(protoARP, pcap.FieldClassSrc, 4, 1)) {
t.Errorf("request: mismatched ARP target proto")
}
@@ -579,13 +579,13 @@ func (tst *tester) ARPExchangeOnly(querying, target *StackAsync) {
if !bytes.Equal(tgtHw[:], tst.getFieldByClassLen(protoARP, pcap.FieldClassSrc, 6, 0)) {
t.Errorf("reply: mismatched ARP sender HW (should be target's MAC)")
}
if !bytes.Equal(tgtIP.AsSlice(), tst.getFieldByClassLen(protoARP, pcap.FieldClassSrc, 4, 0)) {
if !bytes.Equal(tgtIP[:], tst.getFieldByClassLen(protoARP, pcap.FieldClassSrc, 4, 0)) {
t.Errorf("reply: mismatched ARP sender proto (should be target's IP)")
}
if !bytes.Equal(qHw[:], tst.getFieldByClassLen(protoARP, pcap.FieldClassSrc, 6, 1)) {
t.Errorf("reply: mismatched ARP target HW (should be querying's MAC)")
}
if !bytes.Equal(qIP.AsSlice(), tst.getFieldByClassLen(protoARP, pcap.FieldClassSrc, 4, 1)) {
if !bytes.Equal(qIP[:], tst.getFieldByClassLen(protoARP, pcap.FieldClassSrc, 4, 1)) {
t.Errorf("reply: mismatched ARP target proto (should be querying's IP)")
}
@@ -597,7 +597,7 @@ func (tst *tester) ARPExchangeOnly(querying, target *StackAsync) {
setzero(buf[:n])
// === PHASE 3: Verify querying stack learned target's MAC ===
resolvedHw, err := querying.ResultResolveHardwareAddress6(tgtIP)
resolvedHw, err := querying.ResultResolveHardwareAddress6(netip.AddrFrom4(tgtIP))
if err != nil {
t.Errorf("ARP query result failed: %v", err)
} else if resolvedHw != tgtHw {
@@ -929,7 +929,7 @@ func TestTCPConn_BufferNotClearedOnPassiveClose(t *testing.T) {
func TestStackAsync_ICMPEchoChecksum(t *testing.T) {
const MTU = ethernet.MaxMTU
const MaxFrameLength = MTU + ethernet.MaxOverheadSize // Ethernet header+FCS+VLAN.
stackAddr := netip.AddrFrom4([4]byte{192, 168, 1, 99})
stackAddr := [4]byte{192, 168, 1, 99}
stackMAC := [6]byte{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}
routerAddr := [4]byte{192, 168, 1, 1}
routerMAC := [6]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55}
@@ -938,7 +938,7 @@ func TestStackAsync_ICMPEchoChecksum(t *testing.T) {
err := stack.Reset(StackConfig{
Hostname: "ICMPTest",
RandSeed: 42,
StaticAddress: stackAddr,
StaticAddress4: stackAddr,
HardwareAddress: stackMAC,
MTU: MTU,
ICMPQueueLimit: 2,
@@ -954,7 +954,7 @@ func TestStackAsync_ICMPEchoChecksum(t *testing.T) {
SrcMAC: routerMAC,
DstMAC: stackMAC,
SrcIPv4: routerAddr,
DstIPv4: stackAddr.As4(),
DstIPv4: stackAddr,
}
icmpPayload := []byte("abcdefghijklmnopqrstuvwxyz012345") // 32 bytes, typical ping payload.
const (