Skip to content

Commit

Permalink
chore: Update Go 1.23 TCP keep alive usage
Browse files Browse the repository at this point in the history
  • Loading branch information
layou233 committed Aug 17, 2024
1 parent 807c7a0 commit 947c42f
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 25 deletions.
40 changes: 40 additions & 0 deletions common/network/keep_alive_go122.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//go:build !go1.23

package network

import (
"net"
"time"
)

// KeepAliveConfig is a copy of net.KeepAliveConfig backported from go1.23.
type KeepAliveConfig struct {
// If Enable is true, keep-alive probes are enabled.
Enable bool

// Idle is the time that the connection must be idle before
// the first keep-alive probe is sent.
// If zero, a default value of 15 seconds is used.
Idle time.Duration

// Interval is the time between keep-alive probes.
// If zero, a default value of 15 seconds is used.
Interval time.Duration

// Count is the maximum number of keep-alive probes that
// can go unanswered before dropping a connection.
// If zero, a default value of 9 is used.
Count int
}

func SetDialerTCPKeepAlive(dialer *net.Dialer, config KeepAliveConfig) {
if config.Enable {
dialer.KeepAlive = config.Idle
}
}

func SetListenerTCPKeepAlive(listenConfig *net.ListenConfig, config KeepAliveConfig) {
if config.Enable {
listenConfig.KeepAlive = config.Idle
}
}
19 changes: 19 additions & 0 deletions common/network/keep_alive_go123.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//go:build go1.23

package network

import "net"

type KeepAliveConfig = net.KeepAliveConfig

func SetDialerTCPKeepAlive(dialer *net.Dialer, config KeepAliveConfig) {
if config.Enable {
dialer.KeepAliveConfig = config
}
}

func SetListenerTCPKeepAlive(listenConfig *net.ListenConfig, config KeepAliveConfig) {
if config.Enable {
listenConfig.KeepAliveConfig = config
}
}
66 changes: 46 additions & 20 deletions common/network/sockopt.go
Original file line number Diff line number Diff line change
@@ -1,36 +1,62 @@
package network

import "github.com/layou233/zbproxy/v3/common/jsonx"
import (
"time"

"github.com/layou233/zbproxy/v3/common/jsonx"
)

type InboundSocketOptions struct {
KeepAlivePeriod jsonx.Duration `json:",omitempty"`
Mark int `json:",omitempty"`
SendThrough string `json:",omitempty"`
TCPCongestion string `json:",omitempty"`
TCPFastOpen bool `json:",omitempty"`
MultiPathTCP bool `json:",omitempty"`
keepAliveOptions
Mark int `json:",omitempty"`
SendThrough string `json:",omitempty"`
TCPCongestion string `json:",omitempty"`
TCPFastOpen bool `json:",omitempty"`
MultiPathTCP bool `json:",omitempty"`
}

type OutboundSocketOptions struct {
KeepAlivePeriod jsonx.Duration `json:",omitempty"`
Mark int `json:",omitempty"`
Interface string `json:",omitempty"`
SendThrough string `json:",omitempty"`
TCPCongestion string `json:",omitempty"`
TCPFastOpen bool `json:",omitempty"`
MultiPathTCP bool `json:",omitempty"`
keepAliveOptions
Mark int `json:",omitempty"`
Interface string `json:",omitempty"`
SendThrough string `json:",omitempty"`
TCPCongestion string `json:",omitempty"`
TCPFastOpen bool `json:",omitempty"`
MultiPathTCP bool `json:",omitempty"`
}

type keepAliveOptions struct {
KeepAliveIdle jsonx.Duration `json:",omitempty"`
KeepAliveInterval jsonx.Duration `json:",omitempty"`
KeepAliveCount int `json:",omitempty"`
}

func (o *keepAliveOptions) KeepAliveConfig() (c KeepAliveConfig) {
c = KeepAliveConfig{
Idle: time.Duration(o.KeepAliveIdle),
Interval: time.Duration(o.KeepAliveInterval),
Count: o.KeepAliveCount,
}
if c.Idle > 0 || c.Interval > 0 || c.Count > 0 {
c.Enable = true
}
return
}

func ConvertLegacyOutboundOptions(inbound *InboundSocketOptions) *OutboundSocketOptions {
if inbound == nil {
return nil
}
return &OutboundSocketOptions{
KeepAlivePeriod: inbound.KeepAlivePeriod,
Mark: inbound.Mark,
SendThrough: inbound.SendThrough,
TCPCongestion: inbound.TCPCongestion,
TCPFastOpen: inbound.TCPFastOpen,
MultiPathTCP: inbound.MultiPathTCP,
keepAliveOptions: keepAliveOptions{
KeepAliveIdle: inbound.KeepAliveIdle,
KeepAliveInterval: inbound.KeepAliveInterval,
KeepAliveCount: inbound.KeepAliveCount,
},
Mark: inbound.Mark,
SendThrough: inbound.SendThrough,
TCPCongestion: inbound.TCPCongestion,
TCPFastOpen: inbound.TCPFastOpen,
MultiPathTCP: inbound.MultiPathTCP,
}
}
5 changes: 2 additions & 3 deletions common/network/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"net"
"syscall"
"time"
)

var SystemDialer Dialer = &systemOutbound{}
Expand All @@ -16,10 +15,10 @@ func NewSystemDialer(options *OutboundSocketOptions) Dialer {

out := &systemOutbound{
Dialer: net.Dialer{
Control: NewDialerControlFromOptions(options),
KeepAlive: time.Duration(options.KeepAlivePeriod),
Control: NewDialerControlFromOptions(options),
},
}
SetDialerTCPKeepAlive(&out.Dialer, options.KeepAliveConfig())
if options.SendThrough != "" {
out.Dialer.LocalAddr = &net.TCPAddr{IP: net.ParseIP(options.SendThrough)}
}
Expand Down
3 changes: 1 addition & 2 deletions service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"net/netip"
"os"
"strconv"
"time"

"github.com/layou233/zbproxy/v3/adapter"
"github.com/layou233/zbproxy/v3/common"
Expand Down Expand Up @@ -131,7 +130,7 @@ func (s *Service) Start(ctx context.Context) error {
Control: network.NewListenerControlFromOptions(s.config.SocketOptions),
}
if s.config.SocketOptions != nil {
listenConfig.KeepAlive = time.Duration(s.config.SocketOptions.KeepAlivePeriod)
network.SetListenerTCPKeepAlive(listenConfig, s.config.SocketOptions.KeepAliveConfig())
if s.config.SocketOptions.MultiPathTCP {
network.SetListenerMultiPathTCP(listenConfig, true)
}
Expand Down

0 comments on commit 947c42f

Please sign in to comment.