mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-05-13 20:44:12 +08:00
fix udp original destination on windows
This commit is contained in:
parent
e9b3c53a0d
commit
d5c53b1ddd
@ -1,5 +1,5 @@
|
|||||||
//go:build !linux
|
//go:build !linux && !windows
|
||||||
// +build !linux
|
// +build !linux,!windows
|
||||||
|
|
||||||
package dokodemo
|
package dokodemo
|
||||||
|
|
||||||
|
27
proxy/dokodemo/fakeudp_windows.go
Normal file
27
proxy/dokodemo/fakeudp_windows.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
//go:build windows
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package dokodemo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func FakeUDP(addr *net.UDPAddr, mark int) (net.PacketConn, error) {
|
||||||
|
udpConn, err := net.ListenUDP("udp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return udpConn, err
|
||||||
|
}
|
||||||
|
rawConn, err := udpConn.SyscallConn()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = rawConn.Control(func(fd uintptr) {
|
||||||
|
syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return udpConn, nil
|
||||||
|
}
|
@ -11,6 +11,7 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/errors"
|
"github.com/xtls/xray-core/common/errors"
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -142,6 +143,15 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.ReceiveOriginalDestAddress && isUDPSocket(network) {
|
||||||
|
if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_IP, windows.IP_PKTINFO, 1); err != nil {
|
||||||
|
return errors.New("failed to set IP_PKTINFO").Base(err)
|
||||||
|
}
|
||||||
|
if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_IPV6, windows.IPV6_PKTINFO, 1); err != nil {
|
||||||
|
return errors.New("failed to set IPV6_PKTINFO").Base(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(config.CustomSockopt) > 0 {
|
if len(config.CustomSockopt) > 0 {
|
||||||
for _, custom := range config.CustomSockopt {
|
for _, custom := range config.CustomSockopt {
|
||||||
if custom.System != "" && custom.System != runtime.GOOS {
|
if custom.System != "" && custom.System != runtime.GOOS {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//go:build !linux && !freebsd && !darwin
|
//go:build !linux && !freebsd && !darwin && !windows
|
||||||
// +build !linux,!freebsd,!darwin
|
// +build !linux,!freebsd,!darwin,!windows
|
||||||
|
|
||||||
package udp
|
package udp
|
||||||
|
|
||||||
|
54
transport/internet/udp/hub_windows.go
Normal file
54
transport/internet/udp/hub_windows.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
//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
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user