Xray-core/transport/internet/udp/hub_windows.go
2025-05-09 18:40:23 +03:30

55 lines
1.6 KiB
Go

//go:build windows
// +build windows
package udp
import (
"encoding/binary"
"unsafe"
"github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/net"
"golang.org/x/sys/windows"
)
func RetrieveOriginalDest(oob []byte) net.Destination {
dest := net.Destination{}
port := binary.LittleEndian.Uint16(oob[:2])
buf := buf.FromBytes(oob[2:])
defer buf.Release()
for !buf.IsEmpty() {
cm := &windows.WSACMSGHDR{}
len := make([]byte, unsafe.Sizeof(cm.Len))
nRead, err := buf.Read(len)
if err != nil {
return dest
}
cm.Len = uintptr(binary.LittleEndian.Uint16(len))
binary.Read(buf, binary.LittleEndian, &cm.Level)
binary.Read(buf, binary.LittleEndian, &cm.Type)
nRead += 8 // len cm.Level + cm.Type
if cm.Type == windows.IP_PKTINFO {
if cm.Level == windows.IPPROTO_IP { // IPv4
pktinf := &windows.IN_PKTINFO{}
binary.Read(buf, binary.LittleEndian, pktinf)
return net.UDPDestination(net.IPAddress(pktinf.Addr[:]), net.Port(port))
} else { // IPv6
pktinfv6 := &windows.IN6_PKTINFO{}
binary.Read(buf, binary.LittleEndian, pktinfv6)
return net.UDPDestination(net.IPAddress(pktinfv6.Addr[:]), net.Port(port))
}
}
buf.Advance(int32(cm.Len) - int32(nRead))
}
return dest
}
func ReadUDPMsg(conn *net.UDPConn, payload []byte, oob []byte) (int, int, int, *net.UDPAddr, error) {
udpAddr, _ := net.ResolveUDPAddr(conn.LocalAddr().Network(), conn.LocalAddr().String())
binary.LittleEndian.PutUint16(oob[:2], uint16(udpAddr.Port))
n, oobn, flags, addr, err := conn.ReadMsgUDP(payload, oob[2:])
return n, oobn + 2, flags, addr, err
}