From bce67f096156eed6c615f74469be352d112b71f4 Mon Sep 17 00:00:00 2001 From: Mark Jeffery Date: Sat, 3 Jul 2021 17:34:48 +0200 Subject: [PATCH] unix: add SetsockoptTCPRepairOpt on Linux There is currently no function to allow for setting repair options for sockets in repair mode. There are 4 options catered for in the linux implementation. TCPOPT_WINDOW TCPOPT_MAXSEG TCPOPT_SACK_PERMITTED TCPOPT_TIMESTAMP Details of the patch to the kernel and the thinking behind it is here https://lwn.net/Articles/495304 Work done in this commit Included the tcp options type and length for inclusion in the Docker build Added TCPOPT to the regular expression in mkerrors.sh. There was only TCP_ previously Add the new function to syscall_unix.go I have tested locally and verified each option with ss -i I am not sure whether to commit tests because I don't know if socket creation is possible on the test runs in the offical pipeline. I did check for existing tests but didn't see any that created sockets, only one that validated a string option. Fixes golang/go#46984 Change-Id: Iade0434c05cebf2fbdfb5f04b2a7b51c8b358423 Reviewed-on: https://go-review.googlesource.com/c/sys/+/332709 Reviewed-by: Ian Lance Taylor Reviewed-by: Tobias Klauser Run-TryBot: Ian Lance Taylor TryBot-Result: Go Bot --- unix/linux/types.go | 3 +++ unix/mkerrors.sh | 2 +- unix/syscall_linux.go | 7 +++++++ unix/zerrors_linux.go | 8 ++++++++ unix/ztypes_linux.go | 6 ++++++ 5 files changed, 25 insertions(+), 1 deletion(-) diff --git a/unix/linux/types.go b/unix/linux/types.go index d57c1db7..0cbea612 100644 --- a/unix/linux/types.go +++ b/unix/linux/types.go @@ -637,6 +637,8 @@ type CanFilter C.struct_can_filter type ifreq C.struct_ifreq +type TCPRepairOpt C.struct_tcp_repair_opt + const ( SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 @@ -673,6 +675,7 @@ const ( SizeofUcred = C.sizeof_struct_ucred SizeofTCPInfo = C.sizeof_struct_tcp_info SizeofCanFilter = C.sizeof_struct_can_filter + SizeofTCPRepairOpt = C.sizeof_struct_tcp_repair_opt ) // Netlink routing and interface messages diff --git a/unix/mkerrors.sh b/unix/mkerrors.sh index 2ed4b6d9..0bcb8c32 100755 --- a/unix/mkerrors.sh +++ b/unix/mkerrors.sh @@ -500,7 +500,7 @@ ccflags="$@" $2 ~ /^LOCK_(SH|EX|NB|UN)$/ || $2 ~ /^LO_(KEY|NAME)_SIZE$/ || $2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ || - $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL)_/ || + $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT)_/ || $2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ || $2 ~ /^NFC_.*_(MAX)?SIZE$/ || $2 ~ /^RAW_PAYLOAD_/ || diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go index 43569fe7..2839435e 100644 --- a/unix/syscall_linux.go +++ b/unix/syscall_linux.go @@ -1355,6 +1355,13 @@ func SetsockoptTpacketReq3(fd, level, opt int, tp *TpacketReq3) error { return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp)) } +func SetsockoptTCPRepairOpt(fd, level, opt int, o []TCPRepairOpt) (err error) { + if len(o) == 0 { + return EINVAL + } + return setsockopt(fd, level, opt, unsafe.Pointer(&o[0]), uintptr(SizeofTCPRepairOpt*len(o))) +} + // Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html) // KeyctlInt calls keyctl commands in which each argument is an int. diff --git a/unix/zerrors_linux.go b/unix/zerrors_linux.go index 5ed10c4a..135e3a47 100644 --- a/unix/zerrors_linux.go +++ b/unix/zerrors_linux.go @@ -2548,6 +2548,14 @@ const ( TCOFLUSH = 0x1 TCOOFF = 0x0 TCOON = 0x1 + TCPOPT_EOL = 0x0 + TCPOPT_MAXSEG = 0x2 + TCPOPT_NOP = 0x1 + TCPOPT_SACK = 0x5 + TCPOPT_SACK_PERMITTED = 0x4 + TCPOPT_TIMESTAMP = 0x8 + TCPOPT_TSTAMP_HDR = 0x101080a + TCPOPT_WINDOW = 0x3 TCP_CC_INFO = 0x1a TCP_CM_INQ = 0x24 TCP_CONGESTION = 0xd diff --git a/unix/ztypes_linux.go b/unix/ztypes_linux.go index 93a64c18..878141d6 100644 --- a/unix/ztypes_linux.go +++ b/unix/ztypes_linux.go @@ -452,6 +452,11 @@ type CanFilter struct { Mask uint32 } +type TCPRepairOpt struct { + Code uint32 + Val uint32 +} + const ( SizeofSockaddrInet4 = 0x10 SizeofSockaddrInet6 = 0x1c @@ -484,6 +489,7 @@ const ( SizeofUcred = 0xc SizeofTCPInfo = 0x68 SizeofCanFilter = 0x8 + SizeofTCPRepairOpt = 0x8 ) const (