Skip to content

Commit

Permalink
Fix ipv6 dns entries (#1371)
Browse files Browse the repository at this point in the history
Signed-off-by: Artem Glazychev <artem.glazychev@xored.com>

Signed-off-by: Artem Glazychev <artem.glazychev@xored.com>
  • Loading branch information
glazychev-art authored Nov 21, 2022
1 parent e51c7ad commit 1d79bf8
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ import (
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/metadata"
"github.com/networkservicemesh/sdk/pkg/tools/dnsconfig"
"github.com/networkservicemesh/sdk/pkg/tools/dnsutils"
dnschain "github.com/networkservicemesh/sdk/pkg/tools/dnsutils/chain"
"github.com/networkservicemesh/sdk/pkg/tools/dnsutils/dnsconfigs"
"github.com/networkservicemesh/sdk/pkg/tools/dnsutils/fanout"
"github.com/networkservicemesh/sdk/pkg/tools/dnsutils/memory"
dnsnext "github.com/networkservicemesh/sdk/pkg/tools/dnsutils/next"
"github.com/networkservicemesh/sdk/pkg/tools/dnsutils/noloop"
"github.com/networkservicemesh/sdk/pkg/tools/dnsutils/norecursion"
"github.com/networkservicemesh/sdk/pkg/tools/ippool"
Expand Down Expand Up @@ -70,7 +70,7 @@ func NewServer(chanCtx context.Context, getDNSServerIP func() net.IP, opts ...Op
}

if result.dnsServer == nil {
result.dnsServer = dnsnext.NewDNSHandler(
result.dnsServer = dnschain.NewDNSHandler(
dnsconfigs.NewDNSHandler(result.dnsConfigs),
noloop.NewDNSHandler(),
norecursion.NewDNSHandler(),
Expand Down
22 changes: 13 additions & 9 deletions pkg/tools/dnsutils/memory/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ func (f *memoryHandler) ServeDNS(ctx context.Context, rw dns.ResponseWriter, msg
if !ok {
next.Handler(ctx).ServeDNS(ctx, rwWrapper, msg)
if !rwWrapper.passed {
dns.HandleFailed(rw, msg)
// Send NXDomain because we didn't find anything
m := new(dns.Msg)
_ = rw.WriteMsg(m.SetRcode(msg, dns.RcodeNameError))
}
return
}
Expand All @@ -81,7 +83,9 @@ func (f *memoryHandler) ServeDNS(ctx context.Context, rw dns.ResponseWriter, msg
if len(resp.Answer) == 0 {
next.Handler(ctx).ServeDNS(ctx, rwWrapper, msg)
if !rwWrapper.passed {
dns.HandleFailed(rw, msg)
// Send NXDomain because we didn't find anything
m := new(dns.Msg)
_ = rw.WriteMsg(m.SetRcode(msg, dns.RcodeNameError))
}
return
}
Expand All @@ -99,29 +103,29 @@ func NewDNSHandler(records *Map) dnsutils.Handler {
return &memoryHandler{records: records}
}
func a(domain string, ips []net.IP) []dns.RR {
answers := make([]dns.RR, len(ips))
for i, ip := range ips {
var answers []dns.RR
for _, ip := range ips {
if ip.To4() == nil {
continue
}
r := new(dns.A)
r.Hdr = dns.RR_Header{Name: domain, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: defaultTTL}
r.A = ip
answers[i] = r
answers = append(answers, r)
}
return answers
}

func aaaa(domain string, ips []net.IP) []dns.RR {
answers := make([]dns.RR, len(ips))
for i, ip := range ips {
if ip.To16() == nil {
var answers []dns.RR
for _, ip := range ips {
if ip.To4() != nil {
continue
}
r := new(dns.AAAA)
r.Hdr = dns.RR_Header{Name: domain, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: defaultTTL}
r.AAAA = ip
answers[i] = r
answers = append(answers, r)
}
return answers
}
88 changes: 88 additions & 0 deletions pkg/tools/dnsutils/memory/handler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright (c) 2022 Cisco and/or its affiliates.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package memory_test

import (
"context"
"net"
"testing"
"time"

"github.com/miekg/dns"
"github.com/stretchr/testify/require"

"github.com/networkservicemesh/sdk/pkg/tools/dnsutils/memory"
"github.com/networkservicemesh/sdk/pkg/tools/dnsutils/next"
)

type responseWriter struct {
dns.ResponseWriter
Response *dns.Msg
}

func (r *responseWriter) WriteMsg(m *dns.Msg) error {
r.Response = m
return nil
}

func TestDomainSearches(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()

// Store two entries for IPv4 and IPv6
records := new(memory.Map)
records.Store("example.com.", []net.IP{net.ParseIP("1.1.1.1")})
records.Store("example.net.", []net.IP{net.ParseIP("2001:db8::68")})

handler := next.NewDNSHandler(
memory.NewDNSHandler(records),
)
rw := &responseWriter{}
m := &dns.Msg{}

// Get example.com IPv4. Expect success
m.SetQuestion(dns.Fqdn("example.com"), dns.TypeA)
handler.ServeDNS(ctx, rw, m)

resp := rw.Response.Copy()
require.Equal(t, resp.MsgHdr.Rcode, dns.RcodeSuccess)
require.NotNil(t, resp.Answer)
require.Equal(t, resp.Answer[0].(*dns.A).A.String(), "1.1.1.1")

// Get example.com IPv6. Expect NXDomain
m.SetQuestion(dns.Fqdn("example.com"), dns.TypeAAAA)
handler.ServeDNS(ctx, rw, m)

resp = rw.Response.Copy()
require.Equal(t, resp.MsgHdr.Rcode, dns.RcodeNameError)

// Get example.net IPv4. Expect NXDomain
m.SetQuestion(dns.Fqdn("example.net"), dns.TypeA)
handler.ServeDNS(ctx, rw, m)

resp = rw.Response.Copy()
require.Equal(t, resp.MsgHdr.Rcode, dns.RcodeNameError)

// Get example.net IPv6. Expect success
m.SetQuestion(dns.Fqdn("example.net"), dns.TypeAAAA)
handler.ServeDNS(ctx, rw, m)

resp = rw.Response.Copy()
require.Equal(t, resp.MsgHdr.Rcode, dns.RcodeSuccess)
require.NotNil(t, resp.Answer)
require.Equal(t, resp.Answer[0].(*dns.AAAA).AAAA.String(), "2001:db8::68")
}

0 comments on commit 1d79bf8

Please sign in to comment.