Переглянути джерело

Add TCP_USER_TIMEOUT support

tags/v2.2.8^2^2
9seconds 4 тижднів тому
джерело
коміт
b58ac669d5

+ 1
- 0
network/v2/sockopts.go Переглянути файл

@@ -24,6 +24,7 @@ func setCommonSocketOptions(conn *net.TCPConn, keepAliveConfig net.KeepAliveConf
24 24
 	}
25 25
 
26 26
 	setCongestionControl(rawConn)
27
+	setTCPUserTimeout(rawConn, keepAliveConfig)
27 28
 
28 29
 	return nil
29 30
 }

+ 39
- 0
network/v2/sockopts_linux.go Переглянути файл

@@ -3,11 +3,50 @@
3 3
 package network
4 4
 
5 5
 import (
6
+	"net"
6 7
 	"syscall"
8
+	"time"
7 9
 
8 10
 	"golang.org/x/sys/unix"
9 11
 )
10 12
 
13
+// Go runtime defaults for KeepAliveConfig when fields are zero.
14
+const (
15
+	goDefaultKeepAliveIdle     = 15 * time.Second
16
+	goDefaultKeepAliveInterval = 15 * time.Second
17
+	goDefaultKeepAliveCount    = 9
18
+)
19
+
20
+// setTCPUserTimeout sets TCP_USER_TIMEOUT on a socket. If transmitted
21
+// data remains unacknowledged for this long, the kernel closes the
22
+// connection. As recommended by Cloudflare
23
+// (https://blog.cloudflare.com/when-tcp-sockets-refuse-to-die/),
24
+// the value is computed as: keepidle + keepintvl * keepcnt. This
25
+// ensures TCP_USER_TIMEOUT and keepalives agree on when to give up.
26
+// Best-effort: silently ignored if unsupported.
27
+func setTCPUserTimeout(conn syscall.RawConn, cfg net.KeepAliveConfig) {
28
+	idle := cfg.Idle
29
+	if idle == 0 {
30
+		idle = goDefaultKeepAliveIdle
31
+	}
32
+
33
+	interval := cfg.Interval
34
+	if interval == 0 {
35
+		interval = goDefaultKeepAliveInterval
36
+	}
37
+
38
+	count := cfg.Count
39
+	if count == 0 {
40
+		count = goDefaultKeepAliveCount
41
+	}
42
+
43
+	timeout := idle + interval*time.Duration(count)
44
+
45
+	conn.Control(func(fd uintptr) { //nolint: errcheck
46
+		unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_USER_TIMEOUT, int(timeout.Milliseconds())) //nolint: errcheck
47
+	})
48
+}
49
+
11 50
 func setCongestionControl(conn syscall.RawConn) {
12 51
 	conn.Control(func(fd uintptr) { //nolint: errcheck
13 52
 		// BBR provides better throughput over lossy and high-latency links compared

+ 6
- 2
network/v2/sockopts_nolinux.go Переглянути файл

@@ -2,6 +2,10 @@
2 2
 
3 3
 package network
4 4
 
5
-import "syscall"
5
+import (
6
+	"net"
7
+	"syscall"
8
+)
6 9
 
7
-func setCongestionControl(conn syscall.RawConn) {}
10
+func setCongestionControl(conn syscall.RawConn)                       {}
11
+func setTCPUserTimeout(conn syscall.RawConn, cfg net.KeepAliveConfig) {}

Завантаження…
Відмінити
Зберегти