chore: proxyDialer can limited support old dial function

This commit is contained in:
gVisor bot 2023-04-11 12:51:24 +08:00
parent 72447a529d
commit 1151fc4e2f
15 changed files with 78 additions and 42 deletions

View file

@ -3,7 +3,6 @@ package outbound
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"errors"
"net" "net"
"strings" "strings"
@ -47,31 +46,31 @@ func (b *Base) Type() C.AdapterType {
// StreamConn implements C.ProxyAdapter // StreamConn implements C.ProxyAdapter
func (b *Base) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) { func (b *Base) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
return c, errors.New("no support") return c, C.ErrNotSupport
} }
func (b *Base) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.Conn, error) { func (b *Base) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.Conn, error) {
return nil, errors.New("no support") return nil, C.ErrNotSupport
} }
// DialContextWithDialer implements C.ProxyAdapter // DialContextWithDialer implements C.ProxyAdapter
func (b *Base) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.Conn, err error) { func (b *Base) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.Conn, err error) {
return nil, errors.New("no support") return nil, C.ErrNotSupport
} }
// ListenPacketContext implements C.ProxyAdapter // ListenPacketContext implements C.ProxyAdapter
func (b *Base) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) { func (b *Base) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) {
return nil, errors.New("no support") return nil, C.ErrNotSupport
} }
// ListenPacketWithDialer implements C.ProxyAdapter // ListenPacketWithDialer implements C.ProxyAdapter
func (b *Base) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.PacketConn, err error) { func (b *Base) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.PacketConn, err error) {
return nil, errors.New("no support") return nil, C.ErrNotSupport
} }
// SupportWithDialer implements C.ProxyAdapter // SupportWithDialer implements C.ProxyAdapter
func (b *Base) SupportWithDialer() bool { func (b *Base) SupportWithDialer() C.NetWork {
return false return C.InvalidNet
} }
// SupportUOT implements C.ProxyAdapter // SupportUOT implements C.ProxyAdapter

View file

@ -92,8 +92,8 @@ func (h *Http) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metad
} }
// SupportWithDialer implements C.ProxyAdapter // SupportWithDialer implements C.ProxyAdapter
func (h *Http) SupportWithDialer() bool { func (h *Http) SupportWithDialer() C.NetWork {
return true return C.TCP
} }
func (h *Http) shakeHand(metadata *C.Metadata, rw io.ReadWriter) error { func (h *Http) shakeHand(metadata *C.Metadata, rw io.ReadWriter) error {

View file

@ -205,8 +205,8 @@ func (ss *ShadowSocks) ListenPacketWithDialer(ctx context.Context, dialer C.Dial
} }
// SupportWithDialer implements C.ProxyAdapter // SupportWithDialer implements C.ProxyAdapter
func (ss *ShadowSocks) SupportWithDialer() bool { func (ss *ShadowSocks) SupportWithDialer() C.NetWork {
return true return C.ALLNet
} }
// ListenPacketOnStreamConn implements C.ProxyAdapter // ListenPacketOnStreamConn implements C.ProxyAdapter
@ -219,7 +219,7 @@ func (ss *ShadowSocks) ListenPacketOnStreamConn(c net.Conn, metadata *C.Metadata
return newPacketConn(uot.NewLazyConn(c, uot.Request{Destination: destination}), ss), nil return newPacketConn(uot.NewLazyConn(c, uot.Request{Destination: destination}), ss), nil
} }
} }
return nil, errors.New("no support") return nil, C.ErrNotSupport
} }
// SupportUOT implements C.ProxyAdapter // SupportUOT implements C.ProxyAdapter

View file

@ -116,8 +116,8 @@ func (ssr *ShadowSocksR) ListenPacketWithDialer(ctx context.Context, dialer C.Di
} }
// SupportWithDialer implements C.ProxyAdapter // SupportWithDialer implements C.ProxyAdapter
func (ssr *ShadowSocksR) SupportWithDialer() bool { func (ssr *ShadowSocksR) SupportWithDialer() C.NetWork {
return true return C.ALLNet
} }
func NewShadowSocksR(option ShadowSocksROption) (*ShadowSocksR, error) { func NewShadowSocksR(option ShadowSocksROption) (*ShadowSocksR, error) {

View file

@ -136,8 +136,8 @@ func (s *Snell) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, met
} }
// SupportWithDialer implements C.ProxyAdapter // SupportWithDialer implements C.ProxyAdapter
func (s *Snell) SupportWithDialer() bool { func (s *Snell) SupportWithDialer() C.NetWork {
return true return C.ALLNet
} }
// SupportUOT implements C.ProxyAdapter // SupportUOT implements C.ProxyAdapter

View file

@ -97,8 +97,8 @@ func (ss *Socks5) DialContextWithDialer(ctx context.Context, dialer C.Dialer, me
} }
// SupportWithDialer implements C.ProxyAdapter // SupportWithDialer implements C.ProxyAdapter
func (ss *Socks5) SupportWithDialer() bool { func (ss *Socks5) SupportWithDialer() C.NetWork {
return true return C.TCP
} }
// ListenPacketContext implements C.ProxyAdapter // ListenPacketContext implements C.ProxyAdapter

View file

@ -214,8 +214,8 @@ func (t *Trojan) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, me
} }
// SupportWithDialer implements C.ProxyAdapter // SupportWithDialer implements C.ProxyAdapter
func (t *Trojan) SupportWithDialer() bool { func (t *Trojan) SupportWithDialer() C.NetWork {
return true return C.ALLNet
} }
// ListenPacketOnStreamConn implements C.ProxyAdapter // ListenPacketOnStreamConn implements C.ProxyAdapter

View file

@ -86,8 +86,8 @@ func (t *Tuic) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, meta
} }
// SupportWithDialer implements C.ProxyAdapter // SupportWithDialer implements C.ProxyAdapter
func (t *Tuic) SupportWithDialer() bool { func (t *Tuic) SupportWithDialer() C.NetWork {
return true return C.ALLNet
} }
func (t *Tuic) dial(ctx context.Context, opts ...dialer.Option) (pc net.PacketConn, addr net.Addr, err error) { func (t *Tuic) dial(ctx context.Context, opts ...dialer.Option) (pc net.PacketConn, addr net.Addr, err error) {

View file

@ -345,8 +345,8 @@ func (v *Vless) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, met
} }
// SupportWithDialer implements C.ProxyAdapter // SupportWithDialer implements C.ProxyAdapter
func (v *Vless) SupportWithDialer() bool { func (v *Vless) SupportWithDialer() C.NetWork {
return true return C.ALLNet
} }
// ListenPacketOnStreamConn implements C.ProxyAdapter // ListenPacketOnStreamConn implements C.ProxyAdapter

View file

@ -368,8 +368,8 @@ func (v *Vmess) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, met
} }
// SupportWithDialer implements C.ProxyAdapter // SupportWithDialer implements C.ProxyAdapter
func (v *Vmess) SupportWithDialer() bool { func (v *Vmess) SupportWithDialer() C.NetWork {
return true return C.ALLNet
} }
// ListenPacketOnStreamConn implements C.ProxyAdapter // ListenPacketOnStreamConn implements C.ProxyAdapter

View file

@ -89,7 +89,10 @@ func (r *Relay) SupportUDP() bool {
if proxy.SupportUOT() { if proxy.SupportUOT() {
return true return true
} }
if !proxy.SupportWithDialer() { switch proxy.SupportWithDialer() {
case C.ALLNet:
case C.UDP:
default: // C.TCP and C.NONet
return false return false
} }
} }

View file

@ -321,15 +321,15 @@ func sortationAddr(ips []netip.Addr) (ipv4s, ipv6s []netip.Addr) {
} }
type Dialer struct { type Dialer struct {
opt option Opt option
} }
func (d Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) { func (d Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
return DialContext(ctx, network, address, WithOption(d.opt)) return DialContext(ctx, network, address, WithOption(d.Opt))
} }
func (d Dialer) ListenPacket(ctx context.Context, network, address string, rAddrPort netip.AddrPort) (net.PacketConn, error) { func (d Dialer) ListenPacket(ctx context.Context, network, address string, rAddrPort netip.AddrPort) (net.PacketConn, error) {
opt := WithOption(d.opt) opt := WithOption(d.Opt)
if rAddrPort.Addr().Unmap().IsLoopback() { if rAddrPort.Addr().Unmap().IsLoopback() {
// avoid "The requested address is not valid in its context." // avoid "The requested address is not valid in its context."
opt = WithInterface("") opt = WithInterface("")
@ -339,5 +339,5 @@ func (d Dialer) ListenPacket(ctx context.Context, network, address string, rAddr
func NewDialer(options ...Option) Dialer { func NewDialer(options ...Option) Dialer {
opt := applyOptions(options...) opt := applyOptions(options...)
return Dialer{opt: *opt} return Dialer{Opt: *opt}
} }

View file

@ -8,16 +8,17 @@ import (
"strings" "strings"
N "github.com/Dreamacro/clash/common/net" N "github.com/Dreamacro/clash/common/net"
"github.com/Dreamacro/clash/component/dialer"
C "github.com/Dreamacro/clash/constant" C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/tunnel" "github.com/Dreamacro/clash/tunnel"
) )
type proxyDialer struct { type proxyDialer struct {
proxy C.Proxy proxy C.ProxyAdapter
dialer C.Dialer dialer C.Dialer
} }
func New(proxy C.Proxy, dialer C.Dialer) C.Dialer { func New(proxy C.ProxyAdapter, dialer C.Dialer) C.Dialer {
return proxyDialer{proxy: proxy, dialer: dialer} return proxyDialer{proxy: proxy, dialer: dialer}
} }
@ -35,14 +36,23 @@ func (p proxyDialer) DialContext(ctx context.Context, network, address string) (
return nil, err return nil, err
} }
if strings.Contains(network, "udp") { // using in wireguard outbound if strings.Contains(network, "udp") { // using in wireguard outbound
currentMeta.NetWork = C.UDP pc, err := p.listenPacket(ctx, currentMeta)
pc, err := p.proxy.ListenPacketWithDialer(ctx, p.dialer, currentMeta)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return N.NewBindPacketConn(pc, currentMeta.UDPAddr()), nil return N.NewBindPacketConn(pc, currentMeta.UDPAddr()), nil
} }
switch p.proxy.SupportWithDialer() {
case C.ALLNet:
fallthrough
case C.TCP:
return p.proxy.DialContextWithDialer(ctx, p.dialer, currentMeta) return p.proxy.DialContextWithDialer(ctx, p.dialer, currentMeta)
default: // fallback to old function
if d, ok := p.dialer.(dialer.Dialer); ok { // fallback to old function
return p.proxy.DialContext(ctx, currentMeta, dialer.WithOption(d.Opt))
}
return nil, C.ErrNotSupport
}
} }
func (p proxyDialer) ListenPacket(ctx context.Context, network, address string, rAddrPort netip.AddrPort) (net.PacketConn, error) { func (p proxyDialer) ListenPacket(ctx context.Context, network, address string, rAddrPort netip.AddrPort) (net.PacketConn, error) {
@ -50,8 +60,22 @@ func (p proxyDialer) ListenPacket(ctx context.Context, network, address string,
if err != nil { if err != nil {
return nil, err return nil, err
} }
return p.listenPacket(ctx, currentMeta)
}
func (p proxyDialer) listenPacket(ctx context.Context, currentMeta *C.Metadata) (net.PacketConn, error) {
currentMeta.NetWork = C.UDP currentMeta.NetWork = C.UDP
switch p.proxy.SupportWithDialer() {
case C.ALLNet:
fallthrough
case C.UDP:
return p.proxy.ListenPacketWithDialer(ctx, p.dialer, currentMeta) return p.proxy.ListenPacketWithDialer(ctx, p.dialer, currentMeta)
default: // fallback to old function
if d, ok := p.dialer.(dialer.Dialer); ok { // fallback to old function
return p.proxy.ListenPacketContext(ctx, currentMeta, dialer.WithOption(d.Opt))
}
return nil, C.ErrNotSupport
}
} }
func addrToMetadata(rawAddress string) (addr *C.Metadata, err error) { func addrToMetadata(rawAddress string) (addr *C.Metadata, err error) {

View file

@ -2,6 +2,7 @@ package constant
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"net" "net"
"net/netip" "net/netip"
@ -44,6 +45,8 @@ const (
DefaultTLSTimeout = DefaultTCPTimeout DefaultTLSTimeout = DefaultTCPTimeout
) )
var ErrNotSupport = errors.New("no support")
type Connection interface { type Connection interface {
Chains() Chain Chains() Chain
AppendToChains(adapter ProxyAdapter) AppendToChains(adapter ProxyAdapter)
@ -117,7 +120,7 @@ type ProxyAdapter interface {
// SupportUOT return UDP over TCP support // SupportUOT return UDP over TCP support
SupportUOT() bool SupportUOT() bool
SupportWithDialer() bool SupportWithDialer() NetWork
DialContextWithDialer(ctx context.Context, dialer Dialer, metadata *Metadata) (Conn, error) DialContextWithDialer(ctx context.Context, dialer Dialer, metadata *Metadata) (Conn, error)
ListenPacketWithDialer(ctx context.Context, dialer Dialer, metadata *Metadata) (PacketConn, error) ListenPacketWithDialer(ctx context.Context, dialer Dialer, metadata *Metadata) (PacketConn, error)

View file

@ -15,7 +15,10 @@ const (
TCP NetWork = iota TCP NetWork = iota
UDP UDP
ALLNet ALLNet
InvalidNet = 0xff
)
const (
HTTP Type = iota HTTP Type = iota
HTTPS HTTPS
SOCKS4 SOCKS4
@ -33,12 +36,16 @@ const (
type NetWork int type NetWork int
func (n NetWork) String() string { func (n NetWork) String() string {
if n == TCP { switch n {
case TCP:
return "tcp" return "tcp"
} else if n == UDP { case UDP:
return "udp" return "udp"
} case ALLNet:
return "all" return "all"
default:
return "invalid"
}
} }
func (n NetWork) MarshalJSON() ([]byte, error) { func (n NetWork) MarshalJSON() ([]byte, error) {