From fd679c329c1a4369cd7b6a76a426dbd3818cb0fa Mon Sep 17 00:00:00 2001 From: Andrew Harding Date: Sat, 16 Sep 2023 09:05:11 -0600 Subject: [PATCH] private/server: FreeBSD TCP fastopen support detection Detects whether or not TCP fastopen is supported by running sysctl to grab the current value of net.inet.tcp.fastopen.server_enable. If not enabled, directs the operator to use sysctl to set it temporarily and /etc/sysctl.conf to set it on-boot. Setting the socket option always works whether it is enabled or not. Verified that fastopen works on FreeBSD 13. Did not attempt on earlier versions but support has been there since FreeBSD 10. Change-Id: I2e0c457558a6fa7b7a1b18bc3c6684aff50b81a2 --- private/server/fastopen_freebsd.go | 51 ++++++++++++++++++++++++++++++ private/server/fastopen_other.go | 4 +-- 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 private/server/fastopen_freebsd.go diff --git a/private/server/fastopen_freebsd.go b/private/server/fastopen_freebsd.go new file mode 100644 index 000000000..1949397aa --- /dev/null +++ b/private/server/fastopen_freebsd.go @@ -0,0 +1,51 @@ +// Copyright (C) 2023 Storj Labs, Inc. +// See LICENSE for copying information. + +package server + +import ( + "os/exec" + "strconv" + "strings" + "sync" + "syscall" + + "go.uber.org/zap" +) + +const tcpFastOpen = 1025 + +func setTCPFastOpen(fd uintptr, _queue int) error { + return syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, tcpFastOpen, 1) +} + +var tryInitFastOpenOnce sync.Once +var initFastOpenPossiblyEnabled bool + +// tryInitFastOpen returns true if fastopen support is possibly enabled. +func tryInitFastOpen(log *zap.Logger) bool { + tryInitFastOpenOnce.Do(func() { + initFastOpenPossiblyEnabled = true + output, err := exec.Command("sysctl", "-n", "net.inet.tcp.fastopen.server_enable").Output() + if err != nil { + log.Sugar().Infof("kernel support for tcp fast open unknown") + initFastOpenPossiblyEnabled = true + return + } + enabled, err := strconv.ParseBool(strings.TrimSpace(string(output))) + if err != nil { + log.Sugar().Infof("kernel support for tcp fast open unparsable") + initFastOpenPossiblyEnabled = true + return + } + if enabled { + log.Sugar().Infof("kernel support for server-side tcp fast open enabled.") + } else { + log.Sugar().Infof("kernel support for server-side tcp fast open not enabled.") + log.Sugar().Infof("enable with: sysctl net.inet.tcp.fastopen.server_enable=1") + log.Sugar().Infof("enable on-boot by setting net.inet.tcp.fastopen.server_enable=1 in /etc/sysctl.conf") + } + initFastOpenPossiblyEnabled = enabled + }) + return initFastOpenPossiblyEnabled +} diff --git a/private/server/fastopen_other.go b/private/server/fastopen_other.go index edeb5af07..72a9c3018 100644 --- a/private/server/fastopen_other.go +++ b/private/server/fastopen_other.go @@ -1,8 +1,8 @@ // Copyright (C) 2023 Storj Labs, Inc. // See LICENSE for copying information. -//go:build !linux && !windows -// +build !linux,!windows +//go:build !linux && !windows && !freebsd +// +build !linux,!windows,!freebsd package server