From 3dbba5d8d2f36588ca850be60563ca7c6699e554 Mon Sep 17 00:00:00 2001 From: yaling888 <73897884+yaling888@users.noreply.github.com> Date: Fri, 3 Jun 2022 11:27:41 +0800 Subject: [PATCH] Chore: mix the proxy adapter and interface to dns client --- README.md | 4 ++-- dns/client.go | 10 +++++++--- dns/doh.go | 18 +++++++++++++----- dns/util.go | 5 ++++- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 84cdc612..9efa6928 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ mitm: ``` ### DNS configuration -Support resolve ip with a proxy tunnel. +Support resolve ip with a proxy tunnel or interface. Support `geosite` with `fallback-filter`. @@ -96,8 +96,8 @@ Use `curl -X POST controllerip:port/cache/fakeip/flush` to flush persistence fak - https://doh.pub/dns-query - tls://223.5.5.5:853 fallback: + - 'tls://8.8.4.4:853#proxy or interface' - 'https://1.0.0.1/dns-query#Proxy' # append the proxy adapter name to the end of DNS URL with '#' prefix. - - 'tls://8.8.4.4:853#Proxy' fallback-filter: geoip: false geosite: diff --git a/dns/client.go b/dns/client.go index b536f0b1..4795e58c 100644 --- a/dns/client.go +++ b/dns/client.go @@ -54,10 +54,14 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error) } var conn net.Conn - if c.proxyAdapter == "" { - conn, err = dialer.DialContext(ctx, network, net.JoinHostPort(ip.String(), c.port), options...) - } else { + if c.proxyAdapter != "" { conn, err = dialContextWithProxyAdapter(ctx, c.proxyAdapter, network, ip, c.port, options...) + if err == errProxyNotFound { + options = append(options[:0], dialer.WithInterface(c.proxyAdapter), dialer.WithRoutingMark(0)) + conn, err = dialer.DialContext(ctx, network, net.JoinHostPort(ip.String(), c.port), options...) + } + } else { + conn, err = dialer.DialContext(ctx, network, net.JoinHostPort(ip.String(), c.port), options...) } if err != nil { diff --git a/dns/doh.go b/dns/doh.go index 51352a0e..28c23164 100644 --- a/dns/doh.go +++ b/dns/doh.go @@ -69,7 +69,9 @@ func (dc *dohClient) doRequest(req *http.Request) (msg *D.Msg, err error) { if err != nil { return nil, err } - defer resp.Body.Close() + defer func() { + _ = resp.Body.Close() + }() buf, err := io.ReadAll(resp.Body) if err != nil { @@ -97,11 +99,17 @@ func newDoHClient(url string, r *Resolver, proxyAdapter string) *dohClient { return nil, err } - if proxyAdapter == "" { - return dialer.DialContext(ctx, "tcp", net.JoinHostPort(ip.String(), port)) - } else { - return dialContextWithProxyAdapter(ctx, proxyAdapter, "tcp", ip, port) + if proxyAdapter != "" { + var conn net.Conn + conn, err = dialContextWithProxyAdapter(ctx, proxyAdapter, "tcp", ip, port) + if err == errProxyNotFound { + options := []dialer.Option{dialer.WithInterface(proxyAdapter), dialer.WithRoutingMark(0)} + conn, err = dialer.DialContext(ctx, "tcp", net.JoinHostPort(ip.String(), port), options...) + } + return conn, err } + + return dialer.DialContext(ctx, "tcp", net.JoinHostPort(ip.String(), port)) }, }, } diff --git a/dns/util.go b/dns/util.go index 515bb88f..f573fe7a 100644 --- a/dns/util.go +++ b/dns/util.go @@ -3,6 +3,7 @@ package dns import ( "context" "crypto/tls" + "errors" "fmt" "net" "net/netip" @@ -19,6 +20,8 @@ import ( D "github.com/miekg/dns" ) +var errProxyNotFound = errors.New("proxy adapter not found") + func putMsgToCache(c *cache.LruCache[string, *D.Msg], key string, msg *D.Msg) { var ttl uint32 switch { @@ -135,7 +138,7 @@ 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) { proxy, ok := tunnel.Proxies()[adapterName] if !ok { - return nil, fmt.Errorf("proxy adapter [%s] not found", adapterName) + return nil, errProxyNotFound } networkType := C.TCP