mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-10-27 21:46:58 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d830eea02 |
@@ -558,19 +558,16 @@ func ioctlPtr(fd int, req uint, arg unsafe.Pointer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setinterface(network, address string, fd uintptr, iface *net.Interface) error {
|
func setinterface(network, address string, fd uintptr, iface *net.Interface) error {
|
||||||
var err1, err2 error
|
|
||||||
|
|
||||||
switch network {
|
switch network {
|
||||||
case "tcp6", "udp6", "ip6":
|
case "tcp6", "udp6", "ip6":
|
||||||
err1 = unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_BOUND_IF, iface.Index)
|
// IPV6_BOUND_IF binds the IPv4 traffic of a dual-stack socket as
|
||||||
fallthrough
|
// well, and an IPv6 socket rejects IP_BOUND_IF with EINVAL.
|
||||||
|
return unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_BOUND_IF, iface.Index)
|
||||||
case "tcp4", "udp4", "ip4":
|
case "tcp4", "udp4", "ip4":
|
||||||
err2 = unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_BOUND_IF, iface.Index)
|
return unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_BOUND_IF, iface.Index)
|
||||||
default:
|
default:
|
||||||
panic(network + " " + address)
|
panic(network + " " + address)
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors.Join(err1, err2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func findOutboundInterface(tunIndex int, fixedName string) (*net.Interface, error) {
|
func findOutboundInterface(tunIndex int, fixedName string) (*net.Interface, error) {
|
||||||
|
|||||||
@@ -3,7 +3,10 @@
|
|||||||
package tun
|
package tun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -231,3 +234,40 @@ func TestWaitKqueueReportsPersistentFailure(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestSetinterfaceSocketFamilies binds each kind of socket Xray's dialers
|
||||||
|
// open to lo0, including the dual-stack one Go opens for UDP.
|
||||||
|
func TestSetinterfaceSocketFamilies(t *testing.T) {
|
||||||
|
lo, err := net.InterfaceByName("lo0")
|
||||||
|
if err != nil {
|
||||||
|
t.Skip(err)
|
||||||
|
}
|
||||||
|
lc := net.ListenConfig{Control: func(network, address string, c syscall.RawConn) error {
|
||||||
|
var err error
|
||||||
|
if controlErr := c.Control(func(fd uintptr) {
|
||||||
|
err = setinterface(network, address, fd, lo)
|
||||||
|
}); controlErr != nil {
|
||||||
|
return controlErr
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}}
|
||||||
|
for _, s := range []struct{ network, address string }{
|
||||||
|
{"udp", "0.0.0.0:0"}, // dual-stack
|
||||||
|
{"udp4", "127.0.0.1:0"},
|
||||||
|
{"udp6", "[::1]:0"},
|
||||||
|
{"tcp4", "127.0.0.1:0"},
|
||||||
|
{"tcp6", "[::1]:0"},
|
||||||
|
} {
|
||||||
|
var closer interface{ Close() error }
|
||||||
|
if s.network[:3] == "udp" {
|
||||||
|
closer, err = lc.ListenPacket(context.Background(), s.network, s.address)
|
||||||
|
} else {
|
||||||
|
closer, err = lc.Listen(context.Background(), s.network, s.address)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%s %s: %v", s.network, s.address, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
closer.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user