Example #1
0
// An A record is generated when there is only one ZknsAddr, it
// has no port component and provides an IPv4 address.
func (rz *zknsResolver) getA(qname string) ([]*pdnsReply, error) {
	if !strings.HasSuffix(qname, rz.zknsDomain) {
		return nil, fmt.Errorf("invalid domain for query: %v", qname)
	}
	if qname[0] == '_' {
		// Since PDNS probes for all types, use some heuristics to limit error noise.
		relog.Debug("skipping A query: %v", qname)
		return nil, nil
	}
	zkname := qname[:len(qname)-len(rz.zknsDomain)]
	nameParts := reverse(strings.Split(zkname, "."))
	zkPath := path.Join(rz.zkRoot, path.Join(nameParts...))
	addrs, err := zkns.ReadAddrs(rz.zconn, zkPath)
	if err != nil {
		return nil, err
	}

	if len(addrs.Entries) != 1 || addrs.Entries[0].IPv4 == "" {
		// Since PDNS probes for all types, this isn't really an error worth mentioning.
		// return nil, fmt.Errorf("invalid response for CNAME query: %v", qname)
		return nil, nil
	}

	return []*pdnsReply{&pdnsReply{qname, "IN", "A", defaultTTL, defaultId, addrs.Entries[0].IPv4}}, nil
}
Example #2
0
func (rz *zknsResolver) getSRV(qname string) ([]*pdnsReply, error) {
	if !strings.HasSuffix(qname, rz.zknsDomain) {
		return nil, fmt.Errorf("invalid domain for query: %v", qname)
	}
	zkname := qname[:len(qname)-len(rz.zknsDomain)]
	nameParts := strings.Split(zkname, ".")
	portName := nameParts[0]
	if portName[0] != '_' {
		// Since PDNS probes for all types, this isn't really an error worth mentioning.
		// fmt.Errorf("invalid port name for query: %v", portName)
		relog.Debug("skipping SRV query: %v", qname)
		return nil, nil
	}
	nameParts = reverse(nameParts[1:])

	zkPath := path.Join(rz.zkRoot, path.Join(nameParts...))
	addrs, err := zkns.ReadAddrs(rz.zconn, zkPath)
	if err != nil {
		return nil, err
	}

	replies := make([]*pdnsReply, 0, 16)
	for _, addr := range addrs.Entries {
		content := fmt.Sprintf("%v\t%v %v %v", defaultPriority, defaultWeight, addr.NamedPortMap[portName], addr.Host)
		replies = append(replies, &pdnsReply{qname, "IN", "SRV", defaultTTL, defaultId, content})
	}
	return replies, nil
}
Example #3
0
// An CNAME record is generated when there is only one ZknsAddr, it
// has no port component. Multiple CNAMEs violate DNS protocols despite
// support in some versions of BIND.
func (rz *zknsResolver) getCNAME(qname string) ([]*pdnsReply, error) {
	if !strings.HasSuffix(qname, rz.zknsDomain) {
		return nil, fmt.Errorf("invalid domain for query: %v", qname)
	}
	if qname[0] == '_' {
		// Since PDNS probes for all types, use some heuristics to limit error noise.
		log.Infof("skipping CNAME query: %v", qname)
		return nil, nil
	}
	zkname := qname[:len(qname)-len(rz.zknsDomain)]
	nameParts := reverse(strings.Split(zkname, "."))
	zkPath := path.Join(rz.zkRoot, path.Join(nameParts...))
	addrs, err := zkns.ReadAddrs(rz.zconn, zkPath)
	if err != nil {
		return nil, err
	}

	if !addrs.IsValidCNAME() {
		log.Warningf("invalid CNAME record addrs at path %v", zkPath)
		// Since PDNS probes for all types, this isn't really an error worth propagating.
		// return nil, fmt.Errorf("invalid response for CNAME query: %v", qname)
		return nil, nil
	}

	return []*pdnsReply{&pdnsReply{qname, "IN", "CNAME", defaultTTL, defaultId, addrs.Entries[0].Host}}, nil
}
Example #4
0
// An A record is generated when there is only one ZknsAddr, it
// has no port component and provides an IPv4 address.
// FIXME(msolo) Multiple IP addresses could be handed out.
func (rz *zknsResolver) getA(qname string) ([]*pdnsReply, error) {
	if !strings.HasSuffix(qname, rz.zknsDomain) {
		return nil, fmt.Errorf("invalid domain for query: %v", qname)
	}
	if qname[0] == '_' {
		// Since PDNS probes for all types, use some heuristics to limit error noise.
		log.Infof("skipping A query, looks like SRV name: %v", qname)
		return nil, nil
	}
	zkname := qname[:len(qname)-len(rz.zknsDomain)]
	nameParts := reverse(strings.Split(zkname, "."))
	zkPath := path.Join(rz.zkRoot, path.Join(nameParts...))
	addrs, err := zkns.ReadAddrs(rz.zconn, zkPath)
	if err != nil {
		return nil, err
	}

	if !addrs.IsValidA() {
		log.Warningf("invalid A record addrs at path %v", zkPath)
		// Since PDNS probes for all types, this isn't really an error worth propagating.
		// return nil, fmt.Errorf("invalid response for A query: %v", qname)
		return nil, nil
	}

	replies := make([]*pdnsReply, len(addrs.Entries))
	for i, entry := range addrs.Entries {
		replies[i] = &pdnsReply{qname, "IN", "A", defaultTTL, defaultId, entry.IPv4}
	}
	// Shuffle replies since that seems like the only reasonable strategy in a
	// stateless distributed environment.
	for i := range replies {
		j := rand.Intn(i + 1)
		replies[i], replies[j] = replies[j], replies[i]
	}
	return replies, nil
}