-
Notifications
You must be signed in to change notification settings - Fork 54
/
response_writer.go
103 lines (83 loc) · 1.78 KB
/
response_writer.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
package middleware
import (
"errors"
"net"
"github.com/miekg/dns"
)
// ResponseWriter implement of dns.ResponseWriter
type ResponseWriter interface {
dns.ResponseWriter
Msg() *dns.Msg
Rcode() int
Written() bool
Reset(dns.ResponseWriter)
Proto() string
RemoteIP() net.IP
Internal() bool
}
type responseWriter struct {
dns.ResponseWriter
msg *dns.Msg
size int
rcode int
proto string
remoteip net.IP
internal bool
}
var _ ResponseWriter = &responseWriter{}
var errAlreadyWritten = errors.New("msg already written")
func (w *responseWriter) Msg() *dns.Msg {
return w.msg
}
func (w *responseWriter) Reset(writer dns.ResponseWriter) {
w.ResponseWriter = writer
w.size = -1
w.msg = nil
w.rcode = dns.RcodeSuccess
switch writer.LocalAddr().(type) {
case (*net.TCPAddr):
w.proto = "tcp"
w.remoteip = w.RemoteAddr().(*net.TCPAddr).IP
case (*net.UDPAddr):
w.proto = "udp"
w.remoteip = w.RemoteAddr().(*net.UDPAddr).IP
}
w.internal = w.remoteip.String() == "127.0.0.255"
}
func (w *responseWriter) RemoteIP() net.IP {
return w.remoteip
}
func (w *responseWriter) Proto() string {
return w.proto
}
func (w *responseWriter) Rcode() int {
return w.rcode
}
func (w *responseWriter) Written() bool {
return w.size != -1
}
func (w *responseWriter) Write(m []byte) (int, error) {
if w.Written() {
return 0, errAlreadyWritten
}
w.msg = new(dns.Msg)
err := w.msg.Unpack(m)
if err != nil {
return 0, err
}
w.rcode = w.msg.Rcode
n, err := w.ResponseWriter.Write(m)
w.size = n
return n, err
}
func (w *responseWriter) WriteMsg(m *dns.Msg) error {
if w.Written() {
return errAlreadyWritten
}
w.msg = m
w.rcode = m.Rcode
w.size = 0
return w.ResponseWriter.WriteMsg(m)
}
// Internal func
func (w *responseWriter) Internal() bool { return w.internal }