]> Cypherpunks repositories - gostls13.git/commitdiff
net: retry with bigger buffer in resSearch
authorMateusz Poliwczak <mpoliwczak34@gmail.com>
Thu, 1 Dec 2022 17:54:49 +0000 (17:54 +0000)
committerGopher Robot <gobot@golang.org>
Thu, 1 Dec 2022 21:00:45 +0000 (21:00 +0000)
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 <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>

src/net/cgo_unix.go

index b9759d05a3a979e58aa023ac9fb2299a110b0898..ef003b78bd5c8b9d5d8c8ed6fa22763a50a01fbc 100644 (file)
@@ -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()