// Convert a nameserver request object into a nameserver model object. It can return // errors related to the conversion of IP addresses and normalization of nameserver's // hostname func (n *NameserverRequest) toNameserverModel() (model.Nameserver, error) { var nameserver model.Nameserver host, err := model.NormalizeDomainName(n.Host) if err != nil { return nameserver, err } nameserver.Host = host if len(n.IPv4) > 0 { ipv4 := net.ParseIP(n.IPv4) if ipv4 == nil { return nameserver, ErrInvalidIP } nameserver.IPv4 = ipv4 } if len(n.IPv6) > 0 { ipv6 := net.ParseIP(n.IPv6) if ipv6 == nil { return nameserver, ErrInvalidIP } nameserver.IPv6 = ipv6 } return nameserver, nil }
// Method used to retrieve addresses of a given nameserver, if the address does not exist // in the local cache the system will lookup for the domain and will store the result func (q *QuerierCache) Get(nameserver model.Nameserver, fqdn string) ([]net.IP, error) { q.hostsMutex.RLock() host, found := q.hosts[nameserver.Host] q.hostsMutex.RUnlock() if found { if host.timeoutsPerHostExceeded() { return nil, ErrHostTimeout } else if host.queriesPerSecondExceeded() { return nil, ErrHostQPSExceeded } else { return host.addresses, nil } } // Not found in cache, lets discover the address of this name sending DNS requests or // retrieving from the namserver object (glue record) var addresses []net.IP if nameserver.NeedsGlue(fqdn) { if nameserver.IPv4 != nil { addresses = append(addresses, nameserver.IPv4) } if nameserver.IPv6 != nil { addresses = append(addresses, nameserver.IPv6) } } // In case that the nameserver doesn't have a glue record we try to resolve the hostname if len(addresses) == 0 { var err error addresses, err = net.LookupIP(nameserver.Host) if err != nil { return nil, err } } q.hostsMutex.Lock() q.hosts[nameserver.Host] = &hostCache{ addresses: addresses, lastEpoch: 0, queriesPerSecond: 0, timeouts: 0, } q.hostsMutex.Unlock() return addresses, nil }