Skip to content

Commit

Permalink
Support multiple A entries refer: #17
Browse files Browse the repository at this point in the history
  • Loading branch information
kenshinx committed Oct 14, 2015
1 parent dcf31e1 commit 21448a5
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 30 deletions.
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,6 @@ host-file = "/etc/hosts"
Hosts file format is described in [linux man pages](http://man7.org/linux/man-pages/man5/hosts.5.html).
More than that , `*.` wildcard is supported additional.

```
127.0.0.1 *.example.com
```


__redis hosts__

Expand All @@ -114,6 +110,18 @@ _Insert hosts records into redis_
redis > hset godns:hosts www.test.com 1.1.1.1
```

Compared with file-backend records, redis-backend hosts support two advanced records formatting.

1. `*.` wildcard

```
redis > hset 127.0.0.1 *.example.com
```
2. Multiple A entries, delimited by commas

```
redis > hset www.test.com 1.1.1.1,2.2.2.2
```


## Benchmark
Expand Down
14 changes: 9 additions & 5 deletions handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func (h *GODNSHandler) do(Net string, w dns.ResponseWriter, req *dns.Msg) {

// Query hosts
if settings.Hosts.Enable && IPQuery > 0 {
if ip, ok := h.hosts.Get(Q.qname, IPQuery); ok {
if ips, ok := h.hosts.Get(Q.qname, IPQuery); ok {
m := new(dns.Msg)
m.SetReply(req)

Expand All @@ -110,17 +110,21 @@ func (h *GODNSHandler) do(Net string, w dns.ResponseWriter, req *dns.Msg) {
Class: dns.ClassINET,
Ttl: settings.Hosts.TTL,
}
a := &dns.A{rr_header, ip}
m.Answer = append(m.Answer, a)
for _, ip := range ips {
a := &dns.A{rr_header, ip}
m.Answer = append(m.Answer, a)
}
case _IP6Query:
rr_header := dns.RR_Header{
Name: q.Name,
Rrtype: dns.TypeAAAA,
Class: dns.ClassINET,
Ttl: settings.Hosts.TTL,
}
aaaa := &dns.AAAA{rr_header, ip}
m.Answer = append(m.Answer, aaaa)
for _, ip := range ips {
aaaa := &dns.AAAA{rr_header, ip}
m.Answer = append(m.Answer, aaaa)
}
}

w.WriteMsg(m)
Expand Down
54 changes: 33 additions & 21 deletions hosts.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,29 +34,38 @@ func NewHosts(hs HostsSettings, rs RedisSettings) Hosts {
/*
Match local /etc/hosts file first, remote redis records second
*/
func (h *Hosts) Get(domain string, family int) (ip net.IP, ok bool) {
func (h *Hosts) Get(domain string, family int) ([]net.IP, bool) {

var sip string
var sips []string
var ip net.IP
var ips []net.IP

if sip, ok = h.fileHosts.Get(domain); !ok {
sips, ok := h.fileHosts.Get(domain)
if !ok {
if h.redisHosts != nil {
sip, ok = h.redisHosts.Get(domain)
sips, ok = h.redisHosts.Get(domain)
}
}

if sip == "" {
if sips == nil {
return nil, false
}

switch family {
case _IP4Query:
ip = net.ParseIP(sip).To4()
case _IP6Query:
ip = net.ParseIP(sip).To16()
default:
return nil, false
for _, sip := range sips {
switch family {
case _IP4Query:
ip = net.ParseIP(sip).To4()
case _IP6Query:
ip = net.ParseIP(sip).To16()
default:
continue
}
if ip != nil {
ips = append(ips, ip)
}
}
return ip, (ip != nil)

return ips, (ips != nil)
}

/*
Expand Down Expand Up @@ -85,21 +94,21 @@ type RedisHosts struct {
hosts map[string]string
}

func (r *RedisHosts) Get(domain string) (ip string, ok bool) {
ip, ok = r.hosts[domain]
func (r *RedisHosts) Get(domain string) ([]string, bool) {
ip, ok := r.hosts[domain]
if ok {
return
return strings.Split(ip, ","), true
}

for host, ip := range r.hosts {
if strings.HasPrefix(host, "*.") {
upperLevelDomain := strings.Split(host, "*.")[1]
if strings.HasSuffix(domain, upperLevelDomain) {
return ip, true
return strings.Split(ip, ","), true
}
}
}
return
return nil, false
}

func (r *RedisHosts) Set(domain, ip string) (bool, error) {
Expand All @@ -120,9 +129,12 @@ type FileHosts struct {
hosts map[string]string
}

func (f *FileHosts) Get(domain string) (ip string, ok bool) {
ip, ok = f.hosts[domain]
return
func (f *FileHosts) Get(domain string) ([]string, bool) {
ip, ok := f.hosts[domain]
if !ok {
return nil, false
}
return []string{ip}, true
}

func (f *FileHosts) Refresh() {
Expand Down

0 comments on commit 21448a5

Please sign in to comment.