Преглед на файлове

Merge pull request #891 from mavenugo/tcpdns

Adding TCP listener to the resolver
aboch преди 9 години
родител
ревизия
079ec162bc
променени са 1 файла, в които са добавени 34 реда и са изтрити 7 реда
  1. 34 7
      libnetwork/resolver.go

+ 34 - 7
libnetwork/resolver.go

@@ -41,11 +41,13 @@ const (
 
 
 // resolver implements the Resolver interface
 // resolver implements the Resolver interface
 type resolver struct {
 type resolver struct {
-	sb     *sandbox
-	extDNS []string
-	server *dns.Server
-	conn   *net.UDPConn
-	err    error
+	sb        *sandbox
+	extDNS    []string
+	server    *dns.Server
+	conn      *net.UDPConn
+	tcpServer *dns.Server
+	tcpListen *net.TCPListener
+	err       error
 }
 }
 
 
 // NewResolver creates a new instance of the Resolver
 // NewResolver creates a new instance of the Resolver
@@ -60,6 +62,7 @@ func (r *resolver) SetupFunc() func() {
 	return (func() {
 	return (func() {
 		var err error
 		var err error
 
 
+		// DNS operates primarily on UDP
 		addr := &net.UDPAddr{
 		addr := &net.UDPAddr{
 			IP: net.ParseIP(resolverIP),
 			IP: net.ParseIP(resolverIP),
 		}
 		}
@@ -72,9 +75,23 @@ func (r *resolver) SetupFunc() func() {
 		laddr := r.conn.LocalAddr()
 		laddr := r.conn.LocalAddr()
 		_, ipPort, _ := net.SplitHostPort(laddr.String())
 		_, ipPort, _ := net.SplitHostPort(laddr.String())
 
 
+		// Listen on a TCP as well
+		tcpaddr := &net.TCPAddr{
+			IP: net.ParseIP(resolverIP),
+		}
+
+		r.tcpListen, err = net.ListenTCP("tcp", tcpaddr)
+		if err != nil {
+			r.err = fmt.Errorf("error in opening name TCP server socket %v", err)
+			return
+		}
+		ltcpaddr := r.tcpListen.Addr()
+		_, tcpPort, _ := net.SplitHostPort(ltcpaddr.String())
 		rules := [][]string{
 		rules := [][]string{
 			{"-t", "nat", "-A", "OUTPUT", "-d", resolverIP, "-p", "udp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", laddr.String()},
 			{"-t", "nat", "-A", "OUTPUT", "-d", resolverIP, "-p", "udp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", laddr.String()},
 			{"-t", "nat", "-A", "POSTROUTING", "-s", resolverIP, "-p", "udp", "--sport", ipPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
 			{"-t", "nat", "-A", "POSTROUTING", "-s", resolverIP, "-p", "udp", "--sport", ipPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
+			{"-t", "nat", "-A", "OUTPUT", "-d", resolverIP, "-p", "tcp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", ltcpaddr.String()},
+			{"-t", "nat", "-A", "POSTROUTING", "-s", resolverIP, "-p", "tcp", "--sport", tcpPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
 		}
 		}
 
 
 		for _, rule := range rules {
 		for _, rule := range rules {
@@ -97,6 +114,12 @@ func (r *resolver) Start() error {
 	go func() {
 	go func() {
 		s.ActivateAndServe()
 		s.ActivateAndServe()
 	}()
 	}()
+
+	tcpServer := &dns.Server{Handler: r, Listener: r.tcpListen}
+	r.tcpServer = tcpServer
+	go func() {
+		tcpServer.ActivateAndServe()
+	}()
 	return nil
 	return nil
 }
 }
 
 
@@ -104,7 +127,11 @@ func (r *resolver) Stop() {
 	if r.server != nil {
 	if r.server != nil {
 		r.server.Shutdown()
 		r.server.Shutdown()
 	}
 	}
+	if r.tcpServer != nil {
+		r.tcpServer.Shutdown()
+	}
 	r.conn = nil
 	r.conn = nil
+	r.tcpServer = nil
 	r.err = fmt.Errorf("setup not done yet")
 	r.err = fmt.Errorf("setup not done yet")
 }
 }
 
 
@@ -195,9 +222,9 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
 			num = len(r.extDNS)
 			num = len(r.extDNS)
 		}
 		}
 		for i := 0; i < num; i++ {
 		for i := 0; i < num; i++ {
-			log.Debugf("Querying ext dns %s for %s[%d]", r.extDNS[i], name, query.Question[0].Qtype)
+			log.Debugf("Querying ext dns %s:%s for %s[%d]", w.LocalAddr().Network(), r.extDNS[i], name, query.Question[0].Qtype)
 
 
-			c := &dns.Client{Net: "udp"}
+			c := &dns.Client{Net: w.LocalAddr().Network()}
 			addr := fmt.Sprintf("%s:%d", r.extDNS[i], 53)
 			addr := fmt.Sprintf("%s:%d", r.extDNS[i], 53)
 
 
 			resp, _, err = c.Exchange(query, addr)
 			resp, _, err = c.Exchange(query, addr)