Skip to content

Commit

Permalink
opt: make TCP Keep-Alives settings practicable (#522)
Browse files Browse the repository at this point in the history
* opt: make TCP Keep-Alives settings practicable

* chore: correct the year in copyright info

* chore: bump up golangci-lint to v1.55.2

* chore: bump up modules
  • Loading branch information
panjf2000 authored Jan 4, 2024
1 parent 5905890 commit f975647
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
- name: Setup and run golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.52.2
version: v1.55.2
args: -v -E gofumpt -E gocritic -E misspell -E revive -E godot --timeout 5m
test:
needs: lint
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test_gc_opt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
- name: Setup and run golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.52.2
version: v1.55.2
args: -v -E gofumpt -E gocritic -E misspell -E revive -E godot --timeout 5m
test:
needs: lint
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test_poll_opt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
- name: Setup and run golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.52.2
version: v1.55.2
args: -v -E gofumpt -E gocritic -E misspell -E revive -E godot
test:
needs: lint
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test_poll_opt_gc_opt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
- name: Setup and run golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.52.2
version: v1.55.2
args: -v -E gofumpt -E gocritic -E misspell -E revive -E godot
test:
needs: lint
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ require (
github.com/stretchr/testify v1.8.4
github.com/valyala/bytebufferpool v1.0.0
go.uber.org/zap v1.21.0
golang.org/x/sync v0.3.0
golang.org/x/sys v0.12.0
golang.org/x/sync v0.5.0
golang.org/x/sys v0.15.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
)

Expand Down
7 changes: 4 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,16 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
Expand Down
29 changes: 22 additions & 7 deletions internal/socket/sockopts_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,28 @@ func SetKeepAlivePeriod(fd, secs int) error {
if secs <= 0 {
return errors.New("invalid time duration")
}
if err := os.NewSyscallError("setsockopt", unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1)); err != nil {
return err

if err := unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1); err != nil {
return os.NewSyscallError("setsockopt", err)
}

if err := unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_KEEPALIVE, secs); err != nil {
return os.NewSyscallError("setsockopt", err)
}
switch err := os.NewSyscallError("setsockopt", unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_KEEPINTVL, secs)); err {
case nil, unix.ENOPROTOOPT: // OS X 10.7 and earlier don't support this option
default:
return err

interval := secs / 5
if interval == 0 {
interval = 1
}
if err := unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_KEEPINTVL, interval); err != nil {
// In earlier versions, macOS only supported setting TCP_KEEPALIVE (the equivalent of TCP_KEEPIDLE on other platforms),
// but since macOS 10.8 it has supported TCP_KEEPINTVL and TCP_KEEPCNT.
// If the current OS is macOS and the error is ENOPROTOOPT, ignore it.
if err == unix.ENOPROTOOPT {
err = nil
}
return os.NewSyscallError("setsockopt", err)
}
return os.NewSyscallError("setsockopt", unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_KEEPALIVE, secs))

return os.NewSyscallError("setsockopt", unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_KEEPCNT, 5))
}
24 changes: 24 additions & 0 deletions internal/socket/sockopts_openbsd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) 2024 The Gnet Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package socket

import "golang.org/x/sys/unix"

// SetKeepAlivePeriod sets whether the operating system should send
// keep-alive messages on the connection and sets period between TCP keep-alive probes.
func SetKeepAlivePeriod(_, _ int) error {
// OpenBSD has no user-settable per-socket TCP keepalive options.
return unix.ENOPROTOOPT
}
25 changes: 18 additions & 7 deletions internal/socket/sockopts_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build linux || freebsd || dragonfly || netbsd || openbsd
// +build linux freebsd dragonfly netbsd openbsd
//go:build linux || freebsd || dragonfly || netbsd
// +build linux freebsd dragonfly netbsd

package socket

Expand All @@ -30,11 +30,22 @@ func SetKeepAlivePeriod(fd, secs int) error {
if secs <= 0 {
return errors.New("invalid time duration")
}
if err := os.NewSyscallError("setsockopt", unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1)); err != nil {
return err

if err := unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1); err != nil {
return os.NewSyscallError("setsockopt", err)
}

if err := unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_KEEPIDLE, secs); err != nil {
return os.NewSyscallError("setsockopt", err)
}
if err := os.NewSyscallError("setsockopt", unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_KEEPINTVL, secs)); err != nil {
return err

interval := secs / 5
if interval == 0 {
interval = 1
}
if err := unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_KEEPINTVL, interval); err != nil {
return os.NewSyscallError("setsockopt", err)
}
return os.NewSyscallError("setsockopt", unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_KEEPIDLE, secs))

return os.NewSyscallError("setsockopt", unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_KEEPCNT, 5))
}

0 comments on commit f975647

Please sign in to comment.