chore: proxyDialer can limited support old dial function
This commit is contained in:
parent
ab3fce29ab
commit
92cc268209
15 changed files with 78 additions and 42 deletions
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue