Moved DoH/DoT/UDP configuration from command line to PT-compatible SOCKS CONNECT configuration.

This commit is contained in:
Benjamin Erhart
2022-07-15 15:39:19 +02:00
parent 057566a0b2
commit c9c02b827b
2 changed files with 56 additions and 86 deletions
+54 -74
View File
@@ -119,10 +119,9 @@ func handle(local *net.TCPConn, sess *smux.Session, conv uint32) error {
return err
}
func acceptLoop(ln *pt.SocksListener, pconn net.PacketConn, remoteAddr net.Addr, shutdown chan struct{}, wg *sync.WaitGroup) {
func acceptLoop(ln *pt.SocksListener, utlsClientHelloID *utls.ClientHelloID, shutdown chan struct{}, wg *sync.WaitGroup) {
defer func() {
_ = ln.Close()
_ = pconn.Close()
}()
for {
@@ -146,6 +145,57 @@ func acceptLoop(ln *pt.SocksListener, pconn net.PacketConn, remoteAddr net.Addr,
}()
var pubkey []byte
var remoteAddr net.Addr
var pconn net.PacketConn
var err error
if arg, ok := local.Req.Args.Get("doh"); ok {
remoteAddr = turbotunnel.DummyAddr{}
var rt http.RoundTripper
if utlsClientHelloID == nil {
transport := http.DefaultTransport.(*http.Transport).Clone()
// Disable DefaultTransport's default Proxy =
// ProxyFromEnvironment setting, for conformity
// with utlsRoundTripper and with DoT mode,
// which do not take a proxy from the
// environment.
transport.Proxy = nil
rt = transport
} else {
rt = NewUTLSRoundTripper(nil, utlsClientHelloID)
}
pconn, err = NewHTTPPacketConn(rt, arg, 32)
} else if arg, ok := local.Req.Args.Get("dot"); ok {
remoteAddr = turbotunnel.DummyAddr{}
var dialTLSContext func(ctx context.Context, network, addr string) (net.Conn, error)
if utlsClientHelloID == nil {
dialTLSContext = (&tls.Dialer{}).DialContext
} else {
dialTLSContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
return utlsDialContext(ctx, network, addr, nil, utlsClientHelloID)
}
}
pconn, err = NewTLSPacketConn(arg, dialTLSContext)
} else if arg, ok := local.Req.Args.Get("udp"); ok {
remoteAddr, err = net.ResolveUDPAddr("udp", arg)
if err == nil {
pconn, err = net.ListenUDP("udp", nil)
}
}
if err != nil {
log.Printf("DNS server error: %v\n", err)
_ = local.Reject()
return
}
if remoteAddr == nil || pconn == nil {
log.Printf("Missing DNS server. Use 'doh', 'dot' or 'udp' argument to provide one!")
_ = local.Reject()
return
}
if arg, ok := local.Req.Args.Get("pubkey"); ok {
pubkey, err = noise.DecodeKey(arg)
@@ -279,7 +329,7 @@ func acceptLoop(ln *pt.SocksListener, pconn net.PacketConn, remoteAddr net.Addr,
}
}
func Start(dohURL, dotAddr, udpAddr, listenAddr string, utlsClientHelloID *utls.ClientHelloID) {
func Start(listenAddr string, utlsClientHelloID *utls.ClientHelloID) {
if listenAddr == "" {
listenAddr = "127.0.0.1:0"
@@ -296,76 +346,6 @@ func Start(dohURL, dotAddr, udpAddr, listenAddr string, utlsClientHelloID *utls.
log.Printf("uTLS fingerprint %s %s", utlsClientHelloID.Client, utlsClientHelloID.Version)
}
// Iterate over the remote resolver address options and select one and
// only one.
var remoteAddr net.Addr
var pconn net.PacketConn
for _, opt := range []struct {
s string
f func(string) (net.Addr, net.PacketConn, error)
}{
// -doh
{dohURL, func(s string) (net.Addr, net.PacketConn, error) {
addr := turbotunnel.DummyAddr{}
var rt http.RoundTripper
if utlsClientHelloID == nil {
transport := http.DefaultTransport.(*http.Transport).Clone()
// Disable DefaultTransport's default Proxy =
// ProxyFromEnvironment setting, for conformity
// with utlsRoundTripper and with DoT mode,
// which do not take a proxy from the
// environment.
transport.Proxy = nil
rt = transport
} else {
rt = NewUTLSRoundTripper(nil, utlsClientHelloID)
}
pconn, err := NewHTTPPacketConn(rt, dohURL, 32)
return addr, pconn, err
}},
// -dot
{dotAddr, func(s string) (net.Addr, net.PacketConn, error) {
addr := turbotunnel.DummyAddr{}
var dialTLSContext func(ctx context.Context, network, addr string) (net.Conn, error)
if utlsClientHelloID == nil {
dialTLSContext = (&tls.Dialer{}).DialContext
} else {
dialTLSContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
return utlsDialContext(ctx, network, addr, nil, utlsClientHelloID)
}
}
pconn, err := NewTLSPacketConn(dotAddr, dialTLSContext)
return addr, pconn, err
}},
// -udp
{udpAddr, func(s string) (net.Addr, net.PacketConn, error) {
addr, err := net.ResolveUDPAddr("udp", s)
if err != nil {
return nil, nil, err
}
pconn, err := net.ListenUDP("udp", nil)
return addr, pconn, err
}},
} {
if opt.s == "" {
continue
}
if pconn != nil {
log.Printf("only one of -doh, -dot, and -udp may be given\n")
return
}
var err error
remoteAddr, pconn, err = opt.f(opt.s)
if err != nil {
log.Print(err)
return
}
}
if pconn == nil {
log.Printf("one of -doh, -dot, or -udp is required\n")
return
}
// Begin goptlib client process.
ptInfo, err := pt.ClientSetup(nil)
if err != nil {
@@ -392,7 +372,7 @@ func Start(dohURL, dotAddr, udpAddr, listenAddr string, utlsClientHelloID *utls.
break
}
go acceptLoop(ln, pconn, remoteAddr, shutdown, &wg)
go acceptLoop(ln, utlsClientHelloID, shutdown, &wg)
pt.Cmethod(methodName, ln.Version(), ln.Addr())
listeners = append(listeners, ln)
+2 -12
View File
@@ -39,18 +39,11 @@ import (
)
func main() {
var dohURL string
var dotAddr string
var udpAddr string
var utlsDistribution string
flag.Usage = func() {
_, _ = fmt.Fprintf(flag.CommandLine.Output(), `Usage:
%[1]s [-doh URL|-dot ADDR|-udp ADDR]
Examples:
%[1]s -doh https://resolver.example/dns-query t.example.com
%[1]s -dot resolver.example:853 t.example.com
%[1]s [-utls FINGERPRINTS]
`, os.Args[0])
flag.PrintDefaults()
@@ -76,9 +69,6 @@ Known TLS fingerprints for -utls are:
_, _ = fmt.Fprintln(flag.CommandLine.Output(), line.String())
}
}
flag.StringVar(&dohURL, "doh", "", "URL of DoH resolver")
flag.StringVar(&dotAddr, "dot", "", "address of DoT resolver")
flag.StringVar(&udpAddr, "udp", "", "address of UDP DNS resolver")
flag.StringVar(&utlsDistribution, "utls",
"3*Firefox_65,1*Firefox_63,1*iOS_12_1",
"choose TLS fingerprint from weighted distribution")
@@ -95,5 +85,5 @@ Known TLS fingerprints for -utls are:
os.Exit(1)
}
dc.Start(dohURL, dotAddr, udpAddr, "", utlsClientHelloID)
dc.Start("", utlsClientHelloID)
}