Refactor: use raw proxy adapter to get proxy connection by dns client

This commit is contained in:
yaling888 2022-05-18 20:35:59 +08:00
parent 3d2b4b1f3a
commit f788411154
2 changed files with 19 additions and 12 deletions

View File

@ -3,14 +3,12 @@ package adapter
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
"net/netip" "net/netip"
"net/url" "net/url"
"time" "time"
_ "unsafe"
"github.com/Dreamacro/clash/common/queue" "github.com/Dreamacro/clash/common/queue"
"github.com/Dreamacro/clash/component/dialer" "github.com/Dreamacro/clash/component/dialer"
@ -19,9 +17,6 @@ import (
"go.uber.org/atomic" "go.uber.org/atomic"
) )
//go:linkname errCanceled net.errCanceled
var errCanceled error
type Proxy struct { type Proxy struct {
C.ProxyAdapter C.ProxyAdapter
history *queue.Queue[C.DelayHistory] history *queue.Queue[C.DelayHistory]
@ -43,7 +38,7 @@ func (p *Proxy) Dial(metadata *C.Metadata) (C.Conn, error) {
// DialContext implements C.ProxyAdapter // DialContext implements C.ProxyAdapter
func (p *Proxy) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.Conn, error) { func (p *Proxy) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.Conn, error) {
conn, err := p.ProxyAdapter.DialContext(ctx, metadata, opts...) conn, err := p.ProxyAdapter.DialContext(ctx, metadata, opts...)
p.alive.Store(err == nil || errors.Is(err, errCanceled)) p.alive.Store(err == nil)
return conn, err return conn, err
} }

View File

@ -8,6 +8,7 @@ import (
"net/netip" "net/netip"
"time" "time"
"github.com/Dreamacro/clash/adapter"
"github.com/Dreamacro/clash/common/cache" "github.com/Dreamacro/clash/common/cache"
"github.com/Dreamacro/clash/common/nnip" "github.com/Dreamacro/clash/common/nnip"
"github.com/Dreamacro/clash/component/dialer" "github.com/Dreamacro/clash/component/dialer"
@ -132,16 +133,13 @@ func (wpc *wrapPacketConn) RemoteAddr() net.Addr {
} }
func dialContextWithProxyAdapter(ctx context.Context, adapterName string, network string, dstIP netip.Addr, port string, opts ...dialer.Option) (net.Conn, error) { func dialContextWithProxyAdapter(ctx context.Context, adapterName string, network string, dstIP netip.Addr, port string, opts ...dialer.Option) (net.Conn, error) {
adapter, ok := tunnel.Proxies()[adapterName] proxy, ok := tunnel.Proxies()[adapterName]
if !ok { if !ok {
return nil, fmt.Errorf("proxy adapter [%s] not found", adapterName) return nil, fmt.Errorf("proxy adapter [%s] not found", adapterName)
} }
networkType := C.TCP networkType := C.TCP
if network == "udp" { if network == "udp" {
if !adapter.SupportUDP() {
return nil, fmt.Errorf("proxy adapter [%s] UDP is not supported", adapterName)
}
networkType = C.UDP networkType = C.UDP
} }
@ -158,8 +156,14 @@ func dialContextWithProxyAdapter(ctx context.Context, adapterName string, networ
DstPort: port, DstPort: port,
} }
rawAdapter := fetchRawProxyAdapter(proxy.(*adapter.Proxy).ProxyAdapter, metadata)
if networkType == C.UDP { if networkType == C.UDP {
packetConn, err := adapter.ListenPacketContext(ctx, metadata, opts...) if !rawAdapter.SupportUDP() {
return nil, fmt.Errorf("proxy adapter [%s] UDP is not supported", rawAdapter.Name())
}
packetConn, err := rawAdapter.ListenPacketContext(ctx, metadata, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -170,5 +174,13 @@ func dialContextWithProxyAdapter(ctx context.Context, adapterName string, networ
}, nil }, nil
} }
return adapter.DialContext(ctx, metadata, opts...) return rawAdapter.DialContext(ctx, metadata, opts...)
}
func fetchRawProxyAdapter(proxyAdapter C.ProxyAdapter, metadata *C.Metadata) C.ProxyAdapter {
if p := proxyAdapter.Unwrap(metadata); p != nil {
return fetchRawProxyAdapter(p.(*adapter.Proxy).ProxyAdapter, metadata)
}
return proxyAdapter
} }