-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathipin.go
90 lines (74 loc) · 2.35 KB
/
ipin.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Package whoami implements a plugin that returns details about the resolving
// querying it.
package ipin
import (
"github.com/coredns/coredns/request"
"net"
"github.com/coredns/coredns/plugin"
"github.com/miekg/dns"
"golang.org/x/net/context"
"regexp"
"strconv"
"strings"
)
const Name = "ipin"
type IpInName struct {
// When process failed, will call next plugin
Fallback bool
Ttl uint32
Next plugin.Handler
}
var regIpDash = regexp.MustCompile(`^(\d{1,3}-\d{1,3}-\d{1,3}-\d{1,3})(-\d+)?\.`)
var regIpv6Dash = regexp.MustCompile(`^([a-f\d]{1,4}-[a-f\d]{0,4}-[a-f\d]{0,4}-?[a-f\d]{0,4}-?[a-f\d]{0,4}-?[a-f\d]{0,4}-?[a-f\d]{0,4}-?[a-f\d]{0,4})\.`)
func (self IpInName) Name() string { return Name }
func (self IpInName) Resolve(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (*dns.Msg, int, error) {
state := request.Request{W: w, Req: r}
a := new(dns.Msg)
a.SetReply(r)
a.Compress = true
a.Authoritative = true
matches := regIpDash.FindStringSubmatch(state.QName())
matches_v6 := regIpv6Dash.FindStringSubmatch(state.QName())
if len(matches) > 1 {
ip := matches[1]
ip = strings.Replace(ip, "-", ".", -1)
var rr dns.RR
rr = new(dns.A)
rr.(*dns.A).Hdr = dns.RR_Header{Name: state.QName(), Rrtype: dns.TypeA, Class: state.QClass(), Ttl: self.Ttl}
rr.(*dns.A).A = net.ParseIP(ip).To4()
a.Answer = []dns.RR{rr}
if len(matches[2]) > 0 {
srv := new(dns.SRV)
srv.Hdr = dns.RR_Header{Name: "_port." + state.QName(), Rrtype: dns.TypeSRV, Class: state.QClass(), Ttl: self.Ttl}
if state.QName() == "." {
srv.Hdr.Name = "_port." + state.QName()
}
port, _ := strconv.Atoi(matches[2][1:])
srv.Port = uint16(port)
srv.Target = "."
a.Extra = []dns.RR{srv}
}
} else if len(matches_v6) > 1 {
ip := matches_v6[1]
ip = strings.Replace(ip, "-", ":", -1)
var rr dns.RR
rr = new(dns.AAAA)
rr.(*dns.AAAA).Hdr = dns.RR_Header{Name: state.QName(), Rrtype: dns.TypeAAAA, Class: state.QClass(), Ttl: self.Ttl}
rr.(*dns.AAAA).AAAA = net.ParseIP(ip).To16()
a.Answer = []dns.RR{rr}
} else {
// return empty
}
return a, 0, nil
}
func (self IpInName) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
a, i, err := self.Resolve(ctx, w, r)
if err != nil {
return i, err
}
if self.Fallback && len(a.Answer) == 0 {
return self.Next.ServeDNS(ctx, w, r)
} else {
return 0, w.WriteMsg(a)
}
}