refactor: doq dialer
This commit is contained in:
parent
2b8ac19566
commit
fe1099b0c5
2 changed files with 53 additions and 2 deletions
|
@ -5,6 +5,10 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/Dreamacro/clash/component/dialer"
|
||||||
|
"github.com/Dreamacro/clash/component/resolver"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -19,10 +23,20 @@ var bytesPool = sync.Pool{New: func() interface{} { return &bytes.Buffer{} }}
|
||||||
|
|
||||||
type quicClient struct {
|
type quicClient struct {
|
||||||
addr string
|
addr string
|
||||||
|
r *Resolver
|
||||||
session quic.Connection
|
session quic.Connection
|
||||||
|
proxyAdapter string
|
||||||
sync.RWMutex // protects session and bytesPool
|
sync.RWMutex // protects session and bytesPool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newDOQ(r *Resolver, addr, proxyAdapter string) *quicClient {
|
||||||
|
return &quicClient{
|
||||||
|
addr: addr,
|
||||||
|
r: r,
|
||||||
|
proxyAdapter: proxyAdapter,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (dc *quicClient) Exchange(m *D.Msg) (msg *D.Msg, err error) {
|
func (dc *quicClient) Exchange(m *D.Msg) (msg *D.Msg, err error) {
|
||||||
return dc.ExchangeContext(context.Background(), m)
|
return dc.ExchangeContext(context.Background(), m)
|
||||||
}
|
}
|
||||||
|
@ -127,7 +141,44 @@ func (dc *quicClient) openSession() (quic.Connection, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugln("opening session to %s", dc.addr)
|
log.Debugln("opening session to %s", dc.addr)
|
||||||
session, err := quic.DialAddrContext(context.Background(), dc.addr, tlsConfig, quicConfig)
|
var (
|
||||||
|
udp net.PacketConn
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
host, port, err := net.SplitHostPort(dc.addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ip, err := resolver.ResolveIPv4WithResolver(host, dc.r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
p, err := strconv.Atoi(port)
|
||||||
|
udpAddr := net.UDPAddr{IP: ip.AsSlice(), Port: p}
|
||||||
|
|
||||||
|
if dc.proxyAdapter == "" {
|
||||||
|
udp, err = dialer.ListenPacket(context.Background(), "udp", "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
conn, err := dialContextWithProxyAdapter(context.Background(), dc.proxyAdapter, "udp", ip, port)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapConn, ok := conn.(*wrapPacketConn)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("quio create packet failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
udp = wrapConn.PacketConn
|
||||||
|
}
|
||||||
|
|
||||||
|
session, err := quic.Dial(udp, &udpAddr, host, tlsConfig, quicConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to open QUIC session: %w", err)
|
return nil, fmt.Errorf("failed to open QUIC session: %w", err)
|
||||||
}
|
}
|
|
@ -64,7 +64,7 @@ func transform(servers []NameServer, resolver *Resolver) []dnsClient {
|
||||||
ret = append(ret, newDHCPClient(s.Addr))
|
ret = append(ret, newDHCPClient(s.Addr))
|
||||||
continue
|
continue
|
||||||
case "quic":
|
case "quic":
|
||||||
ret = append(ret, &quicClient{addr: s.Addr})
|
ret = append(ret, newDOQ(resolver, s.Addr, s.ProxyAdapter))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue