-
Notifications
You must be signed in to change notification settings - Fork 63
/
net-resolver.go
111 lines (93 loc) · 2.28 KB
/
net-resolver.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package rdns
import (
"context"
"errors"
"net"
"time"
"github.com/miekg/dns"
)
func NewNetDialer(r Resolver) *net.Dialer {
return &net.Dialer{
Resolver: NewNetResolver(r),
}
}
// NewNetResolver returns a new.Resolver that is backed by a RouteDNS resolver
// instead of the system's.
func NewNetResolver(r Resolver) *net.Resolver {
return &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
return newConn(r, network, address), nil
},
}
}
// var _ net.PacketConn = &packetConn{}
var _ net.Conn = &packetConn{}
// packetConn implements net.PacketConn and is used in the Dial() func in a
// net.Resolver to redirect lookups through one of RouteDNS' resolvers instead
// of the system ones.
type packetConn struct {
network string
address string
r Resolver
ch chan *dns.Msg
}
func newConn(r Resolver, network, address string) *packetConn {
return &packetConn{
network: network,
address: address,
r: r,
ch: make(chan *dns.Msg, 1),
}
}
func (c *packetConn) Read(p []byte) (n int, err error) {
a := <-c.ch
b, err := a.Pack()
if err != nil {
return 0, err
}
if len(p) < len(b) {
return 0, errors.New("read buffer too small")
}
copy(p, b)
return len(b), nil
}
// These functions need to exist to implement net.PacketConn as the net.Resolver
// then uses Read/Write in UDP mode. They're not called but need to be present.
func (c *packetConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
return 0, nil, nil
}
func (c *packetConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
return len(p), nil
}
func (c *packetConn) Write(p []byte) (n int, err error) {
// Decode the query
q := new(dns.Msg)
if err := q.Unpack(p); err != nil {
return len(p), err
}
a, err := c.r.Resolve(q, ClientInfo{SourceIP: net.IP{127, 0, 0, 1}})
if err != nil {
return len(p), err
}
c.ch <- a
return len(p), nil
}
func (c *packetConn) Close() error {
return nil
}
func (c *packetConn) LocalAddr() net.Addr {
return nil
}
func (c *packetConn) RemoteAddr() net.Addr {
return nil
}
func (c *packetConn) SetDeadline(t time.Time) error {
return nil
}
func (c *packetConn) SetReadDeadline(t time.Time) error {
return nil
}
func (c *packetConn) SetWriteDeadline(t time.Time) error {
return nil
}