mirror of
				https://github.com/golang/go.git
				synced 2025-10-31 00:30:57 +00:00 
			
		
		
		
	net: prefer error for original name on lookups
With certain names and search domain configurations the returned error would be one encountered while querying a generated name instead of the original name. This caused confusion when a manual check of the same name produced different results. Now prefer errors encountered for the original name. Also makes the low-level DNS connection plumbing swappable in tests enabling tighter control over responses without relying on the network. Fixes #12712 Updates #13295 Change-Id: I780d628a762006bb11899caf20b5f97b462a717f Reviewed-on: https://go-review.googlesource.com/16953 Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
		
							parent
							
								
									be7544be23
								
							
						
					
					
						commit
						5c0629b503
					
				
					 3 changed files with 98 additions and 5 deletions
				
			
		|  | @ -424,6 +424,57 @@ func TestGoLookupIPOrderFallbackToFile(t *testing.T) { | |||
| 	defer conf.teardown() | ||||
| } | ||||
| 
 | ||||
| // Issue 12712. | ||||
| // When using search domains, return the error encountered | ||||
| // querying the original name instead of an error encountered | ||||
| // querying a generated name. | ||||
| func TestErrorForOriginalNameWhenSearching(t *testing.T) { | ||||
| 	const fqdn = "doesnotexist.domain" | ||||
| 
 | ||||
| 	origTestHookDNSDialer := testHookDNSDialer | ||||
| 	defer func() { testHookDNSDialer = origTestHookDNSDialer }() | ||||
| 
 | ||||
| 	conf, err := newResolvConfTest() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	defer conf.teardown() | ||||
| 
 | ||||
| 	if err := conf.writeAndUpdate([]string{"search servfail"}); err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	d := &fakeDNSConn{} | ||||
| 	testHookDNSDialer = func(time.Duration) dnsDialer { return d } | ||||
| 
 | ||||
| 	d.rh = func(q *dnsMsg) (*dnsMsg, error) { | ||||
| 		r := &dnsMsg{ | ||||
| 			dnsMsgHdr: dnsMsgHdr{ | ||||
| 				id: q.id, | ||||
| 			}, | ||||
| 		} | ||||
| 
 | ||||
| 		switch q.question[0].Name { | ||||
| 		case fqdn + ".servfail.": | ||||
| 			r.rcode = dnsRcodeServerFailure | ||||
| 		default: | ||||
| 			r.rcode = dnsRcodeNameError | ||||
| 		} | ||||
| 
 | ||||
| 		return r, nil | ||||
| 	} | ||||
| 
 | ||||
| 	_, err = goLookupIP(fqdn) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("expected an error") | ||||
| 	} | ||||
| 
 | ||||
| 	want := &DNSError{Name: fqdn, Err: errNoSuchHost.Error()} | ||||
| 	if err, ok := err.(*DNSError); !ok || err.Name != want.Name || err.Err != want.Err { | ||||
| 		t.Errorf("got %v; want %v", err, want) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func BenchmarkGoLookupIP(b *testing.B) { | ||||
| 	testHookUninstaller.Do(uninstallTestHooks) | ||||
| 
 | ||||
|  | @ -461,3 +512,31 @@ func BenchmarkGoLookupIPWithBrokenNameServer(b *testing.B) { | |||
| 		goLookupIP("www.example.com") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| type fakeDNSConn struct { | ||||
| 	// last query | ||||
| 	q *dnsMsg | ||||
| 	// reply handler | ||||
| 	rh func(*dnsMsg) (*dnsMsg, error) | ||||
| } | ||||
| 
 | ||||
| func (f *fakeDNSConn) dialDNS(n, s string) (dnsConn, error) { | ||||
| 	return f, nil | ||||
| } | ||||
| 
 | ||||
| func (f *fakeDNSConn) Close() error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (f *fakeDNSConn) SetDeadline(time.Time) error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (f *fakeDNSConn) writeDNSQuery(q *dnsMsg) error { | ||||
| 	f.q = q | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (f *fakeDNSConn) readDNSResponse() (*dnsMsg, error) { | ||||
| 	return f.rh(f.q) | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Peterson
						Dan Peterson