//go:build windows package win32api import ( "fmt" "io" "net" "os" "runtime" "strings" "testing" "time" "unsafe" ) func TestGetHostName(t *testing.T) { host, err := GetHostName() if err != nil { t.Fatalf("GetHostName failed: %v", err) } host = strings.TrimSpace(host) if host == "" { t.Fatal("GetHostName returned empty string") } } func TestInetPtonNtopIPv4(t *testing.T) { raw, err := InetPton(AF_INET, "127.0.0.1") if err != nil { t.Fatalf("InetPton ipv4 failed: %v", err) } if len(raw) != 4 { t.Fatalf("InetPton ipv4 len mismatch: got=%d", len(raw)) } ip, err := InetNtop(AF_INET, raw) if err != nil { t.Fatalf("InetNtop ipv4 failed: %v", err) } if !net.ParseIP(ip).Equal(net.ParseIP("127.0.0.1")) { t.Fatalf("InetNtop ipv4 mismatch: got=%q", ip) } } func TestInetPtonNtopIPv6(t *testing.T) { raw, err := InetPton(AF_INET6, "::1") if err != nil { t.Fatalf("InetPton ipv6 failed: %v", err) } if len(raw) != 16 { t.Fatalf("InetPton ipv6 len mismatch: got=%d", len(raw)) } ip, err := InetNtop(AF_INET6, raw) if err != nil { t.Fatalf("InetNtop ipv6 failed: %v", err) } if !net.ParseIP(ip).Equal(net.ParseIP("::1")) { t.Fatalf("InetNtop ipv6 mismatch: got=%q", ip) } } func TestInetPtonInvalidInput(t *testing.T) { if _, err := InetPton(AF_INET, "999.999.999.999"); err == nil { t.Fatal("InetPton should fail on invalid ipv4 address") } } func TestGetAddrInfoLocalhost(t *testing.T) { hints := &ADDRINFOW{ Family: AF_UNSPEC, Socktype: SOCK_STREAM, Protocol: IPPROTO_TCP, } result, err := GetAddrInfo("localhost", "80", hints) if err != nil { t.Fatalf("GetAddrInfo failed: %v", err) } defer func() { if freeErr := FreeAddrInfo(result); freeErr != nil { t.Fatalf("FreeAddrInfo failed: %v", freeErr) } }() total := 0 validIP := 0 for p := result; p != nil; p = p.Next { total++ if p.Addr == nil { continue } switch p.Family { case AF_INET, AF_INET6: ip, ipErr := SockaddrIPString(p.Addr) if ipErr != nil { t.Fatalf("SockaddrIPString failed: %v", ipErr) } if net.ParseIP(ip) == nil { t.Fatalf("invalid ip parsed from addrinfo: %q", ip) } validIP++ } } if total == 0 { t.Fatal("GetAddrInfo returned empty result list") } if validIP == 0 { t.Fatal("GetAddrInfo returned no AF_INET/AF_INET6 entries") } } func TestGetNameInfoNumericIPv4(t *testing.T) { sa := SOCKADDR_IN{ Family: ADDRESS_FAMILY(AF_INET), Port: htons(80), Addr: [4]byte{127, 0, 0, 1}, } host, service, err := GetNameInfo((*SOCKADDR)(unsafe.Pointer(&sa)), int32(unsafe.Sizeof(sa)), NI_NUMERICHOST|NI_NUMERICSERV) if err != nil { t.Fatalf("GetNameInfo failed: %v", err) } if host != "127.0.0.1" { t.Fatalf("GetNameInfo host mismatch: got=%q", host) } if service != "80" { t.Fatalf("GetNameInfo service mismatch: got=%q", service) } } func TestHostNetworkByteOrderHelpers(t *testing.T) { if Htons(0x1234) != 0x3412 { t.Fatalf("Htons mismatch: got=%#x", Htons(0x1234)) } if Ntohs(0x3412) != 0x1234 { t.Fatalf("Ntohs mismatch: got=%#x", Ntohs(0x3412)) } tcp4 := MIB_TCPROW_OWNER_PID{LocalPort: uint32(Htons(8080)), RemotePort: uint32(Htons(443))} if tcp4.LocalPortHost() != 8080 || tcp4.RemotePortHost() != 443 { t.Fatalf("tcp4 port helper mismatch: local=%d remote=%d", tcp4.LocalPortHost(), tcp4.RemotePortHost()) } tcp6 := MIB_TCP6ROW_OWNER_PID{LocalPort: uint32(Htons(8081)), RemotePort: uint32(Htons(8443))} if tcp6.LocalPortHost() != 8081 || tcp6.RemotePortHost() != 8443 { t.Fatalf("tcp6 port helper mismatch: local=%d remote=%d", tcp6.LocalPortHost(), tcp6.RemotePortHost()) } udp4 := MIB_UDPROW_OWNER_PID{LocalPort: uint32(Htons(5353))} if udp4.LocalPortHost() != 5353 { t.Fatalf("udp4 port helper mismatch: local=%d", udp4.LocalPortHost()) } udp6 := MIB_UDP6ROW_OWNER_PID{LocalPort: uint32(Htons(5354))} if udp6.LocalPortHost() != 5354 { t.Fatalf("udp6 port helper mismatch: local=%d", udp6.LocalPortHost()) } } func TestIphlpapiTableLayouts(t *testing.T) { wantIfTableOffset := uintptr(8) wantIfRowSize := uintptr(1352) if runtime.GOARCH == "386" { wantIfTableOffset = 4 wantIfRowSize = 1348 } if got := unsafe.Offsetof(MIB_IF_TABLE2{}.Table); got != wantIfTableOffset { t.Fatalf("MIB_IF_TABLE2.Table offset mismatch: got=%d want=%d", got, wantIfTableOffset) } if got := unsafe.Sizeof(MIB_IF_ROW2{}); got != wantIfRowSize { t.Fatalf("MIB_IF_ROW2 size mismatch: got=%d want=%d", got, wantIfRowSize) } if got := unsafe.Offsetof(MIB_TCPTABLE_OWNER_PID{}.Table); got != 4 { t.Fatalf("MIB_TCPTABLE_OWNER_PID.Table offset mismatch: got=%d want=4", got) } if got := unsafe.Sizeof(MIB_TCPROW_OWNER_PID{}); got != 24 { t.Fatalf("MIB_TCPROW_OWNER_PID size mismatch: got=%d want=24", got) } if got := unsafe.Offsetof(MIB_TCP6TABLE_OWNER_PID{}.Table); got != 4 { t.Fatalf("MIB_TCP6TABLE_OWNER_PID.Table offset mismatch: got=%d want=4", got) } if got := unsafe.Sizeof(MIB_TCP6ROW_OWNER_PID{}); got != 56 { t.Fatalf("MIB_TCP6ROW_OWNER_PID size mismatch: got=%d want=56", got) } if got := unsafe.Offsetof(MIB_UDPTABLE_OWNER_PID{}.Table); got != 4 { t.Fatalf("MIB_UDPTABLE_OWNER_PID.Table offset mismatch: got=%d want=4", got) } if got := unsafe.Sizeof(MIB_UDPROW_OWNER_PID{}); got != 12 { t.Fatalf("MIB_UDPROW_OWNER_PID size mismatch: got=%d want=12", got) } if got := unsafe.Offsetof(MIB_UDP6TABLE_OWNER_PID{}.Table); got != 4 { t.Fatalf("MIB_UDP6TABLE_OWNER_PID.Table offset mismatch: got=%d want=4", got) } if got := unsafe.Sizeof(MIB_UDP6ROW_OWNER_PID{}); got != 28 { t.Fatalf("MIB_UDP6ROW_OWNER_PID size mismatch: got=%d want=28", got) } } func requireWSA(t *testing.T) { t.Helper() var data WSADATA if err := WSAStartup(makeWord(2, 2), &data); err != nil { t.Fatalf("WSAStartup failed: %v", err) } t.Cleanup(func() { _ = WSACleanup() }) } func TestSocketConnectSendRecv(t *testing.T) { requireWSA(t) ln, err := net.Listen("tcp4", "127.0.0.1:0") if err != nil { t.Fatalf("listen failed: %v", err) } defer func() { _ = ln.Close() }() done := make(chan error, 1) go func() { conn, acceptErr := ln.Accept() if acceptErr != nil { done <- acceptErr return } defer func() { _ = conn.Close() }() buf := make([]byte, 4) if _, readErr := io.ReadFull(conn, buf); readErr != nil { done <- readErr return } if string(buf) != "ping" { done <- io.ErrUnexpectedEOF return } _, writeErr := conn.Write([]byte("pong")) done <- writeErr }() s, err := Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) if err != nil { t.Fatalf("Socket failed: %v", err) } defer func() { _ = Closesocket(s) }() tcpAddr, ok := ln.Addr().(*net.TCPAddr) if !ok { t.Fatalf("listen addr type mismatch: %T", ln.Addr()) } sa := SOCKADDR_IN{ Family: ADDRESS_FAMILY(AF_INET), Port: htons(uint16(tcpAddr.Port)), Addr: [4]byte{127, 0, 0, 1}, } if err := Connect(s, (*SOCKADDR)(unsafe.Pointer(&sa)), int32(unsafe.Sizeof(sa))); err != nil { t.Fatalf("Connect failed: %v", err) } payload := []byte("ping") written, err := Send(s, payload, 0) if err != nil { t.Fatalf("Send failed: %v", err) } if written != len(payload) { t.Fatalf("Send wrote mismatch: got=%d want=%d", written, len(payload)) } reply := make([]byte, 4) read, err := Recv(s, reply, 0) if err != nil { t.Fatalf("Recv failed: %v", err) } if string(reply[:read]) != "pong" { t.Fatalf("Recv data mismatch: got=%q", string(reply[:read])) } if err := Shutdown(s, SD_BOTH); err != nil { t.Fatalf("Shutdown failed: %v", err) } select { case serverErr := <-done: if serverErr != nil { t.Fatalf("server goroutine failed: %v", serverErr) } case <-time.After(3 * time.Second): t.Fatal("server goroutine timeout") } } func TestBindListenEphemeral(t *testing.T) { requireWSA(t) s, err := Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) if err != nil { t.Fatalf("Socket failed: %v", err) } defer func() { _ = Closesocket(s) }() sa := SOCKADDR_IN{ Family: ADDRESS_FAMILY(AF_INET), Port: 0, Addr: [4]byte{127, 0, 0, 1}, } if err := Bind(s, (*SOCKADDR)(unsafe.Pointer(&sa)), int32(unsafe.Sizeof(sa))); err != nil { t.Fatalf("Bind failed: %v", err) } if err := Listen(s, 1); err != nil { t.Fatalf("Listen failed: %v", err) } } func TestGetSockNameAndPeerName(t *testing.T) { requireWSA(t) ln, err := net.Listen("tcp4", "127.0.0.1:0") if err != nil { t.Fatalf("listen failed: %v", err) } defer func() { _ = ln.Close() }() connCh := make(chan net.Conn, 1) errCh := make(chan error, 1) go func() { conn, acceptErr := ln.Accept() if acceptErr != nil { errCh <- acceptErr return } connCh <- conn }() client, err := Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) if err != nil { t.Fatalf("Socket failed: %v", err) } defer func() { _ = Closesocket(client) }() tcpAddr := ln.Addr().(*net.TCPAddr) peer := SOCKADDR_IN{ Family: ADDRESS_FAMILY(AF_INET), Port: htons(uint16(tcpAddr.Port)), Addr: [4]byte{127, 0, 0, 1}, } if err := Connect(client, (*SOCKADDR)(unsafe.Pointer(&peer)), int32(unsafe.Sizeof(peer))); err != nil { t.Fatalf("Connect failed: %v", err) } var serverConn net.Conn select { case serverConn = <-connCh: defer func() { _ = serverConn.Close() }() case acceptErr := <-errCh: t.Fatalf("accept failed: %v", acceptErr) case <-time.After(3 * time.Second): t.Fatal("accept timeout") } var local SOCKADDR_IN localLen := int32(unsafe.Sizeof(local)) if err := GetSockName(client, (*SOCKADDR)(unsafe.Pointer(&local)), &localLen); err != nil { t.Fatalf("GetSockName failed: %v", err) } if local.Family != ADDRESS_FAMILY(AF_INET) { t.Fatalf("GetSockName family mismatch: got=%d", local.Family) } if htons(local.Port) == 0 { t.Fatal("GetSockName returned zero local port") } var remote SOCKADDR_IN remoteLen := int32(unsafe.Sizeof(remote)) if err := GetPeerName(client, (*SOCKADDR)(unsafe.Pointer(&remote)), &remoteLen); err != nil { t.Fatalf("GetPeerName failed: %v", err) } if remote.Family != ADDRESS_FAMILY(AF_INET) { t.Fatalf("GetPeerName family mismatch: got=%d", remote.Family) } if remote.Addr != [4]byte{127, 0, 0, 1} { t.Fatalf("GetPeerName ip mismatch: got=%v", remote.Addr) } if int(htons(remote.Port)) != tcpAddr.Port { t.Fatalf("GetPeerName port mismatch: got=%d want=%d", htons(remote.Port), tcpAddr.Port) } } func TestSetGetSockOptInt(t *testing.T) { requireWSA(t) s, err := Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) if err != nil { t.Fatalf("Socket failed: %v", err) } defer func() { _ = Closesocket(s) }() if err := SetSockOptInt(s, SOL_SOCKET, SO_REUSEADDR, 1); err != nil { t.Fatalf("SetSockOptInt failed: %v", err) } v, err := GetSockOptInt(s, SOL_SOCKET, SO_REUSEADDR) if err != nil { t.Fatalf("GetSockOptInt failed: %v", err) } if v == 0 { t.Fatalf("GetSockOptInt(SO_REUSEADDR) expected non-zero, got %d", v) } } func TestSendToRecvFromUDP(t *testing.T) { requireWSA(t) receiver, err := Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) if err != nil { t.Fatalf("receiver Socket failed: %v", err) } defer func() { _ = Closesocket(receiver) }() bindAddr := SOCKADDR_IN{ Family: ADDRESS_FAMILY(AF_INET), Port: 0, Addr: [4]byte{127, 0, 0, 1}, } if err := Bind(receiver, (*SOCKADDR)(unsafe.Pointer(&bindAddr)), int32(unsafe.Sizeof(bindAddr))); err != nil { t.Fatalf("receiver Bind failed: %v", err) } var recvBound SOCKADDR_IN recvBoundLen := int32(unsafe.Sizeof(recvBound)) if err := GetSockName(receiver, (*SOCKADDR)(unsafe.Pointer(&recvBound)), &recvBoundLen); err != nil { t.Fatalf("receiver GetSockName failed: %v", err) } recvPort := htons(recvBound.Port) if recvPort == 0 { t.Fatal("receiver bound port is zero") } sender, err := Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) if err != nil { t.Fatalf("sender Socket failed: %v", err) } defer func() { _ = Closesocket(sender) }() target := SOCKADDR_IN{ Family: ADDRESS_FAMILY(AF_INET), Port: recvBound.Port, Addr: [4]byte{127, 0, 0, 1}, } payload := []byte("udp-ping") sent, err := SendTo(sender, payload, 0, (*SOCKADDR)(unsafe.Pointer(&target)), int32(unsafe.Sizeof(target))) if err != nil { t.Fatalf("SendTo failed: %v", err) } if sent != len(payload) { t.Fatalf("SendTo length mismatch: got=%d want=%d", sent, len(payload)) } buf := make([]byte, 64) var from SOCKADDR_IN fromLen := int32(unsafe.Sizeof(from)) n, err := RecvFrom(receiver, buf, 0, (*SOCKADDR)(unsafe.Pointer(&from)), &fromLen) if err != nil { t.Fatalf("RecvFrom failed: %v", err) } if string(buf[:n]) != string(payload) { t.Fatalf("RecvFrom payload mismatch: got=%q want=%q", string(buf[:n]), string(payload)) } if from.Family != ADDRESS_FAMILY(AF_INET) { t.Fatalf("RecvFrom family mismatch: got=%d", from.Family) } if from.Addr != [4]byte{127, 0, 0, 1} { t.Fatalf("RecvFrom source ip mismatch: got=%v", from.Addr) } if htons(from.Port) == 0 { t.Fatal("RecvFrom source port is zero") } } func TestAcceptSendRecvServerFlow(t *testing.T) { requireWSA(t) listener, err := Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) if err != nil { t.Fatalf("listener Socket failed: %v", err) } defer func() { _ = Closesocket(listener) }() if err := SetSockOptInt(listener, SOL_SOCKET, SO_REUSEADDR, 1); err != nil { t.Fatalf("SetSockOptInt(SO_REUSEADDR) failed: %v", err) } bindAddr := SOCKADDR_IN{ Family: ADDRESS_FAMILY(AF_INET), Port: 0, Addr: [4]byte{127, 0, 0, 1}, } if err := Bind(listener, (*SOCKADDR)(unsafe.Pointer(&bindAddr)), int32(unsafe.Sizeof(bindAddr))); err != nil { t.Fatalf("Bind failed: %v", err) } if err := Listen(listener, 1); err != nil { t.Fatalf("Listen failed: %v", err) } var bound SOCKADDR_IN boundLen := int32(unsafe.Sizeof(bound)) if err := GetSockName(listener, (*SOCKADDR)(unsafe.Pointer(&bound)), &boundLen); err != nil { t.Fatalf("GetSockName(listener) failed: %v", err) } port := htons(bound.Port) if port == 0 { t.Fatal("listener port is zero") } serverDone := make(chan error, 1) go func() { var peer SOCKADDR_IN peerLen := int32(unsafe.Sizeof(peer)) clientSock, acceptErr := Accept(listener, (*SOCKADDR)(unsafe.Pointer(&peer)), &peerLen) if acceptErr != nil { serverDone <- acceptErr return } defer func() { _ = Closesocket(clientSock) }() buf := make([]byte, 16) n, recvErr := Recv(clientSock, buf, 0) if recvErr != nil { serverDone <- recvErr return } if string(buf[:n]) != "accept-ping" { serverDone <- fmt.Errorf("server recv mismatch: %q", string(buf[:n])) return } if _, sendErr := Send(clientSock, []byte("accept-pong"), 0); sendErr != nil { serverDone <- sendErr return } serverDone <- nil }() conn, err := net.DialTimeout("tcp4", fmt.Sprintf("127.0.0.1:%d", port), 3*time.Second) if err != nil { t.Fatalf("DialTimeout failed: %v", err) } defer func() { _ = conn.Close() }() if _, err := conn.Write([]byte("accept-ping")); err != nil { t.Fatalf("client Write failed: %v", err) } reply := make([]byte, 16) n, err := io.ReadFull(conn, reply[:11]) if err != nil { t.Fatalf("client ReadFull failed: %v", err) } if string(reply[:n]) != "accept-pong" { t.Fatalf("client recv mismatch: %q", string(reply[:n])) } select { case err := <-serverDone: if err != nil { t.Fatalf("server flow failed: %v", err) } case <-time.After(3 * time.Second): t.Fatal("server flow timeout") } } func TestGetSockOptSOErrorAfterFailedConnect(t *testing.T) { requireWSA(t) s, err := Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) if err != nil { t.Fatalf("Socket failed: %v", err) } defer func() { _ = Closesocket(s) }() target := SOCKADDR_IN{ Family: ADDRESS_FAMILY(AF_INET), Port: htons(1), Addr: [4]byte{127, 0, 0, 1}, } connectErr := Connect(s, (*SOCKADDR)(unsafe.Pointer(&target)), int32(unsafe.Sizeof(target))) if connectErr == nil { t.Skip("port 1 is open in current environment, skip SO_ERROR failure-path test") } soErr, err := GetSockOptInt(s, SOL_SOCKET, SO_ERROR) if err != nil { t.Fatalf("GetSockOptInt(SO_ERROR) failed: %v", err) } if soErr == 0 { // On some stacks the synchronous connect error can be reported directly and // SO_ERROR may already be cleared; keep this as diagnostic instead of flaky fail. t.Logf("SO_ERROR=0 after connect err=%v", connectErr) } } func TestGetAdaptersAddresses(t *testing.T) { adapters, err := GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX|GAA_FLAG_INCLUDE_GATEWAYS) if err != nil { t.Fatalf("GetAdaptersAddresses failed: %v", err) } if len(adapters) == 0 { t.Fatal("GetAdaptersAddresses returned empty list") } foundNamed := false for _, a := range adapters { if strings.TrimSpace(a.FriendlyName) != "" || strings.TrimSpace(a.AdapterName) != "" { foundNamed = true break } } if !foundNamed { t.Fatal("GetAdaptersAddresses returned adapters without names") } for _, a := range adapters { if a.PhysicalAddressLength > 0 { if strings.TrimSpace(a.MACAddress) == "" { t.Fatalf("adapter has physical address length %d but empty MACAddress", a.PhysicalAddressLength) } if _, err := net.ParseMAC(a.MACAddress); err != nil { t.Fatalf("invalid MACAddress format %q: %v", a.MACAddress, err) } } for _, ip := range a.UnicastIPs { if net.ParseIP(ip) == nil { t.Fatalf("invalid unicast ip in adapter info: %q", ip) } } for _, ip := range a.DNSServers { if net.ParseIP(ip) == nil { t.Fatalf("invalid dns server ip in adapter info: %q", ip) } } for _, ip := range a.Gateways { if net.ParseIP(ip) == nil { t.Fatalf("invalid gateway ip in adapter info: %q", ip) } } } } func TestGetIfTable2AndEntry2(t *testing.T) { rows, err := GetIfTable2() if err != nil { t.Fatalf("GetIfTable2 failed: %v", err) } if len(rows) == 0 { t.Fatal("GetIfTable2 returned empty list") } row := rows[0] if row.InterfaceIndex == 0 && row.InterfaceLuid == 0 { t.Fatal("GetIfTable2 returned row without interface identity") } if err := GetIfEntry2(&row); err != nil { t.Fatalf("GetIfEntry2 failed: %v", err) } if row.InterfaceIndex == 0 && row.InterfaceLuid == 0 { t.Fatal("GetIfEntry2 cleared interface identity") } stats := []uint64{ row.InOctets, row.OutOctets, row.InUcastOctets, row.OutUcastOctets, row.InMulticastOctets, row.OutMulticastOctets, row.InBroadcastOctets, row.OutBroadcastOctets, } if len(stats) != 8 { t.Fatalf("unexpected stats field count: got=%d", len(stats)) } } func TestGetExtendedTcp4TableIncludesCurrentListener(t *testing.T) { listener, err := net.Listen("tcp4", "127.0.0.1:0") if err != nil { t.Fatalf("listen tcp4 failed: %v", err) } defer func() { _ = listener.Close() }() port := listener.Addr().(*net.TCPAddr).Port row := waitForTCP4OwnerPIDRow(t, uint32(os.Getpid()), port) if row.State != MIB_TCP_STATE_LISTEN { t.Fatalf("unexpected tcp state: got=%d want=%d", row.State, MIB_TCP_STATE_LISTEN) } } func TestGetExtendedUdp4TableIncludesCurrentSocket(t *testing.T) { packetConn, err := net.ListenPacket("udp4", "127.0.0.1:0") if err != nil { t.Fatalf("listen udp4 failed: %v", err) } defer func() { _ = packetConn.Close() }() port := packetConn.LocalAddr().(*net.UDPAddr).Port _ = waitForUDP4OwnerPIDRow(t, uint32(os.Getpid()), port) } func TestGetExtendedTcp6TableIncludesCurrentListener(t *testing.T) { listener, err := net.Listen("tcp6", "[::1]:0") if err != nil { t.Skipf("tcp6 unavailable: %v", err) } defer func() { _ = listener.Close() }() port := listener.Addr().(*net.TCPAddr).Port row := waitForTCP6OwnerPIDRow(t, uint32(os.Getpid()), port) if row.State != MIB_TCP_STATE_LISTEN { t.Fatalf("unexpected tcp6 state: got=%d want=%d", row.State, MIB_TCP_STATE_LISTEN) } } func TestGetExtendedUdp6TableIncludesCurrentSocket(t *testing.T) { packetConn, err := net.ListenPacket("udp6", "[::1]:0") if err != nil { t.Skipf("udp6 unavailable: %v", err) } defer func() { _ = packetConn.Close() }() port := packetConn.LocalAddr().(*net.UDPAddr).Port _ = waitForUDP6OwnerPIDRow(t, uint32(os.Getpid()), port) } func waitForTCP4OwnerPIDRow(t *testing.T, pid uint32, port int) MIB_TCPROW_OWNER_PID { t.Helper() deadline := time.Now().Add(2 * time.Second) for time.Now().Before(deadline) { rows, err := GetExtendedTcp4Table(false, TCP_TABLE_OWNER_PID_ALL) if err != nil { t.Fatalf("GetExtendedTcp4Table failed: %v", err) } for _, row := range rows { if row.OwningPid == pid && int(row.LocalPortHost()) == port { return row } } time.Sleep(50 * time.Millisecond) } t.Fatalf("did not find tcp4 row for pid=%d port=%d", pid, port) return MIB_TCPROW_OWNER_PID{} } func waitForTCP6OwnerPIDRow(t *testing.T, pid uint32, port int) MIB_TCP6ROW_OWNER_PID { t.Helper() deadline := time.Now().Add(2 * time.Second) for time.Now().Before(deadline) { rows, err := GetExtendedTcp6Table(false, TCP_TABLE_OWNER_PID_ALL) if err != nil { t.Fatalf("GetExtendedTcp6Table failed: %v", err) } for _, row := range rows { if row.OwningPid == pid && int(row.LocalPortHost()) == port { return row } } time.Sleep(50 * time.Millisecond) } t.Fatalf("did not find tcp6 row for pid=%d port=%d", pid, port) return MIB_TCP6ROW_OWNER_PID{} } func waitForUDP4OwnerPIDRow(t *testing.T, pid uint32, port int) MIB_UDPROW_OWNER_PID { t.Helper() deadline := time.Now().Add(2 * time.Second) for time.Now().Before(deadline) { rows, err := GetExtendedUdp4Table(false, UDP_TABLE_OWNER_PID) if err != nil { t.Fatalf("GetExtendedUdp4Table failed: %v", err) } for _, row := range rows { if row.OwningPid == pid && int(row.LocalPortHost()) == port { return row } } time.Sleep(50 * time.Millisecond) } t.Fatalf("did not find udp4 row for pid=%d port=%d", pid, port) return MIB_UDPROW_OWNER_PID{} } func waitForUDP6OwnerPIDRow(t *testing.T, pid uint32, port int) MIB_UDP6ROW_OWNER_PID { t.Helper() deadline := time.Now().Add(2 * time.Second) for time.Now().Before(deadline) { rows, err := GetExtendedUdp6Table(false, UDP_TABLE_OWNER_PID) if err != nil { t.Fatalf("GetExtendedUdp6Table failed: %v", err) } for _, row := range rows { if row.OwningPid == pid && int(row.LocalPortHost()) == port { return row } } time.Sleep(50 * time.Millisecond) } t.Fatalf("did not find udp6 row for pid=%d port=%d", pid, port) return MIB_UDP6ROW_OWNER_PID{} }