diff --git a/cmd/main.go b/cmd/main.go index fadf618..5d3768b 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -55,6 +55,7 @@ type CmdArgs struct { FakeDNSAddr *string FakeDNSHosts *string HijackDNS *string + BackendDNS *string // Session Statistics Monitor EnableMonitor *bool diff --git a/cmd/main_fakedns.go b/cmd/main_fakedns.go index 9dc5ab7..bd5738e 100644 --- a/cmd/main_fakedns.go +++ b/cmd/main_fakedns.go @@ -4,6 +4,7 @@ package main import ( "flag" + "strings" "github.com/xjasonlyu/tun2socks/component/fakedns" "github.com/xjasonlyu/tun2socks/log" @@ -15,6 +16,7 @@ func init() { args.FakeIPRange = flag.String("fakeIPRange", "198.18.0.0/15", "Fake IP CIDR range for DNS") args.FakeDNSHosts = flag.String("fakeDNSHosts", "", "DNS hosts mapping, e.g. 'example.com=1.1.1.1,example.net=2.2.2.2'") args.HijackDNS = flag.String("hijackDNS", "", "Hijack the DNS query to get a fake ip, e.g. '*:53' or '8.8.8.8:53,8.8.4.4:53'") + args.BackendDNS = flag.String("backendDNS", "8.8.8.8:53", "Backend DNS to resolve !TypeA or !ClassINET query. (must support tcp)") registerInitFn(func() { if *args.EnableFakeDNS { @@ -26,6 +28,7 @@ func init() { // Set fakeDNS variables fakedns.ServeAddr = *args.FakeDNSAddr + fakedns.BackendDNS = strings.Split(*args.BackendDNS, ",") // Start fakeDNS server if err := fakeDNS.Start(); err != nil { diff --git a/component/fakedns/middleware.go b/component/fakedns/middleware.go index a91e89d..809e195 100644 --- a/component/fakedns/middleware.go +++ b/component/fakedns/middleware.go @@ -11,20 +11,28 @@ import ( ) var ( - nameserver = "8.8.8.8:53" + BackendDNS = []string{} ) -func dnsExchange(r *D.Msg) *D.Msg { +func dnsExchange(r *D.Msg) (msg *D.Msg) { + defer func() { + if msg == nil { + // empty DNS response + rr := &D.A{} + rr.Hdr = D.RR_Header{Name: r.Question[0].Name, Rrtype: D.TypeA, Class: D.ClassINET, Ttl: dnsDefaultTTL} + msg = r.Copy() + msg.Answer = []D.RR{rr} + setMsgTTL(msg, dnsDefaultTTL) + } + }() + c := new(D.Client) c.Net = "tcp" - msg, _, err := c.Exchange(r, nameserver) - if err != nil { - // empty DNS response - rr := &D.A{} - rr.Hdr = D.RR_Header{Name: r.Question[0].Name, Rrtype: D.TypeA, Class: D.ClassINET, Ttl: dnsDefaultTTL} - msg = r.Copy() - msg.Answer = []D.RR{rr} - setMsgTTL(msg, dnsDefaultTTL) + for _, dns := range BackendDNS { + msg, _, _ = c.Exchange(r, dns) + if msg != nil { + break + } } return msg }