Use socketcall on x86

This commit is contained in:
Jason A. Donenfeld 2018-04-18 07:54:39 +02:00
parent eb6728400b
commit 0b940a7568
3 changed files with 89 additions and 44 deletions

View file

@ -391,14 +391,7 @@ func send6(sock int, end *NativeEndpoint, buff []byte) error {
msghdr.SetControllen(int(unsafe.Sizeof(cmsg)))
// sendmsg(sock, &msghdr, 0)
_, _, errno := unix.Syscall(
unix.SYS_SENDMSG,
uintptr(sock),
uintptr(unsafe.Pointer(&msghdr)),
0,
)
_, _, errno := sendmsg(sock, &msghdr, 0)
if errno == 0 {
return nil
@ -409,12 +402,7 @@ func send6(sock int, end *NativeEndpoint, buff []byte) error {
if errno == unix.EINVAL {
end.ClearSrc()
cmsg.pktinfo = unix.Inet6Pktinfo{}
_, _, errno = unix.Syscall(
unix.SYS_SENDMSG,
uintptr(sock),
uintptr(unsafe.Pointer(&msghdr)),
0,
)
_, _, errno = sendmsg(sock, &msghdr, 0)
}
return errno
@ -455,26 +443,14 @@ func send4(sock int, end *NativeEndpoint, buff []byte) error {
}
msghdr.SetControllen(int(unsafe.Sizeof(cmsg)))
// sendmsg(sock, &msghdr, 0)
_, _, errno := unix.Syscall(
unix.SYS_SENDMSG,
uintptr(sock),
uintptr(unsafe.Pointer(&msghdr)),
0,
)
_, _, errno := sendmsg(sock, &msghdr, 0)
// clear source and try again
if errno == unix.EINVAL {
end.ClearSrc()
cmsg.pktinfo = unix.Inet4Pktinfo{}
_, _, errno = unix.Syscall(
unix.SYS_SENDMSG,
uintptr(sock),
uintptr(unsafe.Pointer(&msghdr)),
0,
)
_, _, errno = sendmsg(sock, &msghdr, 0)
}
// errno = 0 is still an error instance
@ -507,14 +483,7 @@ func receive4(sock int, buff []byte, end *NativeEndpoint) (int, error) {
msghdr.Control = (*byte)(unsafe.Pointer(&cmsg))
msghdr.SetControllen(int(unsafe.Sizeof(cmsg)))
// recvmsg(sock, &mskhdr, 0)
size, _, errno := unix.Syscall(
unix.SYS_RECVMSG,
uintptr(sock),
uintptr(unsafe.Pointer(&msghdr)),
0,
)
size, _, errno := recvmsg(sock, &msghdr, 0)
if errno != 0 {
return 0, errno
@ -555,14 +524,7 @@ func receive6(sock int, buff []byte, end *NativeEndpoint) (int, error) {
msg.Control = (*byte)(unsafe.Pointer(&cmsg))
msg.SetControllen(int(unsafe.Sizeof(cmsg)))
// recvmsg(sock, &mskhdr, 0)
size, _, errno := unix.Syscall(
unix.SYS_RECVMSG,
uintptr(sock),
uintptr(unsafe.Pointer(&msg)),
0,
)
size, _, errno := recvmsg(sock, &msg, 0)
if errno != 0 {
return 0, errno

30
syscall_linux.go Normal file
View file

@ -0,0 +1,30 @@
// +build linux,!386
/* Copyright 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/
package main
import (
"golang.org/x/sys/unix"
"syscall"
"unsafe"
)
func sendmsg(fd int, msghdr *unix.Msghdr, flags int) (uintptr, uintptr, syscall.Errno) {
return unix.Syscall(
unix.SYS_SENDMSG,
uintptr(fd),
uintptr(unsafe.Pointer(msghdr)),
uintptr(flags),
)
}
func recvmsg(fd int, msghdr *unix.Msghdr, flags int) (uintptr, uintptr, syscall.Errno) {
return unix.Syscall(
unix.SYS_RECVMSG,
uintptr(fd),
uintptr(unsafe.Pointer(msghdr)),
uintptr(flags),
)
}

53
syscall_linux_386.go Normal file
View file

@ -0,0 +1,53 @@
// +build linux,386
/* Copyright 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/
package main
import (
"golang.org/x/sys/unix"
"syscall"
"unsafe"
)
const (
_SENDMSG = 16
_RECVMSG = 17
)
func sendmsg(fd int, msghdr *unix.Msghdr, flags int) (uintptr, uintptr, syscall.Errno) {
args := struct {
fd uintptr
msghdr uintptr
flags uintptr
}{
uintptr(fd),
uintptr(unsafe.Pointer(msghdr)),
uintptr(flags),
}
return unix.Syscall(
unix.SYS_SOCKETCALL,
_SENDMSG,
uintptr(unsafe.Pointer(&args)),
0,
)
}
func recvmsg(fd int, msghdr *unix.Msghdr, flags int) (uintptr, uintptr, syscall.Errno) {
args := struct {
fd uintptr
msghdr uintptr
flags uintptr
}{
uintptr(fd),
uintptr(unsafe.Pointer(msghdr)),
uintptr(flags),
}
return unix.Syscall(
unix.SYS_SOCKETCALL,
_RECVMSG,
uintptr(unsafe.Pointer(&args)),
0,
)
}