Skip to content

Commit

Permalink
net: use libc (not cgo) for DNS on macOS
Browse files Browse the repository at this point in the history
Change the macOS implementation to use libc calls.
Using libc calls directly is what we do for all the runtime and os syscalls.
Doing so here as well improves consistency and also makes it possible
to cross-compile (from non-Mac systems) macOS binaries that use the
native name resolver.

Fixes #12524.

Change-Id: I011f4fcc5c50fbb5396e494889765dcbb9342336
Reviewed-on: https://go-review.googlesource.com/c/go/+/446178
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
  • Loading branch information
rsc committed Nov 1, 2022
1 parent 661e931 commit a3559f3
Show file tree
Hide file tree
Showing 11 changed files with 467 additions and 70 deletions.
12 changes: 12 additions & 0 deletions src/internal/syscall/unix/asm_darwin.s
Expand Up @@ -6,3 +6,15 @@

TEXT ·libc_getentropy_trampoline(SB),NOSPLIT,$0-0
JMP libc_getentropy(SB)

TEXT ·libc_getaddrinfo_trampoline(SB),NOSPLIT,$0-0
JMP libc_getaddrinfo(SB)

TEXT ·libc_freeaddrinfo_trampoline(SB),NOSPLIT,$0-0
JMP libc_freeaddrinfo(SB)

TEXT ·libc_getnameinfo_trampoline(SB),NOSPLIT,$0-0
JMP libc_getnameinfo(SB)

TEXT ·libc_gai_strerror_trampoline(SB),NOSPLIT,$0-0
JMP libc_gai_strerror(SB)
4 changes: 0 additions & 4 deletions src/internal/syscall/unix/getentropy_darwin.go
Expand Up @@ -8,7 +8,6 @@ package unix

import (
"internal/abi"
"syscall"
"unsafe"
)

Expand All @@ -27,6 +26,3 @@ func GetEntropy(p []byte) error {
}
return nil
}

//go:linkname syscall_syscall syscall.syscall
func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
116 changes: 116 additions & 0 deletions src/internal/syscall/unix/net_darwin.go
@@ -0,0 +1,116 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package unix

import (
"internal/abi"
"syscall"
"unsafe"
)

const (
AI_CANONNAME = 0x2
AI_ALL = 0x100
AI_V4MAPPED = 0x800
AI_MASK = 0x1407

EAI_AGAIN = 2
EAI_NONAME = 8
EAI_SYSTEM = 11
EAI_OVERFLOW = 14

NI_NAMEREQD = 4
)

type Addrinfo struct {
Flags int32
Family int32
Socktype int32
Protocol int32
Addrlen uint32
Canonname *byte
Addr *syscall.RawSockaddr
Next *Addrinfo
}

//go:cgo_import_dynamic libc_getaddrinfo getaddrinfo "/usr/lib/libSystem.B.dylib"
func libc_getaddrinfo_trampoline()

func Getaddrinfo(hostname, servname *byte, hints *Addrinfo, res **Addrinfo) (int, error) {
gerrno, _, errno := syscall_syscall6(abi.FuncPCABI0(libc_getaddrinfo_trampoline),
uintptr(unsafe.Pointer(hostname)),
uintptr(unsafe.Pointer(servname)),
uintptr(unsafe.Pointer(hints)),
uintptr(unsafe.Pointer(res)),
0,
0)
var err error
if errno != 0 {
err = errno
}
return int(gerrno), err
}

//go:cgo_import_dynamic libc_freeaddrinfo freeaddrinfo "/usr/lib/libSystem.B.dylib"
func libc_freeaddrinfo_trampoline()

func Freeaddrinfo(ai *Addrinfo) {
syscall_syscall6(abi.FuncPCABI0(libc_freeaddrinfo_trampoline),
uintptr(unsafe.Pointer(ai)),
0, 0, 0, 0, 0)
}

//go:cgo_import_dynamic libc_getnameinfo getnameinfo "/usr/lib/libSystem.B.dylib"
func libc_getnameinfo_trampoline()

func Getnameinfo(sa *syscall.RawSockaddr, salen int, host *byte, hostlen int, serv *byte, servlen int, flags int) (int, error) {
gerrno, _, errno := syscall_syscall9(abi.FuncPCABI0(libc_getnameinfo_trampoline),
uintptr(unsafe.Pointer(sa)),
uintptr(salen),
uintptr(unsafe.Pointer(host)),
uintptr(hostlen),
uintptr(unsafe.Pointer(serv)),
uintptr(servlen),
uintptr(flags),
0,
0)
var err error
if errno != 0 {
err = errno
}
return int(gerrno), err
}

//go:cgo_import_dynamic libc_gai_strerror gai_strerror "/usr/lib/libSystem.B.dylib"
func libc_gai_strerror_trampoline()

func GaiStrerror(ecode int) string {
r1, _, _ := syscall_syscall(abi.FuncPCABI0(libc_gai_strerror_trampoline),
uintptr(ecode),
0, 0)
return GoString((*byte)(unsafe.Pointer(r1)))
}

func GoString(p *byte) string {
if p == nil {
return ""
}
x := unsafe.Slice(p, 1e9)
for i, c := range x {
if c == 0 {
return string(x[:i])
}
}
return ""
}

//go:linkname syscall_syscall syscall.syscall
func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)

//go:linkname syscall_syscall6 syscall.syscall6
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)

//go:linkname syscall_syscall9 syscall.syscall9
func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
2 changes: 1 addition & 1 deletion src/net/cgo_resnew.go
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build cgo && !netgo && (darwin || (linux && !android) || netbsd || solaris)
//go:build cgo && !netgo && ((linux && !android) || netbsd || solaris)

package net

Expand Down
2 changes: 1 addition & 1 deletion src/net/cgo_sockold.go
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build cgo && !netgo && (aix || darwin || dragonfly || freebsd || netbsd || openbsd)
//go:build cgo && !netgo && (aix || dragonfly || freebsd || netbsd || openbsd)

package net

Expand Down

0 comments on commit a3559f3

Please sign in to comment.