Skip to content

Commit 71b99f1

Browse files
committed
update
1 parent b7fcd28 commit 71b99f1

File tree

8 files changed

+60
-331
lines changed

8 files changed

+60
-331
lines changed

src/net/cgo_stub.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func cgoLookupIP(ctx context.Context, network, name string) (addrs []IPAddr, err
3030
return nil, nil, false
3131
}
3232

33-
func cgoLookupCNAME(ctx context.Context, name string) (cname string, err error, completed bool) {
33+
func cgoLookupCNAME(ctx context.Context, name string) (cname string, err error) {
3434
return "", nil, false
3535
}
3636

src/net/cgo_unix.go

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func cgoLookupServicePort(hints *_C_struct_addrinfo, network, service string) (p
141141
return 0, &DNSError{Err: "unknown port", Name: network + "/" + service}
142142
}
143143

144-
func cgoLookupHostIP(network, name string) (addrs []IPAddr, err error) {
144+
func cgoLookupHostIP(network, name string) (addrs []IPAddr, cname string, err error) {
145145
acquireThread()
146146
defer releaseThread()
147147

@@ -158,7 +158,7 @@ func cgoLookupHostIP(network, name string) (addrs []IPAddr, err error) {
158158

159159
h, err := syscall.BytePtrFromString(name)
160160
if err != nil {
161-
return nil, &DNSError{Err: err.Error(), Name: name}
161+
return nil, "", &DNSError{Err: err.Error(), Name: name}
162162
}
163163
var res *_C_struct_addrinfo
164164
gerrno, err := _C_getaddrinfo((*_C_char)(unsafe.Pointer(h)), nil, &hints, &res)
@@ -185,10 +185,20 @@ func cgoLookupHostIP(network, name string) (addrs []IPAddr, err error) {
185185
isTemporary = addrinfoErrno(gerrno).Temporary()
186186
}
187187

188-
return nil, &DNSError{Err: err.Error(), Name: name, IsNotFound: isErrorNoSuchHost, IsTemporary: isTemporary}
188+
return nil, "", &DNSError{Err: err.Error(), Name: name, IsNotFound: isErrorNoSuchHost, IsTemporary: isTemporary}
189189
}
190190
defer _C_freeaddrinfo(res)
191191

192+
if res != nil {
193+
cname = _C_GoString(*_C_ai_canonname(res))
194+
if cname == "" {
195+
cname = name
196+
}
197+
if len(cname) > 0 && cname[len(cname)-1] != '.' {
198+
cname += "."
199+
}
200+
}
201+
192202
for r := res; r != nil; r = *_C_ai_next(r) {
193203
// We only asked for SOCK_STREAM, but check anyhow.
194204
if *_C_ai_socktype(r) != _C_SOCK_STREAM {
@@ -205,12 +215,13 @@ func cgoLookupHostIP(network, name string) (addrs []IPAddr, err error) {
205215
addrs = append(addrs, addr)
206216
}
207217
}
208-
return addrs, nil
218+
return addrs, cname, nil
209219
}
210220

211221
func cgoLookupIP(ctx context.Context, network, name string) (addrs []IPAddr, err error, completed bool) {
212222
addrs, err = doBlockingWithCtx(ctx, func() ([]IPAddr, error) {
213-
return cgoLookupHostIP(network, name)
223+
addrs, _, err := cgoLookupHostIP(network, name)
224+
return addrs, err
214225
})
215226
return addrs, err, true
216227
}
@@ -293,48 +304,49 @@ func cgoSockaddr(ip IP, zone string) (*_C_struct_sockaddr, _C_socklen_t) {
293304
return nil, 0
294305
}
295306

296-
func isErrorNoSuchHost(err error) bool {
297-
var e *DNSError
298-
if errors.As(err, &e) {
299-
if e.IsNotFound {
300-
return true
301-
}
302-
}
303-
return false
307+
// cgoLookupCanonicalName returns the host canonical name.
308+
func cgoLookupCanonicalName(ctx context.Context, network string, name string) (cname string, err error) {
309+
return doBlockingWithCtx(ctx, func() (string, error) {
310+
_, cname, err := cgoLookupHostIP(network, name)
311+
return cname, err
312+
})
304313
}
305314

306-
func cgoLookupCNAME(ctx context.Context, name string) (cname string, err error, completed bool) {
315+
// cgoLookupCNAME queries the CNAME resource using cgo resSearch.
316+
// It returns the last CNAME found in the entire CNAME chain.
317+
func cgoLookupCNAME(ctx context.Context, name string) (cname string, err error) {
307318
msg, err := resSearch(ctx, name, int(dnsmessage.TypeCNAME), int(dnsmessage.ClassINET))
308319
if err != nil {
309-
return "", &DNSError{Err: err.Error(), Name: name, IsNotFound: err == errNoSuchHost}, true
320+
return "", &DNSError{Err: err.Error(), Name: name, IsNotFound: err == errNoSuchHost}
310321
}
311322

312323
var p dnsmessage.Parser
313324
_, err = p.Start(msg)
314325
if err != nil {
315-
return "", &DNSError{Err: errCannotUnmarshalDNSMessage.Error(), Name: name}, true
326+
return "", &DNSError{Err: errCannotUnmarshalDNSMessage.Error(), Name: name}
316327
}
317328

318329
q, err := p.Question()
319330
if err != nil {
320-
return "", &DNSError{Err: errCannotUnmarshalDNSMessage.Error(), Name: name}, true
331+
return "", &DNSError{Err: errCannotUnmarshalDNSMessage.Error(), Name: name}
321332
}
322333

323-
if err := p.SkipAllQuestions(); err != nil {
324-
return "", &DNSError{Err: errCannotUnmarshalDNSMessage.Error(), Name: name}, true
334+
// Multiple questions, this should never happen.
335+
if err := p.SkipQuestion(); err != dnsmessage.ErrSectionDone {
336+
return "", &DNSError{Err: errCannotUnmarshalDNSMessage.Error(), Name: name}
325337
}
326338

327339
// Using name from question, not the one provided in function arguments,
328340
// because of possible search domain in resolv.conf.
329-
cname, err = lastCNAMEinChain(q.Name.String(), p)
341+
cname, err = lastCNAMEinChain(q.Name, p)
330342
if err != nil {
331343
return "", &DNSError{
332344
Err: err.Error(),
333345
Name: name,
334-
}, true
346+
}
335347
}
336348

337-
return cname, nil, true
349+
return cname, nil
338350
}
339351

340352
// resSearch will make a call to the 'res_nsearch' routine in the C library

src/net/cgo_unix_cgo.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ func _C_malloc(n uintptr) unsafe.Pointer { return C.malloc(C.size_t(n)) }
6060
func _C_free(p unsafe.Pointer) { C.free(p) }
6161

6262
func _C_ai_addr(ai *_C_struct_addrinfo) **_C_struct_sockaddr { return &ai.ai_addr }
63+
func _C_ai_canonname(ai *_C_struct_addrinfo) **_C_char { return &ai.ai_canonname }
6364
func _C_ai_family(ai *_C_struct_addrinfo) *_C_int { return &ai.ai_family }
6465
func _C_ai_flags(ai *_C_struct_addrinfo) *_C_int { return &ai.ai_flags }
6566
func _C_ai_next(ai *_C_struct_addrinfo) **_C_struct_addrinfo { return &ai.ai_next }

src/net/cgo_unix_syscall.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ func _C_malloc(n uintptr) unsafe.Pointer {
5353
}
5454

5555
func _C_ai_addr(ai *_C_struct_addrinfo) **_C_struct_sockaddr { return &ai.Addr }
56+
func _C_ai_canonname(ai *_C_struct_addrinfo) **_C_char { return &ai.Canonname }
5657
func _C_ai_family(ai *_C_struct_addrinfo) *_C_int { return &ai.Family }
5758
func _C_ai_flags(ai *_C_struct_addrinfo) *_C_int { return &ai.Flags }
5859
func _C_ai_next(ai *_C_struct_addrinfo) **_C_struct_addrinfo { return &ai.Next }

src/net/dnsclient_unix.go

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,7 @@ func (r *Resolver) goLookupCNAME(ctx context.Context, host string, order hostLoo
813813
continue
814814
}
815815

816-
cname, err := lastCNAMEinChain(fqdn, p)
816+
cname, err := lastCNAMEinChain(dnsmessage.MustNewName(fqdn), p)
817817
if err == nil {
818818
return cname, nil
819819
}
@@ -894,19 +894,13 @@ func (r *Resolver) goLookupPTR(ctx context.Context, addr string, conf *dnsConfig
894894
}
895895

896896
// lastCNAMEinChain returs the last CNAME in CNAME chain.
897-
func lastCNAMEinChain(queryName string, p dnsmessage.Parser) (string, error) {
898-
rooted := len(queryName) > 0 && queryName[len(queryName)-1] == '.'
899-
if !rooted {
900-
queryName += "."
901-
}
902-
903-
curName, err := dnsmessage.NewName(queryName)
904-
if err != nil {
905-
// This should never fail.
906-
return "", err
907-
}
897+
func lastCNAMEinChain(queryName dnsmessage.Name, p dnsmessage.Parser) (string, error) {
898+
curName := queryName
908899

900+
// All (or most) responses contain the CNAMEs in order
901+
// so this in practice should never be used.
909902
var cnames map[dnsmessage.Name]dnsmessage.Name
903+
910904
for {
911905
hdr, err := p.AnswerHeader()
912906
if err == dnsmessage.ErrSectionDone {
@@ -922,6 +916,7 @@ func lastCNAMEinChain(queryName string, p dnsmessage.Parser) (string, error) {
922916
if err != nil {
923917
return "", errCannotUnmarshalDNSMessage
924918
}
919+
// TODO: This should be case insensitive. FIX
925920
if curName == hdr.Name {
926921
curName = cname.CNAME
927922
continue

src/net/dnsclient_unix_test.go

Lines changed: 0 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -2599,101 +2599,6 @@ func TestLookupOrderFilesNoSuchHost(t *testing.T) {
25992599
}
26002600
}
26012601

2602-
func TestLastCNAMEInChain(t *testing.T) {
2603-
type cname struct {
2604-
from string
2605-
to string
2606-
}
2607-
2608-
var tests = []struct {
2609-
testName string
2610-
2611-
queryName string
2612-
cnames []cname
2613-
expectCname string
2614-
}{
2615-
{
2616-
testName: "one CNAME",
2617-
queryName: "go.dev.",
2618-
expectCname: "cname.go.dev.",
2619-
cnames: []cname{{"go.dev.", "cname.go.dev."}},
2620-
},
2621-
{
2622-
testName: "two sequantial CNAMEs",
2623-
queryName: "go.dev.",
2624-
expectCname: "cname2.go.dev.",
2625-
cnames: []cname{
2626-
{"go.dev.", "cname.go.dev."},
2627-
{"cname.go.dev.", "cname2.go.dev."},
2628-
},
2629-
},
2630-
{
2631-
testName: "two non-sequantial CNAMEs",
2632-
queryName: "go.dev.",
2633-
expectCname: "cname2.go.dev.",
2634-
cnames: []cname{
2635-
{"cname.go.dev.", "cname2.go.dev."},
2636-
{"go.dev.", "cname.go.dev."},
2637-
},
2638-
},
2639-
{
2640-
testName: "five non-sequantial CNAMEs",
2641-
queryName: "go.dev.",
2642-
expectCname: "cname5.go.dev.",
2643-
cnames: []cname{
2644-
{"cname4.go.dev.", "cname5.go.dev."},
2645-
{"cname2.go.dev.", "cname3.go.dev."},
2646-
{"cname.go.dev.", "cname2.go.dev."},
2647-
{"go.dev.", "cname.go.dev."},
2648-
{"cname3.go.dev.", "cname4.go.dev."},
2649-
},
2650-
},
2651-
}
2652-
2653-
for _, v := range tests {
2654-
msgNotPacked := dnsmessage.Message{}
2655-
for _, v := range v.cnames {
2656-
msgNotPacked.Answers = append(msgNotPacked.Answers, dnsmessage.Resource{
2657-
Header: dnsmessage.ResourceHeader{
2658-
Name: dnsmessage.MustNewName(v.from),
2659-
Type: dnsmessage.TypeCNAME,
2660-
Class: dnsmessage.ClassINET,
2661-
},
2662-
Body: &dnsmessage.CNAMEResource{CNAME: dnsmessage.MustNewName(v.to)},
2663-
})
2664-
}
2665-
2666-
msg, err := msgNotPacked.Pack()
2667-
if err != nil {
2668-
t.Errorf("%v: failed to pack: %v", v.testName, err)
2669-
continue
2670-
}
2671-
2672-
var p dnsmessage.Parser
2673-
_, err = p.Start(msg)
2674-
if err != nil {
2675-
t.Errorf("%v: failed to unpack: %v", v.testName, err)
2676-
continue
2677-
}
2678-
2679-
err = p.SkipAllQuestions()
2680-
if err != nil {
2681-
t.Errorf("%v: failed to skip all questions: %v", v.testName, err)
2682-
continue
2683-
}
2684-
2685-
cname, err := lastCNAMEinChain(v.queryName, p)
2686-
if err != nil {
2687-
t.Errorf("%v: lastCNAMEinChain() error: %v", v.testName, err)
2688-
continue
2689-
}
2690-
2691-
if cname != v.expectCname {
2692-
t.Errorf("%v: expected: %v, got: %v", v.testName, v.expectCname, cname)
2693-
}
2694-
}
2695-
}
2696-
26972602
func TestLookupCNAMENoSuchHost(t *testing.T) {
26982603
if fixup := forceGoDNS(); fixup != nil {
26992604
_, err := LookupCNAME("invalid.invalid")

0 commit comments

Comments
 (0)