mirror of https://github.com/golang/go.git
parent
c226f6432d
commit
8ce0afdb2b
|
|
@ -131,13 +131,19 @@ func dnsStreamRoundTrip(c Conn, id uint16, query dnsmessage.Question, b []byte)
|
|||
}
|
||||
|
||||
// exchange sends a query on the connection and hopes for a response.
|
||||
func (r *Resolver) exchange(ctx context.Context, server string, q dnsmessage.Question, timeout time.Duration) (dnsmessage.Parser, dnsmessage.Header, error) {
|
||||
func (r *Resolver) exchange(ctx context.Context, server string, q dnsmessage.Question, timeout time.Duration, usetcp bool) (dnsmessage.Parser, dnsmessage.Header, error) {
|
||||
q.Class = dnsmessage.ClassINET
|
||||
id, udpReq, tcpReq, err := newRequest(q)
|
||||
if err != nil {
|
||||
return dnsmessage.Parser{}, dnsmessage.Header{}, errCannotMarshalDNSMessage
|
||||
}
|
||||
for _, network := range []string{"udp", "tcp"} {
|
||||
var networks []string
|
||||
if usetcp {
|
||||
networks = []string{"tcp"}
|
||||
} else {
|
||||
networks = []string{"udp", "tcp"}
|
||||
}
|
||||
for _, network := range networks {
|
||||
ctx, cancel := context.WithDeadline(ctx, time.Now().Add(timeout))
|
||||
defer cancel()
|
||||
|
||||
|
|
@ -241,7 +247,7 @@ func (r *Resolver) tryOneName(ctx context.Context, cfg *dnsConfig, name string,
|
|||
for j := uint32(0); j < sLen; j++ {
|
||||
server := cfg.servers[(serverOffset+j)%sLen]
|
||||
|
||||
p, h, err := r.exchange(ctx, server, q, cfg.timeout)
|
||||
p, h, err := r.exchange(ctx, server, q, cfg.timeout, cfg.usetcp)
|
||||
if err != nil {
|
||||
dnsErr := &DNSError{
|
||||
Err: err.Error(),
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ func TestDNSTransportFallback(t *testing.T) {
|
|||
for _, tt := range dnsTransportFallbackTests {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
_, h, err := r.exchange(ctx, tt.server, tt.question, time.Second)
|
||||
_, h, err := r.exchange(ctx, tt.server, tt.question, time.Second, false)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
|
|
@ -137,7 +137,7 @@ func TestSpecialDomainName(t *testing.T) {
|
|||
for _, tt := range specialDomainNameTests {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
_, h, err := r.exchange(ctx, server, tt.question, 3*time.Second)
|
||||
_, h, err := r.exchange(ctx, server, tt.question, 3*time.Second, false)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
|
|
@ -1564,7 +1564,7 @@ func TestDNSDialTCP(t *testing.T) {
|
|||
}
|
||||
r := Resolver{PreferGo: true, Dial: fake.DialContext}
|
||||
ctx := context.Background()
|
||||
_, _, err := r.exchange(ctx, "0.0.0.0", mustQuestion("com.", dnsmessage.TypeALL, dnsmessage.ClassINET), time.Second)
|
||||
_, _, err := r.exchange(ctx, "0.0.0.0", mustQuestion("com.", dnsmessage.TypeALL, dnsmessage.ClassINET), time.Second, false)
|
||||
if err != nil {
|
||||
t.Fatal("exhange failed:", err)
|
||||
}
|
||||
|
|
@ -1695,3 +1695,30 @@ func TestSingleRequestLookup(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Issue 29358. Add configuration knob to force TCP-only DNS requests in the pure Go resolver.
|
||||
func TestDNSUseTCP(t *testing.T) {
|
||||
fake := fakeDNSServer{
|
||||
rh: func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) {
|
||||
r := dnsmessage.Message{
|
||||
Header: dnsmessage.Header{
|
||||
ID: q.Header.ID,
|
||||
Response: true,
|
||||
RCode: dnsmessage.RCodeSuccess,
|
||||
},
|
||||
Questions: q.Questions,
|
||||
}
|
||||
if n == "udp" {
|
||||
t.Fatal("udp protocol was used instead of tcp")
|
||||
}
|
||||
return r, nil
|
||||
},
|
||||
}
|
||||
r := Resolver{PreferGo: true, Dial: fake.DialContext}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
_, _, err := r.exchange(ctx, "0.0.0.0", mustQuestion("com.", dnsmessage.TypeALL, dnsmessage.ClassINET), time.Second, true)
|
||||
if err != nil {
|
||||
t.Fatal("exchange failed:", err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ type dnsConfig struct {
|
|||
mtime time.Time // time of resolv.conf modification
|
||||
soffset uint32 // used by serverOffset
|
||||
singleRequest bool // use sequential A and AAAA queries instead of parallel queries
|
||||
usetcp bool // force usage of TCP for DNS resolutions
|
||||
}
|
||||
|
||||
// See resolv.conf(5) on a Linux machine.
|
||||
|
|
@ -123,6 +124,8 @@ func dnsReadConfig(filename string) *dnsConfig {
|
|||
// This option disables the behavior and makes glibc
|
||||
// perform the IPv6 and IPv4 requests sequentially."
|
||||
conf.singleRequest = true
|
||||
case s == "use-vc":
|
||||
conf.usetcp = true
|
||||
default:
|
||||
conf.unknownOpt = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,6 +124,17 @@ var dnsReadConfigTests = []struct {
|
|||
search: []string{"domain.local."},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "testdata/use-vc-resolv.conf",
|
||||
want: &dnsConfig{
|
||||
servers: defaultNS,
|
||||
ndots: 1,
|
||||
usetcp: true,
|
||||
timeout: 5 * time.Second,
|
||||
attempts: 2,
|
||||
search: []string{"domain.local."},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestDNSReadConfig(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
options use-vc
|
||||
Loading…
Reference in New Issue