mirror of
https://github.com/golang/go
synced 2024-11-24 00:50:10 -07:00
net: allocate res_state entirely in C memory
The linux-amd64-wsl builder was failing because the res_nsearch implementation was storing pointer to the res_state's own fields in other fields in the res_state. If the res_state is Go memory, this looks like pointers to Go pointers. Moving the res_state to C memory avoids the problem. The linux-amd64-wsl builder has been fixed a different way by replacing res_nsearch with res_search on Linux, where it is thread-safe. But other systems that still need to use res_nsearch (such as macOS) may run into the same kind of problem, so it is probably still worth arranging for the res_state to live entirely in C memory. Fixes #56658 (again). Change-Id: I58a14e72c866eaceb02ad828854a1f626b9b8e73 Reviewed-on: https://go-review.googlesource.com/c/go/+/448798 Run-TryBot: Russ Cox <rsc@golang.org> Auto-Submit: Russ Cox <rsc@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
parent
8befe0e408
commit
896faf306c
@ -331,11 +331,12 @@ func cgoLookupCNAME(ctx context.Context, name string) (cname string, err error,
|
|||||||
// resSearch will make a call to the 'res_nsearch' routine in the C library
|
// resSearch will make a call to the 'res_nsearch' routine in the C library
|
||||||
// and parse the output as a slice of DNS resources.
|
// and parse the output as a slice of DNS resources.
|
||||||
func resSearch(ctx context.Context, hostname string, rtype, class int) ([]dnsmessage.Resource, error) {
|
func resSearch(ctx context.Context, hostname string, rtype, class int) ([]dnsmessage.Resource, error) {
|
||||||
var state _C_struct___res_state
|
state := (*_C_struct___res_state)(_C_malloc(unsafe.Sizeof(_C_struct___res_state{})))
|
||||||
if err := _C_res_ninit(&state); err != nil {
|
defer _C_free(unsafe.Pointer(state))
|
||||||
|
if err := _C_res_ninit(state); err != nil {
|
||||||
return nil, errors.New("res_ninit failure: " + err.Error())
|
return nil, errors.New("res_ninit failure: " + err.Error())
|
||||||
}
|
}
|
||||||
defer _C_res_nclose(&state)
|
defer _C_res_nclose(state)
|
||||||
|
|
||||||
// Some res_nsearch implementations (like macOS) do not set errno.
|
// Some res_nsearch implementations (like macOS) do not set errno.
|
||||||
// They set h_errno, which is not per-thread and useless to us.
|
// They set h_errno, which is not per-thread and useless to us.
|
||||||
@ -350,7 +351,7 @@ func resSearch(ctx context.Context, hostname string, rtype, class int) ([]dnsmes
|
|||||||
defer _C_free(unsafe.Pointer(buf))
|
defer _C_free(unsafe.Pointer(buf))
|
||||||
s := _C_CString(hostname)
|
s := _C_CString(hostname)
|
||||||
defer _C_FreeCString(s)
|
defer _C_FreeCString(s)
|
||||||
size, err := _C_res_nsearch(&state, s, class, rtype, buf, bufSize)
|
size, err := _C_res_nsearch(state, s, class, rtype, buf, bufSize)
|
||||||
if size <= 0 || size > bufSize {
|
if size <= 0 || size > bufSize {
|
||||||
return nil, errors.New("res_nsearch failure")
|
return nil, errors.New("res_nsearch failure")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user