avoid signal handler race. help from deraadt
This commit is contained in:
parent
6f85104748
commit
b2f011d7b6
|
@ -1,5 +1,5 @@
|
||||||
/* $NetBSD: ping6.c,v 1.29 2001/01/12 18:50:58 itojun Exp $ */
|
/* $NetBSD: ping6.c,v 1.30 2001/01/12 19:13:41 itojun Exp $ */
|
||||||
/* $KAME: ping6.c,v 1.109 2000/12/27 11:32:37 itojun Exp $ */
|
/* $KAME: ping6.c,v 1.112 2001/01/12 19:11:49 itojun Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||||
|
@ -81,7 +81,7 @@ static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93";
|
||||||
#else
|
#else
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
__RCSID("$NetBSD: ping6.c,v 1.29 2001/01/12 18:50:58 itojun Exp $");
|
__RCSID("$NetBSD: ping6.c,v 1.30 2001/01/12 19:13:41 itojun Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -248,11 +248,17 @@ struct msghdr smsghdr;
|
||||||
struct iovec smsgiov;
|
struct iovec smsgiov;
|
||||||
char *scmsg = 0;
|
char *scmsg = 0;
|
||||||
|
|
||||||
|
volatile int signo;
|
||||||
|
volatile int seenalrm;
|
||||||
|
volatile int seenint;
|
||||||
|
volatile int seeninfo;
|
||||||
|
|
||||||
int main __P((int, char *[]));
|
int main __P((int, char *[]));
|
||||||
void fill __P((char *, char *));
|
void fill __P((char *, char *));
|
||||||
int get_hoplim __P((struct msghdr *));
|
int get_hoplim __P((struct msghdr *));
|
||||||
struct in6_pktinfo *get_rcvpktinfo __P((struct msghdr *));
|
struct in6_pktinfo *get_rcvpktinfo __P((struct msghdr *));
|
||||||
void onalrm __P((int));
|
void onsignal __P((int));
|
||||||
|
void retransmit __P((void));
|
||||||
void oninfo __P((int));
|
void oninfo __P((int));
|
||||||
void onint __P((int));
|
void onint __P((int));
|
||||||
void pinger __P((void));
|
void pinger __P((void));
|
||||||
|
@ -284,7 +290,7 @@ main(argc, argv)
|
||||||
{
|
{
|
||||||
struct itimerval itimer;
|
struct itimerval itimer;
|
||||||
struct sockaddr_in6 from;
|
struct sockaddr_in6 from;
|
||||||
struct timeval timeout;
|
struct timeval timeout, *tv;
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
fd_set *fdmaskp;
|
fd_set *fdmaskp;
|
||||||
int fdmasks;
|
int fdmasks;
|
||||||
|
@ -300,9 +306,6 @@ main(argc, argv)
|
||||||
#ifdef USE_RFC2292BIS
|
#ifdef USE_RFC2292BIS
|
||||||
struct ip6_rthdr *rthdr = NULL;
|
struct ip6_rthdr *rthdr = NULL;
|
||||||
#endif
|
#endif
|
||||||
#ifndef __OpenBSD__
|
|
||||||
struct timeval tv;
|
|
||||||
#endif
|
|
||||||
#ifdef IPSEC_POLICY_IPSEC
|
#ifdef IPSEC_POLICY_IPSEC
|
||||||
char *policy_in = NULL;
|
char *policy_in = NULL;
|
||||||
char *policy_out = NULL;
|
char *policy_out = NULL;
|
||||||
|
@ -633,8 +636,8 @@ main(argc, argv)
|
||||||
|
|
||||||
ident = getpid() & 0xFFFF;
|
ident = getpid() & 0xFFFF;
|
||||||
#ifndef __OpenBSD__
|
#ifndef __OpenBSD__
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&timeout, NULL);
|
||||||
srand((unsigned int)(tv.tv_sec ^ tv.tv_usec ^ (long)ident));
|
srand((unsigned int)(timeout.tv_sec ^ timeout.tv_usec ^ (long)ident));
|
||||||
memset(nonce, 0, sizeof(nonce));
|
memset(nonce, 0, sizeof(nonce));
|
||||||
for (i = 0; i < sizeof(nonce); i += sizeof(int))
|
for (i = 0; i < sizeof(nonce); i += sizeof(int))
|
||||||
*((int *)&nonce[i]) = rand();
|
*((int *)&nonce[i]) = rand();
|
||||||
|
@ -963,23 +966,25 @@ main(argc, argv)
|
||||||
while (preload--) /* Fire off them quickies. */
|
while (preload--) /* Fire off them quickies. */
|
||||||
pinger();
|
pinger();
|
||||||
|
|
||||||
(void)signal(SIGINT, onint);
|
(void)signal(SIGINT, onsignal);
|
||||||
#ifdef SIGINFO
|
#ifdef SIGINFO
|
||||||
(void)signal(SIGINFO, oninfo);
|
(void)signal(SIGINFO, onsignal);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((options & F_FLOOD) == 0) {
|
if ((options & F_FLOOD) == 0) {
|
||||||
(void)signal(SIGALRM, onalrm);
|
(void)signal(SIGALRM, onsignal);
|
||||||
itimer.it_interval = interval;
|
itimer.it_interval = interval;
|
||||||
itimer.it_value.tv_sec = 0;
|
itimer.it_value = interval;
|
||||||
itimer.it_value.tv_usec = 1;
|
|
||||||
(void)setitimer(ITIMER_REAL, &itimer, NULL);
|
(void)setitimer(ITIMER_REAL, &itimer, NULL);
|
||||||
|
retransmit();
|
||||||
}
|
}
|
||||||
|
|
||||||
fdmasks = howmany(s + 1, NFDBITS) * sizeof(fd_mask);
|
fdmasks = howmany(s + 1, NFDBITS) * sizeof(fd_mask);
|
||||||
if ((fdmaskp = malloc(fdmasks)) == NULL)
|
if ((fdmaskp = malloc(fdmasks)) == NULL)
|
||||||
err(1, "malloc");
|
err(1, "malloc");
|
||||||
|
|
||||||
|
signo = seenalrm = seenint = seeninfo = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
struct msghdr m;
|
struct msghdr m;
|
||||||
struct cmsghdr *cm;
|
struct cmsghdr *cm;
|
||||||
|
@ -990,11 +995,30 @@ main(argc, argv)
|
||||||
pinger();
|
pinger();
|
||||||
timeout.tv_sec = 0;
|
timeout.tv_sec = 0;
|
||||||
timeout.tv_usec = 10000;
|
timeout.tv_usec = 10000;
|
||||||
memset(fdmaskp, 0, fdmasks);
|
tv = &timeout;
|
||||||
FD_SET(s, fdmaskp);
|
} else
|
||||||
if (select(s + 1, fdmaskp, NULL, NULL, &timeout) < 1)
|
tv = NULL;
|
||||||
continue;
|
memset(fdmaskp, 0, fdmasks);
|
||||||
}
|
FD_SET(s, fdmaskp);
|
||||||
|
cc = select(s + 1, fdmaskp, NULL, NULL, tv);
|
||||||
|
if ((cc < 0 && errno == EINTR) || ((options & F_FLOOD) && signo)) {
|
||||||
|
if (seenalrm) {
|
||||||
|
retransmit();
|
||||||
|
seenalrm = 0;
|
||||||
|
}
|
||||||
|
if (seenint) {
|
||||||
|
onint(SIGINT);
|
||||||
|
seenint = 0;
|
||||||
|
}
|
||||||
|
if (seeninfo) {
|
||||||
|
oninfo(SIGINFO);
|
||||||
|
seeninfo = 0;
|
||||||
|
}
|
||||||
|
signo = 0;
|
||||||
|
continue;
|
||||||
|
} else if (cc == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
fromlen = sizeof(from);
|
fromlen = sizeof(from);
|
||||||
|
|
||||||
m.msg_name = (caddr_t)&from;
|
m.msg_name = (caddr_t)&from;
|
||||||
|
@ -1008,14 +1032,33 @@ main(argc, argv)
|
||||||
m.msg_control = (caddr_t)buf;
|
m.msg_control = (caddr_t)buf;
|
||||||
m.msg_controllen = sizeof(buf);
|
m.msg_controllen = sizeof(buf);
|
||||||
|
|
||||||
if ((cc = recvmsg(s, &m, 0)) < 0) {
|
cc = recvmsg(s, &m, 0);
|
||||||
if (errno == EINTR)
|
if (cc < 0) {
|
||||||
|
if (errno != EINTR) {
|
||||||
|
warn("recvmsg");
|
||||||
continue;
|
continue;
|
||||||
warn("recvfrom");
|
}
|
||||||
|
if (!signo)
|
||||||
|
continue;
|
||||||
|
if (seenalrm) {
|
||||||
|
retransmit();
|
||||||
|
seenalrm = 0;
|
||||||
|
}
|
||||||
|
if (seenint) {
|
||||||
|
onint(SIGINT);
|
||||||
|
seenint = 0;
|
||||||
|
}
|
||||||
|
if (seeninfo) {
|
||||||
|
oninfo(SIGINFO);
|
||||||
|
seeninfo = 0;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* an ICMPv6 message (probably an echoreply) arrived.
|
||||||
|
*/
|
||||||
|
pr_pack(packet, cc, &m);
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_pack(packet, cc, &m);
|
|
||||||
if (npackets && nreceived >= npackets)
|
if (npackets && nreceived >= npackets)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1023,14 +1066,30 @@ main(argc, argv)
|
||||||
exit(nreceived == 0);
|
exit(nreceived == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
onsignal(sig)
|
||||||
|
int sig;
|
||||||
|
{
|
||||||
|
signo = sig;
|
||||||
|
switch (sig) {
|
||||||
|
case SIGALRM:
|
||||||
|
seenalrm++;
|
||||||
|
break;
|
||||||
|
case SIGINT:
|
||||||
|
seenint++;
|
||||||
|
break;
|
||||||
|
case SIGINFO:
|
||||||
|
seeninfo++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* onalrm --
|
* retransmit --
|
||||||
* This routine transmits another ping6.
|
* This routine transmits another ping6.
|
||||||
*/
|
*/
|
||||||
/* ARGSUSED */
|
|
||||||
void
|
void
|
||||||
onalrm(signo)
|
retransmit()
|
||||||
int signo;
|
|
||||||
{
|
{
|
||||||
struct itimerval itimer;
|
struct itimerval itimer;
|
||||||
|
|
||||||
|
@ -1909,10 +1968,8 @@ void
|
||||||
oninfo(notused)
|
oninfo(notused)
|
||||||
int notused;
|
int notused;
|
||||||
{
|
{
|
||||||
int save_errno = errno;
|
|
||||||
|
|
||||||
summary();
|
summary();
|
||||||
errno = save_errno;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue