4
* DEBUG: section 42 ICMP Pinger program
5
* AUTHOR: Duane Wessels
7
* SQUID Web Proxy Cache http://www.squid-cache.org/
8
* ----------------------------------------------------------
10
* Squid is the result of efforts by numerous individuals from
11
* the Internet community; see the CONTRIBUTORS file for full
12
* details. Many organizations have provided support for Squid's
13
* development; see the SPONSORS file for full details. Squid is
14
* Copyrighted (C) 2001 by the Regents of the University of
15
* California; see the COPYRIGHT file for full details. Squid
16
* incorporates software developed and/or copyrighted by other
17
* sources; see the CREDITS file for full details.
19
* This program is free software; you can redistribute it and/or modify
20
* it under the terms of the GNU General Public License as published by
21
* the Free Software Foundation; either version 2 of the License, or
22
* (at your option) any later version.
24
* This program is distributed in the hope that it will be useful,
25
* but WITHOUT ANY WARRANTY; without even the implied warranty of
26
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
* GNU General Public License for more details.
29
* You should have received a copy of the GNU General Public License
30
* along with this program; if not, write to the Free Software
31
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
35
#define SQUID_HELPER 1
38
\defgroup pinger pinger
39
\ingroup ExternalPrograms
41
* Although it would be possible for Squid to send and receive
42
* ICMP messages directly, we use an external process for
43
* two important reasons:
45
\li Because squid handles many filedescriptors simultaneously,
46
* we get much more accurate RTT measurements when ICMP is
47
* handled by a separate process.
49
\li Superuser privileges are required to send and receive ICMP.
50
* Rather than require Squid to be started as root, we prefer
51
* to have the smaller and simpler pinger program installed
52
* with setuid permissions.
55
* If you want to use Squid's ICMP features (highly recommended!)
56
* When USE_ICMP is defined, Squid will send ICMP pings
57
* to origin server sites.
58
* This information is used in numerous ways:
59
\li - Sent in ICP replies so neighbor caches know how close
60
* you are to the source.
61
\li - For finding the closest instance of a URN.
62
\li - With the 'test_reachability' option. Squid will return
63
* ICP_OP_MISS_NOFETCH for sites which it cannot ping.
67
#include "SquidTime.h"
73
#include "IcmpPinger.h"
83
#define PINGER_TIMEOUT 5
85
/* windows uses the control socket for feedback to squid */
86
#define LINK_TO_SQUID squid_link
88
// windows still requires WSAFD but there are too many dependancy problems
89
// to just link to win32.cc where it is normally defined.
92
Win32__WSAFDIsSet(int fd, fd_set FAR * set)
94
fde *F = &fd_table[fd];
95
SOCKET s = F->win32.handle;
97
return __WSAFDIsSet(s, set);
102
#define PINGER_TIMEOUT 10
104
/* non-windows use STDOUT for feedback to squid */
105
#define LINK_TO_SQUID 1
107
#endif /* _SQUID_MSWIN_ */
109
// ICMP Engines are declared global here so they can call each other easily.
116
int icmp_pkts_sent = 0;
120
\par This is the pinger external process.
126
main(int argc, char *argv[])
133
const char *debug_args = "ALL,10";
135
time_t last_check_time = 0;
138
* cevans - do this first. It grabs a raw socket. After this we can
141
int icmp4_worker = -1;
143
int icmp6_worker = -1;
147
/** start by initializing the pinger debug cache.log-pinger. */
148
if ((t = getenv("SQUID_DEBUG")))
149
debug_args = xstrdup(t);
153
_db_init(NULL, debug_args);
155
debugs(42, 0, "pinger: Initialising ICMP pinger ...");
157
icmp4_worker = icmp4.Open();
158
if (icmp4_worker < 0) {
159
debugs(42, 0, "pinger: Unable to start ICMP pinger.");
161
max_fd = max(max_fd, icmp4_worker);
164
icmp6_worker = icmp6.Open();
165
if (icmp6_worker <0 ) {
166
debugs(42, 0, "pinger: Unable to start ICMPv6 pinger.");
168
max_fd = max(max_fd, icmp6_worker);
171
/** abort if neither worker could open a socket. */
172
if (icmp4_worker == -1) {
174
if (icmp6_worker == -1)
177
debugs(42, 0, "FATAL: pinger: Unable to open any ICMP sockets.");
182
if ( (squid_link = control.Open()) < 0) {
183
debugs(42, 0, "FATAL: pinger: Unable to setup Pinger control sockets.");
188
exit(1); // fatal error if the control channel fails.
190
max_fd = max(max_fd, squid_link);
195
last_check_time = squid_curtime;
198
tv.tv_sec = PINGER_TIMEOUT;
201
if (icmp4_worker >= 0) {
202
FD_SET(icmp4_worker, &R);
206
if (icmp6_worker >= 0) {
207
FD_SET(icmp6_worker, &R);
210
FD_SET(squid_link, &R);
211
x = select(10, &R, NULL, NULL, &tv);
215
debugs(42, 0, HERE << " FATAL Shutdown. select()==" << x << ", ERR: " << xstrerror());
220
if (FD_ISSET(squid_link, &R)) {
225
if (icmp6_worker >= 0 && FD_ISSET(icmp6_worker, &R)) {
230
if (icmp4_worker >= 0 && FD_ISSET(icmp4_worker, &R)) {
234
if (PINGER_TIMEOUT + last_check_time < squid_curtime) {
235
if (send(LINK_TO_SQUID, &tv, 0, 0) < 0) {
236
debugs(42, 0, "pinger: Closing. No requests in last " << PINGER_TIMEOUT << " seconds.");
241
last_check_time = squid_curtime;
252
main(int argc, char *argv[])
254
fprintf(stderr, "%s: ICMP support not compiled in.\n", argv[0]);
258
#endif /* USE_ICMP */