Skip to content

Commit d97de3a

Browse files
committed
client: set TCP_USER_TIMEOUT socket option for linux
Signed-off-by: zhangzujian <zhangzujian.7@gmail.com>
1 parent 67a3f3d commit d97de3a

File tree

4 files changed

+57
-1
lines changed

4 files changed

+57
-1
lines changed

client/client.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,12 @@ func (o *ovsdbClient) tryEndpoint(ctx context.Context, u *url.URL) (string, erro
353353
return "", fmt.Errorf("failed to open connection: %w", err)
354354
}
355355

356+
if o.options.timeout != 0 {
357+
if err = setTCPUserTimeout(c, o.options.timeout); err != nil {
358+
return "", fmt.Errorf("failed to set TCP_USER_TIMEOUT: %v", err)
359+
}
360+
}
361+
356362
o.createRPC2Client(c)
357363

358364
serverDBNames, err := o.listDbs(ctx)

client/syscall_linux.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//go:build linux
2+
// +build linux
3+
4+
// from https://github.com/grpc/grpc-go/internal/syscall/syscall_linux.go
5+
6+
package client
7+
8+
import (
9+
"fmt"
10+
"net"
11+
"syscall"
12+
"time"
13+
14+
"golang.org/x/sys/unix"
15+
)
16+
17+
// setTCPUserTimeout sets the TCP user timeout on a connection's socket
18+
func setTCPUserTimeout(conn net.Conn, timeout time.Duration) error {
19+
tcpconn, ok := conn.(*net.TCPConn)
20+
if !ok {
21+
// not a TCP connection. exit early
22+
return nil
23+
}
24+
rawConn, err := tcpconn.SyscallConn()
25+
if err != nil {
26+
return fmt.Errorf("error getting raw connection: %v", err)
27+
}
28+
err = rawConn.Control(func(fd uintptr) {
29+
err = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_USER_TIMEOUT, int(timeout/time.Millisecond))
30+
})
31+
if err != nil {
32+
return fmt.Errorf("error setting option on socket: %v", err)
33+
}
34+
35+
return nil
36+
}

client/syscall_nonlinux.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//go:build !linux
2+
// +build !linux
3+
4+
package client
5+
6+
import (
7+
"net"
8+
"time"
9+
)
10+
11+
// setTCPUserTimeout is a no-op function under non-linux environments
12+
func setTCPUserTimeout(conn net.Conn, timeout time.Duration) error {
13+
return nil
14+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ require (
1313
github.com/ovn-kubernetes/libovsdb v0.8.1
1414
github.com/prometheus/client_golang v1.23.2
1515
github.com/stretchr/testify v1.11.1
16+
golang.org/x/sys v0.39.0
1617
golang.org/x/text v0.32.0
1718
)
1819

@@ -55,7 +56,6 @@ require (
5556
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
5657
go.yaml.in/yaml/v2 v2.4.3 // indirect
5758
golang.org/x/crypto v0.46.0 // indirect
58-
golang.org/x/sys v0.39.0 // indirect
5959
google.golang.org/protobuf v1.36.10 // indirect
6060
gopkg.in/yaml.v2 v2.4.0 // indirect
6161
gopkg.in/yaml.v3 v3.0.1 // indirect

0 commit comments

Comments
 (0)