Use socketcall on x86
This commit is contained in:
		
							parent
							
								
									eb6728400b
								
							
						
					
					
						commit
						0b940a7568
					
				
					 3 changed files with 89 additions and 44 deletions
				
			
		|  | @ -391,14 +391,7 @@ func send6(sock int, end *NativeEndpoint, buff []byte) error { | ||||||
| 
 | 
 | ||||||
| 	msghdr.SetControllen(int(unsafe.Sizeof(cmsg))) | 	msghdr.SetControllen(int(unsafe.Sizeof(cmsg))) | ||||||
| 
 | 
 | ||||||
| 	// sendmsg(sock, &msghdr, 0)
 | 	_, _, errno := sendmsg(sock, &msghdr, 0) | ||||||
| 
 |  | ||||||
| 	_, _, errno := unix.Syscall( |  | ||||||
| 		unix.SYS_SENDMSG, |  | ||||||
| 		uintptr(sock), |  | ||||||
| 		uintptr(unsafe.Pointer(&msghdr)), |  | ||||||
| 		0, |  | ||||||
| 	) |  | ||||||
| 
 | 
 | ||||||
| 	if errno == 0 { | 	if errno == 0 { | ||||||
| 		return nil | 		return nil | ||||||
|  | @ -409,12 +402,7 @@ func send6(sock int, end *NativeEndpoint, buff []byte) error { | ||||||
| 	if errno == unix.EINVAL { | 	if errno == unix.EINVAL { | ||||||
| 		end.ClearSrc() | 		end.ClearSrc() | ||||||
| 		cmsg.pktinfo = unix.Inet6Pktinfo{} | 		cmsg.pktinfo = unix.Inet6Pktinfo{} | ||||||
| 		_, _, errno = unix.Syscall( | 		_, _, errno = sendmsg(sock, &msghdr, 0) | ||||||
| 			unix.SYS_SENDMSG, |  | ||||||
| 			uintptr(sock), |  | ||||||
| 			uintptr(unsafe.Pointer(&msghdr)), |  | ||||||
| 			0, |  | ||||||
| 		) |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return errno | 	return errno | ||||||
|  | @ -455,26 +443,14 @@ func send4(sock int, end *NativeEndpoint, buff []byte) error { | ||||||
| 	} | 	} | ||||||
| 	msghdr.SetControllen(int(unsafe.Sizeof(cmsg))) | 	msghdr.SetControllen(int(unsafe.Sizeof(cmsg))) | ||||||
| 
 | 
 | ||||||
| 	// sendmsg(sock, &msghdr, 0)
 | 	_, _, errno := sendmsg(sock, &msghdr, 0) | ||||||
| 
 |  | ||||||
| 	_, _, errno := unix.Syscall( |  | ||||||
| 		unix.SYS_SENDMSG, |  | ||||||
| 		uintptr(sock), |  | ||||||
| 		uintptr(unsafe.Pointer(&msghdr)), |  | ||||||
| 		0, |  | ||||||
| 	) |  | ||||||
| 
 | 
 | ||||||
| 	// clear source and try again
 | 	// clear source and try again
 | ||||||
| 
 | 
 | ||||||
| 	if errno == unix.EINVAL { | 	if errno == unix.EINVAL { | ||||||
| 		end.ClearSrc() | 		end.ClearSrc() | ||||||
| 		cmsg.pktinfo = unix.Inet4Pktinfo{} | 		cmsg.pktinfo = unix.Inet4Pktinfo{} | ||||||
| 		_, _, errno = unix.Syscall( | 		_, _, errno = sendmsg(sock, &msghdr, 0) | ||||||
| 			unix.SYS_SENDMSG, |  | ||||||
| 			uintptr(sock), |  | ||||||
| 			uintptr(unsafe.Pointer(&msghdr)), |  | ||||||
| 			0, |  | ||||||
| 		) |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// errno = 0 is still an error instance
 | 	// 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.Control = (*byte)(unsafe.Pointer(&cmsg)) | ||||||
| 	msghdr.SetControllen(int(unsafe.Sizeof(cmsg))) | 	msghdr.SetControllen(int(unsafe.Sizeof(cmsg))) | ||||||
| 
 | 
 | ||||||
| 	// recvmsg(sock, &mskhdr, 0)
 | 	size, _, errno := recvmsg(sock, &msghdr, 0) | ||||||
| 
 |  | ||||||
| 	size, _, errno := unix.Syscall( |  | ||||||
| 		unix.SYS_RECVMSG, |  | ||||||
| 		uintptr(sock), |  | ||||||
| 		uintptr(unsafe.Pointer(&msghdr)), |  | ||||||
| 		0, |  | ||||||
| 	) |  | ||||||
| 
 | 
 | ||||||
| 	if errno != 0 { | 	if errno != 0 { | ||||||
| 		return 0, errno | 		return 0, errno | ||||||
|  | @ -555,14 +524,7 @@ func receive6(sock int, buff []byte, end *NativeEndpoint) (int, error) { | ||||||
| 	msg.Control = (*byte)(unsafe.Pointer(&cmsg)) | 	msg.Control = (*byte)(unsafe.Pointer(&cmsg)) | ||||||
| 	msg.SetControllen(int(unsafe.Sizeof(cmsg))) | 	msg.SetControllen(int(unsafe.Sizeof(cmsg))) | ||||||
| 
 | 
 | ||||||
| 	// recvmsg(sock, &mskhdr, 0)
 | 	size, _, errno := recvmsg(sock, &msg, 0) | ||||||
| 
 |  | ||||||
| 	size, _, errno := unix.Syscall( |  | ||||||
| 		unix.SYS_RECVMSG, |  | ||||||
| 		uintptr(sock), |  | ||||||
| 		uintptr(unsafe.Pointer(&msg)), |  | ||||||
| 		0, |  | ||||||
| 	) |  | ||||||
| 
 | 
 | ||||||
| 	if errno != 0 { | 	if errno != 0 { | ||||||
| 		return 0, errno | 		return 0, errno | ||||||
|  |  | ||||||
							
								
								
									
										30
									
								
								syscall_linux.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								syscall_linux.go
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										53
									
								
								syscall_linux_386.go
									
									
									
									
									
										Normal 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, | ||||||
|  | 	) | ||||||
|  | } | ||||||
		Loading…
	
		Reference in a new issue