github.com/database64128/shadowsocks-go@v1.10.2-0.20240315062903-143a773533f1/conn/sockaddr_windows.go (about) 1 package conn 2 3 import ( 4 "fmt" 5 "net/netip" 6 "unsafe" 7 8 "golang.org/x/sys/windows" 9 ) 10 11 const ( 12 SizeofSockaddrInet4 = uint32(unsafe.Sizeof(windows.RawSockaddrInet4{})) 13 SizeofSockaddrInet6 = uint32(unsafe.Sizeof(windows.RawSockaddrInet6{})) 14 ) 15 16 func AddrPortToSockaddrValue(addrPort netip.AddrPort) (rsa6 windows.RawSockaddrInet6, namelen uint32) { 17 addr, port := addrPort.Addr(), addrPort.Port() 18 p := (*[2]byte)(unsafe.Pointer(&rsa6.Port)) 19 p[0] = byte(port >> 8) 20 p[1] = byte(port) 21 if addr.Is4() { 22 rsa6.Family = windows.AF_INET 23 a := (*[4]byte)(unsafe.Pointer(&rsa6.Flowinfo)) 24 *a = addr.As4() 25 namelen = SizeofSockaddrInet4 26 return 27 } 28 rsa6.Family = windows.AF_INET6 29 rsa6.Addr = addr.As16() 30 namelen = SizeofSockaddrInet6 31 return 32 } 33 34 func SockaddrValueToAddrPort(rsa6 windows.RawSockaddrInet6, namelen uint32) (netip.AddrPort, error) { 35 p := (*[2]byte)(unsafe.Pointer(&rsa6.Port)) 36 port := uint16(p[0])<<8 + uint16(p[1]) 37 var addr netip.Addr 38 switch namelen { 39 case SizeofSockaddrInet4: 40 addr = netip.AddrFrom4(*(*[4]byte)(unsafe.Pointer(&rsa6.Flowinfo))) 41 case SizeofSockaddrInet6: 42 addr = netip.AddrFrom16(rsa6.Addr) 43 default: 44 return netip.AddrPort{}, fmt.Errorf("bad sockaddr length: %d", namelen) 45 } 46 return netip.AddrPortFrom(addr, port), nil 47 } 48 49 func AddrPortToSockaddr(addrPort netip.AddrPort) (name *byte, namelen uint32) { 50 if addrPort.Addr().Is4() { 51 rsa4 := AddrPortToSockaddrInet4(addrPort) 52 name = (*byte)(unsafe.Pointer(&rsa4)) 53 namelen = SizeofSockaddrInet4 54 } else { 55 rsa6 := AddrPortToSockaddrInet6(addrPort) 56 name = (*byte)(unsafe.Pointer(&rsa6)) 57 namelen = SizeofSockaddrInet6 58 } 59 return 60 } 61 62 func AddrPortUnmappedToSockaddr(addrPort netip.AddrPort) (name *byte, namelen uint32) { 63 if addr := addrPort.Addr(); addr.Is4() || addr.Is4In6() { 64 rsa4 := AddrPortToSockaddrInet4(addrPort) 65 name = (*byte)(unsafe.Pointer(&rsa4)) 66 namelen = SizeofSockaddrInet4 67 } else { 68 rsa6 := AddrPortToSockaddrInet6(addrPort) 69 name = (*byte)(unsafe.Pointer(&rsa6)) 70 namelen = SizeofSockaddrInet6 71 } 72 return 73 } 74 75 func AddrPortToSockaddrInet4(addrPort netip.AddrPort) windows.RawSockaddrInet4 { 76 addr := addrPort.Addr() 77 port := addrPort.Port() 78 rsa4 := windows.RawSockaddrInet4{ 79 Family: windows.AF_INET, 80 Addr: addr.As4(), 81 } 82 p := (*[2]byte)(unsafe.Pointer(&rsa4.Port)) 83 p[0] = byte(port >> 8) 84 p[1] = byte(port) 85 return rsa4 86 } 87 88 func AddrPortToSockaddrInet6(addrPort netip.AddrPort) windows.RawSockaddrInet6 { 89 addr := addrPort.Addr() 90 port := addrPort.Port() 91 rsa6 := windows.RawSockaddrInet6{ 92 Family: windows.AF_INET6, 93 Addr: addr.As16(), 94 } 95 p := (*[2]byte)(unsafe.Pointer(&rsa6.Port)) 96 p[0] = byte(port >> 8) 97 p[1] = byte(port) 98 return rsa6 99 } 100 101 func SockaddrToAddrPort(name *byte, namelen uint32) (netip.AddrPort, error) { 102 switch namelen { 103 case SizeofSockaddrInet4: 104 rsa4 := (*windows.RawSockaddrInet4)(unsafe.Pointer(name)) 105 return SockaddrInet4ToAddrPort(rsa4), nil 106 107 case SizeofSockaddrInet6: 108 rsa6 := (*windows.RawSockaddrInet6)(unsafe.Pointer(name)) 109 return SockaddrInet6ToAddrPort(rsa6), nil 110 111 default: 112 return netip.AddrPort{}, fmt.Errorf("bad sockaddr length: %d", namelen) 113 } 114 } 115 116 func SockaddrInet4ToAddrPort(sa *windows.RawSockaddrInet4) netip.AddrPort { 117 portp := (*[2]byte)(unsafe.Pointer(&sa.Port)) 118 port := uint16(portp[0])<<8 + uint16(portp[1]) 119 ip := netip.AddrFrom4(sa.Addr) 120 return netip.AddrPortFrom(ip, port) 121 } 122 123 func SockaddrInet6ToAddrPort(sa *windows.RawSockaddrInet6) netip.AddrPort { 124 portp := (*[2]byte)(unsafe.Pointer(&sa.Port)) 125 port := uint16(portp[0])<<8 + uint16(portp[1]) 126 ip := netip.AddrFrom16(sa.Addr) 127 return netip.AddrPortFrom(ip, port) 128 }