From 6a2430b799c92a903ce5ae7889d34207e1759165 Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Mon, 16 Dec 2019 12:36:52 +0300 Subject: [PATCH] Merge: - clients: IPv6 address matching didn't work Close #1261 Squashed commit of the following: commit acc39ea6c0d88cb9d2b07837e89db2c170263891 Author: Simon Zolin Date: Mon Dec 16 12:29:33 2019 +0300 minor commit 0d2ef3d53185d5ca17797e2ac20f0efc1498a53c Author: Simon Zolin Date: Mon Dec 16 12:13:17 2019 +0300 add link to GH commit 0da754b1751057968780b457a2f490f4148275a8 Author: Simon Zolin Date: Mon Dec 16 11:53:42 2019 +0300 - clients: IPv6 address matching didn't work --- dnsforward/dnsforward.go | 23 ++++++++++++++++------- dnsforward/dnsforward_test.go | 12 ++++++++++++ home/clients_test.go | 13 ++++++------- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/dnsforward/dnsforward.go b/dnsforward/dnsforward.go index 8027bc5b..356b835f 100644 --- a/dnsforward/dnsforward.go +++ b/dnsforward/dnsforward.go @@ -400,8 +400,21 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { } } +// Get IP address from net.Addr object +// Note: we can't use net.SplitHostPort(a.String()) because of IPv6 zone: +// https://github.com/AdguardTeam/AdGuardHome/issues/1261 +func ipFromAddr(a net.Addr) string { + switch addr := a.(type) { + case *net.UDPAddr: + return addr.IP.String() + case *net.TCPAddr: + return addr.IP.String() + } + return "" +} + func (s *Server) beforeRequestHandler(p *proxy.Proxy, d *proxy.DNSContext) (bool, error) { - ip, _, _ := net.SplitHostPort(d.Addr.String()) + ip := ipFromAddr(d.Addr) if s.access.IsBlockedIP(ip) { log.Tracef("Client IP %s is blocked by settings", ip) return false, nil @@ -460,7 +473,7 @@ func (s *Server) handleDNSRequest(p *proxy.Proxy, d *proxy.DNSContext) error { } if d.Addr != nil && s.conf.GetUpstreamsByClient != nil { - clientIP, _, _ := net.SplitHostPort(d.Addr.String()) + clientIP := ipFromAddr(d.Addr) upstreams := s.conf.GetUpstreamsByClient(clientIP) for _, us := range upstreams { u, err := upstream.AddressToUpstream(us, upstream.Options{Timeout: 30 * time.Second}) @@ -596,14 +609,10 @@ func (s *Server) filterDNSRequest(d *proxy.DNSContext) (*dnsfilter.Result, error return &dnsfilter.Result{}, nil } - clientAddr := "" - if d.Addr != nil { - clientAddr, _, _ = net.SplitHostPort(d.Addr.String()) - } - setts := s.dnsFilter.GetConfig() setts.FilteringEnabled = true if s.conf.FilterHandler != nil { + clientAddr := ipFromAddr(d.Addr) s.conf.FilterHandler(clientAddr, &setts) } diff --git a/dnsforward/dnsforward_test.go b/dnsforward/dnsforward_test.go index 0e7339ce..155d6f95 100644 --- a/dnsforward/dnsforward_test.go +++ b/dnsforward/dnsforward_test.go @@ -784,3 +784,15 @@ func TestValidateUpstreamsSet(t *testing.T) { t.Fatalf("there is an invalid upstream in set, but it pass through validation") } } + +func TestIpFromAddr(t *testing.T) { + addr := net.UDPAddr{} + addr.IP = net.ParseIP("1:2:3::4") + addr.Port = 12345 + addr.Zone = "eth0" + a := ipFromAddr(&addr) + assert.True(t, a == "1:2:3::4") + + a = ipFromAddr(nil) + assert.True(t, a == "") +} diff --git a/home/clients_test.go b/home/clients_test.go index 99a5404d..2573d48f 100644 --- a/home/clients_test.go +++ b/home/clients_test.go @@ -17,7 +17,7 @@ func TestClients(t *testing.T) { // add c = Client{ - IDs: []string{"1.1.1.1", "aa:aa:aa:aa:aa:aa"}, + IDs: []string{"1.1.1.1", "1:2:3::4", "aa:aa:aa:aa:aa:aa"}, Name: "client1", } b, e = clients.Add(c) @@ -36,14 +36,13 @@ func TestClients(t *testing.T) { } c, b = clients.Find("1.1.1.1") - if !b || c.Name != "client1" { - t.Fatalf("Find #1") - } + assert.True(t, b && c.Name == "client1") + + c, b = clients.Find("1:2:3::4") + assert.True(t, b && c.Name == "client1") c, b = clients.Find("2.2.2.2") - if !b || c.Name != "client2" { - t.Fatalf("Find #2") - } + assert.True(t, b && c.Name == "client2") // failed add - name in use c = Client{