Просмотр исходного кода

Propagate keep alive settings from the config

pull/455/head
9seconds 4 недель назад
Родитель
Сommit
9d24f92a57

+ 11
- 1
example.config.toml Просмотреть файл

@@ -219,13 +219,23 @@ proxies = [
219 219
 # define a global timeout on establishing of network connections. idle
220 220
 # means a timeout on pumping data between sockset when nothing is
221 221
 # happening.
222
-#
223 222
 [network.timeout]
224 223
 tcp = "5s"
225 224
 http = "10s"
226 225
 idle = "5m"
227 226
 handshake = "10s"
228 227
 
228
+# this defines a configuration for TCP keep alives. Default values are taken
229
+# from Golang default behavior.
230
+[network.keep-alive]
231
+disabled = false
232
+# idle means a time period after which we start sending TCP Keep Alive probes
233
+idle = "15s"
234
+# interval is a period between 2 consecutive probes
235
+interval = "15s"
236
+# if we miss that many probes, a connection will be considered as a dead one.
237
+count = 9
238
+
229 239
 # mtg has to mimic real websites. It does not mean domain fronting, it also
230 240
 # means that traffic characteristics should be similar to real world traffic.
231 241
 # websites and applications behave differently, their traffic patterns are also

+ 6
- 0
internal/cli/doctor.go Просмотреть файл

@@ -97,6 +97,12 @@ func (d *Doctor) Run(cli *CLI, version string) error {
97 97
 		conf.Network.Timeout.TCP.Get(10*time.Second),
98 98
 		conf.Network.Timeout.HTTP.Get(0),
99 99
 		conf.Network.Timeout.Idle.Get(0),
100
+		net.KeepAliveConfig{
101
+			Enable:   !conf.Network.KeepAlive.Disabled.Get(false),
102
+			Idle:     conf.Network.KeepAlive.Idle.Get(0),
103
+			Interval: conf.Network.KeepAlive.Interval.Get(0),
104
+			Count:    int(conf.Network.KeepAlive.Count.Get(0)),
105
+		},
100 106
 	)
101 107
 
102 108
 	fmt.Println("Validate native network connectivity")

+ 6
- 0
internal/cli/run_proxy.go Просмотреть файл

@@ -51,6 +51,12 @@ func makeNetwork(conf *config.Config, version string) (mtglib.Network, error) {
51 51
 		conf.Network.Timeout.TCP.Get(0),
52 52
 		conf.Network.Timeout.HTTP.Get(0),
53 53
 		conf.Network.Timeout.Idle.Get(0),
54
+		net.KeepAliveConfig{
55
+			Enable:   !conf.Network.KeepAlive.Disabled.Get(false),
56
+			Idle:     conf.Network.KeepAlive.Idle.Get(0),
57
+			Interval: conf.Network.KeepAlive.Interval.Get(0),
58
+			Count:    int(conf.Network.KeepAlive.Count.Get(0)),
59
+		},
54 60
 	)
55 61
 
56 62
 	proxyDialers := make([]mtglib.Network, len(conf.Network.Proxies))

+ 6
- 0
internal/config/config.go Просмотреть файл

@@ -66,6 +66,12 @@ type Config struct {
66 66
 			Idle      TypeDuration `json:"idle"`
67 67
 			Handshake TypeDuration `json:"handshake"`
68 68
 		} `json:"timeout"`
69
+		KeepAlive struct {
70
+			Disabled TypeBool        `json:"disabled"`
71
+			Idle     TypeDuration    `json:"idle"`
72
+			Interval TypeDuration    `json:"interval"`
73
+			Count    TypeConcurrency `json:"count"`
74
+		} `json:"keepAlive"`
69 75
 		DOHIP   TypeIP         `json:"dohIp"`
70 76
 		DNS     TypeDNSURI     `json:"dns"`
71 77
 		Proxies []TypeProxyURL `json:"proxies"`

+ 6
- 0
internal/config/parse.go Просмотреть файл

@@ -61,6 +61,12 @@ type tomlConfig struct {
61 61
 			Idle      string `toml:"idle" json:"idle,omitempty"`
62 62
 			Handshake string `toml:"handshake" json:"handshake,omitempty"`
63 63
 		} `toml:"timeout" json:"timeout,omitempty"`
64
+		KeepAlive struct {
65
+			Disabled bool   `toml:"disabled" json:"disabled,omitempty"`
66
+			Idle     string `toml:"idle" json:"idle,omitempty"`
67
+			Interval string `toml:"interval" json:"interval,omitempty"`
68
+			Count    uint   `toml:"count" json:"count,omitempty"`
69
+		} `toml:"keep-alive" json:"keepAlive,omitempty"`
64 70
 		DOHIP   string   `toml:"doh-ip" json:"dohIp,omitempty"`
65 71
 		DNS     string   `toml:"dns" json:"dns,omitempty"`
66 72
 		Proxies []string `toml:"proxies" json:"proxies,omitempty"`

+ 1
- 1
network/v2/base_http_test.go Просмотреть файл

@@ -25,7 +25,7 @@ func (suite *BaseHTTPTestSuite) SetupSuite() {
25 25
 }
26 26
 
27 27
 func (suite *BaseHTTPTestSuite) SetupTest() {
28
-	suite.client = network.New(nil, "mtg/1", 0, 0, 0).MakeHTTPClient(nil)
28
+	suite.client = network.New(nil, "mtg/1", 0, 0, 0, network.DefaultKeepAliveConfig).MakeHTTPClient(nil)
29 29
 }
30 30
 
31 31
 func (suite *BaseHTTPTestSuite) TestGet() {

+ 1
- 1
network/v2/base_network_test.go Просмотреть файл

@@ -19,7 +19,7 @@ type BaseNetworkTestSuite struct {
19 19
 func (suite *BaseNetworkTestSuite) SetupSuite() {
20 20
 	suite.EchoServerTestSuite.SetupSuite()
21 21
 
22
-	suite.net = network.New(nil, "agent", 0, 0, 0)
22
+	suite.net = network.New(nil, "agent", 0, 0, 0, network.DefaultKeepAliveConfig)
23 23
 }
24 24
 
25 25
 func (suite *BaseNetworkTestSuite) TestDialUnknownNetwork() {

+ 22
- 2
network/v2/init.go Просмотреть файл

@@ -11,6 +11,7 @@ package network
11 11
 
12 12
 import (
13 13
 	"errors"
14
+	"net"
14 15
 	"time"
15 16
 )
16 17
 
@@ -27,19 +28,25 @@ const (
27 28
 	// DefaultTCPKeepAlivePeriod defines a time period between 2 consecuitive
28 29
 	// probes.
29 30
 	//
30
-	// Deprecated: use DefaultKeepAliveIdle and DefaultKeepAliveInterval instead.
31
+	// Deprecated: use DefaultKeepAliveConfig
31 32
 	DefaultTCPKeepAlivePeriod = 10 * time.Second
32 33
 
33 34
 	// DefaultKeepAliveIdle is the time a connection must be idle before
34 35
 	// the first keepalive probe is sent.
36
+	//
37
+	// Deprecated: use DefaultKeepAliveConfig
35 38
 	DefaultKeepAliveIdle = 30 * time.Second
36 39
 
37 40
 	// DefaultKeepAliveInterval is the time between consecutive keepalive
38 41
 	// probes.
42
+	//
43
+	// Deprecated: use DefaultKeepAliveConfig
39 44
 	DefaultKeepAliveInterval = 10 * time.Second
40 45
 
41 46
 	// DefaultKeepAliveCount is the number of unacknowledged probes before
42 47
 	// the connection is considered dead.
48
+	//
49
+	// Deprecated: use DefaultKeepAliveConfig
43 50
 	DefaultKeepAliveCount = 3
44 51
 
45 52
 	// User Agent to use in HTTP client.
@@ -50,4 +57,17 @@ const (
50 57
 	tcpLingerTimeout = 1
51 58
 )
52 59
 
53
-var ErrCannotDial = errors.New("cannot dial to any address")
60
+var (
61
+	ErrCannotDial = errors.New("cannot dial to any address")
62
+
63
+	// DefaultKeepAliveConfig defines a default configuration for
64
+	// keep alive settings. As per official documentation, if keep alive
65
+	// is enabled, then:
66
+	//
67
+	//  Idle = 15 * time.Second
68
+	//  Interval = 15 * time.Second
69
+	//  Count = 9
70
+	DefaultKeepAliveConfig = net.KeepAliveConfig{
71
+		Enable: true,
72
+	}
73
+)

+ 10
- 7
network/v2/network.go Просмотреть файл

@@ -14,9 +14,10 @@ import (
14 14
 type network struct {
15 15
 	net.Dialer
16 16
 
17
-	httpTimeout time.Duration
18
-	idleTimeout time.Duration
19
-	userAgent   string
17
+	keepAliveConfig net.KeepAliveConfig
18
+	httpTimeout     time.Duration
19
+	idleTimeout     time.Duration
20
+	userAgent       string
20 21
 }
21 22
 
22 23
 func (n *network) Dial(network, address string) (essentials.Conn, error) {
@@ -37,7 +38,7 @@ func (n *network) DialContext(ctx context.Context, network, address string) (ess
37 38
 
38 39
 	tcpConn := conn.(*net.TCPConn)
39 40
 
40
-	return tcpConn, setCommonSocketOptions(tcpConn)
41
+	return tcpConn, setCommonSocketOptions(tcpConn, n.keepAliveConfig)
41 42
 }
42 43
 
43 44
 func (n *network) MakeHTTPClient(
@@ -71,6 +72,7 @@ func New(
71 72
 	tcpTimeout,
72 73
 	httpTimeout,
73 74
 	idleTimeout time.Duration,
75
+	keepAliveConfig net.KeepAliveConfig,
74 76
 ) mtglib.Network {
75 77
 	if dnsResolver == nil {
76 78
 		dnsResolver = net.DefaultResolver
@@ -86,8 +88,9 @@ func New(
86 88
 			Resolver:      dnsResolver,
87 89
 			FallbackDelay: -1,
88 90
 		},
89
-		userAgent:   userAgent,
90
-		idleTimeout: idleTimeout,
91
-		httpTimeout: httpTimeout,
91
+		userAgent:       userAgent,
92
+		idleTimeout:     idleTimeout,
93
+		httpTimeout:     httpTimeout,
94
+		keepAliveConfig: keepAliveConfig,
92 95
 	}
93 96
 }

+ 2
- 7
network/v2/sockopts.go Просмотреть файл

@@ -5,13 +5,8 @@ import (
5 5
 	"net"
6 6
 )
7 7
 
8
-func setCommonSocketOptions(conn *net.TCPConn) error {
9
-	if err := conn.SetKeepAliveConfig(net.KeepAliveConfig{
10
-		Enable:   true,
11
-		Idle:     DefaultKeepAliveIdle,
12
-		Interval: DefaultKeepAliveInterval,
13
-		Count:    DefaultKeepAliveCount,
14
-	}); err != nil {
8
+func setCommonSocketOptions(conn *net.TCPConn, keepAliveConfig net.KeepAliveConfig) error {
9
+	if err := conn.SetKeepAliveConfig(keepAliveConfig); err != nil {
15 10
 		return fmt.Errorf("cannot configure TCP keepalive: %w", err)
16 11
 	}
17 12
 

+ 4
- 4
network/v2/sockopts_test.go Просмотреть файл

@@ -65,7 +65,7 @@ func TestSetCommonSocketOptionsKeepAlive(t *testing.T) {
65 65
 
66 66
 	tcpConn := accepted.(*net.TCPConn)
67 67
 
68
-	err = setCommonSocketOptions(tcpConn)
68
+	err = setCommonSocketOptions(tcpConn, DefaultKeepAliveConfig)
69 69
 	require.NoError(t, err)
70 70
 
71 71
 	rawConn, err := tcpConn.SyscallConn()
@@ -78,15 +78,15 @@ func TestSetCommonSocketOptionsKeepAlive(t *testing.T) {
78 78
 
79 79
 		idle, err := unix.GetsockoptInt(int(fd), syscall.IPPROTO_TCP, tcpKeepIdleOption())
80 80
 		require.NoError(t, err)
81
-		require.Equal(t, int(DefaultKeepAliveIdle.Seconds()), idle, "keepalive idle should match DefaultKeepAliveIdle")
81
+		require.Equal(t, 15, idle, "keepalive idle should match DefaultKeepAliveIdle")
82 82
 
83 83
 		interval, err := unix.GetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_KEEPINTVL)
84 84
 		require.NoError(t, err)
85
-		require.Equal(t, int(DefaultKeepAliveInterval.Seconds()), interval, "keepalive interval should match DefaultKeepAliveInterval")
85
+		require.Equal(t, 15, interval, "keepalive interval should match DefaultKeepAliveInterval")
86 86
 
87 87
 		count, err := unix.GetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_KEEPCNT)
88 88
 		require.NoError(t, err)
89
-		require.Equal(t, DefaultKeepAliveCount, count, "keepalive count should match DefaultKeepAliveCount")
89
+		require.Equal(t, 9, count, "keepalive count should match DefaultKeepAliveCount")
90 90
 	})
91 91
 	require.NoError(t, err)
92 92
 }

+ 1
- 1
network/v2/socks_proxy_test.go Просмотреть файл

@@ -66,7 +66,7 @@ func (suite *SocksProxyTestSuite) SetupSuite() {
66 66
 	require.NoError(suite.T(), err)
67 67
 	suite.authURL = parsed
68 68
 
69
-	suite.baseNetwork = network.New(nil, "mtg", 0, 0, 0)
69
+	suite.baseNetwork = network.New(nil, "mtg", 0, 0, 0, network.DefaultKeepAliveConfig)
70 70
 }
71 71
 
72 72
 func (suite *SocksProxyTestSuite) TestIncorrectSchema() {

Загрузка…
Отмена
Сохранить