mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-05-13 20:44:12 +08:00
55 lines
1.6 KiB
Go
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
|
|
}
|