Source file
src/net/tcpsockopt_windows.go
1
2
3
4
5 package net
6
7 import (
8 "internal/syscall/windows"
9 "os"
10 "runtime"
11 "syscall"
12 "time"
13 "unsafe"
14 )
15
16
17
18 const (
19 defaultKeepAliveIdle = 2 * time.Hour
20 defaultKeepAliveInterval = time.Second
21 )
22
23 func setKeepAliveIdle(fd *netFD, d time.Duration) error {
24 if !windows.SupportTCPKeepAliveIdle() {
25 return setKeepAliveIdleAndInterval(fd, d, -1)
26 }
27
28 if d == 0 {
29 d = defaultTCPKeepAliveIdle
30 } else if d < 0 {
31 return nil
32 }
33
34 secs := int(roundDurationUp(d, time.Second))
35 err := fd.pfd.SetsockoptInt(syscall.IPPROTO_TCP, windows.TCP_KEEPIDLE, secs)
36 runtime.KeepAlive(fd)
37 return os.NewSyscallError("setsockopt", err)
38 }
39
40 func setKeepAliveInterval(fd *netFD, d time.Duration) error {
41 if !windows.SupportTCPKeepAliveInterval() {
42 return setKeepAliveIdleAndInterval(fd, -1, d)
43 }
44
45 if d == 0 {
46 d = defaultTCPKeepAliveInterval
47 } else if d < 0 {
48 return nil
49 }
50
51 secs := int(roundDurationUp(d, time.Second))
52 err := fd.pfd.SetsockoptInt(syscall.IPPROTO_TCP, windows.TCP_KEEPINTVL, secs)
53 runtime.KeepAlive(fd)
54 return os.NewSyscallError("setsockopt", err)
55 }
56
57 func setKeepAliveCount(fd *netFD, n int) error {
58 if n == 0 {
59 n = defaultTCPKeepAliveCount
60 } else if n < 0 {
61 return nil
62 }
63
64 err := fd.pfd.SetsockoptInt(syscall.IPPROTO_TCP, windows.TCP_KEEPCNT, n)
65 runtime.KeepAlive(fd)
66 return os.NewSyscallError("setsockopt", err)
67 }
68
69
70 func setKeepAliveIdleAndInterval(fd *netFD, idle, interval time.Duration) error {
71
72
73
74
75
76
77
78 switch {
79 case idle < 0 && interval >= 0:
80
81
82 return syscall.WSAENOPROTOOPT
83 case idle >= 0 && interval < 0:
84
85
86
87
88
89 interval = defaultKeepAliveInterval
90 case idle < 0 && interval < 0:
91
92 return nil
93 case idle >= 0 && interval >= 0:
94
95 }
96
97 if idle == 0 {
98 idle = defaultTCPKeepAliveIdle
99 }
100 if interval == 0 {
101 interval = defaultTCPKeepAliveInterval
102 }
103
104
105
106 tcpKeepAliveIdle := uint32(roundDurationUp(idle, time.Millisecond))
107 tcpKeepAliveInterval := uint32(roundDurationUp(interval, time.Millisecond))
108 ka := syscall.TCPKeepalive{
109 OnOff: 1,
110 Time: tcpKeepAliveIdle,
111 Interval: tcpKeepAliveInterval,
112 }
113 ret := uint32(0)
114 size := uint32(unsafe.Sizeof(ka))
115 err := fd.pfd.WSAIoctl(syscall.SIO_KEEPALIVE_VALS, (*byte)(unsafe.Pointer(&ka)), size, nil, 0, &ret, nil, 0)
116 runtime.KeepAlive(fd)
117 return os.NewSyscallError("wsaioctl", err)
118 }
119
View as plain text