private/server: support tcp fastopen
we are not enabling it on client-side code yet, but it will be hard to test this in the wild without server-side support. this is phase 2 of tcp fast open support. see https://forum.storj.io/t/two-new-blueprints-design-drafts-seeking-feedback-replacing-tls-with-noise-and-tcp-fastopen/21053/12 for more details Change-Id: I20362be4c49abab90afcc9b6572ef9f79816345b
This commit is contained in:
parent
3e01e9c07a
commit
2a641b60d3
55
private/server/fastopen_linux.go
Normal file
55
private/server/fastopen_linux.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// Copyright (C) 2023 Storj Labs, Inc.
|
||||||
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
const tcpFastOpen = 0x17
|
||||||
|
const tcpFastOpenSysctlPath = "/proc/sys/net/ipv4/tcp_fastopen"
|
||||||
|
|
||||||
|
func setTCPFastOpen(fd uintptr, queue int) error {
|
||||||
|
return syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, tcpFastOpen, queue)
|
||||||
|
}
|
||||||
|
|
||||||
|
var tryInitFastOpenOnce sync.Once
|
||||||
|
|
||||||
|
func tryInitFastOpen(log *zap.Logger) {
|
||||||
|
tryInitFastOpenOnce.Do(func() {
|
||||||
|
data, err := os.ReadFile(tcpFastOpenSysctlPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Sugar().Infof("kernel support for tcp fast open unknown")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fastOpenFlags, err := strconv.Atoi(strings.TrimSpace(string(data)))
|
||||||
|
if err != nil {
|
||||||
|
log.Sugar().Infof("kernel support for tcp fast open unparsable")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if fastOpenFlags&0x2 != 0 {
|
||||||
|
log.Sugar().Infof("existing kernel support for server-side tcp fast open detected")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = os.WriteFile(tcpFastOpenSysctlPath, []byte(fmt.Sprint(fastOpenFlags|0x2)), 0o644)
|
||||||
|
if err != nil {
|
||||||
|
log.Sugar().Infof("kernel support for server-side tcp fast open remains disabled.")
|
||||||
|
|
||||||
|
// really, it's just the secondmost least significant bit that needs to
|
||||||
|
// be flipped, but maybe this isn't the place to explain that. 0x3 will
|
||||||
|
// enable standard fast open with standard cookies for both clients and
|
||||||
|
// servers, so it's probably the right advice.
|
||||||
|
log.Sugar().Infof("enable with: sysctl -w net.ipv4.tcp_fastopen=3")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Sugar().Infof("kernel support for server-side tcp fast open enabled.")
|
||||||
|
})
|
||||||
|
}
|
15
private/server/fastopen_other.go
Normal file
15
private/server/fastopen_other.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright (C) 2023 Storj Labs, Inc.
|
||||||
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
|
//go:build !linux && !windows
|
||||||
|
// +build !linux,!windows
|
||||||
|
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setTCPFastOpen(fd uintptr, queue int) error { return nil }
|
||||||
|
|
||||||
|
func tryInitFastOpen(*zap.Logger) {}
|
18
private/server/fastopen_windows.go
Normal file
18
private/server/fastopen_windows.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright (C) 2023 Storj Labs, Inc.
|
||||||
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
const tcpFastOpen = 0x17
|
||||||
|
|
||||||
|
func setTCPFastOpen(fd uintptr, queue int) error {
|
||||||
|
return syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_TCP, tcpFastOpen, queue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func tryInitFastOpen(*zap.Logger) {}
|
@ -47,6 +47,9 @@ type Config struct {
|
|||||||
|
|
||||||
DisableTCP bool `help:"disable TCP listener on a server" internal:"true"`
|
DisableTCP bool `help:"disable TCP listener on a server" internal:"true"`
|
||||||
DebugLogTraffic bool `hidden:"true" default:"false"` // Deprecated
|
DebugLogTraffic bool `hidden:"true" default:"false"` // Deprecated
|
||||||
|
|
||||||
|
TCPFastOpen bool `help:"enable support for tcp fast open experiment" default:"true"`
|
||||||
|
TCPFastOpenQueue int `help:"the size of the tcp fast open queue" default:"256"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Server represents a bundle of services defined by a specific ID.
|
// Server represents a bundle of services defined by a specific ID.
|
||||||
@ -123,10 +126,22 @@ func New(log *zap.Logger, tlsOptions *tlsopts.Options, config Config) (_ *Server
|
|||||||
done: make(chan struct{}),
|
done: make(chan struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listenConfig := net.ListenConfig{}
|
||||||
|
if config.TCPFastOpen {
|
||||||
|
tryInitFastOpen(log)
|
||||||
|
listenConfig.Control = func(network, address string, c syscall.RawConn) error {
|
||||||
|
var internalErr error
|
||||||
|
err := c.Control(func(fd uintptr) {
|
||||||
|
internalErr = setTCPFastOpen(fd, config.TCPFastOpenQueue)
|
||||||
|
})
|
||||||
|
return errs.Combine(err, internalErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for retry := 0; ; retry++ {
|
for retry := 0; ; retry++ {
|
||||||
addr := config.Address
|
addr := config.Address
|
||||||
if !config.DisableTCP {
|
if !config.DisableTCP {
|
||||||
publicTCPListener, err := net.Listen("tcp", addr)
|
publicTCPListener, err := listenConfig.Listen(context.Background(), "tcp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
6
scripts/testdata/satellite-config.yaml.lock
vendored
6
scripts/testdata/satellite-config.yaml.lock
vendored
@ -1021,6 +1021,12 @@ server.private-address: 127.0.0.1:7778
|
|||||||
# url for revocation database (e.g. bolt://some.db OR redis://127.0.0.1:6378?db=2&password=abc123)
|
# url for revocation database (e.g. bolt://some.db OR redis://127.0.0.1:6378?db=2&password=abc123)
|
||||||
# server.revocation-dburl: bolt://testdata/revocations.db
|
# server.revocation-dburl: bolt://testdata/revocations.db
|
||||||
|
|
||||||
|
# enable support for tcp fast open experiment
|
||||||
|
# server.tcp-fast-open: true
|
||||||
|
|
||||||
|
# the size of the tcp fast open queue
|
||||||
|
# server.tcp-fast-open-queue: 256
|
||||||
|
|
||||||
# if true, uses peer ca whitelist checking
|
# if true, uses peer ca whitelist checking
|
||||||
# server.use-peer-ca-whitelist: true
|
# server.use-peer-ca-whitelist: true
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user