1// Copyright 2023 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	"internal/syscall/windows"
9	"syscall"
10)
11
12// SetKeepAliveConfig configures keep-alive messages sent by the operating system.
13func (c *TCPConn) SetKeepAliveConfig(config KeepAliveConfig) error {
14	if !c.ok() {
15		return syscall.EINVAL
16	}
17
18	if err := setKeepAlive(c.fd, config.Enable); err != nil {
19		return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
20	}
21	if windows.SupportTCPKeepAliveIdle() && windows.SupportTCPKeepAliveInterval() {
22		if err := setKeepAliveIdle(c.fd, config.Idle); err != nil {
23			return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
24		}
25		if err := setKeepAliveInterval(c.fd, config.Interval); err != nil {
26			return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
27		}
28	} else if err := setKeepAliveIdleAndInterval(c.fd, config.Idle, config.Interval); err != nil {
29		return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
30	}
31	if err := setKeepAliveCount(c.fd, config.Count); err != nil {
32		return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
33	}
34
35	return nil
36}
37