Skip to content

Commit 85e24f2

Browse files
committed
Maintenance: use SetSocketOption() template
1 parent f35c1dc commit 85e24f2

19 files changed

Lines changed: 154 additions & 221 deletions

src/Makefile.am

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -917,10 +917,13 @@ nodist_tests_testURL_SOURCES = \
917917
tests/stub_access_log.cc \
918918
anyp/Uri.h \
919919
anyp/UriScheme.h \
920+
tests/stub_cache_manager.cc \
920921
tests/stub_cbdata.cc \
921922
tests/stub_debug.cc \
923+
tests/stub_libcomm.cc \
922924
tests/stub_libhttp.cc \
923-
tests/stub_libmem.cc
925+
tests/stub_libmem.cc \
926+
tests/stub_MemBuf.cc
924927
tests_testURL_LDADD = \
925928
libsquid.la \
926929
anyp/libanyp.la \
@@ -2033,6 +2036,7 @@ tests_testHttp1Parser_SOURCES = \
20332036
wordlist.h
20342037
nodist_tests_testHttp1Parser_SOURCES = \
20352038
$(TESTSOURCES) \
2039+
tests/stub_libcomm.cc \
20362040
tests/stub_libtime.cc
20372041
tests_testHttp1Parser_LDADD= \
20382042
http/libhttp.la \
@@ -2363,8 +2367,8 @@ tests_testHttpRequest_LDADD = \
23632367
anyp/libanyp.la \
23642368
$(SNMP_LIBS) \
23652369
icmp/libicmp.la \
2366-
comm/libcomm.la \
23672370
ip/libip.la \
2371+
comm/libcomm.la \
23682372
log/liblog.la \
23692373
format/libformat.la \
23702374
store/libstore.la \
@@ -2397,8 +2401,12 @@ check_PROGRAMS += tests/testIpAddress
23972401
tests_testIpAddress_SOURCES = \
23982402
tests/testIpAddress.cc
23992403
nodist_tests_testIpAddress_SOURCES = \
2404+
tests/stub_MemBuf.cc \
24002405
tests/stub_SBuf.cc \
2406+
tests/stub_cache_manager.cc \
2407+
tests/stub_cbdata.cc \
24012408
tests/stub_debug.cc \
2409+
tests/stub_libcomm.cc \
24022410
tests/stub_libmem.cc \
24032411
tests/stub_tools.cc
24042412
tests_testIpAddress_LDADD = \
@@ -2416,9 +2424,13 @@ check_PROGRAMS += tests/testIcmp
24162424
tests_testIcmp_SOURCES = \
24172425
tests/testIcmp.cc
24182426
nodist_tests_testIcmp_SOURCES = \
2427+
tests/stub_MemBuf.cc \
24192428
tests/stub_SBuf.cc \
2429+
tests/stub_cache_manager.cc \
2430+
tests/stub_cbdata.cc \
24202431
tests/stub_debug.cc \
24212432
icmp/Icmp.h \
2433+
tests/stub_libcomm.cc \
24222434
tests/stub_libmem.cc \
24232435
tests/stub_libtime.cc
24242436
tests_testIcmp_LDADD=\

src/client_side.cc

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2134,10 +2134,7 @@ ConnStateData::start()
21342134
(transparent() || port->disable_pmtu_discovery == DISABLE_PMTU_ALWAYS)) {
21352135
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
21362136
int i = IP_PMTUDISC_DONT;
2137-
if (setsockopt(clientConnection->fd, SOL_IP, IP_MTU_DISCOVER, &i, sizeof(i)) < 0) {
2138-
int xerrno = errno;
2139-
debugs(33, 2, "WARNING: Path MTU discovery disabling failed on " << clientConnection << " : " << xstrerr(xerrno));
2140-
}
2137+
Comm::SetSocketOption(clientConnection->fd, SOL_IP, IP_MTU_DISCOVER, i, ToSBuf("IP_MTU_DISCOVER disabled for client ", clientConnection));
21412138
#else
21422139
static bool reported = false;
21432140

src/client_side_request.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,8 +1708,7 @@ ClientHttpRequest::doCallouts()
17081708

17091709
if (!calloutContext->toClientMarkingDone) {
17101710
calloutContext->toClientMarkingDone = true;
1711-
tos_t tos = aclMapTOS(Ip::Qos::TheConfig.tosToClient, &ch);
1712-
if (tos)
1711+
if (tos_t tos = aclMapTOS(Ip::Qos::TheConfig.tosToClient, &ch))
17131712
Ip::Qos::setSockTos(getConn()->clientConnection, tos);
17141713

17151714
const auto packetMark = aclFindNfMarkConfig(Ip::Qos::TheConfig.nfmarkToClient, &ch);

src/clients/FtpGateway.cc

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1774,15 +1774,7 @@ ftpOpenListenSocket(Ftp::Gateway * ftpState, int fallback)
17741774
* REUSEADDR is needed in fallback mode, since the same port is
17751775
* used for both control and data.
17761776
*/
1777-
if (fallback) {
1778-
int on = 1;
1779-
errno = 0;
1780-
if (setsockopt(ftpState->ctrl.conn->fd, SOL_SOCKET, SO_REUSEADDR,
1781-
(char *) &on, sizeof(on)) == -1) {
1782-
int xerrno = errno;
1783-
// SO_REUSEADDR is only an optimization, no need to be verbose about error
1784-
debugs(9, 4, "setsockopt failed: " << xstrerr(xerrno));
1785-
}
1777+
if (fallback && Comm::SetBooleanSocketOption(ftpState->ctrl.conn->fd, SOL_SOCKET, SO_REUSEADDR, true, SBuf("SO_REUSEADDR"))) {
17861778
ftpState->ctrl.conn->flags |= COMM_REUSEADDR;
17871779
temp->flags |= COMM_REUSEADDR;
17881780
} else {

src/comm.cc

Lines changed: 21 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,7 @@ static void
210210
commSetBindAddressNoPort(const int fd)
211211
{
212212
#if defined(IP_BIND_ADDRESS_NO_PORT)
213-
int flag = 1;
214-
if (setsockopt(fd, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, reinterpret_cast<char*>(&flag), sizeof(flag)) < 0) {
215-
const auto savedErrno = errno;
216-
debugs(50, DBG_IMPORTANT, "ERROR: setsockopt(IP_BIND_ADDRESS_NO_PORT) failure: " << xstrerr(savedErrno));
217-
}
213+
Comm::SetBooleanSocketOption(fd, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, true, SBuf("IP_BIND_ADDRESS_NO_PORT"));
218214
#else
219215
(void)fd;
220216
#endif
@@ -291,16 +287,13 @@ limitError(int const anErrno)
291287
}
292288

293289
static void
294-
comm_set_v6only(int fd, int tos)
290+
comm_set_v6only(int fd, bool enabled)
295291
{
296-
#ifdef IPV6_V6ONLY
297-
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &tos, sizeof(int)) < 0) {
298-
int xerrno = errno;
299-
debugs(50, DBG_IMPORTANT, MYNAME << "setsockopt(IPV6_V6ONLY) " << (tos?"ON":"OFF") << " for FD " << fd << ": " << xstrerr(xerrno));
300-
}
292+
#if defined(IPV6_V6ONLY)
293+
Comm::SetBooleanSocketOption(fd, IPPROTO_IPV6, IPV6_V6ONLY, enabled, SBuf("IPV6_V6ONLY"));
301294
#else
302-
debugs(50, DBG_CRITICAL, MYNAME << "WARNING: setsockopt(IPV6_V6ONLY) not supported on this platform");
303-
#endif /* sockopt */
295+
debugs(50, DBG_CRITICAL, "WARNING: setsockopt(IPV6_V6ONLY) not supported on this platform");
296+
#endif
304297
}
305298

306299
/**
@@ -315,17 +308,20 @@ comm_set_transparent(int fd)
315308
#if _SQUID_LINUX_ && defined(IP_TRANSPARENT) // Linux
316309
# define soLevel SOL_IP
317310
# define soFlag IP_TRANSPARENT
311+
const SBuf name("IP_TRANSPARENT");
318312
bool doneSuid = false;
319313

320314
#elif defined(SO_BINDANY) // OpenBSD 4.7+ and NetBSD with PF
321315
# define soLevel SOL_SOCKET
322316
# define soFlag SO_BINDANY
317+
const SBuf name("SO_BINDANY");
323318
enter_suid();
324319
bool doneSuid = true;
325320

326321
#elif defined(IP_BINDANY) // FreeBSD with IPFW
327322
# define soLevel IPPROTO_IP
328323
# define soFlag IP_BINDANY
324+
const SBuf name("IP_BINDANY");
329325
enter_suid();
330326
bool doneSuid = true;
331327

@@ -335,11 +331,7 @@ comm_set_transparent(int fd)
335331
#endif /* sockopt */
336332

337333
#if defined(soLevel) && defined(soFlag)
338-
int tos = 1;
339-
if (setsockopt(fd, soLevel, soFlag, (char *) &tos, sizeof(int)) < 0) {
340-
int xerrno = errno;
341-
debugs(50, DBG_IMPORTANT, MYNAME << "setsockopt(TPROXY) on FD " << fd << ": " << xstrerr(xerrno));
342-
} else {
334+
if (Comm::SetBooleanSocketOption(fd, soLevel, soFlag, true, name)) {
343335
/* mark the socket as having transparent options */
344336
fd_table[fd].flags.transparent = true;
345337
}
@@ -423,12 +415,12 @@ comm_openex(int sock_type,
423415
debugs(50, 3, "comm_openex: Opened socket " << conn << " : family=" << AI->ai_family << ", type=" << AI->ai_socktype << ", protocol=" << AI->ai_protocol );
424416

425417
if ( Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && addr.isIPv6() )
426-
comm_set_v6only(conn->fd, 1);
418+
comm_set_v6only(conn->fd, true);
427419

428420
/* Windows Vista supports Dual-Sockets. BUT defaults them to V6ONLY. Turn it OFF. */
429421
/* Other OS may have this administratively disabled for general use. Same deal. */
430422
if ( Ip::EnableIpv6&IPV6_SPECIAL_V4MAPPING && addr.isIPv6() )
431-
comm_set_v6only(conn->fd, 0);
423+
comm_set_v6only(conn->fd, false);
432424

433425
comm_init_opened(conn, note, AI);
434426
new_socket = comm_apply_flags(conn->fd, addr, flags, AI);
@@ -505,8 +497,7 @@ comm_apply_flags(int new_socket,
505497

506498
#if defined(SO_REUSEPORT)
507499
if (flags & COMM_REUSEPORT) {
508-
int on = 1;
509-
if (setsockopt(new_socket, SOL_SOCKET, SO_REUSEPORT, reinterpret_cast<char*>(&on), sizeof(on)) < 0) {
500+
if (!Comm::SetBooleanSocketOption(new_socket, SOL_SOCKET, SO_REUSEPORT, true, ToSBuf("SO_REUSEPORT on ", addr))) {
510501
const auto savedErrno = errno;
511502
const auto errorMessage = ToSBuf("cannot enable SO_REUSEPORT socket option when binding to ",
512503
addr, ": ", xstrerr(savedErrno));
@@ -770,10 +761,7 @@ commConfigureLinger(const int fd, const OnOff enabled)
770761

771762
fd_table[fd].flags.harshClosureRequested = (l.l_onoff && !l.l_linger); // close(2) sends TCP RST if true
772763

773-
if (setsockopt(fd, SOL_SOCKET, SO_LINGER, reinterpret_cast<char*>(&l), sizeof(l)) < 0) {
774-
const auto xerrno = errno;
775-
debugs(50, DBG_CRITICAL, "ERROR: Failed to set closure behavior (SO_LINGER) for FD " << fd << ": " << xstrerr(xerrno));
776-
}
764+
Comm::SetSocketOption(fd, SOL_SOCKET, SO_LINGER, l, ToSBuf("SO_LINGER (0 seconds) ", (l.l_onoff?"enabled":"disabled")));
777765
}
778766

779767
/**
@@ -1011,29 +999,16 @@ comm_remove_close_handler(int fd, AsyncCall::Pointer &call)
1011999
static void
10121000
commSetReuseAddr(int fd)
10131001
{
1014-
int on = 1;
1015-
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) < 0) {
1016-
int xerrno = errno;
1017-
debugs(50, DBG_IMPORTANT, MYNAME << "FD " << fd << ": " << xstrerr(xerrno));
1018-
}
1002+
Comm::SetBooleanSocketOption(fd, SOL_SOCKET, SO_REUSEADDR, true, SBuf("SO_REUSEADDR"));
10191003
}
10201004

10211005
static void
10221006
commSetTcpRcvbuf(int fd, int size)
10231007
{
1024-
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof(size)) < 0) {
1025-
int xerrno = errno;
1026-
debugs(50, DBG_IMPORTANT, MYNAME << "FD " << fd << ", SIZE " << size << ": " << xstrerr(xerrno));
1027-
}
1028-
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *) &size, sizeof(size)) < 0) {
1029-
int xerrno = errno;
1030-
debugs(50, DBG_IMPORTANT, MYNAME << "FD " << fd << ", SIZE " << size << ": " << xstrerr(xerrno));
1031-
}
1032-
#ifdef TCP_WINDOW_CLAMP
1033-
if (setsockopt(fd, SOL_TCP, TCP_WINDOW_CLAMP, (char *) &size, sizeof(size)) < 0) {
1034-
int xerrno = errno;
1035-
debugs(50, DBG_IMPORTANT, MYNAME << "FD " << fd << ", SIZE " << size << ": " << xstrerr(xerrno));
1036-
}
1008+
Comm::SetSocketOption(fd, SOL_SOCKET, SO_RCVBUF, size, ToSBuf("SO_RCVBUF to ", size, " bytes"));
1009+
Comm::SetSocketOption(fd, SOL_SOCKET, SO_SNDBUF, size, ToSBuf("SO_SNDBUF to ", size, " bytes"));
1010+
#if defined(TCP_WINDOW_CLAMP)
1011+
Comm::SetSocketOption(fd, SOL_TCP, TCP_WINDOW_CLAMP, size, ToSBuf("TCP_WINDOW_CLAMP to ", size, " bytes"));
10371012
#endif
10381013
}
10391014

@@ -1118,20 +1093,13 @@ commSetCloseOnExec(int fd)
11181093
#endif
11191094
}
11201095

1121-
#ifdef TCP_NODELAY
1096+
#if defined(TCP_NODELAY)
11221097
static void
11231098
commSetTcpNoDelay(int fd)
11241099
{
1125-
int on = 1;
1126-
1127-
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) < 0) {
1128-
int xerrno = errno;
1129-
debugs(50, DBG_IMPORTANT, MYNAME << "FD " << fd << ": " << xstrerr(xerrno));
1130-
}
1131-
1100+
Comm::SetBooleanSocketOption(fd, IPPROTO_TCP, TCP_NODELAY, true, SBuf("TCP_NODELAY"));
11321101
fd_table[fd].flags.nodelay = true;
11331102
}
1134-
11351103
#endif
11361104

11371105
void

src/comm/ConnOpener.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,12 +291,10 @@ Comm::ConnOpener::createFd()
291291
}
292292

293293
// Set TOS if needed.
294-
if (conn_->tos &&
295-
Ip::Qos::setSockTos(temporaryFd_, conn_->tos, conn_->remote.isIPv4() ? AF_INET : AF_INET6) < 0)
294+
if (conn_->tos && !Ip::Qos::setSockTos(temporaryFd_, conn_->tos, conn_->remote.isIPv4() ? AF_INET : AF_INET6))
296295
conn_->tos = 0;
297296
#if SO_MARK
298-
if (conn_->nfmark &&
299-
Ip::Qos::setSockNfmark(temporaryFd_, conn_->nfmark) < 0)
297+
if (conn_->nfmark && !Ip::Qos::setSockNfmark(temporaryFd_, conn_->nfmark))
300298
conn_->nfmark = 0;
301299
#endif
302300

src/comm/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,6 @@ libcomm_la_SOURCES = \
4343

4444
# a bare-bones implementation of few Comm APIs sufficient for helpers use
4545
libminimal_la_SOURCES = \
46+
Tcp.cc \
47+
Tcp.h \
4648
minimal.cc

src/comm/Tcp.cc

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "squid.h"
1212
#include "comm/Tcp.h"
1313
#include "debug/Stream.h"
14+
#include "sbuf/Stream.h"
1415

1516
#if HAVE_NETINET_TCP_H
1617
#include <netinet/tcp.h>
@@ -23,28 +24,11 @@
2324
#endif
2425
#include <type_traits>
2526

26-
/// setsockopt(2) wrapper
27-
template <typename Option>
28-
static bool
29-
SetSocketOption(const int fd, const int level, const int optName, const Option &optValue)
30-
{
31-
static_assert(std::is_trivially_copyable<Option>::value, "setsockopt() expects POD-like options");
32-
static_assert(!std::is_same<Option, bool>::value, "setsockopt() uses int to represent boolean options");
33-
if (setsockopt(fd, level, optName, reinterpret_cast<const char *>(&optValue), sizeof(optValue)) < 0) {
34-
const auto xerrno = errno;
35-
debugs(5, DBG_IMPORTANT, "ERROR: setsockopt(2) failure: " << xstrerr(xerrno));
36-
// TODO: Generalize to throw on errors when some callers need that.
37-
return false;
38-
}
39-
return true;
40-
}
41-
42-
/// setsockopt(2) wrapper for setting typical on/off options
43-
static bool
44-
SetBooleanSocketOption(const int fd, const int level, const int optName, const bool enable)
27+
bool
28+
Comm::SetBooleanSocketOption(const int fd, const int level, const int optName, const bool enable, const SBuf &description)
4529
{
4630
const int optValue = enable ? 1 :0;
47-
return SetSocketOption(fd, level, optName, optValue);
31+
return SetSocketOption(fd, level, optName, optValue, ToSBuf((enable ? "enable ":"disable "), description));
4832
}
4933

5034
void
@@ -56,20 +40,20 @@ Comm::ApplyTcpKeepAlive(int fd, const TcpKeepAlive &cfg)
5640
#if defined(TCP_KEEPCNT)
5741
if (cfg.timeout && cfg.interval) {
5842
const int count = (cfg.timeout + cfg.interval - 1) / cfg.interval; // XXX: unsigned-to-signed conversion
59-
(void)SetSocketOption(fd, IPPROTO_TCP, TCP_KEEPCNT, count);
43+
SetSocketOption(fd, IPPROTO_TCP, TCP_KEEPCNT, count, ToSBuf("TCP_KEEPCNT to ", count));
6044
}
6145
#endif
6246
#if defined(TCP_KEEPIDLE)
6347
if (cfg.idle) {
6448
// XXX: TCP_KEEPIDLE expects an int; cfg.idle is unsigned
65-
(void)SetSocketOption(fd, IPPROTO_TCP, TCP_KEEPIDLE, cfg.idle);
49+
SetSocketOption(fd, IPPROTO_TCP, TCP_KEEPIDLE, cfg.idle, ToSBuf("TCP_KEEPIDLE to ", cfg.idle));
6650
}
6751
#endif
6852
#if defined(TCP_KEEPINTVL)
6953
if (cfg.interval) {
7054
// XXX: TCP_KEEPINTVL expects an int; cfg.interval is unsigned
71-
(void)SetSocketOption(fd, IPPROTO_TCP, TCP_KEEPINTVL, cfg.interval);
55+
SetSocketOption(fd, IPPROTO_TCP, TCP_KEEPINTVL, cfg.interval, ToSBuf("TCP_KEEPINTVL to ", cfg.interval));
7256
}
7357
#endif
74-
(void)SetBooleanSocketOption(fd, SOL_SOCKET, SO_KEEPALIVE, true);
58+
SetBooleanSocketOption(fd, SOL_SOCKET, SO_KEEPALIVE, true, SBuf("SO_KEEPALIVE"));
7559
}

src/comm/Tcp.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
#ifndef SQUID_SRC_COMM_TCP_H
1010
#define SQUID_SRC_COMM_TCP_H
1111

12+
#include "debug/Stream.h"
13+
#include "sbuf/SBuf.h"
14+
1215
namespace Comm
1316
{
1417

@@ -25,6 +28,26 @@ class TcpKeepAlive
2528
/// apply configured TCP keep-alive settings to the given FD socket
2629
void ApplyTcpKeepAlive(int fd, const TcpKeepAlive &);
2730

31+
/// setsockopt(2) wrapper
32+
template <typename Option>
33+
bool
34+
SetSocketOption(const int fd, const int level, const int optName, const Option &optValue, const SBuf &description)
35+
{
36+
static_assert(std::is_trivially_copyable<Option>::value, "setsockopt() expects POD-like options");
37+
static_assert(!std::is_same<Option, bool>::value, "setsockopt() uses int to represent boolean options");
38+
if (setsockopt(fd, level, optName, reinterpret_cast<const char *>(&optValue), sizeof(optValue)) < 0) {
39+
const auto xerrno = errno;
40+
debugs(5, DBG_IMPORTANT, "ERROR: setsockopt(2) failure on FD " << fd << " : " << xstrerr(xerrno)
41+
<< Debug::Extra << "setting " << description);
42+
// TODO: Generalize to throw on errors when some callers need that.
43+
return false;
44+
}
45+
return true;
46+
}
47+
48+
/// setsockopt(2) wrapper for setting typical on/off options
49+
bool SetBooleanSocketOption(const int fd, const int level, const int optName, const bool enable, const SBuf &description);
50+
2851
} // namespace Comm
2952

3053
#endif /* SQUID_SRC_COMM_TCP_H */

0 commit comments

Comments
 (0)