storagenode: report fastopen support

Change-Id: Ic707bce32729540391d5139e7f3a82c693bcb834
This commit is contained in:
JT Olio 2023-06-02 10:17:23 -04:00 committed by Storj Robot
parent 128b0a86e3
commit 1966340b2a
6 changed files with 38 additions and 13 deletions

View File

@ -22,21 +22,26 @@ func setTCPFastOpen(fd uintptr, queue int) error {
} }
var tryInitFastOpenOnce sync.Once var tryInitFastOpenOnce sync.Once
var initFastOpenPossiblyEnabled bool
func tryInitFastOpen(log *zap.Logger) { // tryInitFastOpen returns true if fastopen support is possibly enabled.
func tryInitFastOpen(log *zap.Logger) bool {
tryInitFastOpenOnce.Do(func() { tryInitFastOpenOnce.Do(func() {
data, err := os.ReadFile(tcpFastOpenSysctlPath) data, err := os.ReadFile(tcpFastOpenSysctlPath)
if err != nil { if err != nil {
log.Sugar().Infof("kernel support for tcp fast open unknown") log.Sugar().Infof("kernel support for tcp fast open unknown")
initFastOpenPossiblyEnabled = true
return return
} }
fastOpenFlags, err := strconv.Atoi(strings.TrimSpace(string(data))) fastOpenFlags, err := strconv.Atoi(strings.TrimSpace(string(data)))
if err != nil { if err != nil {
log.Sugar().Infof("kernel support for tcp fast open unparsable") log.Sugar().Infof("kernel support for tcp fast open unparsable")
initFastOpenPossiblyEnabled = true
return return
} }
if fastOpenFlags&0x2 != 0 { if fastOpenFlags&0x2 != 0 {
log.Sugar().Infof("existing kernel support for server-side tcp fast open detected") log.Sugar().Infof("existing kernel support for server-side tcp fast open detected")
initFastOpenPossiblyEnabled = true
return return
} }
err = os.WriteFile(tcpFastOpenSysctlPath, []byte(fmt.Sprint(fastOpenFlags|0x2)), 0o644) err = os.WriteFile(tcpFastOpenSysctlPath, []byte(fmt.Sprint(fastOpenFlags|0x2)), 0o644)
@ -48,8 +53,11 @@ func tryInitFastOpen(log *zap.Logger) {
// enable standard fast open with standard cookies for both clients and // enable standard fast open with standard cookies for both clients and
// servers, so it's probably the right advice. // servers, so it's probably the right advice.
log.Sugar().Infof("enable with: sysctl -w net.ipv4.tcp_fastopen=3") log.Sugar().Infof("enable with: sysctl -w net.ipv4.tcp_fastopen=3")
initFastOpenPossiblyEnabled = false
return return
} }
log.Sugar().Infof("kernel support for server-side tcp fast open enabled.") log.Sugar().Infof("kernel support for server-side tcp fast open enabled.")
initFastOpenPossiblyEnabled = true
}) })
return initFastOpenPossiblyEnabled
} }

View File

@ -12,4 +12,5 @@ import (
func setTCPFastOpen(fd uintptr, queue int) error { return nil } func setTCPFastOpen(fd uintptr, queue int) error { return nil }
func tryInitFastOpen(*zap.Logger) {} // tryInitFastOpen returns true if fastopen support is possibly enabled.
func tryInitFastOpen(*zap.Logger) bool { return false }

View File

@ -15,9 +15,11 @@ func setTCPFastOpen(fd uintptr, queue int) error {
return syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_TCP, tcpFastOpenServer, 1) return syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_TCP, tcpFastOpenServer, 1)
} }
func tryInitFastOpen(*zap.Logger) { // tryInitFastOpen returns true if fastopen support is possibly enabled.
func tryInitFastOpen(*zap.Logger) bool {
// should we log or check something along the lines of // should we log or check something along the lines of
// netsh int tcp set global fastopen=enabled // netsh int tcp set global fastopen=enabled
// netsh int tcp set global fastopenfallback=disabled // netsh int tcp set global fastopenfallback=disabled
// ? // ?
return false
} }

View File

@ -72,6 +72,7 @@ type Server struct {
tlsOptions *tlsopts.Options tlsOptions *tlsopts.Options
noiseConf noise.Config noiseConf noise.Config
config Config config Config
fastOpen bool
publicTCPListener net.Listener publicTCPListener net.Listener
publicUDPConn *net.UDPConn publicUDPConn *net.UDPConn
@ -115,14 +116,16 @@ func New(log *zap.Logger, tlsOptions *tlsopts.Options, config Config) (_ *Server
listenConfig := net.ListenConfig{} listenConfig := net.ListenConfig{}
if config.TCPFastOpen { if config.TCPFastOpen {
tryInitFastOpen(log) server.fastOpen = tryInitFastOpen(log)
listenConfig.Control = func(network, address string, c syscall.RawConn) error { if server.fastOpen {
return c.Control(func(fd uintptr) { listenConfig.Control = func(network, address string, c syscall.RawConn) error {
err := setTCPFastOpen(fd, config.TCPFastOpenQueue) return c.Control(func(fd uintptr) {
if err != nil { err := setTCPFastOpen(fd, config.TCPFastOpenQueue)
log.Sugar().Infof("failed to set tcp fast open for this socket: %v", err) if err != nil {
} log.Sugar().Infof("failed to set tcp fast open for this socket: %v", err)
}) }
})
}
} }
} }
@ -232,6 +235,12 @@ func (p *Server) DebounceLimit() int {
return debounceLimit return debounceLimit
} }
// FastOpen returns true if FastOpen is possibly open. false means we
// know FastOpen is off.
func (p *Server) FastOpen() bool {
return p.fastOpen
}
// Close shuts down the server. // Close shuts down the server.
func (p *Server) Close() error { func (p *Server) Close() error {
p.mu.Lock() p.mu.Lock()

View File

@ -49,6 +49,7 @@ type NodeInfo struct {
Operator pb.NodeOperator Operator pb.NodeOperator
NoiseKeyAttestation *pb.NoiseKeyAttestation NoiseKeyAttestation *pb.NoiseKeyAttestation
DebounceLimit int DebounceLimit int
FastOpen bool
} }
// Service is the contact service between storage nodes and satellites. // Service is the contact service between storage nodes and satellites.
@ -96,7 +97,6 @@ func (service *Service) pingSatellite(ctx context.Context, satellite storj.NodeI
interval := initialBackOff interval := initialBackOff
attempts := 0 attempts := 0
for { for {
mon.Meter("satellite_contact_request").Mark(1) //mon:locked mon.Meter("satellite_contact_request").Mark(1) //mon:locked
err := service.pingSatelliteOnce(ctx, satellite) err := service.pingSatelliteOnce(ctx, satellite)
@ -117,7 +117,6 @@ func (service *Service) pingSatellite(ctx context.Context, satellite storj.NodeI
return nil return nil
} }
} }
} }
func (service *Service) pingSatelliteOnce(ctx context.Context, id storj.NodeID) (err error) { func (service *Service) pingSatelliteOnce(ctx context.Context, id storj.NodeID) (err error) {
@ -130,6 +129,10 @@ func (service *Service) pingSatelliteOnce(ctx context.Context, id storj.NodeID)
defer func() { err = errs.Combine(err, conn.Close()) }() defer func() { err = errs.Combine(err, conn.Close()) }()
self := service.Local() self := service.Local()
var features uint64
if self.FastOpen {
features |= uint64(pb.NodeAddress_TCP_FASTOPEN_ENABLED)
}
resp, err := pb.NewDRPCNodeClient(conn).CheckIn(ctx, &pb.CheckInRequest{ resp, err := pb.NewDRPCNodeClient(conn).CheckIn(ctx, &pb.CheckInRequest{
Address: self.Address, Address: self.Address,
Version: &self.Version, Version: &self.Version,
@ -137,6 +140,7 @@ func (service *Service) pingSatelliteOnce(ctx context.Context, id storj.NodeID)
Operator: &self.Operator, Operator: &self.Operator,
NoiseKeyAttestation: self.NoiseKeyAttestation, NoiseKeyAttestation: self.NoiseKeyAttestation,
DebounceLimit: int32(self.DebounceLimit), DebounceLimit: int32(self.DebounceLimit),
Features: features,
}) })
service.quicStats.SetStatus(false) service.quicStats.SetStatus(false)
if err != nil { if err != nil {

View File

@ -441,6 +441,7 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, revocationDB exten
Version: *pbVersion, Version: *pbVersion,
NoiseKeyAttestation: noiseKeyAttestation, NoiseKeyAttestation: noiseKeyAttestation,
DebounceLimit: peer.Server.DebounceLimit(), DebounceLimit: peer.Server.DebounceLimit(),
FastOpen: peer.Server.FastOpen(),
} }
peer.Contact.PingStats = new(contact.PingStats) peer.Contact.PingStats = new(contact.PingStats)
peer.Contact.QUICStats = contact.NewQUICStats(peer.Server.IsQUICEnabled()) peer.Contact.QUICStats = contact.NewQUICStats(peer.Server.IsQUICEnabled())