From 0b940a756838efcb90363ad99cb085d077b78e96 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 18 Apr 2018 07:54:39 +0200 Subject: [PATCH] Use socketcall on x86 --- conn_linux.go | 50 +++++------------------------------------ syscall_linux.go | 30 +++++++++++++++++++++++++ syscall_linux_386.go | 53 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 44 deletions(-) create mode 100644 syscall_linux.go create mode 100644 syscall_linux_386.go diff --git a/conn_linux.go b/conn_linux.go index cdba74f..8b60d65 100644 --- a/conn_linux.go +++ b/conn_linux.go @@ -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 diff --git a/syscall_linux.go b/syscall_linux.go new file mode 100644 index 0000000..3403544 --- /dev/null +++ b/syscall_linux.go @@ -0,0 +1,30 @@ +// +build linux,!386 + +/* Copyright 2018 Jason A. Donenfeld . 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), + ) +} diff --git a/syscall_linux_386.go b/syscall_linux_386.go new file mode 100644 index 0000000..76d7c7e --- /dev/null +++ b/syscall_linux_386.go @@ -0,0 +1,53 @@ +// +build linux,386 + +/* Copyright 2018 Jason A. Donenfeld . 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, + ) +}