~clint-fewbar/ubuntu/precise/squid3/ignore-sighup-early

« back to all changes in this revision

Viewing changes to src/pinger.cc

  • Committer: Bazaar Package Importer
  • Author(s): Luigi Gangitano
  • Date: 2010-05-04 11:15:49 UTC
  • mfrom: (1.3.1 upstream)
  • mto: (20.3.1 squeeze) (21.2.1 sid)
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: james.westby@ubuntu.com-20100504111549-1apjh2g5sndki4te
Tags: upstream-3.1.3
ImportĀ upstreamĀ versionĀ 3.1.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
/*
3
 
 * $Id: pinger.cc,v 1.59 2007/04/30 16:56:09 wessels Exp $
4
 
 *
5
 
 * DEBUG: section 42    ICMP Pinger program
6
 
 * AUTHOR: Duane Wessels
7
 
 *
8
 
 * SQUID Web Proxy Cache          http://www.squid-cache.org/
9
 
 * ----------------------------------------------------------
10
 
 *
11
 
 *  Squid is the result of efforts by numerous individuals from
12
 
 *  the Internet community; see the CONTRIBUTORS file for full
13
 
 *  details.   Many organizations have provided support for Squid's
14
 
 *  development; see the SPONSORS file for full details.  Squid is
15
 
 *  Copyrighted (C) 2001 by the Regents of the University of
16
 
 *  California; see the COPYRIGHT file for full details.  Squid
17
 
 *  incorporates software developed and/or copyrighted by other
18
 
 *  sources; see the CREDITS file for full details.
19
 
 *
20
 
 *  This program is free software; you can redistribute it and/or modify
21
 
 *  it under the terms of the GNU General Public License as published by
22
 
 *  the Free Software Foundation; either version 2 of the License, or
23
 
 *  (at your option) any later version.
24
 
 *  
25
 
 *  This program is distributed in the hope that it will be useful,
26
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
27
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28
 
 *  GNU General Public License for more details.
29
 
 *  
30
 
 *  You should have received a copy of the GNU General Public License
31
 
 *  along with this program; if not, write to the Free Software
32
 
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
33
 
 *
34
 
 */
35
 
 
36
 
#define SQUID_HELPER 1
37
 
 
38
 
#include "squid.h"
39
 
#include "SquidTime.h"
40
 
 
41
 
#if USE_ICMP
42
 
 
43
 
/* Native Windows port doesn't have netinet support, so we emulate it.
44
 
   At this time, Cygwin lacks icmp support in its include files, so we need
45
 
   to use the native Windows port definitions.
46
 
 */
47
 
 
48
 
#ifndef _SQUID_WIN32_
49
 
 
50
 
#include <netinet/in_systm.h>
51
 
#include <netinet/in.h>
52
 
#include <netinet/ip.h>
53
 
#include <netinet/ip_icmp.h>
54
 
 
55
 
#define PINGER_TIMEOUT 10
56
 
 
57
 
static int socket_from_squid = 0;
58
 
static int socket_to_squid = 1;
59
 
 
60
 
#else /* _SQUID_WIN32_ */
61
 
 
62
 
#include "fde.h"
63
 
 
64
 
#ifdef _SQUID_MSWIN_
65
 
 
66
 
#if HAVE_WINSOCK2_H
67
 
#include <winsock2.h>
68
 
#endif
69
 
#include <process.h>
70
 
 
71
 
#define PINGER_TIMEOUT 5
72
 
 
73
 
static int socket_to_squid = -1;
74
 
#define socket_from_squid socket_to_squid
75
 
 
76
 
#else /* _SQUID_CYGWIN_ */ 
77
 
#include <netinet/in_systm.h>
78
 
#include <netinet/in.h>
79
 
#include <netinet/ip.h>
80
 
#include <netinet/ip_icmp.h>
81
 
 
82
 
#define PINGER_TIMEOUT 10
83
 
 
84
 
static int socket_from_squid = 0;
85
 
static int socket_to_squid = 1;
86
 
 
87
 
#endif
88
 
 
89
 
#define ICMP_ECHO 8
90
 
#define ICMP_ECHOREPLY 0
91
 
 
92
 
typedef struct iphdr
93
 
{
94
 
 
95
 
u_int8_t  ip_vhl:
96
 
    4;          /* Length of the header in dwords */
97
 
 
98
 
u_int8_t  version:
99
 
    4;  /* Version of IP                  */
100
 
    u_int8_t  tos;              /* Type of service                */
101
 
    u_int16_t total_len;        /* Length of the packet in dwords */
102
 
    u_int16_t ident;            /* unique identifier              */
103
 
    u_int16_t flags;            /* Flags                          */
104
 
    u_int8_t  ip_ttl;           /* Time to live                   */
105
 
    u_int8_t  proto;            /* Protocol number (TCP, UDP etc) */
106
 
    u_int16_t checksum;         /* IP checksum                    */
107
 
    u_int32_t source_ip;
108
 
    u_int32_t dest_ip;
109
 
}
110
 
 
111
 
iphdr;
112
 
 
113
 
/* ICMP header */
114
 
 
115
 
typedef struct icmphdr
116
 
{
117
 
    u_int8_t  icmp_type;        /* ICMP packet type                 */
118
 
    u_int8_t  icmp_code;        /* Type sub code                    */
119
 
    u_int16_t icmp_cksum;
120
 
    u_int16_t icmp_id;
121
 
    u_int16_t icmp_seq;
122
 
    u_int32_t timestamp;        /* not part of ICMP, but we need it */
123
 
}
124
 
 
125
 
icmphdr;
126
 
 
127
 
#endif  /* _SQUID_MSWIN_ */
128
 
 
129
 
#ifndef _SQUID_LINUX_
130
 
#ifndef _SQUID_CYGWIN_
131
 
#ifndef _SQUID_MSWIN_
132
 
#define icmphdr icmp
133
 
#define iphdr ip
134
 
#endif
135
 
#endif
136
 
#endif
137
 
 
138
 
#if defined (_SQUID_LINUX_)
139
 
#ifdef icmp_id
140
 
#undef icmp_id
141
 
#endif
142
 
#ifdef icmp_seq
143
 
#undef icmp_seq
144
 
#endif
145
 
#define icmp_type type
146
 
#define icmp_code code
147
 
#define icmp_cksum checksum
148
 
#define icmp_id un.echo.id
149
 
#define icmp_seq un.echo.sequence
150
 
#define ip_hl ihl
151
 
#define ip_v version
152
 
#define ip_tos tos
153
 
#define ip_len tot_len
154
 
#define ip_id id
155
 
#define ip_off frag_off
156
 
#define ip_ttl ttl
157
 
#define ip_p protocol
158
 
#define ip_sum check
159
 
#define ip_src saddr
160
 
#define ip_dst daddr
161
 
#endif
162
 
 
163
 
#if ALLOW_SOURCE_PING
164
 
#define MAX_PKT_SZ 8192
165
 
#define MAX_PAYLOAD (MAX_PKT_SZ - sizeof(struct icmphdr) - sizeof (char) - sizeof(struct timeval) - 1)
166
 
#else
167
 
#define MAX_PAYLOAD SQUIDHOSTNAMELEN
168
 
#define MAX_PKT_SZ (MAX_PAYLOAD + sizeof(struct timeval) + sizeof (char) + sizeof(struct icmphdr) + 1)
169
 
#endif
170
 
 
171
 
typedef struct
172
 
{
173
 
 
174
 
    struct timeval tv;
175
 
    unsigned char opcode;
176
 
    char payload[MAX_PAYLOAD];
177
 
}
178
 
 
179
 
icmpEchoData;
180
 
 
181
 
int icmp_ident = -1;
182
 
int icmp_pkts_sent = 0;
183
 
 
184
 
static const char *icmpPktStr[] =
185
 
    {
186
 
        "Echo Reply",
187
 
        "ICMP 1",
188
 
        "ICMP 2",
189
 
        "Destination Unreachable",
190
 
        "Source Quench",
191
 
        "Redirect",
192
 
        "ICMP 6",
193
 
        "ICMP 7",
194
 
        "Echo",
195
 
        "ICMP 9",
196
 
        "ICMP 10",
197
 
        "Time Exceeded",
198
 
        "Parameter Problem",
199
 
        "Timestamp",
200
 
        "Timestamp Reply",
201
 
        "Info Request",
202
 
        "Info Reply",
203
 
        "Out of Range Type"
204
 
    };
205
 
 
206
 
static int in_cksum(unsigned short *ptr, int size);
207
 
static void pingerRecv(void);
208
 
 
209
 
static void pingerLog(struct icmphdr *, struct IN_ADDR, int, int);
210
 
static int ipHops(int ttl);
211
 
static void pingerSendtoSquid(pingerReplyData * preply);
212
 
static void pingerOpen(void);
213
 
static void pingerClose(void);
214
 
 
215
 
#ifdef _SQUID_MSWIN_
216
 
 
217
 
int Win32__WSAFDIsSet(int fd, fd_set FAR * set
218
 
                         )
219
 
{
220
 
    fde *F = &fd_table[fd];
221
 
    SOCKET s = F->win32.handle;
222
 
 
223
 
    return __WSAFDIsSet(s, set
224
 
                           );
225
 
}
226
 
 
227
 
void
228
 
Win32SockCleanup(void)
229
 
{
230
 
    WSACleanup();
231
 
    return;
232
 
}
233
 
#endif
234
 
 
235
 
void
236
 
pingerOpen(void)
237
 
{
238
 
 
239
 
    struct protoent *proto = NULL;
240
 
#ifdef _SQUID_MSWIN_
241
 
 
242
 
    WSADATA wsaData;
243
 
    WSAPROTOCOL_INFO wpi;
244
 
    char buf[sizeof(wpi)];
245
 
    int x;
246
 
 
247
 
    struct sockaddr_in PS;
248
 
 
249
 
    WSAStartup(2, &wsaData);
250
 
    atexit(Win32SockCleanup);
251
 
 
252
 
    getCurrentTime();
253
 
    _db_init(NULL, "ALL,1");
254
 
    setmode(0, O_BINARY);
255
 
    setmode(1, O_BINARY);
256
 
    x = read(0, buf, sizeof(wpi));
257
 
 
258
 
    if (x < (int)sizeof(wpi)) {
259
 
        getCurrentTime();
260
 
        debugs(42, 0, "pingerOpen: read: FD 0: " << xstrerror());
261
 
        write(1, "ERR\n", 4);
262
 
        exit(1);
263
 
    }
264
 
 
265
 
    xmemcpy(&wpi, buf, sizeof(wpi));
266
 
 
267
 
    write(1, "OK\n", 3);
268
 
    x = read(0, buf, sizeof(PS));
269
 
 
270
 
    if (x < (int)sizeof(PS)) {
271
 
        getCurrentTime();
272
 
        debugs(42, 0, "pingerOpen: read: FD 0: " << xstrerror());
273
 
        write(1, "ERR\n", 4);
274
 
        exit(1);
275
 
    }
276
 
 
277
 
    xmemcpy(&PS, buf, sizeof(PS));
278
 
#endif
279
 
 
280
 
    if ((proto = getprotobyname("icmp")) == 0) {
281
 
        debugs(42, 0, "pingerOpen: unknown protocol: icmp");
282
 
        exit(1);
283
 
    }
284
 
 
285
 
    icmp_sock = socket(PF_INET, SOCK_RAW, proto->p_proto);
286
 
 
287
 
    if (icmp_sock < 0) {
288
 
        debugs(50, 0, "pingerOpen: icmp_sock: " << xstrerror());
289
 
        exit(1);
290
 
    }
291
 
 
292
 
    icmp_ident = getpid() & 0xffff;
293
 
    debugs(42, 0, "pinger: ICMP socket opened");
294
 
#ifdef _SQUID_MSWIN_
295
 
 
296
 
    socket_to_squid =
297
 
        WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
298
 
                  &wpi, 0, 0);
299
 
 
300
 
    if (socket_to_squid == -1) {
301
 
        getCurrentTime();
302
 
        debugs(42, 0, "pingerOpen: WSASocket: " << xstrerror());
303
 
        write(1, "ERR\n", 4);
304
 
        exit(1);
305
 
    }
306
 
 
307
 
    x = connect(socket_to_squid, (struct sockaddr *) &PS, sizeof(PS));
308
 
 
309
 
    if (SOCKET_ERROR == x) {
310
 
        getCurrentTime();
311
 
        debugs(42, 0, "pingerOpen: connect: " << xstrerror());
312
 
        write(1, "ERR\n", 4);
313
 
        exit(1);
314
 
    }
315
 
 
316
 
    write(1, "OK\n", 3);
317
 
    memset(buf, 0, sizeof(buf));
318
 
    x = recv(socket_to_squid, (void *) buf, sizeof(buf), 0);
319
 
 
320
 
    if (x < 3) {
321
 
        debugs(42, 0, "icmpOpen: recv: " << xstrerror());
322
 
        exit(1);
323
 
    }
324
 
 
325
 
    x = send(socket_to_squid, (const void *) buf, strlen(buf), 0);
326
 
 
327
 
    if (x < 3 || strncmp("OK\n", buf, 3)) {
328
 
        debugs(42, 0, "icmpOpen: recv: " << xstrerror());
329
 
        exit(1);
330
 
    }
331
 
 
332
 
    getCurrentTime();
333
 
    debugs(42, 0, "pinger: Squid socket opened");
334
 
#endif
335
 
}
336
 
 
337
 
void
338
 
pingerClose(void)
339
 
{
340
 
    close(icmp_sock);
341
 
#ifdef _SQUID_MSWIN_
342
 
 
343
 
    shutdown(socket_to_squid, SD_BOTH);
344
 
    close(socket_to_squid);
345
 
    socket_to_squid = -1;
346
 
#endif
347
 
 
348
 
    icmp_sock = -1;
349
 
    icmp_ident = 0;
350
 
}
351
 
 
352
 
static void
353
 
 
354
 
pingerSendEcho(struct IN_ADDR to, int opcode, char *payload, int len)
355
 
{
356
 
    LOCAL_ARRAY(char, pkt, MAX_PKT_SZ);
357
 
 
358
 
    struct icmphdr *icmp = NULL;
359
 
    icmpEchoData *echo;
360
 
 
361
 
    size_t icmp_pktsize = sizeof(struct icmphdr);
362
 
 
363
 
    struct sockaddr_in S;
364
 
    memset(pkt, '\0', MAX_PKT_SZ);
365
 
 
366
 
    icmp = (struct icmphdr *) (void *) pkt;
367
 
 
368
 
    /*
369
 
     * cevans - beware signed/unsigned issues in untrusted data from
370
 
     * the network!!
371
 
     */
372
 
 
373
 
    if (len < 0)
374
 
    {
375
 
        len = 0;
376
 
    }
377
 
 
378
 
    icmp->icmp_type = ICMP_ECHO;
379
 
    icmp->icmp_code = 0;
380
 
    icmp->icmp_cksum = 0;
381
 
    icmp->icmp_id = icmp_ident;
382
 
    icmp->icmp_seq = (u_short) icmp_pkts_sent++;
383
 
    echo = (icmpEchoData *) (icmp + 1);
384
 
    echo->opcode = (unsigned char) opcode;
385
 
    echo->tv = current_time;
386
 
 
387
 
    icmp_pktsize += sizeof(struct timeval) + sizeof(char);
388
 
 
389
 
    if (payload)
390
 
    {
391
 
        if (len > MAX_PAYLOAD)
392
 
            len = MAX_PAYLOAD;
393
 
 
394
 
        xmemcpy(echo->payload, payload, len);
395
 
 
396
 
        icmp_pktsize += len;
397
 
    }
398
 
 
399
 
    icmp->icmp_cksum = in_cksum((u_short *) icmp, icmp_pktsize);
400
 
    S.sin_family = AF_INET;
401
 
    /*
402
 
     * cevans: alert: trusting to-host, was supplied in network packet
403
 
     */
404
 
    S.sin_addr = to;
405
 
    S.sin_port = 0;
406
 
    assert(icmp_pktsize <= MAX_PKT_SZ);
407
 
    sendto(icmp_sock,
408
 
           (const void *) pkt,
409
 
           icmp_pktsize,
410
 
           0,
411
 
 
412
 
           (struct sockaddr *) &S,
413
 
 
414
 
           sizeof(struct sockaddr_in));
415
 
    pingerLog(icmp, to, 0, 0);
416
 
}
417
 
 
418
 
static void
419
 
pingerRecv(void)
420
 
{
421
 
    int n;
422
 
    socklen_t fromlen;
423
 
 
424
 
    struct sockaddr_in from;
425
 
    int iphdrlen = 20;
426
 
 
427
 
    struct iphdr *ip = NULL;
428
 
 
429
 
    struct icmphdr *icmp = NULL;
430
 
    static char *pkt = NULL;
431
 
 
432
 
    struct timeval now;
433
 
    icmpEchoData *echo;
434
 
    static pingerReplyData preply;
435
 
 
436
 
    if (pkt == NULL)
437
 
        pkt = (char *)xmalloc(MAX_PKT_SZ);
438
 
 
439
 
    fromlen = sizeof(from);
440
 
 
441
 
    n = recvfrom(icmp_sock,
442
 
                 (void *)pkt,
443
 
                 MAX_PKT_SZ,
444
 
                 0,
445
 
 
446
 
                 (struct sockaddr *) &from,
447
 
                 &fromlen);
448
 
 
449
 
#if GETTIMEOFDAY_NO_TZP
450
 
 
451
 
    gettimeofday(&now);
452
 
 
453
 
#else
454
 
 
455
 
    gettimeofday(&now, NULL);
456
 
 
457
 
#endif
458
 
 
459
 
    debugs(42, 9, "pingerRecv: " << n << " bytes from " <<
460
 
           inet_ntoa(from.sin_addr));
461
 
 
462
 
    ip = (struct iphdr *) (void *) pkt;
463
 
 
464
 
#if HAVE_STRUCT_IPHDR_IP_HL
465
 
 
466
 
    iphdrlen = ip->ip_hl << 2;
467
 
 
468
 
#else /* HAVE_STRUCT_IPHDR_IP_HL */
469
 
#if WORDS_BIGENDIAN
470
 
 
471
 
    iphdrlen = (ip->ip_vhl >> 4) << 2;
472
 
 
473
 
#else
474
 
 
475
 
    iphdrlen = (ip->ip_vhl & 0xF) << 2;
476
 
 
477
 
#endif
478
 
#endif /* HAVE_STRUCT_IPHDR_IP_HL */
479
 
 
480
 
    icmp = (struct icmphdr *) (void *) (pkt + iphdrlen);
481
 
 
482
 
    if (icmp->icmp_type != ICMP_ECHOREPLY)
483
 
        return;
484
 
 
485
 
    if (icmp->icmp_id != icmp_ident)
486
 
        return;
487
 
 
488
 
    echo = (icmpEchoData *) (void *) (icmp + 1);
489
 
 
490
 
    preply.from = from.sin_addr;
491
 
 
492
 
    preply.opcode = echo->opcode;
493
 
 
494
 
    preply.hops = ipHops(ip->ip_ttl);
495
 
 
496
 
    preply.rtt = tvSubMsec(echo->tv, now);
497
 
 
498
 
    preply.psize = n - iphdrlen - (sizeof(icmpEchoData) - MAX_PKT_SZ);
499
 
 
500
 
    pingerSendtoSquid(&preply);
501
 
 
502
 
    pingerLog(icmp, from.sin_addr, preply.rtt, preply.hops);
503
 
}
504
 
 
505
 
 
506
 
static int
507
 
in_cksum(unsigned short *ptr, int size)
508
 
{
509
 
    long sum;
510
 
    unsigned short oddbyte;
511
 
    unsigned short answer;
512
 
    sum = 0;
513
 
 
514
 
    while (size > 1) {
515
 
        sum += *ptr++;
516
 
        size -= 2;
517
 
    }
518
 
 
519
 
    if (size == 1) {
520
 
        oddbyte = 0;
521
 
        *((unsigned char *) &oddbyte) = *(unsigned char *) ptr;
522
 
        sum += oddbyte;
523
 
    }
524
 
 
525
 
    sum = (sum >> 16) + (sum & 0xffff);
526
 
    sum += (sum >> 16);
527
 
    answer = (unsigned short) ~sum;
528
 
    return (answer);
529
 
}
530
 
 
531
 
static void
532
 
 
533
 
pingerLog(struct icmphdr *icmp, struct IN_ADDR addr, int rtt, int hops)
534
 
{
535
 
    debugs(42, 2, "pingerLog: " << std::setw(9) << current_time.tv_sec  <<
536
 
           "."<< std::setfill('0') << std::setw(6) <<
537
 
           current_time.tv_usec  << " "<< std::left << std::setfill(' ')<<
538
 
           std::setw(16) << inet_ntoa(addr)  << " "<< icmp->icmp_type  <<
539
 
           " " << std::setw(15) <<  icmpPktStr[icmp->icmp_type] << " " << rtt  <<
540
 
           "ms " << hops  << " hops");
541
 
}
542
 
 
543
 
static int
544
 
ipHops(int ttl)
545
 
{
546
 
    if (ttl < 33)
547
 
        return 33 - ttl;
548
 
 
549
 
    if (ttl < 63)
550
 
        return 63 - ttl;        /* 62 = (64+60)/2 */
551
 
 
552
 
    if (ttl < 65)
553
 
        return 65 - ttl;        /* 62 = (64+60)/2 */
554
 
 
555
 
    if (ttl < 129)
556
 
        return 129 - ttl;
557
 
 
558
 
    if (ttl < 193)
559
 
        return 193 - ttl;
560
 
 
561
 
    return 256 - ttl;
562
 
}
563
 
 
564
 
static int
565
 
pingerReadRequest(void)
566
 
{
567
 
    static pingerEchoData pecho;
568
 
    int n;
569
 
    int guess_size;
570
 
    memset(&pecho, '\0', sizeof(pecho));
571
 
    n = recv(socket_from_squid, &pecho, sizeof(pecho), 0);
572
 
 
573
 
    if (n < 0)
574
 
        return n;
575
 
 
576
 
    if (0 == n) {
577
 
        /* EOF indicator */
578
 
        fprintf(stderr, "EOF encountered\n");
579
 
        errno = 0;
580
 
        return -1;
581
 
    }
582
 
 
583
 
    guess_size = n - (sizeof(pingerEchoData) - PINGER_PAYLOAD_SZ);
584
 
 
585
 
    if (guess_size != pecho.psize) {
586
 
        fprintf(stderr, "size mismatch, guess=%d psize=%d\n",
587
 
                guess_size, pecho.psize);
588
 
        /* don't process this message, but keep running */
589
 
        return 0;
590
 
    }
591
 
 
592
 
    pingerSendEcho(pecho.to,
593
 
                   pecho.opcode,
594
 
                   pecho.payload,
595
 
                   pecho.psize);
596
 
    return n;
597
 
}
598
 
 
599
 
static void
600
 
pingerSendtoSquid(pingerReplyData * preply)
601
 
{
602
 
    int len = sizeof(pingerReplyData) - MAX_PKT_SZ + preply->psize;
603
 
 
604
 
    if (send(socket_to_squid, preply, len, 0) < 0) {
605
 
        debugs(50, 0, "pinger: send: " << xstrerror());
606
 
        pingerClose();
607
 
        exit(1);
608
 
    }
609
 
}
610
 
 
611
 
int
612
 
main(int argc, char *argv[])
613
 
{
614
 
    fd_set R;
615
 
    int x;
616
 
 
617
 
    struct timeval tv;
618
 
    const char *debug_args = "ALL,1";
619
 
    char *t;
620
 
    time_t last_check_time = 0;
621
 
 
622
 
    /*
623
 
     * cevans - do this first. It grabs a raw socket. After this we can
624
 
     * drop privs
625
 
     */
626
 
    pingerOpen();
627
 
    setgid(getgid());
628
 
    setuid(getuid());
629
 
 
630
 
    if ((t = getenv("SQUID_DEBUG")))
631
 
        debug_args = xstrdup(t);
632
 
 
633
 
    getCurrentTime();
634
 
 
635
 
    _db_init(NULL, debug_args);
636
 
 
637
 
    for (;;) {
638
 
        tv.tv_sec = PINGER_TIMEOUT;
639
 
        tv.tv_usec = 0;
640
 
        FD_ZERO(&R);
641
 
        FD_SET(socket_from_squid, &R);
642
 
        FD_SET(icmp_sock, &R);
643
 
        x = select(icmp_sock + 1, &R, NULL, NULL, &tv);
644
 
        getCurrentTime();
645
 
 
646
 
        if (x < 0) {
647
 
            pingerClose();
648
 
            exit(1);
649
 
        }
650
 
 
651
 
        if (FD_ISSET(socket_from_squid, &R))
652
 
            if (pingerReadRequest() < 0) {
653
 
                debugs(42, 0, "Pinger exiting.");
654
 
                pingerClose();
655
 
                exit(1);
656
 
            }
657
 
 
658
 
        if (FD_ISSET(icmp_sock, &R))
659
 
            pingerRecv();
660
 
 
661
 
        if (PINGER_TIMEOUT + last_check_time < squid_curtime) {
662
 
            if (send(socket_to_squid, &tv, 0, 0) < 0) {
663
 
                pingerClose();
664
 
                exit(1);
665
 
            }
666
 
 
667
 
            last_check_time = squid_curtime;
668
 
        }
669
 
    }
670
 
 
671
 
    /* NOTREACHED */
672
 
    return 0;
673
 
}
674
 
 
675
 
#else
676
 
#include <stdio.h>
677
 
int
678
 
main(int argc, char *argv[])
679
 
{
680
 
    fprintf(stderr, "%s: ICMP support not compiled in.\n", argv[0]);
681
 
    return 1;
682
 
}
683
 
 
684
 
#endif /* USE_ICMP */