]> git.ipfire.org Git - thirdparty/squid.git/blame - src/pinger.cc
Initial shift
[thirdparty/squid.git] / src / pinger.cc
CommitLineData
9d90e665 1/*
63be0a78 2 * $Id: pinger.cc,v 1.62 2008/02/26 21:49:35 amosjeffries Exp $
9d90e665 3 *
f43e2ec2 4 * DEBUG: section 42 ICMP Pinger program
9d90e665 5 * AUTHOR: Duane Wessels
6 *
2b6662ba 7 * SQUID Web Proxy Cache http://www.squid-cache.org/
e25c139f 8 * ----------------------------------------------------------
9d90e665 9 *
2b6662ba 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.
9d90e665 18 *
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.
23 *
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.
28 *
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
cbdec147 31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
e25c139f 32 *
9d90e665 33 */
34
128fe1c6 35#define SQUID_HELPER 1
36
63be0a78 37/**
38 \defgroup pinger pinger
39 \ingroup ExternalPrograms
40 \par
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:
44 *
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.
48 *
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.
53 *
54 \par
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.
64 */
65
9d90e665 66#include "squid.h"
985c86bc 67#include "SquidTime.h"
9d90e665 68
43426991 69#if USE_ICMP
70
cc192b50 71#include "ICMPv4.h"
72#include "ICMPv6.h"
73#include "ICMPPinger.h"
0ab98d6b 74
bdb741f4 75#ifdef _SQUID_MSWIN_
76
bfe8dedf 77#if HAVE_WINSOCK2_H
bdb741f4 78#include <winsock2.h>
bfe8dedf 79#endif
bdb741f4 80#include <process.h>
cc192b50 81#include "fde.h"
bdb741f4 82
83#define PINGER_TIMEOUT 5
84
cc192b50 85/* windows uses the control socket for feedback to squid */
86#define LINK_TO_SQUID squid_link
bdb741f4 87
cc192b50 88// windows still requires WSAFD but there are too many dependancy problems
89// to just link to win32.cc where it is normally defined.
bdb741f4 90
cc192b50 91int
92Win32__WSAFDIsSet(int fd, fd_set FAR * set)
bdb741f4 93{
cc192b50 94 fde *F = &fd_table[fd];
95 SOCKET s = F->win32.handle;
bdb741f4 96
cc192b50 97 return __WSAFDIsSet(s, set);
bdb741f4 98}
99
cc192b50 100#else
bdb741f4 101
cc192b50 102#define PINGER_TIMEOUT 10
bdb741f4 103
cc192b50 104/* non-windows use STDOUT for feedback to squid */
105#define LINK_TO_SQUID 1
bdb741f4 106
107#endif /* _SQUID_MSWIN_ */
108
cc192b50 109// ICMP Engines are declared global here so they can call each other easily.
110ICMPPinger control;
111ICMPv4 icmp4;
112#if USE_IPV6
113ICMPv6 icmp6;
6637e3a5 114#endif
62e76326 115
5be53f2d 116int icmp_pkts_sent = 0;
9d90e665 117
63be0a78 118/**
119 \ingroup pinger
120 \par This is the pinger external process.
121 *
122 \param argc Ignored.
123 \param argv Ignored.
124 */
cc192b50 125int
126main(int argc, char *argv[])
9d90e665 127{
cc192b50 128 fd_set R;
bdb741f4 129 int x;
cc192b50 130 int max_fd = 0;
bdb741f4 131
cc192b50 132 struct timeval tv;
133 const char *debug_args = "ALL,10";
134 char *t;
135 time_t last_check_time = 0;
bdb741f4 136
cc192b50 137 /*
138 * cevans - do this first. It grabs a raw socket. After this we can
139 * drop privs
140 */
141 int icmp4_worker = -1;
142#if USE_IPV6
143 int icmp6_worker = -1;
bdb741f4 144#endif
cc192b50 145 int squid_link = -1;
62e76326 146
63be0a78 147 /** start by initializing the pinger debug cache.log-pinger. */
cc192b50 148 if ((t = getenv("SQUID_DEBUG")))
149 debug_args = xstrdup(t);
bdb741f4 150
151 getCurrentTime();
62e76326 152
cc192b50 153 _db_init(NULL, debug_args);
b6a2f15e 154
cc192b50 155 debugs(42, 0, "pinger: Initialising ICMP pinger ...");
62e76326 156
cc192b50 157 icmp4_worker = icmp4.Open();
158 if(icmp4_worker < 0) {
159 debugs(42, 0, "pinger: Unable to start ICMP pinger.");
b6a2f15e 160 }
cc192b50 161 max_fd = max(max_fd, icmp4_worker);
62e76326 162
cc192b50 163#if USE_IPV6
164 icmp6_worker = icmp6.Open();
165 if(icmp6_worker <0 ) {
166 debugs(42, 0, "pinger: Unable to start ICMPv6 pinger.");
9d90e665 167 }
cc192b50 168 max_fd = max(max_fd, icmp6_worker);
d20b1cd0 169#endif
62e76326 170
63be0a78 171 /** abort if neither worker could open a socket. */
cc192b50 172 if(icmp4_worker == -1) {
173#if USE_IPV6
174 if(icmp6_worker == -1)
9d90e665 175#endif
f5b2e1ba 176 {
cc192b50 177 debugs(42, 0, "FATAL: pinger: Unable to open any ICMP sockets.");
178 exit(1);
f5b2e1ba 179 }
b6a2f15e 180 }
62e76326 181
cc192b50 182 if( (squid_link = control.Open()) < 0) {
183 debugs(42, 0, "FATAL: pinger: Unable to setup Pinger control sockets.");
184 icmp4.Close();
185#if USE_IPV6
186 icmp6.Close();
187#endif
188 exit(1); // fatal error if the control channel fails.
365a4bce 189 }
cc192b50 190 max_fd = max(max_fd, squid_link);
62e76326 191
b6a2f15e 192 setgid(getgid());
193 setuid(getuid());
194
9d90e665 195 for (;;) {
bdb741f4 196 tv.tv_sec = PINGER_TIMEOUT;
62e76326 197 tv.tv_usec = 0;
198 FD_ZERO(&R);
cc192b50 199 if(icmp4_worker >= 0) {
200 FD_SET(icmp4_worker, &R);
201 }
202#if USE_IPV6
203
204 if(icmp6_worker >= 0) {
205 FD_SET(icmp6_worker, &R);
206 }
207#endif
208 FD_SET(squid_link, &R);
209 x = select(10, &R, NULL, NULL, &tv);
62e76326 210 getCurrentTime();
211
bdb741f4 212 if (x < 0) {
cc192b50 213 debugs(42, 0, HERE << " FATAL Shutdown. select()==" << x << ", ERR: " << xstrerror());
214 control.Close();
62e76326 215 exit(1);
bdb741f4 216 }
62e76326 217
cc192b50 218 if (FD_ISSET(squid_link, &R)) {
219 control.Recv();
220 }
62e76326 221
cc192b50 222#if USE_IPV6
223 if (icmp6_worker >= 0 && FD_ISSET(icmp6_worker, &R)) {
224 icmp6.Recv();
225 }
226#endif
227
228 if (icmp4_worker >= 0 && FD_ISSET(icmp4_worker, &R)) {
229 icmp4.Recv();
230 }
62e76326 231
bdb741f4 232 if (PINGER_TIMEOUT + last_check_time < squid_curtime) {
cc192b50 233 if (send(LINK_TO_SQUID, &tv, 0, 0) < 0) {
234 debugs(42, 0, "pinger: Closing. No requests in last " << PINGER_TIMEOUT << " seconds.");
235 control.Close();
62e76326 236 exit(1);
bdb741f4 237 }
62e76326 238
239 last_check_time = squid_curtime;
240 }
9d90e665 241 }
62e76326 242
145766ef 243 /* NOTREACHED */
bdb741f4 244 return 0;
9d90e665 245}
365a4bce 246
9d90e665 247#else
248#include <stdio.h>
249int
250main(int argc, char *argv[])
251{
252 fprintf(stderr, "%s: ICMP support not compiled in.\n", argv[0]);
253 return 1;
254}
62e76326 255
9d90e665 256#endif /* USE_ICMP */