dns: add a parameter in dns struct to identify tunnel

This commit is contained in:
nadoo 2018-01-08 23:37:58 +08:00
parent 050489806c
commit a652f8db04
3 changed files with 36 additions and 19 deletions

43
dns.go
View File

@ -4,6 +4,8 @@ package main
import ( import (
"encoding/binary" "encoding/binary"
"encoding/hex"
"fmt"
"io" "io"
"net" "net"
"strings" "strings"
@ -56,6 +58,8 @@ type DNS struct {
*Forwarder // as proxy client *Forwarder // as proxy client
sDialer Dialer // dialer for server sDialer Dialer // dialer for server
tunnel bool
dnsServer string dnsServer string
dnsServerMap map[string]string dnsServerMap map[string]string
@ -63,11 +67,13 @@ type DNS struct {
} }
// NewDNS returns a dns forwarder. client[dns.udp] -> glider[tcp] -> forwarder[dns.tcp] -> remote dns addr // NewDNS returns a dns forwarder. client[dns.udp] -> glider[tcp] -> forwarder[dns.tcp] -> remote dns addr
func NewDNS(addr, raddr string, sDialer Dialer) (*DNS, error) { func NewDNS(addr, raddr string, sDialer Dialer, tunnel bool) (*DNS, error) {
s := &DNS{ s := &DNS{
Forwarder: NewForwarder(addr, nil), Forwarder: NewForwarder(addr, nil),
sDialer: sDialer, sDialer: sDialer,
tunnel: tunnel,
dnsServer: raddr, dnsServer: raddr,
dnsServerMap: make(map[string]string), dnsServerMap: make(map[string]string),
} }
@ -90,7 +96,7 @@ func (s *DNS) ListenAndServeUDP() {
} }
defer c.Close() defer c.Close()
logf("proxy-dns listening UDP on %s", s.addr) logf("proxy-dns listening on udp:%s", s.addr)
for { for {
data := make([]byte, DNSUDPMaxLen) data := make([]byte, DNSUDPMaxLen)
@ -107,9 +113,9 @@ func (s *DNS) ListenAndServeUDP() {
query := parseQuery(data) query := parseQuery(data)
domain := query.DomainName domain := query.DomainName
dnsServer := s.dnsServer dnsServer := s.GetServer(domain)
if dnsServer == "" { if s.tunnel {
dnsServer = s.GetServer(domain) dnsServer = s.dnsServer
} }
rc, err := s.sDialer.NextDialer(domain+":53").Dial("tcp", dnsServer) rc, err := s.sDialer.NextDialer(domain+":53").Dial("tcp", dnsServer)
@ -122,6 +128,7 @@ func (s *DNS) ListenAndServeUDP() {
// 2 bytes length after tcp header, before dns message // 2 bytes length after tcp header, before dns message
reqLen := make([]byte, 2) reqLen := make([]byte, 2)
binary.BigEndian.PutUint16(reqLen, uint16(len(data))) binary.BigEndian.PutUint16(reqLen, uint16(len(data)))
rc.Write(reqLen) rc.Write(reqLen)
rc.Write(data) rc.Write(data)
@ -187,7 +194,7 @@ func (s *DNS) ListenAndServeTCP() {
return return
} }
logf("proxy-dns-tcp listening TCP on %s", s.addr) logf("proxy-dns-tcp listening on tcp:%s", s.addr)
for { for {
c, err := l.Accept() c, err := l.Accept()
@ -223,9 +230,9 @@ func (s *DNS) ServeTCP(c net.Conn) {
query := parseQuery(reqMsg) query := parseQuery(reqMsg)
domain := query.DomainName domain := query.DomainName
dnsServer := s.dnsServer dnsServer := s.GetServer(domain)
if dnsServer == "" { if s.tunnel {
dnsServer = s.GetServer(domain) dnsServer = s.dnsServer
} }
rc, err := s.sDialer.NextDialer(domain+":53").Dial("tcp", dnsServer) rc, err := s.sDialer.NextDialer(domain+":53").Dial("tcp", dnsServer)
@ -235,8 +242,12 @@ func (s *DNS) ServeTCP(c net.Conn) {
} }
defer rc.Close() defer rc.Close()
binary.Write(rc, binary.BigEndian, reqLen) if err := binary.Write(rc, binary.BigEndian, reqLen); err != nil {
binary.Write(rc, binary.BigEndian, reqMsg)
}
if err := binary.Write(rc, binary.BigEndian, reqMsg); err != nil {
}
var respLen uint16 var respLen uint16
if err := binary.Read(rc, binary.BigEndian, &respLen); err != nil { if err := binary.Read(rc, binary.BigEndian, &respLen); err != nil {
@ -251,6 +262,8 @@ func (s *DNS) ServeTCP(c net.Conn) {
return return
} }
fmt.Printf("dns resp len %d:\n%s\n\n", respLen, hex.Dump(respMsg[:]))
var ip string var ip string
if respLen > 0 { if respLen > 0 {
query := parseQuery(respMsg) query := parseQuery(respMsg)
@ -270,8 +283,12 @@ func (s *DNS) ServeTCP(c net.Conn) {
} }
} }
binary.Write(c, binary.BigEndian, respLen) if err := binary.Write(c, binary.BigEndian, respLen); err != nil {
binary.Write(c, binary.BigEndian, respMsg) logf("proxy-dns-tcp error in local write respLen: %s\n", err)
}
if err := binary.Write(c, binary.BigEndian, respMsg); err != nil {
logf("proxy-dns-tcp error in local write respMsg: %s\n", err)
}
} }
logf("proxy-dns-tcp %s <-> %s, type: %d, %s: %s", c.RemoteAddr(), dnsServer, query.QueryType, domain, ip) logf("proxy-dns-tcp %s <-> %s, type: %d, %s: %s", c.RemoteAddr(), dnsServer, query.QueryType, domain, ip)

View File

@ -22,7 +22,7 @@ func NewDNSTun(addr, raddr string, sDialer Dialer) (*DNSTun, error) {
raddr: raddr, raddr: raddr,
} }
s.dns, _ = NewDNS(addr, raddr, sDialer) s.dns, _ = NewDNS(addr, raddr, sDialer, true)
return s, nil return s, nil
} }

10
main.go
View File

@ -49,16 +49,16 @@ func main() {
} }
if conf.DNS != "" { if conf.DNS != "" {
dns, err := NewDNS(conf.DNS, conf.DNSServer[0], sDialer) dns, err := NewDNS(conf.DNS, conf.DNSServer[0], sDialer, false)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
// rule // rule
for _, fwdr := range conf.rules { for _, r := range conf.rules {
for _, domain := range fwdr.Domain { for _, domain := range r.Domain {
if len(fwdr.DNSServer) > 0 { if len(r.DNSServer) > 0 {
dns.SetServer(domain, fwdr.DNSServer[0]) dns.SetServer(domain, r.DNSServer[0])
} }
} }
} }