| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package netstack |
| |
| import ( |
| "context" |
| "net" |
| "testing" |
| |
| "netstack/dns" |
| |
| fidlnet "fidl/fuchsia/net" |
| |
| "golang.org/x/net/dns/dnsmessage" |
| "gvisor.dev/gvisor/pkg/tcpip/network/arp" |
| "gvisor.dev/gvisor/pkg/tcpip/network/ipv4" |
| "gvisor.dev/gvisor/pkg/tcpip/network/ipv6" |
| "gvisor.dev/gvisor/pkg/tcpip/stack" |
| ) |
| |
| func TestLookupHostname(t *testing.T) { |
| ns := stack.New(stack.Options{ |
| NetworkProtocols: []stack.NetworkProtocol{ |
| arp.NewProtocol(), |
| ipv4.NewProtocol(), |
| ipv6.NewProtocol(), |
| }, |
| }) |
| dnsClient := dns.NewClient(ns) |
| ni := nameLookupImpl{dnsClient: dnsClient} |
| |
| var v4loopback fidlnet.IpAddress |
| v4loopback.SetIpv4(fidlnet.Ipv4Address{ |
| Addr: ipv4LoopbackBytes, |
| }) |
| host, err := ni.LookupHostname(context.Background(), v4loopback) |
| AssertNoError(t, err) |
| switch typ := host.Which(); typ { |
| case fidlnet.NameLookupLookupHostnameResultResponse: |
| break |
| case fidlnet.NameLookupLookupHostnameResultErr: |
| t.Fatalf("LookupHostname(%s) returned error: %s", net.IP(v4loopback.Ipv4.Addr[:]), host.Err) |
| default: |
| t.Fatalf("LookupHostname(%s) returned unexpected variant %d", net.IP(v4loopback.Ipv4.Addr[:]), typ) |
| } |
| if host.Response.Hostname != "localhost" { |
| t.Errorf("LookupHostname(%s) != localhost (got %s)", net.IP(v4loopback.Ipv4.Addr[:]), host.Response.Hostname) |
| } |
| |
| var v6loopback fidlnet.IpAddress |
| v6loopback.SetIpv6(fidlnet.Ipv6Address{Addr: ipv6LoopbackBytes}) |
| host, err = ni.LookupHostname(context.Background(), v6loopback) |
| AssertNoError(t, err) |
| switch typ := host.Which(); typ { |
| case fidlnet.NameLookupLookupHostnameResultResponse: |
| break |
| case fidlnet.NameLookupLookupHostnameResultErr: |
| t.Fatalf("LookupHostname(%s) returned error: %s", net.IP(v4loopback.Ipv4.Addr[:]), host.Err) |
| default: |
| t.Fatalf("LookupHostname(%s) returned unexpected variant %d", net.IP(v4loopback.Ipv4.Addr[:]), typ) |
| } |
| if host.Response.Hostname != "localhost" { |
| t.Errorf("LookupHostname(%s) != localhost (got %s)", net.IP(v6loopback.Ipv6.Addr[:]), host.Response.Hostname) |
| } |
| } |
| |
| func TestLookupIpLocalhost(t *testing.T) { |
| ns := stack.New(stack.Options{ |
| NetworkProtocols: []stack.NetworkProtocol{ |
| arp.NewProtocol(), |
| ipv4.NewProtocol(), |
| ipv6.NewProtocol(), |
| }, |
| }) |
| dnsClient := dns.NewClient(ns) |
| ni := nameLookupImpl{dnsClient: dnsClient} |
| |
| testHostname := "localhost" |
| ip, err := ni.LookupIp(context.Background(), testHostname, fidlnet.LookupIpOptionsV4Addrs) |
| AssertNoError(t, err) |
| switch typ := ip.Which(); typ { |
| case fidlnet.NameLookupLookupIpResultResponse: |
| break |
| case fidlnet.NameLookupLookupIpResultErr: |
| t.Fatalf("LookupIp(%#v) returned error: %s", testHostname, ip.Err) |
| default: |
| t.Fatalf("LookupIp(%#v) returned unexpected variant %d", testHostname, typ) |
| } |
| if want, got := 1, len(ip.Response.Addr.Ipv4Addrs); got != want { |
| t.Fatalf("got len(LookupIp(%#v)) = %d, want = %d", testHostname, got, want) |
| } |
| if want, got := ipv4LoopbackBytes, ip.Response.Addr.Ipv4Addrs[0].Addr; got != want { |
| t.Errorf("got LookupIp(%#v) = %s, want = %s", testHostname, got, want) |
| } |
| } |
| |
| func TestLookupIp(t *testing.T) { |
| ns := stack.New(stack.Options{ |
| NetworkProtocols: []stack.NetworkProtocol{ |
| arp.NewProtocol(), |
| ipv4.NewProtocol(), |
| ipv6.NewProtocol(), |
| }, |
| }) |
| dnsClient := dns.NewClient(ns) |
| testaddr := [4]byte{192, 0, 2, 1} |
| dnsClient.SetResolver(func(question dnsmessage.Question) (dnsmessage.Name, []dnsmessage.Resource, dnsmessage.Message, error) { |
| r := dnsmessage.Message{ |
| Header: dnsmessage.Header{ |
| ID: 0, |
| Response: true, |
| }, |
| Questions: []dnsmessage.Question{question}, |
| } |
| |
| if question.Type == dnsmessage.TypeA { |
| r.Answers = []dnsmessage.Resource{ |
| { |
| Header: dnsmessage.ResourceHeader{ |
| Name: question.Name, |
| Type: dnsmessage.TypeA, |
| Class: dnsmessage.ClassINET, |
| Length: 4, |
| }, |
| Body: &dnsmessage.AResource{ |
| A: testaddr, |
| }, |
| }, |
| } |
| } |
| |
| return question.Name, r.Answers, r, nil |
| }) |
| ni := nameLookupImpl{dnsClient: dnsClient} |
| |
| testHostname := "example.com" |
| ip, err := ni.LookupIp(context.Background(), testHostname, fidlnet.LookupIpOptionsV4Addrs) |
| AssertNoError(t, err) |
| switch typ := ip.Which(); typ { |
| case fidlnet.NameLookupLookupIpResultResponse: |
| break |
| case fidlnet.NameLookupLookupIpResultErr: |
| t.Fatalf("LookupIp(%#v) returned error: %s", testHostname, ip.Err) |
| default: |
| t.Fatalf("LookupIp(%#v) returned unexpected variant %d", testHostname, typ) |
| } |
| if want, got := 1, len(ip.Response.Addr.Ipv4Addrs); got != want { |
| t.Fatalf("got len(LookupIp(%#v)) = %d, want = %d", testHostname, got, want) |
| } |
| if want, got := testaddr, ip.Response.Addr.Ipv4Addrs[0].Addr; want != got { |
| t.Errorf("got LookupIp(%#v) = %s, want = %s", testHostname, got, want) |
| } |
| } |