]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/icmp/pinger.cc
2 * DEBUG: section 42 ICMP Pinger program
3 * AUTHOR: Duane Wessels
5 * SQUID Web Proxy Cache http://www.squid-cache.org/
6 * ----------------------------------------------------------
8 * Squid is the result of efforts by numerous individuals from
9 * the Internet community; see the CONTRIBUTORS file for full
10 * details. Many organizations have provided support for Squid's
11 * development; see the SPONSORS file for full details. Squid is
12 * Copyrighted (C) 2001 by the Regents of the University of
13 * California; see the COPYRIGHT file for full details. Squid
14 * incorporates software developed and/or copyrighted by other
15 * sources; see the CREDITS file for full details.
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
33 #define SQUID_HELPER 1
36 \defgroup pinger pinger
37 \ingroup ExternalPrograms
39 * Although it would be possible for Squid to send and receive
40 * ICMP messages directly, we use an external process for
41 * two important reasons:
43 \li Because squid handles many filedescriptors simultaneously,
44 * we get much more accurate RTT measurements when ICMP is
45 * handled by a separate process.
47 \li Superuser privileges are required to send and receive ICMP.
48 * Rather than require Squid to be started as root, we prefer
49 * to have the smaller and simpler pinger program installed
50 * with setuid permissions.
53 * If you want to use Squid's ICMP features (highly recommended!)
54 * When USE_ICMP is defined, Squid will send ICMP pings
55 * to origin server sites.
56 * This information is used in numerous ways:
57 \li - Sent in ICP replies so neighbor caches know how close
58 * you are to the source.
59 \li - For finding the closest instance of a URN.
60 \li - With the 'test_reachability' option. Squid will return
61 * ICP_OP_MISS_NOFETCH for sites which it cannot ping.
66 #include "SquidTime.h"
72 #include "IcmpPinger.h"
85 #define PINGER_TIMEOUT 5
87 /* windows uses the control socket for feedback to squid */
88 #define LINK_TO_SQUID squid_link
90 // windows still requires WSAFD but there are too many dependancy problems
91 // to just link to win32.cc where it is normally defined.
94 Win32__WSAFDIsSet(int fd
, fd_set FAR
* set
)
96 fde
*F
= &fd_table
[fd
];
97 SOCKET s
= F
->win32
.handle
;
99 return __WSAFDIsSet(s
, set
);
104 #define PINGER_TIMEOUT 10
106 /* non-windows use STDOUT for feedback to squid */
107 #define LINK_TO_SQUID 1
109 #endif /* _SQUID_WINDOWS_ */
111 // 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;
142 int icmp6_worker
= -1;
145 /** start by initializing the pinger debug cache.log-pinger. */
146 if ((t
= getenv("SQUID_DEBUG")))
147 debug_args
= xstrdup(t
);
151 // determine IPv4 or IPv6 capabilities before using sockets.
152 Ip::ProbeTransport();
154 _db_init(NULL
, debug_args
);
156 debugs(42, DBG_CRITICAL
, "pinger: Initialising ICMP pinger ...");
158 icmp4_worker
= icmp4
.Open();
159 if (icmp4_worker
< 0) {
160 debugs(42, DBG_CRITICAL
, "pinger: Unable to start ICMP pinger.");
162 max_fd
= max(max_fd
, icmp4_worker
);
165 icmp6_worker
= icmp6
.Open();
166 if (icmp6_worker
<0 ) {
167 debugs(42, DBG_CRITICAL
, "pinger: Unable to start ICMPv6 pinger.");
169 max_fd
= max(max_fd
, icmp6_worker
);
172 /** abort if neither worker could open a socket. */
173 if (icmp4_worker
< 0 && icmp6_worker
< 0) {
174 debugs(42, DBG_CRITICAL
, "FATAL: pinger: Unable to open any ICMP sockets.");
178 if ( (squid_link
= control
.Open()) < 0) {
179 debugs(42, DBG_CRITICAL
, "FATAL: pinger: Unable to setup Pinger control sockets.");
182 exit(1); // fatal error if the control channel fails.
184 max_fd
= max(max_fd
, squid_link
);
186 if (setgid(getgid()) < 0) {
187 debugs(42, DBG_CRITICAL
, "FATAL: pinger: setgid(" << getgid() << ") failed: " << xstrerror());
192 if (setuid(getuid()) < 0) {
193 debugs(42, DBG_CRITICAL
, "FATAL: pinger: setuid(" << getuid() << ") failed: " << xstrerror());
199 last_check_time
= squid_curtime
;
202 tv
.tv_sec
= PINGER_TIMEOUT
;
205 if (icmp4_worker
>= 0) {
206 FD_SET(icmp4_worker
, &R
);
208 if (icmp6_worker
>= 0) {
209 FD_SET(icmp6_worker
, &R
);
212 FD_SET(squid_link
, &R
);
213 x
= select(10, &R
, NULL
, NULL
, &tv
);
217 debugs(42, DBG_CRITICAL
, HERE
<< " FATAL Shutdown. select()==" << x
<< ", ERR: " << xstrerror());
222 if (FD_ISSET(squid_link
, &R
)) {
226 if (icmp6_worker
>= 0 && FD_ISSET(icmp6_worker
, &R
)) {
229 if (icmp4_worker
>= 0 && FD_ISSET(icmp4_worker
, &R
)) {
233 if (PINGER_TIMEOUT
+ last_check_time
< squid_curtime
) {
234 if (send(LINK_TO_SQUID
, &tv
, 0, 0) < 0) {
235 debugs(42, DBG_CRITICAL
, "pinger: Closing. No requests in last " << PINGER_TIMEOUT
<< " seconds.");
240 last_check_time
= squid_curtime
;
251 main(int argc
, char *argv
[])
253 fprintf(stderr
, "%s: ICMP support not compiled in.\n", argv
[0]);
257 #endif /* USE_ICMP */