mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 21:34:02 +03:00
Propagate keep alive settings from the config
This commit is contained in:
+11
-1
@@ -204,13 +204,23 @@ proxies = [
|
|||||||
# define a global timeout on establishing of network connections. idle
|
# define a global timeout on establishing of network connections. idle
|
||||||
# means a timeout on pumping data between sockset when nothing is
|
# means a timeout on pumping data between sockset when nothing is
|
||||||
# happening.
|
# happening.
|
||||||
#
|
|
||||||
[network.timeout]
|
[network.timeout]
|
||||||
tcp = "5s"
|
tcp = "5s"
|
||||||
http = "10s"
|
http = "10s"
|
||||||
idle = "5m"
|
idle = "5m"
|
||||||
handshake = "10s"
|
handshake = "10s"
|
||||||
|
|
||||||
|
# this defines a configuration for TCP keep alives. Default values are taken
|
||||||
|
# from Golang default behavior.
|
||||||
|
[network.keep-alive]
|
||||||
|
disabled = false
|
||||||
|
# idle means a time period after which we start sending TCP Keep Alive probes
|
||||||
|
idle = "15s"
|
||||||
|
# interval is a period between 2 consecutive probes
|
||||||
|
interval = "15s"
|
||||||
|
# if we miss that many probes, a connection will be considered as a dead one.
|
||||||
|
count = 9
|
||||||
|
|
||||||
# mtg has to mimic real websites. It does not mean domain fronting, it also
|
# mtg has to mimic real websites. It does not mean domain fronting, it also
|
||||||
# means that traffic characteristics should be similar to real world traffic.
|
# means that traffic characteristics should be similar to real world traffic.
|
||||||
# websites and applications behave differently, their traffic patterns are also
|
# websites and applications behave differently, their traffic patterns are also
|
||||||
|
|||||||
@@ -97,6 +97,12 @@ func (d *Doctor) Run(cli *CLI, version string) error {
|
|||||||
conf.Network.Timeout.TCP.Get(10*time.Second),
|
conf.Network.Timeout.TCP.Get(10*time.Second),
|
||||||
conf.Network.Timeout.HTTP.Get(0),
|
conf.Network.Timeout.HTTP.Get(0),
|
||||||
conf.Network.Timeout.Idle.Get(0),
|
conf.Network.Timeout.Idle.Get(0),
|
||||||
|
net.KeepAliveConfig{
|
||||||
|
Enable: !conf.Network.KeepAlive.Disabled.Get(false),
|
||||||
|
Idle: conf.Network.KeepAlive.Idle.Get(0),
|
||||||
|
Interval: conf.Network.KeepAlive.Interval.Get(0),
|
||||||
|
Count: int(conf.Network.KeepAlive.Count.Get(0)),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
fmt.Println("Validate native network connectivity")
|
fmt.Println("Validate native network connectivity")
|
||||||
|
|||||||
@@ -50,6 +50,12 @@ func makeNetwork(conf *config.Config, version string) (mtglib.Network, error) {
|
|||||||
conf.Network.Timeout.TCP.Get(0),
|
conf.Network.Timeout.TCP.Get(0),
|
||||||
conf.Network.Timeout.HTTP.Get(0),
|
conf.Network.Timeout.HTTP.Get(0),
|
||||||
conf.Network.Timeout.Idle.Get(0),
|
conf.Network.Timeout.Idle.Get(0),
|
||||||
|
net.KeepAliveConfig{
|
||||||
|
Enable: !conf.Network.KeepAlive.Disabled.Get(false),
|
||||||
|
Idle: conf.Network.KeepAlive.Idle.Get(0),
|
||||||
|
Interval: conf.Network.KeepAlive.Interval.Get(0),
|
||||||
|
Count: int(conf.Network.KeepAlive.Count.Get(0)),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
proxyDialers := make([]mtglib.Network, len(conf.Network.Proxies))
|
proxyDialers := make([]mtglib.Network, len(conf.Network.Proxies))
|
||||||
|
|||||||
@@ -65,6 +65,12 @@ type Config struct {
|
|||||||
Idle TypeDuration `json:"idle"`
|
Idle TypeDuration `json:"idle"`
|
||||||
Handshake TypeDuration `json:"handshake"`
|
Handshake TypeDuration `json:"handshake"`
|
||||||
} `json:"timeout"`
|
} `json:"timeout"`
|
||||||
|
KeepAlive struct {
|
||||||
|
Disabled TypeBool `json:"disabled"`
|
||||||
|
Idle TypeDuration `json:"idle"`
|
||||||
|
Interval TypeDuration `json:"interval"`
|
||||||
|
Count TypeConcurrency `json:"count"`
|
||||||
|
} `json:"keepAlive"`
|
||||||
DOHIP TypeIP `json:"dohIp"`
|
DOHIP TypeIP `json:"dohIp"`
|
||||||
DNS TypeDNSURI `json:"dns"`
|
DNS TypeDNSURI `json:"dns"`
|
||||||
Proxies []TypeProxyURL `json:"proxies"`
|
Proxies []TypeProxyURL `json:"proxies"`
|
||||||
|
|||||||
@@ -60,6 +60,12 @@ type tomlConfig struct {
|
|||||||
Idle string `toml:"idle" json:"idle,omitempty"`
|
Idle string `toml:"idle" json:"idle,omitempty"`
|
||||||
Handshake string `toml:"handshake" json:"handshake,omitempty"`
|
Handshake string `toml:"handshake" json:"handshake,omitempty"`
|
||||||
} `toml:"timeout" json:"timeout,omitempty"`
|
} `toml:"timeout" json:"timeout,omitempty"`
|
||||||
|
KeepAlive struct {
|
||||||
|
Disabled bool `toml:"disabled" json:"disabled,omitempty"`
|
||||||
|
Idle string `toml:"idle" json:"idle,omitempty"`
|
||||||
|
Interval string `toml:"interval" json:"interval,omitempty"`
|
||||||
|
Count uint `toml:"count" json:"count,omitempty"`
|
||||||
|
} `toml:"keep-alive" json:"keepAlive,omitempty"`
|
||||||
DOHIP string `toml:"doh-ip" json:"dohIp,omitempty"`
|
DOHIP string `toml:"doh-ip" json:"dohIp,omitempty"`
|
||||||
DNS string `toml:"dns" json:"dns,omitempty"`
|
DNS string `toml:"dns" json:"dns,omitempty"`
|
||||||
Proxies []string `toml:"proxies" json:"proxies,omitempty"`
|
Proxies []string `toml:"proxies" json:"proxies,omitempty"`
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ func (suite *BaseHTTPTestSuite) SetupSuite() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *BaseHTTPTestSuite) SetupTest() {
|
func (suite *BaseHTTPTestSuite) SetupTest() {
|
||||||
suite.client = network.New(nil, "mtg/1", 0, 0, 0).MakeHTTPClient(nil)
|
suite.client = network.New(nil, "mtg/1", 0, 0, 0, network.DefaultKeepAliveConfig).MakeHTTPClient(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *BaseHTTPTestSuite) TestGet() {
|
func (suite *BaseHTTPTestSuite) TestGet() {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ type BaseNetworkTestSuite struct {
|
|||||||
func (suite *BaseNetworkTestSuite) SetupSuite() {
|
func (suite *BaseNetworkTestSuite) SetupSuite() {
|
||||||
suite.EchoServerTestSuite.SetupSuite()
|
suite.EchoServerTestSuite.SetupSuite()
|
||||||
|
|
||||||
suite.net = network.New(nil, "agent", 0, 0, 0)
|
suite.net = network.New(nil, "agent", 0, 0, 0, network.DefaultKeepAliveConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *BaseNetworkTestSuite) TestDialUnknownNetwork() {
|
func (suite *BaseNetworkTestSuite) TestDialUnknownNetwork() {
|
||||||
|
|||||||
+22
-2
@@ -11,6 +11,7 @@ package network
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"net"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -27,19 +28,25 @@ const (
|
|||||||
// DefaultTCPKeepAlivePeriod defines a time period between 2 consecuitive
|
// DefaultTCPKeepAlivePeriod defines a time period between 2 consecuitive
|
||||||
// probes.
|
// probes.
|
||||||
//
|
//
|
||||||
// Deprecated: use DefaultKeepAliveIdle and DefaultKeepAliveInterval instead.
|
// Deprecated: use DefaultKeepAliveConfig
|
||||||
DefaultTCPKeepAlivePeriod = 10 * time.Second
|
DefaultTCPKeepAlivePeriod = 10 * time.Second
|
||||||
|
|
||||||
// DefaultKeepAliveIdle is the time a connection must be idle before
|
// DefaultKeepAliveIdle is the time a connection must be idle before
|
||||||
// the first keepalive probe is sent.
|
// the first keepalive probe is sent.
|
||||||
|
//
|
||||||
|
// Deprecated: use DefaultKeepAliveConfig
|
||||||
DefaultKeepAliveIdle = 30 * time.Second
|
DefaultKeepAliveIdle = 30 * time.Second
|
||||||
|
|
||||||
// DefaultKeepAliveInterval is the time between consecutive keepalive
|
// DefaultKeepAliveInterval is the time between consecutive keepalive
|
||||||
// probes.
|
// probes.
|
||||||
|
//
|
||||||
|
// Deprecated: use DefaultKeepAliveConfig
|
||||||
DefaultKeepAliveInterval = 10 * time.Second
|
DefaultKeepAliveInterval = 10 * time.Second
|
||||||
|
|
||||||
// DefaultKeepAliveCount is the number of unacknowledged probes before
|
// DefaultKeepAliveCount is the number of unacknowledged probes before
|
||||||
// the connection is considered dead.
|
// the connection is considered dead.
|
||||||
|
//
|
||||||
|
// Deprecated: use DefaultKeepAliveConfig
|
||||||
DefaultKeepAliveCount = 3
|
DefaultKeepAliveCount = 3
|
||||||
|
|
||||||
// User Agent to use in HTTP client.
|
// User Agent to use in HTTP client.
|
||||||
@@ -50,4 +57,17 @@ const (
|
|||||||
tcpLingerTimeout = 1
|
tcpLingerTimeout = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrCannotDial = errors.New("cannot dial to any address")
|
var (
|
||||||
|
ErrCannotDial = errors.New("cannot dial to any address")
|
||||||
|
|
||||||
|
// DefaultKeepAliveConfig defines a default configuration for
|
||||||
|
// keep alive settings. As per official documentation, if keep alive
|
||||||
|
// is enabled, then:
|
||||||
|
//
|
||||||
|
// Idle = 15 * time.Second
|
||||||
|
// Interval = 15 * time.Second
|
||||||
|
// Count = 9
|
||||||
|
DefaultKeepAliveConfig = net.KeepAliveConfig{
|
||||||
|
Enable: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
type network struct {
|
type network struct {
|
||||||
net.Dialer
|
net.Dialer
|
||||||
|
|
||||||
|
keepAliveConfig net.KeepAliveConfig
|
||||||
httpTimeout time.Duration
|
httpTimeout time.Duration
|
||||||
idleTimeout time.Duration
|
idleTimeout time.Duration
|
||||||
userAgent string
|
userAgent string
|
||||||
@@ -37,7 +38,7 @@ func (n *network) DialContext(ctx context.Context, network, address string) (ess
|
|||||||
|
|
||||||
tcpConn := conn.(*net.TCPConn)
|
tcpConn := conn.(*net.TCPConn)
|
||||||
|
|
||||||
return tcpConn, setCommonSocketOptions(tcpConn)
|
return tcpConn, setCommonSocketOptions(tcpConn, n.keepAliveConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *network) MakeHTTPClient(
|
func (n *network) MakeHTTPClient(
|
||||||
@@ -71,6 +72,7 @@ func New(
|
|||||||
tcpTimeout,
|
tcpTimeout,
|
||||||
httpTimeout,
|
httpTimeout,
|
||||||
idleTimeout time.Duration,
|
idleTimeout time.Duration,
|
||||||
|
keepAliveConfig net.KeepAliveConfig,
|
||||||
) mtglib.Network {
|
) mtglib.Network {
|
||||||
if dnsResolver == nil {
|
if dnsResolver == nil {
|
||||||
dnsResolver = net.DefaultResolver
|
dnsResolver = net.DefaultResolver
|
||||||
@@ -89,5 +91,6 @@ func New(
|
|||||||
userAgent: userAgent,
|
userAgent: userAgent,
|
||||||
idleTimeout: idleTimeout,
|
idleTimeout: idleTimeout,
|
||||||
httpTimeout: httpTimeout,
|
httpTimeout: httpTimeout,
|
||||||
|
keepAliveConfig: keepAliveConfig,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,13 +5,8 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setCommonSocketOptions(conn *net.TCPConn) error {
|
func setCommonSocketOptions(conn *net.TCPConn, keepAliveConfig net.KeepAliveConfig) error {
|
||||||
if err := conn.SetKeepAliveConfig(net.KeepAliveConfig{
|
if err := conn.SetKeepAliveConfig(keepAliveConfig); err != nil {
|
||||||
Enable: true,
|
|
||||||
Idle: DefaultKeepAliveIdle,
|
|
||||||
Interval: DefaultKeepAliveInterval,
|
|
||||||
Count: DefaultKeepAliveCount,
|
|
||||||
}); err != nil {
|
|
||||||
return fmt.Errorf("cannot configure TCP keepalive: %w", err)
|
return fmt.Errorf("cannot configure TCP keepalive: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ func TestSetCommonSocketOptionsKeepAlive(t *testing.T) {
|
|||||||
|
|
||||||
tcpConn := accepted.(*net.TCPConn)
|
tcpConn := accepted.(*net.TCPConn)
|
||||||
|
|
||||||
err = setCommonSocketOptions(tcpConn)
|
err = setCommonSocketOptions(tcpConn, DefaultKeepAliveConfig)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
rawConn, err := tcpConn.SyscallConn()
|
rawConn, err := tcpConn.SyscallConn()
|
||||||
@@ -78,15 +78,15 @@ func TestSetCommonSocketOptionsKeepAlive(t *testing.T) {
|
|||||||
|
|
||||||
idle, err := unix.GetsockoptInt(int(fd), syscall.IPPROTO_TCP, tcpKeepIdleOption())
|
idle, err := unix.GetsockoptInt(int(fd), syscall.IPPROTO_TCP, tcpKeepIdleOption())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, int(DefaultKeepAliveIdle.Seconds()), idle, "keepalive idle should match DefaultKeepAliveIdle")
|
require.Equal(t, 15, idle, "keepalive idle should match DefaultKeepAliveIdle")
|
||||||
|
|
||||||
interval, err := unix.GetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_KEEPINTVL)
|
interval, err := unix.GetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_KEEPINTVL)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, int(DefaultKeepAliveInterval.Seconds()), interval, "keepalive interval should match DefaultKeepAliveInterval")
|
require.Equal(t, 15, interval, "keepalive interval should match DefaultKeepAliveInterval")
|
||||||
|
|
||||||
count, err := unix.GetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_KEEPCNT)
|
count, err := unix.GetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_KEEPCNT)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, DefaultKeepAliveCount, count, "keepalive count should match DefaultKeepAliveCount")
|
require.Equal(t, 9, count, "keepalive count should match DefaultKeepAliveCount")
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ func (suite *SocksProxyTestSuite) SetupSuite() {
|
|||||||
require.NoError(suite.T(), err)
|
require.NoError(suite.T(), err)
|
||||||
suite.authURL = parsed
|
suite.authURL = parsed
|
||||||
|
|
||||||
suite.baseNetwork = network.New(nil, "mtg", 0, 0, 0)
|
suite.baseNetwork = network.New(nil, "mtg", 0, 0, 0, network.DefaultKeepAliveConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *SocksProxyTestSuite) TestIncorrectSchema() {
|
func (suite *SocksProxyTestSuite) TestIncorrectSchema() {
|
||||||
|
|||||||
Reference in New Issue
Block a user