fix: fix bindIfaceToListenConfig() in windows force bind to an ipv4 address

This commit is contained in:
wwqgtxx 2022-12-13 11:18:32 +08:00
parent f87144f84b
commit 88acf8e098
9 changed files with 34 additions and 30 deletions

View file

@ -27,7 +27,7 @@ func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ...
// ListenPacketContext implements C.ProxyAdapter // ListenPacketContext implements C.ProxyAdapter
func (d *Direct) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) { func (d *Direct) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) {
opts = append(opts, dialer.WithResolver(resolver.DefaultResolver)) opts = append(opts, dialer.WithResolver(resolver.DefaultResolver))
pc, err := dialer.ListenPacket(ctx, "udp", "", d.Base.DialOptions(opts...)...) pc, err := dialer.ListenPacket(ctx, dialer.ParseNetwork("udp", metadata.DstIP), "", d.Base.DialOptions(opts...)...)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -334,9 +334,7 @@ type hyDialerWithContext struct {
func (h *hyDialerWithContext) ListenPacket(rAddr net.Addr) (net.PacketConn, error) { func (h *hyDialerWithContext) ListenPacket(rAddr net.Addr) (net.PacketConn, error) {
network := "udp" network := "udp"
if addrPort, err := netip.ParseAddrPort(rAddr.String()); err == nil { if addrPort, err := netip.ParseAddrPort(rAddr.String()); err == nil {
if addrPort.Addr().Unmap().Is6() { network = dialer.ParseNetwork(network, addrPort.Addr())
network = "udp6"
}
} }
return h.hyDialer(network) return h.hyDialer(network)
} }

View file

@ -105,14 +105,13 @@ func (ss *ShadowSocks) ListenPacketContext(ctx context.Context, metadata *C.Meta
} }
return newPacketConn(uot.NewClientConn(tcpConn), ss), nil return newPacketConn(uot.NewClientConn(tcpConn), ss), nil
} }
pc, err := dialer.ListenPacket(ctx, "udp", "", ss.Base.DialOptions(opts...)...) addr, err := resolveUDPAddrWithPrefer(ctx, "udp", ss.addr, ss.prefer)
if err != nil { if err != nil {
return nil, err return nil, err
} }
addr, err := resolveUDPAddrWithPrefer(ctx, "udp", ss.addr, ss.prefer) pc, err := dialer.ListenPacket(ctx, dialer.ParseNetwork("udp", addr.AddrPort().Addr()), "", ss.Base.DialOptions(opts...)...)
if err != nil { if err != nil {
pc.Close()
return nil, err return nil, err
} }
pc = ss.method.DialPacketConn(&bufio.BindPacketConn{PacketConn: pc, Addr: addr}) pc = ss.method.DialPacketConn(&bufio.BindPacketConn{PacketConn: pc, Addr: addr})

View file

@ -74,14 +74,13 @@ func (ssr *ShadowSocksR) DialContext(ctx context.Context, metadata *C.Metadata,
// ListenPacketContext implements C.ProxyAdapter // ListenPacketContext implements C.ProxyAdapter
func (ssr *ShadowSocksR) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) { func (ssr *ShadowSocksR) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) {
pc, err := dialer.ListenPacket(ctx, "udp", "", ssr.Base.DialOptions(opts...)...) addr, err := resolveUDPAddrWithPrefer(ctx, "udp", ssr.addr, ssr.prefer)
if err != nil { if err != nil {
return nil, err return nil, err
} }
addr, err := resolveUDPAddrWithPrefer(ctx, "udp", ssr.addr, ssr.prefer) pc, err := dialer.ListenPacket(ctx, dialer.ParseNetwork("udp", addr.AddrPort().Addr()), "", ssr.Base.DialOptions(opts...)...)
if err != nil { if err != nil {
pc.Close()
return nil, err return nil, err
} }

View file

@ -114,19 +114,6 @@ func (ss *Socks5) ListenPacketContext(ctx context.Context, metadata *C.Metadata,
return return
} }
pc, err := dialer.ListenPacket(ctx, "udp", "", ss.Base.DialOptions(opts...)...)
if err != nil {
return
}
go func() {
io.Copy(io.Discard, c)
c.Close()
// A UDP association terminates when the TCP connection that the UDP
// ASSOCIATE request arrived on terminates. RFC1928
pc.Close()
}()
// Support unspecified UDP bind address. // Support unspecified UDP bind address.
bindUDPAddr := bindAddr.UDPAddr() bindUDPAddr := bindAddr.UDPAddr()
if bindUDPAddr == nil { if bindUDPAddr == nil {
@ -141,6 +128,19 @@ func (ss *Socks5) ListenPacketContext(ctx context.Context, metadata *C.Metadata,
bindUDPAddr.IP = serverAddr.IP bindUDPAddr.IP = serverAddr.IP
} }
pc, err := dialer.ListenPacket(ctx, dialer.ParseNetwork("udp", bindUDPAddr.AddrPort().Addr()), "", ss.Base.DialOptions(opts...)...)
if err != nil {
return
}
go func() {
io.Copy(io.Discard, c)
c.Close()
// A UDP association terminates when the TCP connection that the UDP
// ASSOCIATE request arrived on terminates. RFC1928
pc.Close()
}()
return newPacketConn(&socksPacketConn{PacketConn: pc, rAddr: bindUDPAddr, tcpConn: c}, ss), nil return newPacketConn(&socksPacketConn{PacketConn: pc, rAddr: bindUDPAddr, tcpConn: c}, ss), nil
} }

View file

@ -79,11 +79,7 @@ func (t *Tuic) dial(ctx context.Context, opts ...dialer.Option) (pc net.PacketCo
return nil, nil, err return nil, nil, err
} }
addr = udpAddr addr = udpAddr
network := "udp" pc, err = dialer.ListenPacket(ctx, dialer.ParseNetwork("udp", udpAddr.AddrPort().Addr()), "", opts...)
if udpAddr.AddrPort().Addr().Unmap().Is6() {
network = "udp6"
}
pc, err = dialer.ListenPacket(ctx, network, "", opts...)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

View file

@ -65,7 +65,7 @@ func (d *wgDialer) DialContext(ctx context.Context, network string, destination
} }
func (d *wgDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { func (d *wgDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
return dialer.ListenPacket(ctx, "udp", "", d.options...) return dialer.ListenPacket(ctx, dialer.ParseNetwork("udp", destination.Addr), "", d.options...)
} }
func NewWireGuard(option WireGuardOption) (*WireGuard, error) { func NewWireGuard(option WireGuardOption) (*WireGuard, error) {

View file

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"net" "net"
"net/netip" "net/netip"
"runtime"
"strings" "strings"
"sync" "sync"
@ -24,6 +25,17 @@ var (
ErrorDisableIPv6 = errors.New("IPv6 is disabled, dialer cancel") ErrorDisableIPv6 = errors.New("IPv6 is disabled, dialer cancel")
) )
func ParseNetwork(network string, addr netip.Addr) string {
if runtime.GOOS == "windows" { // fix bindIfaceToListenConfig() in windows force bind to an ipv4 address
if !strings.HasSuffix(network, "4") &&
!strings.HasSuffix(network, "6") &&
addr.Unmap().Is6() {
network += "6"
}
}
return network
}
func ApplyOptions(options ...Option) *option { func ApplyOptions(options ...Option) *option {
opt := &option{ opt := &option{
interfaceName: DefaultInterface.Load(), interfaceName: DefaultInterface.Load(),

View file

@ -207,7 +207,7 @@ func dialContextExtra(ctx context.Context, adapterName string, network string, a
DstPort: port, DstPort: port,
} }
if !ok { if !ok {
packetConn, err := dialer.ListenPacket(ctx, network, metadata.RemoteAddress(), opts...) packetConn, err := dialer.ListenPacket(ctx, dialer.ParseNetwork(network, dstIP), "", opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }