Updating server dependancies. (#7538)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
8b9dbb8613
Коммит
b84736e9b6
1
vendor/github.com/miekg/dns/CONTRIBUTORS
сгенерированный
поставляемый
1
vendor/github.com/miekg/dns/CONTRIBUTORS
сгенерированный
поставляемый
@@ -7,3 +7,4 @@ Marek Majkowski
|
||||
Peter van Dijk
|
||||
Omri Bahumi
|
||||
Alex Sergeyev
|
||||
James Hartig
|
||||
|
||||
340
vendor/github.com/miekg/dns/client.go
сгенерированный
поставляемый
340
vendor/github.com/miekg/dns/client.go
сгенерированный
поставляемый
@@ -9,6 +9,7 @@ import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -27,11 +28,15 @@ type Conn struct {
|
||||
|
||||
// A Client defines parameters for a DNS client.
|
||||
type Client struct {
|
||||
Net string // if "tcp" or "tcp-tls" (DNS over TLS) a TCP query will be initiated, otherwise an UDP one (default is "" for UDP)
|
||||
UDPSize uint16 // minimum receive buffer for UDP messages
|
||||
TLSConfig *tls.Config // TLS connection configuration
|
||||
Timeout time.Duration // a cumulative timeout for dial, write and read, defaults to 0 (disabled) - overrides DialTimeout, ReadTimeout and WriteTimeout when non-zero
|
||||
DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds - overridden by Timeout when that value is non-zero
|
||||
Net string // if "tcp" or "tcp-tls" (DNS over TLS) a TCP query will be initiated, otherwise an UDP one (default is "" for UDP)
|
||||
UDPSize uint16 // minimum receive buffer for UDP messages
|
||||
TLSConfig *tls.Config // TLS connection configuration
|
||||
Dialer *net.Dialer // a net.Dialer used to set local address, timeouts and more
|
||||
// Timeout is a cumulative timeout for dial, write and read, defaults to 0 (disabled) - overrides DialTimeout, ReadTimeout,
|
||||
// WriteTimeout when non-zero. Can be overridden with net.Dialer.Timeout (see Client.ExchangeWithDialer and
|
||||
// Client.Dialer) or context.Context.Deadline (see the deprecated ExchangeContext)
|
||||
Timeout time.Duration
|
||||
DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds, or net.Dialer.Timeout if expiring earlier - overridden by Timeout when that value is non-zero
|
||||
ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
|
||||
WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
|
||||
TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be fully qualified
|
||||
@@ -44,140 +49,11 @@ type Client struct {
|
||||
// will it fall back to TCP in case of truncation.
|
||||
// See client.Exchange for more information on setting larger buffer sizes.
|
||||
func Exchange(m *Msg, a string) (r *Msg, err error) {
|
||||
var co *Conn
|
||||
co, err = DialTimeout("udp", a, dnsTimeout)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer co.Close()
|
||||
|
||||
opt := m.IsEdns0()
|
||||
// If EDNS0 is used use that for size.
|
||||
if opt != nil && opt.UDPSize() >= MinMsgSize {
|
||||
co.UDPSize = opt.UDPSize()
|
||||
}
|
||||
|
||||
co.SetWriteDeadline(time.Now().Add(dnsTimeout))
|
||||
if err = co.WriteMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
co.SetReadDeadline(time.Now().Add(dnsTimeout))
|
||||
r, err = co.ReadMsg()
|
||||
if err == nil && r.Id != m.Id {
|
||||
err = ErrId
|
||||
}
|
||||
client := Client{Net: "udp"}
|
||||
r, _, err = client.Exchange(m, a)
|
||||
return r, err
|
||||
}
|
||||
|
||||
// ExchangeContext performs a synchronous UDP query, like Exchange. It
|
||||
// additionally obeys deadlines from the passed Context.
|
||||
func ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, err error) {
|
||||
// Combine context deadline with built-in timeout. Context chooses whichever
|
||||
// is sooner.
|
||||
timeoutCtx, cancel := context.WithTimeout(ctx, dnsTimeout)
|
||||
defer cancel()
|
||||
deadline, _ := timeoutCtx.Deadline()
|
||||
|
||||
co := new(Conn)
|
||||
dialer := net.Dialer{}
|
||||
co.Conn, err = dialer.DialContext(timeoutCtx, "udp", a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer co.Conn.Close()
|
||||
|
||||
opt := m.IsEdns0()
|
||||
// If EDNS0 is used use that for size.
|
||||
if opt != nil && opt.UDPSize() >= MinMsgSize {
|
||||
co.UDPSize = opt.UDPSize()
|
||||
}
|
||||
|
||||
co.SetWriteDeadline(deadline)
|
||||
if err = co.WriteMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
co.SetReadDeadline(deadline)
|
||||
r, err = co.ReadMsg()
|
||||
if err == nil && r.Id != m.Id {
|
||||
err = ErrId
|
||||
}
|
||||
return r, err
|
||||
}
|
||||
|
||||
// ExchangeConn performs a synchronous query. It sends the message m via the connection
|
||||
// c and waits for a reply. The connection c is not closed by ExchangeConn.
|
||||
// This function is going away, but can easily be mimicked:
|
||||
//
|
||||
// co := &dns.Conn{Conn: c} // c is your net.Conn
|
||||
// co.WriteMsg(m)
|
||||
// in, _ := co.ReadMsg()
|
||||
// co.Close()
|
||||
//
|
||||
func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
|
||||
println("dns: this function is deprecated")
|
||||
co := new(Conn)
|
||||
co.Conn = c
|
||||
if err = co.WriteMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r, err = co.ReadMsg()
|
||||
if err == nil && r.Id != m.Id {
|
||||
err = ErrId
|
||||
}
|
||||
return r, err
|
||||
}
|
||||
|
||||
// Exchange performs a synchronous query. It sends the message m to the address
|
||||
// contained in a and waits for a reply. Basic use pattern with a *dns.Client:
|
||||
//
|
||||
// c := new(dns.Client)
|
||||
// in, rtt, err := c.Exchange(message, "127.0.0.1:53")
|
||||
//
|
||||
// Exchange does not retry a failed query, nor will it fall back to TCP in
|
||||
// case of truncation.
|
||||
// It is up to the caller to create a message that allows for larger responses to be
|
||||
// returned. Specifically this means adding an EDNS0 OPT RR that will advertise a larger
|
||||
// buffer, see SetEdns0. Messages without an OPT RR will fallback to the historic limit
|
||||
// of 512 bytes.
|
||||
func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
|
||||
return c.ExchangeContext(context.Background(), m, a)
|
||||
}
|
||||
|
||||
// ExchangeContext acts like Exchange, but honors the deadline on the provided
|
||||
// context, if present. If there is both a context deadline and a configured
|
||||
// timeout on the client, the earliest of the two takes effect.
|
||||
func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (
|
||||
r *Msg,
|
||||
rtt time.Duration,
|
||||
err error) {
|
||||
if !c.SingleInflight {
|
||||
return c.exchange(ctx, m, a)
|
||||
}
|
||||
// This adds a bunch of garbage, TODO(miek).
|
||||
t := "nop"
|
||||
if t1, ok := TypeToString[m.Question[0].Qtype]; ok {
|
||||
t = t1
|
||||
}
|
||||
cl := "nop"
|
||||
if cl1, ok := ClassToString[m.Question[0].Qclass]; ok {
|
||||
cl = cl1
|
||||
}
|
||||
r, rtt, err, shared := c.group.Do(m.Question[0].Name+t+cl, func() (*Msg, time.Duration, error) {
|
||||
return c.exchange(ctx, m, a)
|
||||
})
|
||||
if r != nil && shared {
|
||||
r = r.Copy()
|
||||
}
|
||||
if err != nil {
|
||||
return r, rtt, err
|
||||
}
|
||||
return r, rtt, nil
|
||||
}
|
||||
|
||||
func (c *Client) dialTimeout() time.Duration {
|
||||
if c.Timeout != 0 {
|
||||
return c.Timeout
|
||||
@@ -202,40 +78,87 @@ func (c *Client) writeTimeout() time.Duration {
|
||||
return dnsTimeout
|
||||
}
|
||||
|
||||
func (c *Client) exchange(ctx context.Context, m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
|
||||
var co *Conn
|
||||
func (c *Client) Dial(address string) (conn *Conn, err error) {
|
||||
// create a new dialer with the appropriate timeout
|
||||
var d net.Dialer
|
||||
if c.Dialer == nil {
|
||||
d = net.Dialer{}
|
||||
} else {
|
||||
d = net.Dialer(*c.Dialer)
|
||||
}
|
||||
d.Timeout = c.getTimeoutForRequest(c.writeTimeout())
|
||||
|
||||
network := "udp"
|
||||
tls := false
|
||||
useTLS := false
|
||||
|
||||
switch c.Net {
|
||||
case "tcp-tls":
|
||||
network = "tcp"
|
||||
tls = true
|
||||
useTLS = true
|
||||
case "tcp4-tls":
|
||||
network = "tcp4"
|
||||
tls = true
|
||||
useTLS = true
|
||||
case "tcp6-tls":
|
||||
network = "tcp6"
|
||||
tls = true
|
||||
useTLS = true
|
||||
default:
|
||||
if c.Net != "" {
|
||||
network = c.Net
|
||||
}
|
||||
}
|
||||
|
||||
var deadline time.Time
|
||||
if c.Timeout != 0 {
|
||||
deadline = time.Now().Add(c.Timeout)
|
||||
}
|
||||
|
||||
dialDeadline := deadlineOrTimeoutOrCtx(ctx, deadline, c.dialTimeout())
|
||||
dialTimeout := dialDeadline.Sub(time.Now())
|
||||
|
||||
if tls {
|
||||
co, err = DialTimeoutWithTLS(network, a, c.TLSConfig, dialTimeout)
|
||||
conn = new(Conn)
|
||||
if useTLS {
|
||||
conn.Conn, err = tls.DialWithDialer(&d, network, address, c.TLSConfig)
|
||||
} else {
|
||||
co, err = DialTimeout(network, a, dialTimeout)
|
||||
conn.Conn, err = d.Dial(network, address)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// Exchange performs a synchronous query. It sends the message m to the address
|
||||
// contained in a and waits for a reply. Basic use pattern with a *dns.Client:
|
||||
//
|
||||
// c := new(dns.Client)
|
||||
// in, rtt, err := c.Exchange(message, "127.0.0.1:53")
|
||||
//
|
||||
// Exchange does not retry a failed query, nor will it fall back to TCP in
|
||||
// case of truncation.
|
||||
// It is up to the caller to create a message that allows for larger responses to be
|
||||
// returned. Specifically this means adding an EDNS0 OPT RR that will advertise a larger
|
||||
// buffer, see SetEdns0. Messages without an OPT RR will fallback to the historic limit
|
||||
// of 512 bytes
|
||||
// To specify a local address or a timeout, the caller has to set the `Client.Dialer`
|
||||
// attribute appropriately
|
||||
func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Duration, err error) {
|
||||
if !c.SingleInflight {
|
||||
return c.exchange(m, address)
|
||||
}
|
||||
|
||||
t := "nop"
|
||||
if t1, ok := TypeToString[m.Question[0].Qtype]; ok {
|
||||
t = t1
|
||||
}
|
||||
cl := "nop"
|
||||
if cl1, ok := ClassToString[m.Question[0].Qclass]; ok {
|
||||
cl = cl1
|
||||
}
|
||||
r, rtt, err, shared := c.group.Do(m.Question[0].Name+t+cl, func() (*Msg, time.Duration, error) {
|
||||
return c.exchange(m, address)
|
||||
})
|
||||
if r != nil && shared {
|
||||
r = r.Copy()
|
||||
}
|
||||
return r, rtt, err
|
||||
}
|
||||
|
||||
func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
|
||||
var co *Conn
|
||||
|
||||
co, err = c.Dial(a)
|
||||
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
@@ -253,12 +176,13 @@ func (c *Client) exchange(ctx context.Context, m *Msg, a string) (r *Msg, rtt ti
|
||||
}
|
||||
|
||||
co.TsigSecret = c.TsigSecret
|
||||
co.SetWriteDeadline(deadlineOrTimeoutOrCtx(ctx, deadline, c.writeTimeout()))
|
||||
// write with the appropriate write timeout
|
||||
co.SetWriteDeadline(time.Now().Add(c.getTimeoutForRequest(c.writeTimeout())))
|
||||
if err = co.WriteMsg(m); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
co.SetReadDeadline(deadlineOrTimeoutOrCtx(ctx, deadline, c.readTimeout()))
|
||||
co.SetReadDeadline(time.Now().Add(c.getTimeoutForRequest(c.readTimeout())))
|
||||
r, err = co.ReadMsg()
|
||||
if err == nil && r.Id != m.Id {
|
||||
err = ErrId
|
||||
@@ -352,7 +276,7 @@ func tcpMsgLen(t io.Reader) (int, error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// As seen with my local router/switch, retursn 1 byte on the above read,
|
||||
// As seen with my local router/switch, returns 1 byte on the above read,
|
||||
// resulting a a ShortRead. Just write it out (instead of loop) and read the
|
||||
// other byte.
|
||||
if n == 1 {
|
||||
@@ -467,6 +391,24 @@ func (co *Conn) Write(p []byte) (n int, err error) {
|
||||
return n, err
|
||||
}
|
||||
|
||||
// Return the appropriate timeout for a specific request
|
||||
func (c *Client) getTimeoutForRequest(timeout time.Duration) time.Duration {
|
||||
var requestTimeout time.Duration
|
||||
if c.Timeout != 0 {
|
||||
requestTimeout = c.Timeout
|
||||
} else {
|
||||
requestTimeout = timeout
|
||||
}
|
||||
// net.Dialer.Timeout has priority if smaller than the timeouts computed so
|
||||
// far
|
||||
if c.Dialer != nil && c.Dialer.Timeout != 0 {
|
||||
if c.Dialer.Timeout < requestTimeout {
|
||||
requestTimeout = c.Dialer.Timeout
|
||||
}
|
||||
}
|
||||
return requestTimeout
|
||||
}
|
||||
|
||||
// Dial connects to the address on the named network.
|
||||
func Dial(network, address string) (conn *Conn, err error) {
|
||||
conn = new(Conn)
|
||||
@@ -477,10 +419,44 @@ func Dial(network, address string) (conn *Conn, err error) {
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// ExchangeContext performs a synchronous UDP query, like Exchange. It
|
||||
// additionally obeys deadlines from the passed Context.
|
||||
func ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, err error) {
|
||||
client := Client{Net: "udp"}
|
||||
r, _, err = client.ExchangeContext(ctx, m, a)
|
||||
// ignorint rtt to leave the original ExchangeContext API unchanged, but
|
||||
// this function will go away
|
||||
return r, err
|
||||
}
|
||||
|
||||
// ExchangeConn performs a synchronous query. It sends the message m via the connection
|
||||
// c and waits for a reply. The connection c is not closed by ExchangeConn.
|
||||
// This function is going away, but can easily be mimicked:
|
||||
//
|
||||
// co := &dns.Conn{Conn: c} // c is your net.Conn
|
||||
// co.WriteMsg(m)
|
||||
// in, _ := co.ReadMsg()
|
||||
// co.Close()
|
||||
//
|
||||
func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
|
||||
println("dns: ExchangeConn: this function is deprecated")
|
||||
co := new(Conn)
|
||||
co.Conn = c
|
||||
if err = co.WriteMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r, err = co.ReadMsg()
|
||||
if err == nil && r.Id != m.Id {
|
||||
err = ErrId
|
||||
}
|
||||
return r, err
|
||||
}
|
||||
|
||||
// DialTimeout acts like Dial but takes a timeout.
|
||||
func DialTimeout(network, address string, timeout time.Duration) (conn *Conn, err error) {
|
||||
conn = new(Conn)
|
||||
conn.Conn, err = net.DialTimeout(network, address, timeout)
|
||||
|
||||
client := Client{Net: "udp", Dialer: &net.Dialer{Timeout: timeout}}
|
||||
conn, err = client.Dial(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -489,8 +465,12 @@ func DialTimeout(network, address string, timeout time.Duration) (conn *Conn, er
|
||||
|
||||
// DialWithTLS connects to the address on the named network with TLS.
|
||||
func DialWithTLS(network, address string, tlsConfig *tls.Config) (conn *Conn, err error) {
|
||||
conn = new(Conn)
|
||||
conn.Conn, err = tls.Dial(network, address, tlsConfig)
|
||||
if !strings.HasSuffix(network, "-tls") {
|
||||
network += "-tls"
|
||||
}
|
||||
client := Client{Net: network, TLSConfig: tlsConfig}
|
||||
conn, err = client.Dial(address)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -499,33 +479,29 @@ func DialWithTLS(network, address string, tlsConfig *tls.Config) (conn *Conn, er
|
||||
|
||||
// DialTimeoutWithTLS acts like DialWithTLS but takes a timeout.
|
||||
func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout time.Duration) (conn *Conn, err error) {
|
||||
var dialer net.Dialer
|
||||
dialer.Timeout = timeout
|
||||
|
||||
conn = new(Conn)
|
||||
conn.Conn, err = tls.DialWithDialer(&dialer, network, address, tlsConfig)
|
||||
if !strings.HasSuffix(network, "-tls") {
|
||||
network += "-tls"
|
||||
}
|
||||
client := Client{Net: network, Dialer: &net.Dialer{Timeout: timeout}, TLSConfig: tlsConfig}
|
||||
conn, err = client.Dial(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// deadlineOrTimeout chooses between the provided deadline and timeout
|
||||
// by always preferring the deadline so long as it's non-zero (regardless
|
||||
// of which is bigger), and returns the equivalent deadline value.
|
||||
func deadlineOrTimeout(deadline time.Time, timeout time.Duration) time.Time {
|
||||
if deadline.IsZero() {
|
||||
return time.Now().Add(timeout)
|
||||
// ExchangeContext acts like Exchange, but honors the deadline on the provided
|
||||
// context, if present. If there is both a context deadline and a configured
|
||||
// timeout on the client, the earliest of the two takes effect.
|
||||
func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
|
||||
var timeout time.Duration
|
||||
if deadline, ok := ctx.Deadline(); !ok {
|
||||
timeout = 0
|
||||
} else {
|
||||
timeout = deadline.Sub(time.Now())
|
||||
}
|
||||
return deadline
|
||||
}
|
||||
|
||||
// deadlineOrTimeoutOrCtx returns the earliest of: a context deadline, or the
|
||||
// output of deadlineOrtimeout.
|
||||
func deadlineOrTimeoutOrCtx(ctx context.Context, deadline time.Time, timeout time.Duration) time.Time {
|
||||
result := deadlineOrTimeout(deadline, timeout)
|
||||
if ctxDeadline, ok := ctx.Deadline(); ok && ctxDeadline.Before(result) {
|
||||
result = ctxDeadline
|
||||
}
|
||||
return result
|
||||
// not passing the context to the underlying calls, as the API does not support
|
||||
// context. For timeouts you should set up Client.Dialer and call Client.Exchange.
|
||||
c.Dialer = &net.Dialer{Timeout: timeout}
|
||||
return c.Exchange(m, a)
|
||||
}
|
||||
|
||||
168
vendor/github.com/miekg/dns/client_test.go
сгенерированный
поставляемый
168
vendor/github.com/miekg/dns/client_test.go
сгенерированный
поставляемый
@@ -11,6 +11,29 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestDialUDP(t *testing.T) {
|
||||
HandleFunc("miek.nl.", HelloServer)
|
||||
defer HandleRemove("miek.nl.")
|
||||
|
||||
s, addrstr, err := RunLocalUDPServer("[::1]:0")
|
||||
if err != nil {
|
||||
t.Fatalf("unable to run test server: %v", err)
|
||||
}
|
||||
defer s.Shutdown()
|
||||
|
||||
m := new(Msg)
|
||||
m.SetQuestion("miek.nl.", TypeSOA)
|
||||
|
||||
c := new(Client)
|
||||
conn, err := c.Dial(addrstr)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to dial: %v", err)
|
||||
}
|
||||
if conn == nil {
|
||||
t.Fatalf("conn is nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientSync(t *testing.T) {
|
||||
HandleFunc("miek.nl.", HelloServer)
|
||||
defer HandleRemove("miek.nl.")
|
||||
@@ -27,9 +50,12 @@ func TestClientSync(t *testing.T) {
|
||||
c := new(Client)
|
||||
r, _, err := c.Exchange(m, addrstr)
|
||||
if err != nil {
|
||||
t.Errorf("failed to exchange: %v", err)
|
||||
t.Fatalf("failed to exchange: %v", err)
|
||||
}
|
||||
if r != nil && r.Rcode != RcodeSuccess {
|
||||
if r == nil {
|
||||
t.Fatal("response is nil")
|
||||
}
|
||||
if r.Rcode != RcodeSuccess {
|
||||
t.Errorf("failed to get an valid answer\n%v", r)
|
||||
}
|
||||
// And now with plain Exchange().
|
||||
@@ -42,7 +68,42 @@ func TestClientSync(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientTLSSync(t *testing.T) {
|
||||
func TestClientLocalAddress(t *testing.T) {
|
||||
HandleFunc("miek.nl.", HelloServerEchoAddrPort)
|
||||
defer HandleRemove("miek.nl.")
|
||||
|
||||
s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatalf("unable to run test server: %v", err)
|
||||
}
|
||||
defer s.Shutdown()
|
||||
|
||||
m := new(Msg)
|
||||
m.SetQuestion("miek.nl.", TypeSOA)
|
||||
|
||||
c := new(Client)
|
||||
laddr := net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 12345, Zone: ""}
|
||||
c.Dialer = &net.Dialer{LocalAddr: &laddr}
|
||||
r, _, err := c.Exchange(m, addrstr)
|
||||
if err != nil {
|
||||
t.Errorf("failed to exchange: %v", err)
|
||||
}
|
||||
if r != nil && r.Rcode != RcodeSuccess {
|
||||
t.Errorf("failed to get an valid answer\n%v", r)
|
||||
}
|
||||
if len(r.Extra) != 1 {
|
||||
t.Errorf("failed to get additional answers\n%v", r)
|
||||
}
|
||||
txt := r.Extra[0].(*TXT)
|
||||
if txt == nil {
|
||||
t.Errorf("invalid TXT response\n%v", txt)
|
||||
}
|
||||
if len(txt.Txt) != 1 || txt.Txt[0] != "127.0.0.1:12345" {
|
||||
t.Errorf("invalid TXT response\n%v", txt.Txt)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientTLSSyncV4(t *testing.T) {
|
||||
HandleFunc("miek.nl.", HelloServer)
|
||||
defer HandleRemove("miek.nl.")
|
||||
|
||||
@@ -65,6 +126,8 @@ func TestClientTLSSync(t *testing.T) {
|
||||
m.SetQuestion("miek.nl.", TypeSOA)
|
||||
|
||||
c := new(Client)
|
||||
|
||||
// test tcp-tls
|
||||
c.Net = "tcp-tls"
|
||||
c.TLSConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
@@ -72,9 +135,88 @@ func TestClientTLSSync(t *testing.T) {
|
||||
|
||||
r, _, err := c.Exchange(m, addrstr)
|
||||
if err != nil {
|
||||
t.Errorf("failed to exchange: %v", err)
|
||||
t.Fatalf("failed to exchange: %v", err)
|
||||
}
|
||||
if r != nil && r.Rcode != RcodeSuccess {
|
||||
if r == nil {
|
||||
t.Fatal("response is nil")
|
||||
}
|
||||
if r.Rcode != RcodeSuccess {
|
||||
t.Errorf("failed to get an valid answer\n%v", r)
|
||||
}
|
||||
|
||||
// test tcp4-tls
|
||||
c.Net = "tcp4-tls"
|
||||
c.TLSConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
|
||||
r, _, err = c.Exchange(m, addrstr)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to exchange: %v", err)
|
||||
}
|
||||
if r == nil {
|
||||
t.Fatal("response is nil")
|
||||
}
|
||||
if r.Rcode != RcodeSuccess {
|
||||
t.Errorf("failed to get an valid answer\n%v", r)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientTLSSyncV6(t *testing.T) {
|
||||
HandleFunc("miek.nl.", HelloServer)
|
||||
defer HandleRemove("miek.nl.")
|
||||
|
||||
cert, err := tls.X509KeyPair(CertPEMBlock, KeyPEMBlock)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to build certificate: %v", err)
|
||||
}
|
||||
|
||||
config := tls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
}
|
||||
|
||||
s, addrstr, err := RunLocalTLSServer("[::1]:0", &config)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to run test server: %v", err)
|
||||
}
|
||||
defer s.Shutdown()
|
||||
|
||||
m := new(Msg)
|
||||
m.SetQuestion("miek.nl.", TypeSOA)
|
||||
|
||||
c := new(Client)
|
||||
|
||||
// test tcp-tls
|
||||
c.Net = "tcp-tls"
|
||||
c.TLSConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
|
||||
r, _, err := c.Exchange(m, addrstr)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to exchange: %v", err)
|
||||
}
|
||||
if r == nil {
|
||||
t.Fatal("response is nil")
|
||||
}
|
||||
if r.Rcode != RcodeSuccess {
|
||||
t.Errorf("failed to get an valid answer\n%v", r)
|
||||
}
|
||||
|
||||
// test tcp6-tls
|
||||
c.Net = "tcp6-tls"
|
||||
c.TLSConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
|
||||
r, _, err = c.Exchange(m, addrstr)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to exchange: %v", err)
|
||||
}
|
||||
if r == nil {
|
||||
t.Fatal("response is nil")
|
||||
}
|
||||
if r.Rcode != RcodeSuccess {
|
||||
t.Errorf("failed to get an valid answer\n%v", r)
|
||||
}
|
||||
}
|
||||
@@ -120,11 +262,11 @@ func TestClientEDNS0(t *testing.T) {
|
||||
c := new(Client)
|
||||
r, _, err := c.Exchange(m, addrstr)
|
||||
if err != nil {
|
||||
t.Errorf("failed to exchange: %v", err)
|
||||
t.Fatalf("failed to exchange: %v", err)
|
||||
}
|
||||
|
||||
if r != nil && r.Rcode != RcodeSuccess {
|
||||
t.Errorf("failed to get an valid answer\n%v", r)
|
||||
t.Errorf("failed to get a valid answer\n%v", r)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,11 +313,14 @@ func TestClientEDNS0Local(t *testing.T) {
|
||||
c := new(Client)
|
||||
r, _, err := c.Exchange(m, addrstr)
|
||||
if err != nil {
|
||||
t.Errorf("failed to exchange: %s", err)
|
||||
t.Fatalf("failed to exchange: %s", err)
|
||||
}
|
||||
|
||||
if r != nil && r.Rcode != RcodeSuccess {
|
||||
t.Error("failed to get a valid answer")
|
||||
if r == nil {
|
||||
t.Fatal("response is nil")
|
||||
}
|
||||
if r.Rcode != RcodeSuccess {
|
||||
t.Fatal("failed to get a valid answer")
|
||||
t.Logf("%v\n", r)
|
||||
}
|
||||
|
||||
@@ -513,6 +658,9 @@ func TestConcurrentExchanges(t *testing.T) {
|
||||
for i := 0; i < len(r); i++ {
|
||||
go func(i int) {
|
||||
r[i], _, _ = c.Exchange(m.Copy(), addrstr)
|
||||
if r[i] == nil {
|
||||
t.Fatalf("response %d is nil", i)
|
||||
}
|
||||
wg.Done()
|
||||
}(i)
|
||||
}
|
||||
|
||||
2
vendor/github.com/miekg/dns/dnsutil/util.go
сгенерированный
поставляемый
2
vendor/github.com/miekg/dns/dnsutil/util.go
сгенерированный
поставляемый
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// AddDomain adds origin to s if s is not already a FQDN.
|
||||
// AddOrigin adds origin to s if s is not already a FQDN.
|
||||
// Note that the result may not be a FQDN. If origin does not end
|
||||
// with a ".", the result won't either.
|
||||
// This implements the zonefile convention (specified in RFC 1035,
|
||||
|
||||
30
vendor/github.com/miekg/dns/doc.go
сгенерированный
поставляемый
30
vendor/github.com/miekg/dns/doc.go
сгенерированный
поставляемый
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
Package dns implements a full featured interface to the Domain Name System.
|
||||
Server- and client-side programming is supported.
|
||||
The package allows complete control over what is send out to the DNS. The package
|
||||
The package allows complete control over what is sent out to the DNS. The package
|
||||
API follows the less-is-more principle, by presenting a small, clean interface.
|
||||
|
||||
The package dns supports (asynchronous) querying/replying, incoming/outgoing zone transfers,
|
||||
@@ -14,7 +14,7 @@ Basic usage pattern for creating a new resource record:
|
||||
|
||||
r := new(dns.MX)
|
||||
r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX,
|
||||
Class: dns.ClassINET, Ttl: 3600}
|
||||
Class: dns.ClassINET, Ttl: 3600}
|
||||
r.Preference = 10
|
||||
r.Mx = "mx.miek.nl."
|
||||
|
||||
@@ -22,16 +22,16 @@ Or directly from a string:
|
||||
|
||||
mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.")
|
||||
|
||||
Or when the default TTL (3600) and class (IN) suit you:
|
||||
Or when the default origin (.) and TTL (3600) and class (IN) suit you:
|
||||
|
||||
mx, err := dns.NewRR("miek.nl. MX 10 mx.miek.nl.")
|
||||
mx, err := dns.NewRR("miek.nl MX 10 mx.miek.nl")
|
||||
|
||||
Or even:
|
||||
|
||||
mx, err := dns.NewRR("$ORIGIN nl.\nmiek 1H IN MX 10 mx.miek")
|
||||
|
||||
In the DNS messages are exchanged, these messages contain resource
|
||||
records (sets). Use pattern for creating a message:
|
||||
records (sets). Use pattern for creating a message:
|
||||
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion("miek.nl.", dns.TypeMX)
|
||||
@@ -51,7 +51,7 @@ The following is slightly more verbose, but more flexible:
|
||||
m1.Question = make([]dns.Question, 1)
|
||||
m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET}
|
||||
|
||||
After creating a message it can be send.
|
||||
After creating a message it can be sent.
|
||||
Basic use pattern for synchronous querying the DNS at a
|
||||
server configured on 127.0.0.1 and port 53:
|
||||
|
||||
@@ -63,7 +63,23 @@ class) is as easy as setting:
|
||||
|
||||
c.SingleInflight = true
|
||||
|
||||
If these "advanced" features are not needed, a simple UDP query can be send,
|
||||
More advanced options are availabe using a net.Dialer and the corresponding API.
|
||||
For example it is possible to set a timeout, or to specify a source IP address
|
||||
and port to use for the connection:
|
||||
|
||||
c := new(dns.Client)
|
||||
laddr := net.UDPAddr{
|
||||
IP: net.ParseIP("[::1]"),
|
||||
Port: 12345,
|
||||
Zone: "",
|
||||
}
|
||||
d := net.Dialer{
|
||||
Timeout: 200 * time.Millisecond,
|
||||
LocalAddr: &laddr,
|
||||
}
|
||||
in, rtt, err := c.ExchangeWithDialer(&d, m1, "8.8.8.8:53")
|
||||
|
||||
If these "advanced" features are not needed, a simple UDP query can be sent,
|
||||
with:
|
||||
|
||||
in, err := dns.Exchange(m1, "127.0.0.1:53")
|
||||
|
||||
15
vendor/github.com/miekg/dns/edns.go
сгенерированный
поставляемый
15
vendor/github.com/miekg/dns/edns.go
сгенерированный
поставляемый
@@ -21,6 +21,7 @@ const (
|
||||
EDNS0EXPIRE = 0x9 // EDNS0 expire
|
||||
EDNS0COOKIE = 0xa // EDNS0 Cookie
|
||||
EDNS0TCPKEEPALIVE = 0xb // EDNS0 tcp keep alive (RFC7828)
|
||||
EDNS0PADDING = 0xc // EDNS0 padding (RFC7830)
|
||||
EDNS0SUBNETDRAFT = 0x50fa // Don't use! Use EDNS0SUBNET
|
||||
EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (RFC6891)
|
||||
EDNS0LOCALEND = 0xFFFE // End of range reserved for local/experimental use (RFC6891)
|
||||
@@ -74,6 +75,8 @@ func (rr *OPT) String() string {
|
||||
s += "\n; NSEC3 HASH UNDERSTOOD: " + o.String()
|
||||
case *EDNS0_LOCAL:
|
||||
s += "\n; LOCAL OPT: " + o.String()
|
||||
case *EDNS0_PADDING:
|
||||
s += "\n; PADDING: " + o.String()
|
||||
}
|
||||
}
|
||||
return s
|
||||
@@ -595,3 +598,15 @@ func (e *EDNS0_TCP_KEEPALIVE) String() (s string) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// EDNS0_PADDING option is used to add padding to a request/response. The default
|
||||
// value of padding SHOULD be 0x0 but other values MAY be used, for instance if
|
||||
// compression is applied before encryption which may break signatures.
|
||||
type EDNS0_PADDING struct {
|
||||
Padding []byte
|
||||
}
|
||||
|
||||
func (e *EDNS0_PADDING) pack() ([]byte, error) { return e.Padding, nil }
|
||||
func (e *EDNS0_PADDING) Option() uint16 { return EDNS0PADDING }
|
||||
func (e *EDNS0_PADDING) unpack(b []byte) error { e.Padding = b; return nil }
|
||||
func (e *EDNS0_PADDING) String() string { return fmt.Sprintf("%0X", e.Padding) }
|
||||
|
||||
7
vendor/github.com/miekg/dns/internal/socket/cmsghdr.go
сгенерированный
поставляемый
Обычный файл
7
vendor/github.com/miekg/dns/internal/socket/cmsghdr.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,7 @@
|
||||
// +build linux
|
||||
|
||||
package socket
|
||||
|
||||
func (h *cmsghdr) len() int { return int(h.Len) }
|
||||
func (h *cmsghdr) lvl() int { return int(h.Level) }
|
||||
func (h *cmsghdr) typ() int { return int(h.Type) }
|
||||
20
vendor/github.com/miekg/dns/internal/socket/cmsghdr_linux_32bit.go
сгенерированный
поставляемый
Обычный файл
20
vendor/github.com/miekg/dns/internal/socket/cmsghdr_linux_32bit.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,20 @@
|
||||
// +build arm mips mipsle 386
|
||||
// +build linux
|
||||
|
||||
package socket
|
||||
|
||||
type cmsghdr struct {
|
||||
Len uint32
|
||||
Level int32
|
||||
Type int32
|
||||
}
|
||||
|
||||
const (
|
||||
sizeofCmsghdr = 0xc
|
||||
)
|
||||
|
||||
func (h *cmsghdr) set(l, lvl, typ int) {
|
||||
h.Len = uint32(l)
|
||||
h.Level = int32(lvl)
|
||||
h.Type = int32(typ)
|
||||
}
|
||||
20
vendor/github.com/miekg/dns/internal/socket/cmsghdr_linux_64bit.go
сгенерированный
поставляемый
Обычный файл
20
vendor/github.com/miekg/dns/internal/socket/cmsghdr_linux_64bit.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,20 @@
|
||||
// +build arm64 amd64 ppc64 ppc64le mips64 mips64le s390x
|
||||
// +build linux
|
||||
|
||||
package socket
|
||||
|
||||
type cmsghdr struct {
|
||||
Len uint64
|
||||
Level int32
|
||||
Type int32
|
||||
}
|
||||
|
||||
const (
|
||||
sizeofCmsghdr = 0x10
|
||||
)
|
||||
|
||||
func (h *cmsghdr) set(l, lvl, typ int) {
|
||||
h.Len = uint64(l)
|
||||
h.Level = int32(lvl)
|
||||
h.Type = int32(typ)
|
||||
}
|
||||
13
vendor/github.com/miekg/dns/internal/socket/cmsghdr_other.go
сгенерированный
поставляемый
Обычный файл
13
vendor/github.com/miekg/dns/internal/socket/cmsghdr_other.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,13 @@
|
||||
// +build !linux
|
||||
|
||||
package socket
|
||||
|
||||
type cmsghdr struct{}
|
||||
|
||||
const sizeofCmsghdr = 0
|
||||
|
||||
func (h *cmsghdr) len() int { return 0 }
|
||||
func (h *cmsghdr) lvl() int { return 0 }
|
||||
func (h *cmsghdr) typ() int { return 0 }
|
||||
|
||||
func (h *cmsghdr) set(l, lvl, typ int) {}
|
||||
118
vendor/github.com/miekg/dns/internal/socket/controlmessage.go
сгенерированный
поставляемый
Обычный файл
118
vendor/github.com/miekg/dns/internal/socket/controlmessage.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,118 @@
|
||||
package socket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func controlHeaderLen() int {
|
||||
return roundup(sizeofCmsghdr)
|
||||
}
|
||||
|
||||
func controlMessageLen(dataLen int) int {
|
||||
return roundup(sizeofCmsghdr) + dataLen
|
||||
}
|
||||
|
||||
// returns the whole length of control message.
|
||||
func ControlMessageSpace(dataLen int) int {
|
||||
return roundup(sizeofCmsghdr) + roundup(dataLen)
|
||||
}
|
||||
|
||||
// A ControlMessage represents the head message in a stream of control
|
||||
// messages.
|
||||
//
|
||||
// A control message comprises of a header, data and a few padding
|
||||
// fields to conform to the interface to the kernel.
|
||||
//
|
||||
// See RFC 3542 for further information.
|
||||
type ControlMessage []byte
|
||||
|
||||
// Data returns the data field of the control message at the head.
|
||||
func (m ControlMessage) Data(dataLen int) []byte {
|
||||
l := controlHeaderLen()
|
||||
if len(m) < l || len(m) < l+dataLen {
|
||||
return nil
|
||||
}
|
||||
return m[l : l+dataLen]
|
||||
}
|
||||
|
||||
// ParseHeader parses and returns the header fields of the control
|
||||
// message at the head.
|
||||
func (m ControlMessage) ParseHeader() (lvl, typ, dataLen int, err error) {
|
||||
l := controlHeaderLen()
|
||||
if len(m) < l {
|
||||
return 0, 0, 0, errors.New("short message")
|
||||
}
|
||||
h := (*cmsghdr)(unsafe.Pointer(&m[0]))
|
||||
return h.lvl(), h.typ(), int(uint64(h.len()) - uint64(l)), nil
|
||||
}
|
||||
|
||||
// Next returns the control message at the next.
|
||||
func (m ControlMessage) Next(dataLen int) ControlMessage {
|
||||
l := ControlMessageSpace(dataLen)
|
||||
if len(m) < l {
|
||||
return nil
|
||||
}
|
||||
return m[l:]
|
||||
}
|
||||
|
||||
// MarshalHeader marshals the header fields of the control message at
|
||||
// the head.
|
||||
func (m ControlMessage) MarshalHeader(lvl, typ, dataLen int) error {
|
||||
if len(m) < controlHeaderLen() {
|
||||
return errors.New("short message")
|
||||
}
|
||||
h := (*cmsghdr)(unsafe.Pointer(&m[0]))
|
||||
h.set(controlMessageLen(dataLen), lvl, typ)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Marshal marshals the control message at the head, and returns the next
|
||||
// control message.
|
||||
func (m ControlMessage) Marshal(lvl, typ int, data []byte) (ControlMessage, error) {
|
||||
l := len(data)
|
||||
if len(m) < ControlMessageSpace(l) {
|
||||
return nil, errors.New("short message")
|
||||
}
|
||||
h := (*cmsghdr)(unsafe.Pointer(&m[0]))
|
||||
h.set(controlMessageLen(l), lvl, typ)
|
||||
if l > 0 {
|
||||
copy(m.Data(l), data)
|
||||
}
|
||||
return m.Next(l), nil
|
||||
}
|
||||
|
||||
// Parse parses as a single or multiple control messages.
|
||||
func (m ControlMessage) Parse() ([]ControlMessage, error) {
|
||||
var ms []ControlMessage
|
||||
for len(m) >= controlHeaderLen() {
|
||||
h := (*cmsghdr)(unsafe.Pointer(&m[0]))
|
||||
l := h.len()
|
||||
if l <= 0 {
|
||||
return nil, errors.New("invalid header length")
|
||||
}
|
||||
if uint64(l) < uint64(controlHeaderLen()) {
|
||||
return nil, errors.New("invalid message length")
|
||||
}
|
||||
if uint64(l) > uint64(len(m)) {
|
||||
return nil, errors.New("short buffer")
|
||||
}
|
||||
ms = append(ms, ControlMessage(m[:l]))
|
||||
ll := l - controlHeaderLen()
|
||||
if len(m) >= ControlMessageSpace(ll) {
|
||||
m = m[ControlMessageSpace(ll):]
|
||||
} else {
|
||||
m = m[controlMessageLen(ll):]
|
||||
}
|
||||
}
|
||||
return ms, nil
|
||||
}
|
||||
|
||||
// NewControlMessage returns a new stream of control messages.
|
||||
func NewControlMessage(dataLen []int) ControlMessage {
|
||||
var l int
|
||||
for i := range dataLen {
|
||||
l += ControlMessageSpace(dataLen[i])
|
||||
}
|
||||
return make([]byte, l)
|
||||
}
|
||||
103
vendor/github.com/miekg/dns/internal/socket/controlmessage_test.go
сгенерированный
поставляемый
Обычный файл
103
vendor/github.com/miekg/dns/internal/socket/controlmessage_test.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,103 @@
|
||||
// +build linux
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type mockControl struct {
|
||||
Level int
|
||||
Type int
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func TestControlMessage(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
cs []mockControl
|
||||
}{
|
||||
{
|
||||
[]mockControl{
|
||||
{Level: 1, Type: 1},
|
||||
},
|
||||
},
|
||||
{
|
||||
[]mockControl{
|
||||
{Level: 2, Type: 2, Data: []byte{0xfe}},
|
||||
},
|
||||
},
|
||||
{
|
||||
[]mockControl{
|
||||
{Level: 3, Type: 3, Data: []byte{0xfe, 0xff, 0xff, 0xfe}},
|
||||
},
|
||||
},
|
||||
{
|
||||
[]mockControl{
|
||||
{Level: 4, Type: 4, Data: []byte{0xfe, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xfe}},
|
||||
},
|
||||
},
|
||||
{
|
||||
[]mockControl{
|
||||
{Level: 4, Type: 4, Data: []byte{0xfe, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xfe}},
|
||||
{Level: 2, Type: 2, Data: []byte{0xfe}},
|
||||
},
|
||||
},
|
||||
} {
|
||||
var w []byte
|
||||
var tailPadLen int
|
||||
mm := NewControlMessage([]int{0})
|
||||
for i, c := range tt.cs {
|
||||
m := NewControlMessage([]int{len(c.Data)})
|
||||
l := len(m) - len(mm)
|
||||
if i == len(tt.cs)-1 && l > len(c.Data) {
|
||||
tailPadLen = l - len(c.Data)
|
||||
}
|
||||
w = append(w, m...)
|
||||
}
|
||||
|
||||
var err error
|
||||
ww := make([]byte, len(w))
|
||||
copy(ww, w)
|
||||
m := ControlMessage(ww)
|
||||
for _, c := range tt.cs {
|
||||
if err = m.MarshalHeader(c.Level, c.Type, len(c.Data)); err != nil {
|
||||
t.Fatalf("(%v).MarshalHeader() = %v", tt.cs, err)
|
||||
}
|
||||
copy(m.Data(len(c.Data)), c.Data)
|
||||
m = m.Next(len(c.Data))
|
||||
}
|
||||
m = ControlMessage(w)
|
||||
for _, c := range tt.cs {
|
||||
m, err = m.Marshal(c.Level, c.Type, c.Data)
|
||||
if err != nil {
|
||||
t.Fatalf("(%v).Marshal() = %v", tt.cs, err)
|
||||
}
|
||||
}
|
||||
if !bytes.Equal(ww, w) {
|
||||
t.Fatalf("got %#v; want %#v", ww, w)
|
||||
}
|
||||
|
||||
ws := [][]byte{w}
|
||||
if tailPadLen > 0 {
|
||||
// Test a message with no tail padding.
|
||||
nopad := w[:len(w)-tailPadLen]
|
||||
ws = append(ws, [][]byte{nopad}...)
|
||||
}
|
||||
for _, w := range ws {
|
||||
ms, err := ControlMessage(w).Parse()
|
||||
if err != nil {
|
||||
t.Fatalf("(%v).Parse() = %v", tt.cs, err)
|
||||
}
|
||||
for i, m := range ms {
|
||||
lvl, typ, dataLen, err := m.ParseHeader()
|
||||
if err != nil {
|
||||
t.Fatalf("(%v).ParseHeader() = %v", tt.cs, err)
|
||||
}
|
||||
if lvl != tt.cs[i].Level || typ != tt.cs[i].Type || dataLen != len(tt.cs[i].Data) {
|
||||
t.Fatalf("%v: got %d, %d, %d; want %d, %d, %d", tt.cs[i], lvl, typ, dataLen, tt.cs[i].Level, tt.cs[i].Type, len(tt.cs[i].Data))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
4
vendor/github.com/miekg/dns/internal/socket/socket.go
сгенерированный
поставляемый
Обычный файл
4
vendor/github.com/miekg/dns/internal/socket/socket.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,4 @@
|
||||
// Package socket contains ControlMessage parsing code from
|
||||
// golang.org/x/net/internal/socket. Instead of supporting all possible
|
||||
// architectures, we're only supporting linux 32/64 bit.
|
||||
package socket
|
||||
14
vendor/github.com/miekg/dns/internal/socket/sys.go
сгенерированный
поставляемый
Обычный файл
14
vendor/github.com/miekg/dns/internal/socket/sys.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,14 @@
|
||||
package socket
|
||||
|
||||
import "unsafe"
|
||||
|
||||
var (
|
||||
kernelAlign = func() int {
|
||||
var p uintptr
|
||||
return int(unsafe.Sizeof(p))
|
||||
}()
|
||||
)
|
||||
|
||||
func roundup(l int) int {
|
||||
return (l + kernelAlign - 1) & ^(kernelAlign - 1)
|
||||
}
|
||||
7
vendor/github.com/miekg/dns/msg_helpers.go
сгенерированный
поставляемый
7
vendor/github.com/miekg/dns/msg_helpers.go
сгенерированный
поставляемый
@@ -458,6 +458,13 @@ Option:
|
||||
}
|
||||
edns = append(edns, e)
|
||||
off += int(optlen)
|
||||
case EDNS0PADDING:
|
||||
e := new(EDNS0_PADDING)
|
||||
if err := e.unpack(msg[off : off+int(optlen)]); err != nil {
|
||||
return nil, len(msg), err
|
||||
}
|
||||
edns = append(edns, e)
|
||||
off += int(optlen)
|
||||
default:
|
||||
e := new(EDNS0_LOCAL)
|
||||
e.Code = code
|
||||
|
||||
188
vendor/github.com/miekg/dns/parse_test.go
сгенерированный
поставляемый
188
vendor/github.com/miekg/dns/parse_test.go
сгенерированный
поставляемый
@@ -8,6 +8,7 @@ import (
|
||||
"math/rand"
|
||||
"net"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -571,81 +572,88 @@ test IN CNAME test.a.example.com.
|
||||
t.Logf("%d RRs parsed in %.2f s (%.2f RR/s)", i, float32(delta)/1e9, float32(i)/(float32(delta)/1e9))
|
||||
}
|
||||
|
||||
func ExampleParseZone() {
|
||||
zone := `$ORIGIN .
|
||||
$TTL 3600 ; 1 hour
|
||||
name IN SOA a6.nstld.com. hostmaster.nic.name. (
|
||||
203362132 ; serial
|
||||
300 ; refresh (5 minutes)
|
||||
300 ; retry (5 minutes)
|
||||
1209600 ; expire (2 weeks)
|
||||
300 ; minimum (5 minutes)
|
||||
)
|
||||
$TTL 10800 ; 3 hours
|
||||
name. 10800 IN NS name.
|
||||
IN NS g6.nstld.com.
|
||||
7200 NS h6.nstld.com.
|
||||
3600 IN NS j6.nstld.com.
|
||||
IN 3600 NS k6.nstld.com.
|
||||
NS l6.nstld.com.
|
||||
NS a6.nstld.com.
|
||||
NS c6.nstld.com.
|
||||
NS d6.nstld.com.
|
||||
NS f6.nstld.com.
|
||||
NS m6.nstld.com.
|
||||
(
|
||||
NS m7.nstld.com.
|
||||
)
|
||||
$ORIGIN name.
|
||||
0-0onlus NS ns7.ehiweb.it.
|
||||
NS ns8.ehiweb.it.
|
||||
0-g MX 10 mx01.nic
|
||||
MX 10 mx02.nic
|
||||
MX 10 mx03.nic
|
||||
MX 10 mx04.nic
|
||||
$ORIGIN 0-g.name
|
||||
moutamassey NS ns01.yahoodomains.jp.
|
||||
NS ns02.yahoodomains.jp.
|
||||
func TestOmittedTTL(t *testing.T) {
|
||||
zone := `
|
||||
$ORIGIN example.com.
|
||||
example.com. 42 IN SOA ns1.example.com. hostmaster.example.com. 1 86400 60 86400 3600 ; TTL=42 SOA
|
||||
example.com. NS 2 ; TTL=42 absolute owner name
|
||||
@ MD 3 ; TTL=42 current-origin owner name
|
||||
MF 4 ; TTL=42 leading-space implied owner name
|
||||
43 TYPE65280 \# 1 05 ; TTL=43 implied owner name explicit TTL
|
||||
MB 6 ; TTL=43 leading-tab implied owner name
|
||||
$TTL 1337
|
||||
example.com. 88 MG 7 ; TTL=88 explicit TTL
|
||||
example.com. MR 8 ; TTL=1337 after first $TTL
|
||||
$TTL 314
|
||||
1 TXT 9 ; TTL=1 implied owner name explicit TTL
|
||||
example.com. DNAME 10 ; TTL=314 after second $TTL
|
||||
`
|
||||
to := ParseZone(strings.NewReader(zone), "", "testzone")
|
||||
for x := range to {
|
||||
fmt.Println(x.RR)
|
||||
reCaseFromComment := regexp.MustCompile(`TTL=(\d+)\s+(.*)`)
|
||||
records := ParseZone(strings.NewReader(zone), "", "")
|
||||
var i int
|
||||
for record := range records {
|
||||
i++
|
||||
if record.Error != nil {
|
||||
t.Error(record.Error)
|
||||
continue
|
||||
}
|
||||
expected := reCaseFromComment.FindStringSubmatch(record.Comment)
|
||||
expectedTTL, _ := strconv.ParseUint(expected[1], 10, 32)
|
||||
ttl := record.RR.Header().Ttl
|
||||
if ttl != uint32(expectedTTL) {
|
||||
t.Errorf("%s: expected TTL %d, got %d", expected[2], expectedTTL, ttl)
|
||||
}
|
||||
}
|
||||
if i != 10 {
|
||||
t.Errorf("expected %d records, got %d", 5, i)
|
||||
}
|
||||
// Output:
|
||||
// name. 3600 IN SOA a6.nstld.com. hostmaster.nic.name. 203362132 300 300 1209600 300
|
||||
// name. 10800 IN NS name.
|
||||
// name. 10800 IN NS g6.nstld.com.
|
||||
// name. 7200 IN NS h6.nstld.com.
|
||||
// name. 3600 IN NS j6.nstld.com.
|
||||
// name. 3600 IN NS k6.nstld.com.
|
||||
// name. 10800 IN NS l6.nstld.com.
|
||||
// name. 10800 IN NS a6.nstld.com.
|
||||
// name. 10800 IN NS c6.nstld.com.
|
||||
// name. 10800 IN NS d6.nstld.com.
|
||||
// name. 10800 IN NS f6.nstld.com.
|
||||
// name. 10800 IN NS m6.nstld.com.
|
||||
// name. 10800 IN NS m7.nstld.com.
|
||||
// 0-0onlus.name. 10800 IN NS ns7.ehiweb.it.
|
||||
// 0-0onlus.name. 10800 IN NS ns8.ehiweb.it.
|
||||
// 0-g.name. 10800 IN MX 10 mx01.nic.name.
|
||||
// 0-g.name. 10800 IN MX 10 mx02.nic.name.
|
||||
// 0-g.name. 10800 IN MX 10 mx03.nic.name.
|
||||
// 0-g.name. 10800 IN MX 10 mx04.nic.name.
|
||||
// moutamassey.0-g.name.name. 10800 IN NS ns01.yahoodomains.jp.
|
||||
// moutamassey.0-g.name.name. 10800 IN NS ns02.yahoodomains.jp.
|
||||
}
|
||||
|
||||
func ExampleHIP() {
|
||||
h := `www.example.com IN HIP ( 2 200100107B1A74DF365639CC39F1D578
|
||||
AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p
|
||||
9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQ
|
||||
b1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
|
||||
rvs.example.com. )`
|
||||
if hip, err := NewRR(h); err == nil {
|
||||
fmt.Println(hip.String())
|
||||
func TestRelativeNameErrors(t *testing.T) {
|
||||
var badZones = []struct {
|
||||
label string
|
||||
zoneContents string
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
"relative owner name without origin",
|
||||
"example.com 3600 IN SOA ns.example.com. hostmaster.example.com. 1 86400 60 86400 3600",
|
||||
"bad owner name",
|
||||
},
|
||||
{
|
||||
"relative owner name in RDATA",
|
||||
"example.com. 3600 IN SOA ns hostmaster 1 86400 60 86400 3600",
|
||||
"bad SOA Ns",
|
||||
},
|
||||
{
|
||||
"origin reference without origin",
|
||||
"@ 3600 IN SOA ns.example.com. hostmaster.example.com. 1 86400 60 86400 3600",
|
||||
"bad owner name",
|
||||
},
|
||||
{
|
||||
"relative owner name in $INCLUDE",
|
||||
"$INCLUDE file.db example.com",
|
||||
"bad origin name",
|
||||
},
|
||||
{
|
||||
"relative owner name in $ORIGIN",
|
||||
"$ORIGIN example.com",
|
||||
"bad origin name",
|
||||
},
|
||||
}
|
||||
for _, errorCase := range badZones {
|
||||
entries := ParseZone(strings.NewReader(errorCase.zoneContents), "", "")
|
||||
for entry := range entries {
|
||||
if entry.Error == nil {
|
||||
t.Errorf("%s: expected error, got nil", errorCase.label)
|
||||
continue
|
||||
}
|
||||
err := entry.Error.err
|
||||
if err != errorCase.expectedErr {
|
||||
t.Errorf("%s: expected error `%s`, got `%s`", errorCase.label, errorCase.expectedErr, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Output:
|
||||
// www.example.com. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
|
||||
}
|
||||
|
||||
func TestHIP(t *testing.T) {
|
||||
@@ -686,24 +694,6 @@ b1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleSOA() {
|
||||
s := "example.com. 1000 SOA master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100"
|
||||
if soa, err := NewRR(s); err == nil {
|
||||
fmt.Println(soa.String())
|
||||
}
|
||||
// Output:
|
||||
// example.com. 1000 IN SOA master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100
|
||||
}
|
||||
|
||||
func TestLineNumberError(t *testing.T) {
|
||||
s := "example.com. 1000 SOA master.example.com. admin.example.com. monkey 4294967294 4294967293 4294967295 100"
|
||||
if _, err := NewRR(s); err != nil {
|
||||
if err.Error() != "dns: bad SOA zone parameter: \"monkey\" at line: 1:68" {
|
||||
t.Error("not expecting this error: ", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test with no known RR on the line
|
||||
func TestLineNumberError2(t *testing.T) {
|
||||
tests := map[string]string{
|
||||
@@ -801,28 +791,6 @@ func TestLowercaseTokens(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleParseZone_generate() {
|
||||
// From the manual: http://www.bind9.net/manual/bind/9.3.2/Bv9ARM.ch06.html#id2566761
|
||||
zone := "$GENERATE 1-2 0 NS SERVER$.EXAMPLE.\n$GENERATE 1-8 $ CNAME $.0"
|
||||
to := ParseZone(strings.NewReader(zone), "0.0.192.IN-ADDR.ARPA.", "")
|
||||
for x := range to {
|
||||
if x.Error == nil {
|
||||
fmt.Println(x.RR.String())
|
||||
}
|
||||
}
|
||||
// Output:
|
||||
// 0.0.0.192.IN-ADDR.ARPA. 3600 IN NS SERVER1.EXAMPLE.
|
||||
// 0.0.0.192.IN-ADDR.ARPA. 3600 IN NS SERVER2.EXAMPLE.
|
||||
// 1.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 1.0.0.0.192.IN-ADDR.ARPA.
|
||||
// 2.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 2.0.0.0.192.IN-ADDR.ARPA.
|
||||
// 3.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 3.0.0.0.192.IN-ADDR.ARPA.
|
||||
// 4.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 4.0.0.0.192.IN-ADDR.ARPA.
|
||||
// 5.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 5.0.0.0.192.IN-ADDR.ARPA.
|
||||
// 6.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 6.0.0.0.192.IN-ADDR.ARPA.
|
||||
// 7.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 7.0.0.0.192.IN-ADDR.ARPA.
|
||||
// 8.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 8.0.0.0.192.IN-ADDR.ARPA.
|
||||
}
|
||||
|
||||
func TestSRVPacking(t *testing.T) {
|
||||
msg := Msg{}
|
||||
|
||||
|
||||
2
vendor/github.com/miekg/dns/privaterr_test.go
сгенерированный
поставляемый
2
vendor/github.com/miekg/dns/privaterr_test.go
сгенерированный
поставляемый
@@ -143,7 +143,7 @@ func (rd *VERSION) Len() int {
|
||||
}
|
||||
|
||||
var smallzone = `$ORIGIN example.org.
|
||||
@ SOA sns.dns.icann.org. noc.dns.icann.org. (
|
||||
@ 3600 IN SOA sns.dns.icann.org. noc.dns.icann.org. (
|
||||
2014091518 7200 3600 1209600 3600
|
||||
)
|
||||
A 1.2.3.4
|
||||
|
||||
129
vendor/github.com/miekg/dns/scan.go
сгенерированный
поставляемый
129
vendor/github.com/miekg/dns/scan.go
сгенерированный
поставляемый
@@ -105,6 +105,12 @@ type Token struct {
|
||||
Comment string
|
||||
}
|
||||
|
||||
// ttlState describes the state necessary to fill in an omitted RR TTL
|
||||
type ttlState struct {
|
||||
ttl uint32 // ttl is the current default TTL
|
||||
isByDirective bool // isByDirective indicates whether ttl was set by a $TTL directive
|
||||
}
|
||||
|
||||
// NewRR reads the RR contained in the string s. Only the first RR is
|
||||
// returned. If s contains no RR, return nil with no error. The class
|
||||
// defaults to IN and TTL defaults to 3600. The full zone file syntax
|
||||
@@ -120,7 +126,8 @@ func NewRR(s string) (RR, error) {
|
||||
// ReadRR reads the RR contained in q.
|
||||
// See NewRR for more documentation.
|
||||
func ReadRR(q io.Reader, filename string) (RR, error) {
|
||||
r := <-parseZoneHelper(q, ".", filename, 1)
|
||||
defttl := &ttlState{defaultTtl, false}
|
||||
r := <-parseZoneHelper(q, ".", defttl, filename, 1)
|
||||
if r == nil {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -132,10 +139,10 @@ func ReadRR(q io.Reader, filename string) (RR, error) {
|
||||
}
|
||||
|
||||
// ParseZone reads a RFC 1035 style zonefile from r. It returns *Tokens on the
|
||||
// returned channel, which consist out the parsed RR, a potential comment or an error.
|
||||
// If there is an error the RR is nil. The string file is only used
|
||||
// returned channel, each consisting of either a parsed RR and optional comment
|
||||
// or a nil RR and an error. The string file is only used
|
||||
// in error reporting. The string origin is used as the initial origin, as
|
||||
// if the file would start with: $ORIGIN origin .
|
||||
// if the file would start with an $ORIGIN directive.
|
||||
// The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are supported.
|
||||
// The channel t is closed by ParseZone when the end of r is reached.
|
||||
//
|
||||
@@ -157,16 +164,16 @@ func ReadRR(q io.Reader, filename string) (RR, error) {
|
||||
// The text "; this is comment" is returned in Token.Comment. Comments inside the
|
||||
// RR are discarded. Comments on a line by themselves are discarded too.
|
||||
func ParseZone(r io.Reader, origin, file string) chan *Token {
|
||||
return parseZoneHelper(r, origin, file, 10000)
|
||||
return parseZoneHelper(r, origin, nil, file, 10000)
|
||||
}
|
||||
|
||||
func parseZoneHelper(r io.Reader, origin, file string, chansize int) chan *Token {
|
||||
func parseZoneHelper(r io.Reader, origin string, defttl *ttlState, file string, chansize int) chan *Token {
|
||||
t := make(chan *Token, chansize)
|
||||
go parseZone(r, origin, file, t, 0)
|
||||
go parseZone(r, origin, defttl, file, t, 0)
|
||||
return t
|
||||
}
|
||||
|
||||
func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||
func parseZone(r io.Reader, origin string, defttl *ttlState, f string, t chan *Token, include int) {
|
||||
defer func() {
|
||||
if include == 0 {
|
||||
close(t)
|
||||
@@ -186,18 +193,16 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||
// After detecting these, we know the zRrtype so we can jump to functions
|
||||
// handling the rdata for each of these types.
|
||||
|
||||
if origin == "" {
|
||||
origin = "."
|
||||
}
|
||||
origin = Fqdn(origin)
|
||||
if _, ok := IsDomainName(origin); !ok {
|
||||
t <- &Token{Error: &ParseError{f, "bad initial origin name", lex{}}}
|
||||
return
|
||||
if origin != "" {
|
||||
origin = Fqdn(origin)
|
||||
if _, ok := IsDomainName(origin); !ok {
|
||||
t <- &Token{Error: &ParseError{f, "bad initial origin name", lex{}}}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
st := zExpectOwnerDir // initial state
|
||||
var h RR_Header
|
||||
var defttl uint32 = defaultTtl
|
||||
var prevName string
|
||||
for l := range c {
|
||||
// Lexer spotted an error already
|
||||
@@ -209,27 +214,21 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||
switch st {
|
||||
case zExpectOwnerDir:
|
||||
// We can also expect a directive, like $TTL or $ORIGIN
|
||||
h.Ttl = defttl
|
||||
if defttl != nil {
|
||||
h.Ttl = defttl.ttl
|
||||
}
|
||||
h.Class = ClassINET
|
||||
switch l.value {
|
||||
case zNewline:
|
||||
st = zExpectOwnerDir
|
||||
case zOwner:
|
||||
h.Name = l.token
|
||||
if l.token[0] == '@' {
|
||||
h.Name = origin
|
||||
prevName = h.Name
|
||||
st = zExpectOwnerBl
|
||||
break
|
||||
}
|
||||
if h.Name[l.length-1] != '.' {
|
||||
h.Name = appendOrigin(h.Name, origin)
|
||||
}
|
||||
_, ok := IsDomainName(l.token)
|
||||
name, ok := toAbsoluteName(l.token, origin)
|
||||
if !ok {
|
||||
t <- &Token{Error: &ParseError{f, "bad owner name", l}}
|
||||
return
|
||||
}
|
||||
h.Name = name
|
||||
prevName = h.Name
|
||||
st = zExpectOwnerBl
|
||||
case zDirTtl:
|
||||
@@ -258,8 +257,9 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||
return
|
||||
}
|
||||
h.Ttl = ttl
|
||||
// Don't about the defttl, we should take the $TTL value
|
||||
// defttl = ttl
|
||||
if defttl == nil || !defttl.isByDirective {
|
||||
defttl = &ttlState{ttl, false}
|
||||
}
|
||||
st = zExpectAnyNoTtlBl
|
||||
|
||||
default:
|
||||
@@ -282,20 +282,12 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||
case zBlank:
|
||||
l := <-c
|
||||
if l.value == zString {
|
||||
if _, ok := IsDomainName(l.token); !ok || l.length == 0 || l.err {
|
||||
name, ok := toAbsoluteName(l.token, origin)
|
||||
if !ok {
|
||||
t <- &Token{Error: &ParseError{f, "bad origin name", l}}
|
||||
return
|
||||
}
|
||||
// a new origin is specified.
|
||||
if l.token[l.length-1] != '.' {
|
||||
if origin != "." { // Prevent .. endings
|
||||
neworigin = l.token + "." + origin
|
||||
} else {
|
||||
neworigin = l.token + origin
|
||||
}
|
||||
} else {
|
||||
neworigin = l.token
|
||||
}
|
||||
neworigin = name
|
||||
}
|
||||
case zNewline, zEOF:
|
||||
// Ok
|
||||
@@ -313,7 +305,7 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||
t <- &Token{Error: &ParseError{f, "too deeply nested $INCLUDE", l}}
|
||||
return
|
||||
}
|
||||
parseZone(r1, l.token, neworigin, t, include+1)
|
||||
parseZone(r1, neworigin, defttl, l.token, t, include+1)
|
||||
st = zExpectOwnerDir
|
||||
case zExpectDirTtlBl:
|
||||
if l.value != zBlank {
|
||||
@@ -335,7 +327,7 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||
t <- &Token{Error: &ParseError{f, "expecting $TTL value, not this...", l}}
|
||||
return
|
||||
}
|
||||
defttl = ttl
|
||||
defttl = &ttlState{ttl, true}
|
||||
st = zExpectOwnerDir
|
||||
case zExpectDirOriginBl:
|
||||
if l.value != zBlank {
|
||||
@@ -351,19 +343,12 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||
if e, _ := slurpRemainder(c, f); e != nil {
|
||||
t <- &Token{Error: e}
|
||||
}
|
||||
if _, ok := IsDomainName(l.token); !ok {
|
||||
name, ok := toAbsoluteName(l.token, origin)
|
||||
if !ok {
|
||||
t <- &Token{Error: &ParseError{f, "bad origin name", l}}
|
||||
return
|
||||
}
|
||||
if l.token[l.length-1] != '.' {
|
||||
if origin != "." { // Prevent .. endings
|
||||
origin = l.token + "." + origin
|
||||
} else {
|
||||
origin = l.token + origin
|
||||
}
|
||||
} else {
|
||||
origin = l.token
|
||||
}
|
||||
origin = name
|
||||
st = zExpectOwnerDir
|
||||
case zExpectDirGenerateBl:
|
||||
if l.value != zBlank {
|
||||
@@ -390,6 +375,10 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||
case zExpectAny:
|
||||
switch l.value {
|
||||
case zRrtpe:
|
||||
if defttl == nil {
|
||||
t <- &Token{Error: &ParseError{f, "missing TTL with no previous value", l}}
|
||||
return
|
||||
}
|
||||
h.Rrtype = l.torc
|
||||
st = zExpectRdata
|
||||
case zClass:
|
||||
@@ -402,7 +391,9 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||
return
|
||||
}
|
||||
h.Ttl = ttl
|
||||
// defttl = ttl // don't set the defttl here
|
||||
if defttl == nil || !defttl.isByDirective {
|
||||
defttl = &ttlState{ttl, false}
|
||||
}
|
||||
st = zExpectAnyNoTtlBl
|
||||
default:
|
||||
t <- &Token{Error: &ParseError{f, "expecting RR type, TTL or class, not this...", l}}
|
||||
@@ -441,7 +432,9 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
|
||||
return
|
||||
}
|
||||
h.Ttl = ttl
|
||||
// defttl = ttl // don't set the def ttl anymore
|
||||
if defttl == nil || !defttl.isByDirective {
|
||||
defttl = &ttlState{ttl, false}
|
||||
}
|
||||
st = zExpectRrtypeBl
|
||||
case zRrtpe:
|
||||
h.Rrtype = l.torc
|
||||
@@ -918,6 +911,34 @@ func stringToCm(token string) (e, m uint8, ok bool) {
|
||||
return
|
||||
}
|
||||
|
||||
func toAbsoluteName(name, origin string) (absolute string, ok bool) {
|
||||
// check for an explicit origin reference
|
||||
if name == "@" {
|
||||
// require a nonempty origin
|
||||
if origin == "" {
|
||||
return "", false
|
||||
}
|
||||
return origin, true
|
||||
}
|
||||
|
||||
// require a valid domain name
|
||||
_, ok = IsDomainName(name)
|
||||
if !ok || name == "" {
|
||||
return "", false
|
||||
}
|
||||
|
||||
// check if name is already absolute
|
||||
if name[len(name)-1] == '.' {
|
||||
return name, true
|
||||
}
|
||||
|
||||
// require a nonempty origin
|
||||
if origin == "" {
|
||||
return "", false
|
||||
}
|
||||
return appendOrigin(name, origin), true
|
||||
}
|
||||
|
||||
func appendOrigin(name, origin string) string {
|
||||
if origin == "." {
|
||||
return name + origin
|
||||
|
||||
592
vendor/github.com/miekg/dns/scan_rr.go
сгенерированный
поставляемый
592
vendor/github.com/miekg/dns/scan_rr.go
сгенерированный
поставляемый
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
5
vendor/github.com/miekg/dns/scan_test.go
сгенерированный
поставляемый
5
vendor/github.com/miekg/dns/scan_test.go
сгенерированный
поставляемый
@@ -21,13 +21,16 @@ func TestParseZoneInclude(t *testing.T) {
|
||||
t.Fatalf("could not close tmpfile %q: %s", tmpfile.Name(), err)
|
||||
}
|
||||
|
||||
zone := "$INCLUDE " + tmpfile.Name()
|
||||
zone := "$ORIGIN example.org.\n$INCLUDE " + tmpfile.Name()
|
||||
|
||||
tok := ParseZone(strings.NewReader(zone), "", "")
|
||||
for x := range tok {
|
||||
if x.Error != nil {
|
||||
t.Fatalf("expected no error, but got %s", x.Error)
|
||||
}
|
||||
if x.RR.Header().Name != "foo.example.org." {
|
||||
t.Fatalf("expected %s, but got %s", "foo.example.org.", x.RR.Header().Name)
|
||||
}
|
||||
}
|
||||
|
||||
os.Remove(tmpfile.Name())
|
||||
|
||||
10
vendor/github.com/miekg/dns/server_test.go
сгенерированный
поставляемый
10
vendor/github.com/miekg/dns/server_test.go
сгенерированный
поставляемый
@@ -30,6 +30,16 @@ func HelloServerBadID(w ResponseWriter, req *Msg) {
|
||||
w.WriteMsg(m)
|
||||
}
|
||||
|
||||
func HelloServerEchoAddrPort(w ResponseWriter, req *Msg) {
|
||||
m := new(Msg)
|
||||
m.SetReply(req)
|
||||
|
||||
remoteAddr := w.RemoteAddr().String()
|
||||
m.Extra = make([]RR, 1)
|
||||
m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{remoteAddr}}
|
||||
w.WriteMsg(m)
|
||||
}
|
||||
|
||||
func AnotherHelloServer(w ResponseWriter, req *Msg) {
|
||||
m := new(Msg)
|
||||
m.SetReply(req)
|
||||
|
||||
15
vendor/github.com/miekg/dns/udp.go
сгенерированный
поставляемый
15
vendor/github.com/miekg/dns/udp.go
сгенерированный
поставляемый
@@ -27,8 +27,19 @@ func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
|
||||
return n, &SessionUDP{raddr, oob[:oobn]}, err
|
||||
}
|
||||
|
||||
// WriteToSessionUDP acts just like net.UDPConn.WritetTo(), but uses a *SessionUDP instead of a net.Addr.
|
||||
// WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a *SessionUDP instead of a net.Addr.
|
||||
func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
|
||||
n, _, err := conn.WriteMsgUDP(b, session.context, session.raddr)
|
||||
oob := correctSource(session.context)
|
||||
n, _, err := conn.WriteMsgUDP(b, oob, session.raddr)
|
||||
return n, err
|
||||
}
|
||||
|
||||
// correctSource takes oob data and returns new oob data with the Src equal to the Dst
|
||||
func correctSource(oob []byte) []byte {
|
||||
dst, err := parseUDPSocketDst(oob)
|
||||
// If the destination could not be determined, ignore.
|
||||
if err != nil || dst == nil {
|
||||
return nil
|
||||
}
|
||||
return marshalUDPSocketSrc(dst)
|
||||
}
|
||||
|
||||
115
vendor/github.com/miekg/dns/udp_linux.go
сгенерированный
поставляемый
115
vendor/github.com/miekg/dns/udp_linux.go
сгенерированный
поставляемый
@@ -13,8 +13,34 @@ package dns
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/miekg/dns/internal/socket"
|
||||
)
|
||||
|
||||
const (
|
||||
sizeofInet6Pktinfo = 0x14
|
||||
sizeofInetPktinfo = 0xc
|
||||
protocolIP = 0
|
||||
protocolIPv6 = 41
|
||||
)
|
||||
|
||||
type inetPktinfo struct {
|
||||
Ifindex int32
|
||||
Spec_dst [4]byte /* in_addr */
|
||||
Addr [4]byte /* in_addr */
|
||||
}
|
||||
|
||||
type inet6Pktinfo struct {
|
||||
Addr [16]byte /* in6_addr */
|
||||
Ifindex int32
|
||||
}
|
||||
|
||||
type inetControlMessage struct {
|
||||
Src net.IP // source address, specifying only
|
||||
Dst net.IP // destination address, receiving only
|
||||
}
|
||||
|
||||
// setUDPSocketOptions sets the UDP socket options.
|
||||
// This function is implemented on a per platform basis. See udp_*.go for more details
|
||||
func setUDPSocketOptions(conn *net.UDPConn) error {
|
||||
@@ -103,3 +129,92 @@ func getUDPSocketName(conn *net.UDPConn) (syscall.Sockaddr, error) {
|
||||
defer file.Close()
|
||||
return syscall.Getsockname(int(file.Fd()))
|
||||
}
|
||||
|
||||
// marshalInetPacketInfo marshals a ipv4 control message, returning
|
||||
// the byte slice for the next marshal, if any
|
||||
func marshalInetPacketInfo(b []byte, cm *inetControlMessage) []byte {
|
||||
m := socket.ControlMessage(b)
|
||||
m.MarshalHeader(protocolIP, syscall.IP_PKTINFO, sizeofInetPktinfo)
|
||||
if cm != nil {
|
||||
pi := (*inetPktinfo)(unsafe.Pointer(&m.Data(sizeofInetPktinfo)[0]))
|
||||
if ip := cm.Src.To4(); ip != nil {
|
||||
copy(pi.Spec_dst[:], ip)
|
||||
}
|
||||
}
|
||||
return m.Next(sizeofInetPktinfo)
|
||||
}
|
||||
|
||||
// marshalInet6PacketInfo marshals a ipv6 control message, returning
|
||||
// the byte slice for the next marshal, if any
|
||||
func marshalInet6PacketInfo(b []byte, cm *inetControlMessage) []byte {
|
||||
m := socket.ControlMessage(b)
|
||||
m.MarshalHeader(protocolIPv6, syscall.IPV6_PKTINFO, sizeofInet6Pktinfo)
|
||||
if cm != nil {
|
||||
pi := (*inet6Pktinfo)(unsafe.Pointer(&m.Data(sizeofInet6Pktinfo)[0]))
|
||||
if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
|
||||
copy(pi.Addr[:], ip)
|
||||
}
|
||||
}
|
||||
return m.Next(sizeofInet6Pktinfo)
|
||||
}
|
||||
|
||||
func parseInetPacketInfo(cm *inetControlMessage, b []byte) {
|
||||
pi := (*inetPktinfo)(unsafe.Pointer(&b[0]))
|
||||
if len(cm.Dst) < net.IPv4len {
|
||||
cm.Dst = make(net.IP, net.IPv4len)
|
||||
}
|
||||
copy(cm.Dst, pi.Addr[:])
|
||||
}
|
||||
|
||||
func parseInet6PacketInfo(cm *inetControlMessage, b []byte) {
|
||||
pi := (*inet6Pktinfo)(unsafe.Pointer(&b[0]))
|
||||
if len(cm.Dst) < net.IPv6len {
|
||||
cm.Dst = make(net.IP, net.IPv6len)
|
||||
}
|
||||
copy(cm.Dst, pi.Addr[:])
|
||||
}
|
||||
|
||||
// parseUDPSocketDst takes out-of-band data from ReadMsgUDP and parses it for
|
||||
// the Dst address
|
||||
func parseUDPSocketDst(oob []byte) (net.IP, error) {
|
||||
cm := new(inetControlMessage)
|
||||
ms, err := socket.ControlMessage(oob).Parse()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, m := range ms {
|
||||
lvl, typ, l, err := m.ParseHeader()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if lvl == protocolIPv6 { // IPv6
|
||||
if typ == syscall.IPV6_PKTINFO && l >= sizeofInet6Pktinfo {
|
||||
parseInet6PacketInfo(cm, m.Data(l))
|
||||
}
|
||||
} else if lvl == protocolIP { // IPv4
|
||||
if typ == syscall.IP_PKTINFO && l >= sizeofInetPktinfo {
|
||||
parseInetPacketInfo(cm, m.Data(l))
|
||||
}
|
||||
}
|
||||
}
|
||||
return cm.Dst, nil
|
||||
}
|
||||
|
||||
// marshalUDPSocketSrc takes the given src address and returns out-of-band data
|
||||
// to give to WriteMsgUDP
|
||||
func marshalUDPSocketSrc(src net.IP) []byte {
|
||||
var oob []byte
|
||||
// If the dst is definitely an ipv6, then use ipv6 control to respond
|
||||
// otherwise use ipv4 because the ipv6 marshal ignores ipv4 messages.
|
||||
// See marshalInet6PacketInfo
|
||||
cm := new(inetControlMessage)
|
||||
cm.Src = src
|
||||
if src.To4() == nil {
|
||||
oob = make([]byte, socket.ControlMessageSpace(sizeofInet6Pktinfo))
|
||||
marshalInet6PacketInfo(oob, cm)
|
||||
} else {
|
||||
oob = make([]byte, socket.ControlMessageSpace(sizeofInetPktinfo))
|
||||
marshalInetPacketInfo(oob, cm)
|
||||
}
|
||||
return oob
|
||||
}
|
||||
|
||||
68
vendor/github.com/miekg/dns/udp_linux_test.go
сгенерированный
поставляемый
Обычный файл
68
vendor/github.com/miekg/dns/udp_linux_test.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,68 @@
|
||||
// +build linux,!appengine
|
||||
|
||||
package dns
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseUDPSocketDst(t *testing.T) {
|
||||
// dst is :ffff:100.100.100.100
|
||||
oob := []byte{36, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 100, 100, 100, 100, 2, 0, 0, 0}
|
||||
dst, err := parseUDPSocketDst(oob)
|
||||
if err != nil {
|
||||
t.Fatalf("error parsing ipv6 oob: %v", err)
|
||||
}
|
||||
dst4 := dst.To4()
|
||||
if dst4 == nil {
|
||||
t.Errorf("failed to parse ipv4: %v", dst)
|
||||
} else if dst4.String() != "100.100.100.100" {
|
||||
t.Errorf("unexpected ipv4: %v", dst4)
|
||||
}
|
||||
|
||||
// dst is 2001:db8::1
|
||||
oob = []byte{36, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 50, 0, 0, 0, 32, 1, 13, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}
|
||||
dst, err = parseUDPSocketDst(oob)
|
||||
if err != nil {
|
||||
t.Fatalf("error parsing ipv6 oob: %v", err)
|
||||
}
|
||||
dst6 := dst.To16()
|
||||
if dst6 == nil {
|
||||
t.Errorf("failed to parse ipv6: %v", dst)
|
||||
} else if dst6.String() != "2001:db8::1" {
|
||||
t.Errorf("unexpected ipv6: %v", dst4)
|
||||
}
|
||||
|
||||
// dst is 100.100.100.100 but was received on 10.10.10.10
|
||||
oob = []byte{28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 10, 10, 10, 10, 100, 100, 100, 100, 0, 0, 0, 0}
|
||||
dst, err = parseUDPSocketDst(oob)
|
||||
if err != nil {
|
||||
t.Fatalf("error parsing ipv4 oob: %v", err)
|
||||
}
|
||||
dst4 = dst.To4()
|
||||
if dst4 == nil {
|
||||
t.Errorf("failed to parse ipv4: %v", dst)
|
||||
} else if dst4.String() != "100.100.100.100" {
|
||||
t.Errorf("unexpected ipv4: %v", dst4)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarshalUDPSocketSrc(t *testing.T) {
|
||||
// src is 100.100.100.100
|
||||
exoob := []byte{28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 100, 100, 100, 100, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
oob := marshalUDPSocketSrc(net.ParseIP("100.100.100.100"))
|
||||
if !bytes.Equal(exoob, oob) {
|
||||
t.Errorf("expected ipv4 oob:\n%v", exoob)
|
||||
t.Errorf("actual ipv4 oob:\n%v", oob)
|
||||
}
|
||||
|
||||
// src is 2001:db8::1
|
||||
exoob = []byte{36, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 50, 0, 0, 0, 32, 1, 13, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
oob = marshalUDPSocketSrc(net.ParseIP("2001:db8::1"))
|
||||
if !bytes.Equal(exoob, oob) {
|
||||
t.Errorf("expected ipv6 oob:\n%v", exoob)
|
||||
t.Errorf("actual ipv6 oob:\n%v", oob)
|
||||
}
|
||||
}
|
||||
10
vendor/github.com/miekg/dns/udp_other.go
сгенерированный
поставляемый
10
vendor/github.com/miekg/dns/udp_other.go
сгенерированный
поставляемый
@@ -9,7 +9,9 @@ import (
|
||||
// These do nothing. See udp_linux.go for an example of how to implement this.
|
||||
|
||||
// We tried to adhire to some kind of naming scheme.
|
||||
func setUDPSocketOptions(conn *net.UDPConn) error { return nil }
|
||||
func setUDPSocketOptions4(conn *net.UDPConn) error { return nil }
|
||||
func setUDPSocketOptions6(conn *net.UDPConn) error { return nil }
|
||||
func getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error) { return false, nil }
|
||||
func setUDPSocketOptions(conn *net.UDPConn) error { return nil }
|
||||
func setUDPSocketOptions4(conn *net.UDPConn) error { return nil }
|
||||
func setUDPSocketOptions6(conn *net.UDPConn) error { return nil }
|
||||
func getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error) { return false, nil }
|
||||
func parseUDPSocketDst(oob []byte) (net.IP, error) { return nil, nil }
|
||||
func marshalUDPSocketSrc(src net.IP) []byte { return nil }
|
||||
|
||||
5
vendor/github.com/miekg/dns/udp_windows.go
сгенерированный
поставляемый
5
vendor/github.com/miekg/dns/udp_windows.go
сгенерированный
поставляемый
@@ -4,10 +4,12 @@ package dns
|
||||
|
||||
import "net"
|
||||
|
||||
// SessionUDP holds the remote address
|
||||
type SessionUDP struct {
|
||||
raddr *net.UDPAddr
|
||||
}
|
||||
|
||||
// RemoteAddr returns the remote network address.
|
||||
func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
|
||||
|
||||
// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
|
||||
@@ -21,9 +23,8 @@ func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
|
||||
return n, session, err
|
||||
}
|
||||
|
||||
// WriteToSessionUDP acts just like net.UDPConn.WritetTo(), but uses a *SessionUDP instead of a net.Addr.
|
||||
// WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a *SessionUDP instead of a net.Addr.
|
||||
func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
|
||||
n, err := conn.WriteTo(b, session.raddr)
|
||||
return n, err
|
||||
}
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user