Skip to content

Commit

Permalink
feat: add ip-version param
Browse files Browse the repository at this point in the history
  • Loading branch information
Skyxim committed Aug 28, 2022
1 parent 42e489e commit 99effb0
Show file tree
Hide file tree
Showing 20 changed files with 396 additions and 214 deletions.
42 changes: 29 additions & 13 deletions adapter/outbound/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ import (
)

type Base struct {
name string
addr string
iface string
tp C.AdapterType
udp bool
rmark int
id string
name string
addr string
iface string
tp C.AdapterType
udp bool
rmark int
id string
prefer C.DNSPrefer
}

// Name implements C.ProxyAdapter
Expand Down Expand Up @@ -103,12 +104,25 @@ func (b *Base) DialOptions(opts ...dialer.Option) []dialer.Option {
opts = append(opts, dialer.WithRoutingMark(b.rmark))
}

switch b.prefer {
case C.IPv4Only:
opts = append(opts, dialer.WithOnlySingleStack(true))
case C.IPv6Only:
opts = append(opts, dialer.WithOnlySingleStack(false))
case C.IPv4Prefer:
opts = append(opts, dialer.WithPreferIPv4())
case C.IPv6Prefer:
opts = append(opts, dialer.WithPreferIPv6())
default:
}

return opts
}

type BasicOption struct {
Interface string `proxy:"interface-name,omitempty" group:"interface-name,omitempty"`
RoutingMark int `proxy:"routing-mark,omitempty" group:"routing-mark,omitempty"`
IPVersion string `proxy:"ip-version,omitempty" group:"ip-version,omitempty"`
}

type BaseOption struct {
Expand All @@ -118,16 +132,18 @@ type BaseOption struct {
UDP bool
Interface string
RoutingMark int
Prefer C.DNSPrefer
}

func NewBase(opt BaseOption) *Base {
return &Base{
name: opt.Name,
addr: opt.Addr,
tp: opt.Type,
udp: opt.UDP,
iface: opt.Interface,
rmark: opt.RoutingMark,
name: opt.Name,
addr: opt.Addr,
tp: opt.Type,
udp: opt.UDP,
iface: opt.Interface,
rmark: opt.RoutingMark,
prefer: opt.Prefer,
}
}

Expand Down
14 changes: 8 additions & 6 deletions adapter/outbound/direct.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,21 @@ type directPacketConn struct {
func NewDirect() *Direct {
return &Direct{
Base: &Base{
name: "DIRECT",
tp: C.Direct,
udp: true,
name: "DIRECT",
tp: C.Direct,
udp: true,
prefer: C.DualStack,
},
}
}

func NewCompatible() *Direct {
return &Direct{
Base: &Base{
name: "COMPATIBLE",
tp: C.Compatible,
udp: true,
name: "COMPATIBLE",
tp: C.Compatible,
udp: true,
prefer: C.DualStack,
},
}
}
11 changes: 6 additions & 5 deletions adapter/outbound/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,12 @@ func NewHttp(option HttpOption) (*Http, error) {

return &Http{
Base: &Base{
name: option.Name,
addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)),
tp: C.Http,
iface: option.Interface,
rmark: option.RoutingMark,
name: option.Name,
addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)),
tp: C.Http,
iface: option.Interface,
rmark: option.RoutingMark,
prefer: C.NewDNSPrefer(option.IPVersion),
},
user: option.UserName,
pass: option.Password,
Expand Down
29 changes: 19 additions & 10 deletions adapter/outbound/hysteria.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ func (h *Hysteria) DialContext(ctx context.Context, metadata *C.Metadata, opts .
hyDialer: func() (net.PacketConn, error) {
return dialer.ListenPacket(ctx, "udp", "", h.Base.DialOptions(opts...)...)
},
remoteAddr: func(addr string) (net.Addr, error) {
return resolveUDPAddrWithPrefer("udp", addr, h.prefer)
},
}

tcpConn, err := h.client.DialTCP(metadata.RemoteAddress(), &hdc)
Expand Down Expand Up @@ -184,11 +187,11 @@ func NewHysteria(option HysteriaOption) (*Hysteria, error) {
option.Protocol = DefaultProtocol
}
if option.ReceiveWindowConn == 0 {
quicConfig.InitialStreamReceiveWindow = DefaultStreamReceiveWindow
quicConfig.InitialStreamReceiveWindow = DefaultStreamReceiveWindow / 10
quicConfig.MaxStreamReceiveWindow = DefaultStreamReceiveWindow
}
if option.ReceiveWindow == 0 {
quicConfig.InitialConnectionReceiveWindow = DefaultConnectionReceiveWindow
quicConfig.InitialConnectionReceiveWindow = DefaultConnectionReceiveWindow / 10
quicConfig.MaxConnectionReceiveWindow = DefaultConnectionReceiveWindow
}
if !quicConfig.DisablePathMTUDiscovery && pmtud_fix.DisablePathMTUDiscovery {
Expand Down Expand Up @@ -216,12 +219,13 @@ func NewHysteria(option HysteriaOption) (*Hysteria, error) {
}
return &Hysteria{
Base: &Base{
name: option.Name,
addr: addr,
tp: C.Hysteria,
udp: true,
iface: option.Interface,
rmark: option.RoutingMark,
name: option.Name,
addr: addr,
tp: C.Hysteria,
udp: true,
iface: option.Interface,
rmark: option.RoutingMark,
prefer: C.NewDNSPrefer(option.IPVersion),
},
client: client,
}, nil
Expand Down Expand Up @@ -287,8 +291,9 @@ func (c *hyPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
}

type hyDialerWithContext struct {
hyDialer func() (net.PacketConn, error)
ctx context.Context
hyDialer func() (net.PacketConn, error)
ctx context.Context
remoteAddr func(host string) (net.Addr, error)
}

func (h *hyDialerWithContext) ListenPacket() (net.PacketConn, error) {
Expand All @@ -298,3 +303,7 @@ func (h *hyDialerWithContext) ListenPacket() (net.PacketConn, error) {
func (h *hyDialerWithContext) Context() context.Context {
return h.ctx
}

func (h *hyDialerWithContext) RemoteAddr(host string) (net.Addr, error) {
return h.remoteAddr(host)
}
14 changes: 8 additions & 6 deletions adapter/outbound/reject.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,21 @@ func (r *Reject) ListenPacketContext(ctx context.Context, metadata *C.Metadata,
func NewReject() *Reject {
return &Reject{
Base: &Base{
name: "REJECT",
tp: C.Reject,
udp: true,
name: "REJECT",
tp: C.Reject,
udp: true,
prefer: C.DualStack,
},
}
}

func NewPass() *Reject {
return &Reject{
Base: &Base{
name: "PASS",
tp: C.Pass,
udp: true,
name: "PASS",
tp: C.Pass,
udp: true,
prefer: C.DualStack,
},
}
}
Expand Down
15 changes: 8 additions & 7 deletions adapter/outbound/shadowsocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func (ss *ShadowSocks) ListenPacketContext(ctx context.Context, metadata *C.Meta
return nil, err
}

addr, err := resolveUDPAddr("udp", ss.addr)
addr, err := resolveUDPAddrWithPrefer("udp", ss.addr, ss.prefer)
if err != nil {
pc.Close()
return nil, err
Expand Down Expand Up @@ -186,12 +186,13 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {

return &ShadowSocks{
Base: &Base{
name: option.Name,
addr: addr,
tp: C.Shadowsocks,
udp: option.UDP,
iface: option.Interface,
rmark: option.RoutingMark,
name: option.Name,
addr: addr,
tp: C.Shadowsocks,
udp: option.UDP,
iface: option.Interface,
rmark: option.RoutingMark,
prefer: C.NewDNSPrefer(option.IPVersion),
},
method: method,

Expand Down
15 changes: 8 additions & 7 deletions adapter/outbound/shadowsocksr.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (ssr *ShadowSocksR) ListenPacketContext(ctx context.Context, metadata *C.Me
return nil, err
}

addr, err := resolveUDPAddr("udp", ssr.addr)
addr, err := resolveUDPAddrWithPrefer("udp", ssr.addr, ssr.prefer)
if err != nil {
pc.Close()
return nil, err
Expand Down Expand Up @@ -143,12 +143,13 @@ func NewShadowSocksR(option ShadowSocksROption) (*ShadowSocksR, error) {

return &ShadowSocksR{
Base: &Base{
name: option.Name,
addr: addr,
tp: C.ShadowsocksR,
udp: option.UDP,
iface: option.Interface,
rmark: option.RoutingMark,
name: option.Name,
addr: addr,
tp: C.ShadowsocksR,
udp: option.UDP,
iface: option.Interface,
rmark: option.RoutingMark,
prefer: C.NewDNSPrefer(option.IPVersion),
},
cipher: coreCiph,
obfs: obfs,
Expand Down
13 changes: 7 additions & 6 deletions adapter/outbound/snell.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,13 @@ func NewSnell(option SnellOption) (*Snell, error) {

s := &Snell{
Base: &Base{
name: option.Name,
addr: addr,
tp: C.Snell,
udp: option.UDP,
iface: option.Interface,
rmark: option.RoutingMark,
name: option.Name,
addr: addr,
tp: C.Snell,
udp: option.UDP,
iface: option.Interface,
rmark: option.RoutingMark,
prefer: C.NewDNSPrefer(option.IPVersion),
},
psk: psk,
obfsOption: obfsOption,
Expand Down
13 changes: 7 additions & 6 deletions adapter/outbound/socks5.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,13 @@ func NewSocks5(option Socks5Option) (*Socks5, error) {

return &Socks5{
Base: &Base{
name: option.Name,
addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)),
tp: C.Socks5,
udp: option.UDP,
iface: option.Interface,
rmark: option.RoutingMark,
name: option.Name,
addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)),
tp: C.Socks5,
udp: option.UDP,
iface: option.Interface,
rmark: option.RoutingMark,
prefer: C.NewDNSPrefer(option.IPVersion),
},
user: option.UserName,
pass: option.Password,
Expand Down
13 changes: 7 additions & 6 deletions adapter/outbound/trojan.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,12 +209,13 @@ func NewTrojan(option TrojanOption) (*Trojan, error) {

t := &Trojan{
Base: &Base{
name: option.Name,
addr: addr,
tp: C.Trojan,
udp: option.UDP,
iface: option.Interface,
rmark: option.RoutingMark,
name: option.Name,
addr: addr,
tp: C.Trojan,
udp: option.UDP,
iface: option.Interface,
rmark: option.RoutingMark,
prefer: C.NewDNSPrefer(option.IPVersion),
},
instance: trojan.New(tOption),
option: &option,
Expand Down
54 changes: 54 additions & 0 deletions adapter/outbound/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/tls"
xtls "github.com/xtls/go"
"net"
"net/netip"
"strconv"
"sync"
"time"
Expand Down Expand Up @@ -74,6 +75,59 @@ func resolveUDPAddr(network, address string) (*net.UDPAddr, error) {
return net.ResolveUDPAddr(network, net.JoinHostPort(ip.String(), port))
}

func resolveUDPAddrWithPrefer(network, address string, prefer C.DNSPrefer) (*net.UDPAddr, error) {
host, port, err := net.SplitHostPort(address)
if err != nil {
return nil, err
}
var ip netip.Addr
switch prefer {
case C.IPv4Only:
ip, err = resolver.ResolveIPv4ProxyServerHost(host)
case C.IPv6Only:
ip, err = resolver.ResolveIPv6ProxyServerHost(host)
case C.IPv6Prefer:
var ips []netip.Addr
ips, err = resolver.ResolveAllIPProxyServerHost(host)
var fallback netip.Addr
if err == nil {
for _, addr := range ips {
if addr.Is6() {
ip = addr
break
} else {
if !fallback.IsValid() {
fallback = addr
}
}
}
ip = fallback
}
case C.IPv4Prefer | C.DualStack:
var ips []netip.Addr
ips, err = resolver.ResolveAllIPProxyServerHost(host)
var fallback netip.Addr
if err == nil {
for _, addr := range ips {
if addr.Is4() {
ip = addr
break
} else {
if !fallback.IsValid() {
fallback = addr
}
}
}
ip = fallback
}
}

if err != nil {
return nil, err
}
return net.ResolveUDPAddr(network, net.JoinHostPort(ip.String(), port))
}

func safeConnClose(c net.Conn, err error) {
if err != nil {
_ = c.Close()
Expand Down
Loading

0 comments on commit 99effb0

Please sign in to comment.