diff --git a/.github/workflows/vulncheck.yml b/.github/workflows/vulncheck.yml index 9c5ca5b..76e50a0 100644 --- a/.github/workflows/vulncheck.yml +++ b/.github/workflows/vulncheck.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go-version: [ 1.22.5 ] + go-version: [ 1.22.7 ] steps: - name: Check out code into the Go module directory uses: actions/checkout@v3 diff --git a/main.go b/main.go index f2e33b0..cc9ded6 100644 --- a/main.go +++ b/main.go @@ -39,7 +39,6 @@ import ( "github.com/dustin/go-humanize" "github.com/minio/pkg/v3/ellipses" - "golang.org/x/sys/unix" "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss/table" @@ -302,72 +301,6 @@ func runServer(host string) { } } -// DialContext is a function to make custom Dial for internode communications -type DialContext func(ctx context.Context, network, address string) (net.Conn, error) - -func setTCPParametersFn() func(network, address string, c syscall.RawConn) error { - return func(network, address string, c syscall.RawConn) error { - c.Control(func(fdPtr uintptr) { - // got socket file descriptor to set parameters. - fd := int(fdPtr) - - _ = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_REUSEADDR, 1) - - _ = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_REUSEPORT, 1) - - { - // Enable big buffers - _ = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_SNDBUF, 8*humanize.MiByte) - - _ = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_RCVBUF, 8*humanize.MiByte) - } - - // Enable TCP open - // https://lwn.net/Articles/508865/ - 32k queue size. - _ = syscall.SetsockoptInt(fd, syscall.SOL_TCP, unix.TCP_FASTOPEN, 32*1024) - - // Enable TCP fast connect - // TCPFastOpenConnect sets the underlying socket to use - // the TCP fast open connect. This feature is supported - // since Linux 4.11. - _ = syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, unix.TCP_FASTOPEN_CONNECT, 1) - - // Enable TCP quick ACK, John Nagle says - // "Set TCP_QUICKACK. If you find a case where that makes things worse, let me know." - _ = syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, unix.TCP_QUICKACK, 1) - - /// Enable keep-alive - { - _ = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1) - - // The time (in seconds) the connection needs to remain idle before - // TCP starts sending keepalive probes - _ = syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, 15) - - // Number of probes. - // ~ cat /proc/sys/net/ipv4/tcp_keepalive_probes (defaults to 9, we reduce it to 5) - _ = syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_KEEPCNT, 5) - - // Wait time after successful probe in seconds. - // ~ cat /proc/sys/net/ipv4/tcp_keepalive_intvl (defaults to 75 secs, we reduce it to 15 secs) - _ = syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, 15) - } - }) - return nil - } -} - -// NewInternodeDialContext setups a custom dialer for internode communication -func NewInternodeDialContext(dialTimeout time.Duration) DialContext { - d := &net.Dialer{ - Timeout: dialTimeout, - Control: setTCPParametersFn(), - } - return func(ctx context.Context, network, addr string) (net.Conn, error) { - return d.DialContext(ctx, network, addr) - } -} - // Reader to read random data. type netperfReader struct { buf []byte diff --git a/main_linux.go b/main_linux.go new file mode 100644 index 0000000..220145f --- /dev/null +++ b/main_linux.go @@ -0,0 +1,97 @@ +//go:build linux +// +build linux + +// Copyright (c) 2015-2024 MinIO, Inc. +// +// This file is part of MinIO Object Storage stack +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package main + +import ( + "context" + "net" + "syscall" + "time" + + "github.com/dustin/go-humanize" + "golang.org/x/sys/unix" +) + +func setTCPParametersFn() func(network, address string, c syscall.RawConn) error { + return func(network, address string, c syscall.RawConn) error { + c.Control(func(fdPtr uintptr) { + // got socket file descriptor to set parameters. + fd := int(fdPtr) + + _ = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_REUSEADDR, 1) + + _ = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_REUSEPORT, 1) + + { + // Enable big buffers + _ = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_SNDBUF, 8*humanize.MiByte) + + _ = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_RCVBUF, 8*humanize.MiByte) + } + + // Enable TCP open + // https://lwn.net/Articles/508865/ - 32k queue size. + _ = syscall.SetsockoptInt(fd, syscall.SOL_TCP, unix.TCP_FASTOPEN, 32*1024) + + // Enable TCP fast connect + // TCPFastOpenConnect sets the underlying socket to use + // the TCP fast open connect. This feature is supported + // since Linux 4.11. + _ = syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, unix.TCP_FASTOPEN_CONNECT, 1) + + // Enable TCP quick ACK, John Nagle says + // "Set TCP_QUICKACK. If you find a case where that makes things worse, let me know." + _ = syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, unix.TCP_QUICKACK, 1) + + /// Enable keep-alive + { + _ = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1) + + // The time (in seconds) the connection needs to remain idle before + // TCP starts sending keepalive probes + _ = syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, 15) + + // Number of probes. + // ~ cat /proc/sys/net/ipv4/tcp_keepalive_probes (defaults to 9, we reduce it to 5) + _ = syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_KEEPCNT, 5) + + // Wait time after successful probe in seconds. + // ~ cat /proc/sys/net/ipv4/tcp_keepalive_intvl (defaults to 75 secs, we reduce it to 15 secs) + _ = syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, 15) + } + }) + return nil + } +} + +// DialContext is a function to make custom Dial for internode communications +type DialContext func(ctx context.Context, network, address string) (net.Conn, error) + +// NewInternodeDialContext setups a custom dialer for internode communication +func NewInternodeDialContext(dialTimeout time.Duration) DialContext { + d := &net.Dialer{ + Timeout: dialTimeout, + Control: setTCPParametersFn(), + } + return func(ctx context.Context, network, addr string) (net.Conn, error) { + return d.DialContext(ctx, network, addr) + } +} diff --git a/main_others.go b/main_others.go new file mode 100644 index 0000000..90ac0b7 --- /dev/null +++ b/main_others.go @@ -0,0 +1,50 @@ +//go:build !linux +// +build !linux + +// Copyright (c) 2015-2024 MinIO, Inc. +// +// This file is part of MinIO Object Storage stack +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package main + +import ( + "context" + "net" + "syscall" + "time" +) + +// TODO: if possible implement for non-linux platforms, not a priority at the moment +// +//nolint:unused +func setTCPParametersFn() func(network, address string, c syscall.RawConn) error { + return func(network, address string, c syscall.RawConn) error { + return nil + } +} + +// DialContext is a function to make custom Dial for internode communications +type DialContext func(ctx context.Context, network, address string) (net.Conn, error) + +// NewInternodeDialContext configures a custom dialer for internode communications +func NewInternodeDialContext(dialTimeout time.Duration) DialContext { + return func(ctx context.Context, network, addr string) (net.Conn, error) { + dialer := &net.Dialer{ + Timeout: dialTimeout, + } + return dialer.DialContext(ctx, network, addr) + } +}