]> git.ipfire.org Git - thirdparty/squid.git/blame - src/comm/Tcp.cc
Fix build on OpenBSD (#885)
[thirdparty/squid.git] / src / comm / Tcp.cc
CommitLineData
1dde4660
AJ
1/*
2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9/* DEBUG: section 05 TCP Socket Functions */
10
11#include "squid.h"
12#include "comm/Tcp.h"
13#include "Debug.h"
14
15#if HAVE_NETINET_TCP_H
16#include <netinet/tcp.h>
17#endif
61e38858
FC
18#if HAVE_SYS_SOCKET_H
19#include <sys/socket.h>
20#endif
1dde4660
AJ
21#include <type_traits>
22
23/// setsockopt(2) wrapper
24template <typename Option>
25static bool
26SetSocketOption(const int fd, const int level, const int optName, const Option &optValue)
27{
28#if HAVE_STD_IS_TRIVIALLY_COPYABLE
29 static_assert(std::is_trivially_copyable<Option>::value, "setsockopt() expects POD-like options");
30#endif
31 static_assert(!std::is_same<Option, bool>::value, "setsockopt() uses int to represent boolean options");
32 if (setsockopt(fd, level, optName, &optValue, sizeof(optValue)) < 0) {
33 const auto xerrno = errno;
34 debugs(5, DBG_IMPORTANT, "ERROR: setsockopt(2) failure: " << xstrerr(xerrno));
35 // TODO: Generalize to throw on errors when some callers need that.
36 return false;
37 }
38 return true;
39}
40
41/// setsockopt(2) wrapper for setting typical on/off options
42static bool
43SetBooleanSocketOption(const int fd, const int level, const int optName, const bool enable)
44{
45 const int optValue = enable ? 1 : 0;
46 return SetSocketOption(fd, level, optName, optValue);
47}
48
49void
50Comm::ApplyTcpKeepAlive(int fd, const TcpKeepAlive &cfg)
51{
52 if (!cfg.enabled)
53 return;
54
55#if defined(TCP_KEEPCNT)
56 if (cfg.timeout && cfg.interval) {
57 const int count = (cfg.timeout + cfg.interval - 1) / cfg.interval; // XXX: unsigned-to-signed conversion
58 (void)SetSocketOption(fd, IPPROTO_TCP, TCP_KEEPCNT, count);
59 }
60#endif
61#if defined(TCP_KEEPIDLE)
62 if (cfg.idle) {
63 // XXX: TCP_KEEPIDLE expects an int; cfg.idle is unsigned
64 (void)SetSocketOption(fd, IPPROTO_TCP, TCP_KEEPIDLE, cfg.idle);
65 }
66#endif
67#if defined(TCP_KEEPINTVL)
68 if (cfg.interval) {
69 // XXX: TCP_KEEPINTVL expects an int; cfg.interval is unsigned
70 (void)SetSocketOption(fd, IPPROTO_TCP, TCP_KEEPINTVL, cfg.interval);
71 }
72#endif
73 (void)SetBooleanSocketOption(fd, SOL_SOCKET, SO_KEEPALIVE, true);
74}