From 93587d3591f6cb5cd21951a03c3aa750873f2601 Mon Sep 17 00:00:00 2001 From: Mateusz Poliwczak Date: Thu, 1 Dec 2022 17:54:49 +0000 Subject: [PATCH] net: retry with bigger buffer in resSearch Glibc returns size > bufSize, when the entire dns reply does not fit inside the provided buffer. Change-Id: Ie1c1c6a3411880bd8bdb4371f1f1b7bcce837ea2 GitHub-Last-Rev: 488cd3ed0db2a86433aa921117b8f1e9192b1fa5 GitHub-Pull-Request: golang/go#57020 Reviewed-on: https://go-review.googlesource.com/c/go/+/454395 TryBot-Result: Gopher Robot Reviewed-by: Russ Cox Auto-Submit: Ian Lance Taylor Reviewed-by: Ian Lance Taylor Run-TryBot: Ian Lance Taylor --- src/net/cgo_unix.go | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/net/cgo_unix.go b/src/net/cgo_unix.go index b9759d05a3..ef003b78bd 100644 --- a/src/net/cgo_unix.go +++ b/src/net/cgo_unix.go @@ -346,17 +346,30 @@ func resSearch(ctx context.Context, hostname string, rtype, class int) ([]dnsmes // giving us no way to find out how big the packet is. // For now, we are willing to take res_search's word that there's nothing // useful in the response, even though there *is* a response. - const bufSize = 1500 - buf := (*_C_uchar)(_C_malloc(bufSize)) + bufSize := maxDNSPacketSize + buf := (*_C_uchar)(_C_malloc(uintptr(bufSize))) defer _C_free(unsafe.Pointer(buf)) + s := _C_CString(hostname) defer _C_FreeCString(s) - size, err := _C_res_nsearch(state, s, class, rtype, buf, bufSize) - if size <= 0 || size > bufSize { - return nil, errors.New("res_nsearch failure") + + for { + size, _ := _C_res_nsearch(state, s, class, rtype, buf, bufSize) + if size <= 0 || size > 0xffff { + return nil, errors.New("res_nsearch failure") + } + if size <= bufSize { + break + } + + // Allocate a bigger buffer to fit the entire msg. + _C_free(unsafe.Pointer(buf)) + bufSize = size + buf = (*_C_uchar)(_C_malloc(uintptr(bufSize))) } + var p dnsmessage.Parser - if _, err := p.Start(unsafe.Slice((*byte)(unsafe.Pointer(buf)), size)); err != nil { + if _, err := p.Start(unsafe.Slice((*byte)(unsafe.Pointer(buf)), bufSize)); err != nil { return nil, err } p.SkipAllQuestions() -- 2.50.0