Skip to content

Commit

Permalink
⏲️ conn, service: add TCP_DEFER_ACCEPT & TCP_USER_TIMEOUT options
Browse files Browse the repository at this point in the history
  • Loading branch information
database64128 committed Apr 9, 2024
1 parent a1fca28 commit 05c8525
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 0 deletions.
10 changes: 10 additions & 0 deletions conn/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@ type ListenerSocketOptions struct {
// On all platforms, a negative value disables TFO.
TCPFastOpenBacklog int

// TCPDeferAcceptSecs sets TCP_DEFER_ACCEPT to the given number of seconds on the listener.
//
// Available on Linux.
TCPDeferAcceptSecs int

// TCPUserTimeoutMsecs sets TCP_USER_TIMEOUT to the given number of milliseconds on the listener.
//
// Available on Linux.
TCPUserTimeoutMsecs int

// ReusePort enables SO_REUSEPORT on the listener.
//
// Available on Linux and the BSDs.
Expand Down
34 changes: 34 additions & 0 deletions conn/conn_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,20 @@ func setTrafficClass(fd int, network string, trafficClass int) error {
return nil
}

func setTCPDeferAccept(fd, secs int) error {
if err := unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_DEFER_ACCEPT, secs); err != nil {
return fmt.Errorf("failed to set socket option TCP_DEFER_ACCEPT: %w", err)
}
return nil
}

func setTCPUserTimeout(fd, msecs int) error {
if err := unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_USER_TIMEOUT, msecs); err != nil {
return fmt.Errorf("failed to set socket option TCP_USER_TIMEOUT: %w", err)
}
return nil
}

func setTransparent(fd int, network string) error {
switch network {
case "tcp4", "udp4":
Expand Down Expand Up @@ -107,6 +121,24 @@ func setRecvOrigDstAddr(fd int, network string) error {
return nil
}

func (fns setFuncSlice) appendSetTCPDeferAcceptFunc(deferAcceptSecs int) setFuncSlice {
if deferAcceptSecs > 0 {
return append(fns, func(fd int, network string) error {
return setTCPDeferAccept(fd, deferAcceptSecs)
})
}
return fns
}

func (fns setFuncSlice) appendSetTCPUserTimeoutFunc(userTimeoutMsecs int) setFuncSlice {
if userTimeoutMsecs > 0 {
return append(fns, func(fd int, network string) error {
return setTCPUserTimeout(fd, userTimeoutMsecs)
})
}
return fns
}

func (fns setFuncSlice) appendSetTransparentFunc(transparent bool) setFuncSlice {
if transparent {
return append(fns, setTransparent)
Expand All @@ -125,6 +157,8 @@ func (lso ListenerSocketOptions) buildSetFns() setFuncSlice {
return setFuncSlice{}.
appendSetFwmarkFunc(lso.Fwmark).
appendSetTrafficClassFunc(lso.TrafficClass).
appendSetTCPDeferAcceptFunc(lso.TCPDeferAcceptSecs).
appendSetTCPUserTimeoutFunc(lso.TCPUserTimeoutMsecs).
appendSetReusePortFunc(lso.ReusePort).
appendSetTransparentFunc(lso.Transparent).
appendSetPMTUDFunc(lso.PathMTUDiscovery).
Expand Down
12 changes: 12 additions & 0 deletions docs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
"fastOpen": true,
"fastOpenBacklog": 0,
"fastOpenFallback": false,
"multipath": false,
"deferAcceptSecs": 0,
"userTimeoutMsecs": 0,
"disableInitialPayloadWait": false,
"initialPayloadWaitTimeout": "250ms",
"initialPayloadWaitBufferSize": 1440
Expand All @@ -43,6 +46,9 @@
"fastOpen": true,
"fastOpenBacklog": 0,
"fastOpenFallback": false,
"multipath": false,
"deferAcceptSecs": 0,
"userTimeoutMsecs": 0,
"disableInitialPayloadWait": false,
"initialPayloadWaitTimeout": "250ms",
"initialPayloadWaitBufferSize": 1440
Expand All @@ -56,6 +62,9 @@
"fastOpen": true,
"fastOpenBacklog": 0,
"fastOpenFallback": false,
"multipath": false,
"deferAcceptSecs": 0,
"userTimeoutMsecs": 0,
"disableInitialPayloadWait": false,
"initialPayloadWaitTimeout": "250ms",
"initialPayloadWaitBufferSize": 1440
Expand All @@ -69,6 +78,9 @@
"fastOpen": true,
"fastOpenBacklog": 0,
"fastOpenFallback": false,
"multipath": false,
"deferAcceptSecs": 0,
"userTimeoutMsecs": 0,
"disableInitialPayloadWait": false,
"initialPayloadWaitTimeout": "250ms",
"initialPayloadWaitBufferSize": 1440
Expand Down
12 changes: 12 additions & 0 deletions service/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ type TCPListenerConfig struct {
//
// On all platforms, a negative value disables TFO.
FastOpenBacklog int `json:"fastOpenBacklog"`

// DeferAcceptSecs sets TCP_DEFER_ACCEPT to the given number of seconds on the listener.
//
// Available on Linux.
DeferAcceptSecs int `json:"deferAcceptSecs"`

// UserTimeoutMsecs sets TCP_USER_TIMEOUT to the given number of milliseconds on the listener.
//
// Available on Linux.
UserTimeoutMsecs int `json:"userTimeoutMsecs"`
}

// Configure returns a TCP listener configuration.
Expand Down Expand Up @@ -125,6 +135,8 @@ func (lnc *TCPListenerConfig) Configure(listenConfigCache conn.ListenConfigCache
Fwmark: lnc.Fwmark,
TrafficClass: lnc.TrafficClass,
TCPFastOpenBacklog: lnc.FastOpenBacklog,
TCPDeferAcceptSecs: lnc.DeferAcceptSecs,
TCPUserTimeoutMsecs: lnc.UserTimeoutMsecs,
ReusePort: lnc.ReusePort,
Transparent: transparent,
TCPFastOpen: lnc.FastOpen,
Expand Down

0 comments on commit 05c8525

Please sign in to comment.