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 <iant@golang.org>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
diff --git a/unix/linux/types.go b/unix/linux/types.go
index d57c1db..0cbea61 100644
--- a/unix/linux/types.go
+++ b/unix/linux/types.go
@@ -637,6 +637,8 @@
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 @@
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 2ed4b6d..0bcb8c3 100755
--- a/unix/mkerrors.sh
+++ b/unix/mkerrors.sh
@@ -500,7 +500,7 @@
$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 43569fe..2839435 100644
--- a/unix/syscall_linux.go
+++ b/unix/syscall_linux.go
@@ -1355,6 +1355,13 @@
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 5ed10c4..135e3a4 100644
--- a/unix/zerrors_linux.go
+++ b/unix/zerrors_linux.go
@@ -2548,6 +2548,14 @@
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 93a64c1..878141d 100644
--- a/unix/ztypes_linux.go
+++ b/unix/ztypes_linux.go
@@ -452,6 +452,11 @@
Mask uint32
}
+type TCPRepairOpt struct {
+ Code uint32
+ Val uint32
+}
+
const (
SizeofSockaddrInet4 = 0x10
SizeofSockaddrInet6 = 0x1c
@@ -484,6 +489,7 @@
SizeofUcred = 0xc
SizeofTCPInfo = 0x68
SizeofCanFilter = 0x8
+ SizeofTCPRepairOpt = 0x8
)
const (