1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package net
6
7import (
8	"runtime"
9	"syscall"
10	"time"
11)
12
13// syscall.TCP_KEEPINTVL and syscall.TCP_KEEPCNT might be missing on some darwin architectures.
14const (
15	sysTCP_KEEPINTVL = 0x101
16	sysTCP_KEEPCNT   = 0x102
17)
18
19func setKeepAliveIdle(fd *netFD, d time.Duration) error {
20	if d == 0 {
21		d = defaultTCPKeepAliveIdle
22	} else if d < 0 {
23		return nil
24	}
25
26	// The kernel expects seconds so round to next highest second.
27	secs := int(roundDurationUp(d, time.Second))
28	err := fd.pfd.SetsockoptInt(syscall.IPPROTO_TCP, syscall.TCP_KEEPALIVE, secs)
29	runtime.KeepAlive(fd)
30	return wrapSyscallError("setsockopt", err)
31}
32
33func setKeepAliveInterval(fd *netFD, d time.Duration) error {
34	if d == 0 {
35		d = defaultTCPKeepAliveInterval
36	} else if d < 0 {
37		return nil
38	}
39
40	// The kernel expects seconds so round to next highest second.
41	secs := int(roundDurationUp(d, time.Second))
42	err := fd.pfd.SetsockoptInt(syscall.IPPROTO_TCP, sysTCP_KEEPINTVL, secs)
43	runtime.KeepAlive(fd)
44	return wrapSyscallError("setsockopt", err)
45}
46
47func setKeepAliveCount(fd *netFD, n int) error {
48	if n == 0 {
49		n = defaultTCPKeepAliveCount
50	} else if n < 0 {
51		return nil
52	}
53
54	err := fd.pfd.SetsockoptInt(syscall.IPPROTO_TCP, sysTCP_KEEPCNT, n)
55	runtime.KeepAlive(fd)
56	return wrapSyscallError("setsockopt", err)
57}
58