blob: 29550c18cc58dcaea2193b4ffeb86bf8dd4560e2 [file] [log] [blame]
// 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 (
"fmt"
"net"
"syslog"
"netstack/dns"
fidlnet "fidl/fuchsia/net"
)
type nameLookupImpl struct {
dnsClient *dns.Client
}
var _ fidlnet.NameLookup = (*nameLookupImpl)(nil)
func (sp *nameLookupImpl) LookupIp(hostname string, options fidlnet.LookupIpOptions) (fidlnet.NameLookupLookupIpResult, error) {
var result fidlnet.NameLookupLookupIpResult
ips, err := sp.dnsClient.LookupIP(hostname)
if err != nil {
syslog.ErrorTf("DNS", "lookup failed with internal error: %s", err)
result.SetErr(fidlnet.LookupErrorInternalError)
return result, nil
}
if len(ips) == 0 {
result.SetErr(fidlnet.LookupErrorNotFound)
return result, nil
}
var response fidlnet.NameLookupLookupIpResponse
for _, ip := range ips {
// TODO(wesleyac): Consider handling IPv4-mapped addresses as IPv4 addresses
if ip4 := ip.To4(); ip4 != "" && (options&fidlnet.LookupIpOptionsV4Addrs) != 0 {
var addr fidlnet.Ipv4Address
copy(addr.Addr[:], ip4)
response.Addr.Ipv4Addrs = append(response.Addr.Ipv4Addrs, addr)
} else if options&fidlnet.LookupIpOptionsV6Addrs != 0 {
var addr fidlnet.Ipv6Address
copy(addr.Addr[:], ip)
response.Addr.Ipv6Addrs = append(response.Addr.Ipv6Addrs, addr)
}
}
result.SetResponse(response)
return result, nil
}
// This only supports localhost right now, since the netstack DNS client doesn't support reverse DNS.
func (sp *nameLookupImpl) LookupHostname(addr fidlnet.IpAddress) (fidlnet.NameLookupLookupHostnameResult, error) {
var result fidlnet.NameLookupLookupHostnameResult
switch typ := addr.Which(); typ {
case fidlnet.IpAddressIpv4:
if net.IP(addr.Ipv4.Addr[:]).IsLoopback() {
result.SetResponse(fidlnet.NameLookupLookupHostnameResponse{Hostname: "localhost"})
return result, nil
}
case fidlnet.IpAddressIpv6:
if net.IP(addr.Ipv6.Addr[:]).IsLoopback() {
result.SetResponse(fidlnet.NameLookupLookupHostnameResponse{Hostname: "localhost"})
return result, nil
}
default:
panic(fmt.Sprintf("unknown address type: %v", typ))
}
result.SetErr(fidlnet.LookupErrorNotFound)
return result, nil
}