i had observed this before with
for i in `jot 5`;do ping6 -c 1 2001:4860:4860::8888 1>/dev/null &done

diff fixes the problem and looks correct to me.

ok benno@


Florian Obser([email protected]) on 2020.10.20 18:39:58 +0200:
> On Tue, Oct 20, 2020 at 04:07:41PM +0200, Martijn van Duren wrote:
> > When running:
> > /usr/local/libexec/nagios/check_ping -vv -6 -H <ip> -c 500,75% -w 250,50%
> > in a tight loop at some point I get the following output:
> > 
> > CMD: /sbin/ping6 -n -c 5 <ip>
> > Output: PING <ip> (<ip>): 56 data bytes
> > Output: 64 bytes from <ip>: icmp_seq=0 hlim=57 time=1.724 ms
> > Output: 64 bytes from <ip>: icmp_seq=1 hlim=57 time=1.612 ms
> > Output: 64 bytes from <ip>: icmp_seq=2 hlim=57 time=1.785 ms
> > Output: 64 bytes from <ip>: icmp_seq=3 hlim=57 time=1.762 ms
> > Output: 64 bytes from <ip>: icmp_seq=4 hlim=57 time=1.708 ms
> > Output:
> > Output: --- <ip> ping statistics ---
> > Output: 5 packets transmitted, 5 packets received, 0.0% packet loss
> > Output: round-trip min/avg/max/std-dev = 1.612/1.718/1.785/0.060 ms
> > Got stderr: ping6: failed to get receiving hop limit
> > PING WARNING - System call sent warnings to stderr Packet loss = 0%, RTA = 
> > 1.72 ms|rta=1.718000ms;3000.000000;5000.000000;0.000000 pl=0%;80;100;0
> > 3000.000000:80% 5000.000000:100%
> > 
> > So I have 5 echo requests, 5 echo replies and one unrelated packet not
> > related to my ping command. Yet this notice to stderr forces check_ping
> > into a warning state.
> > 
> 
> Oh, got it know. The problem is packets arriving between socket(2) and
> whenever we are finished calling all setsockopt(2)s. In this case
> IPV6_RECVHOPLIMIT.
> 
> We need to drain the socket after we are fully setup.
> 
> Can you give this a spin? OK?
> 
> diff --git ping.c ping.c
> index d198d233921..acfe2ed8e18 100644
> --- ping.c
> +++ ping.c
> @@ -240,6 +240,17 @@ void                      pr_retip6(struct ip6_hdr *, 
> u_char *);
>  int
>  main(int argc, char *argv[])
>  {
> +     struct msghdr           m;
> +     union {
> +             struct cmsghdr hdr;
> +             u_char buf[CMSG_SPACE(1024)];
> +     }                       cmsgbuf;
> +     struct iovec            iov[1];
> +     struct pollfd           pfd;
> +     struct sockaddr_in      peer4;
> +     struct sockaddr_in6     peer6;
> +     ssize_t                 cc;
> +
>       struct addrinfo hints, *res;
>       struct itimerval itimer;
>       struct sockaddr *from, *dst;
> @@ -786,6 +797,44 @@ main(int argc, char *argv[])
>       smsghdr.msg_iov = &smsgiov;
>       smsghdr.msg_iovlen = 1;
>  
> +     if (v6flag) {
> +             m.msg_name = &peer6;
> +             m.msg_namelen = sizeof(peer6);
> +     } else {
> +             m.msg_name = &peer4;
> +             m.msg_namelen = sizeof(peer4);
> +     }
> +     memset(&iov, 0, sizeof(iov));
> +     iov[0].iov_base = (caddr_t)packet;
> +     iov[0].iov_len = packlen;
> +
> +     /* Drain our socket. */
> +     (void)signal(SIGALRM, onsignal);
> +     memset(&itimer, 0, sizeof(itimer));
> +     itimer.it_value.tv_sec = 1; /* make sure we don't get stuck */
> +     (void)setitimer(ITIMER_REAL, &itimer, NULL);
> +     for (;;) {
> +             if (seenalrm)
> +                     break;
> +
> +             pfd.fd = s;
> +             pfd.events = POLLIN;
> +
> +             if (poll(&pfd, 1, 0) <= 0)
> +                     break;
> +
> +             m.msg_iov = iov;
> +             m.msg_iovlen = 1;
> +             m.msg_control = (caddr_t)&cmsgbuf.buf;
> +             m.msg_controllen = sizeof(cmsgbuf.buf);
> +
> +             cc = recvmsg(s, &m, 0);
> +             if (cc == -1 && errno != EINTR)
> +                     break;
> +     }
> +     memset(&itimer, 0, sizeof(itimer));
> +     (void)setitimer(ITIMER_REAL, &itimer, NULL);
> +
>       while (preload--)               /* Fire off them quickies. */
>               pinger(s);
>  
> @@ -805,17 +854,7 @@ main(int argc, char *argv[])
>       seeninfo = 0;
>  
>       for (;;) {
> -             struct msghdr           m;
> -             union {
> -                     struct cmsghdr hdr;
> -                     u_char buf[CMSG_SPACE(1024)];
> -             }                       cmsgbuf;
> -             struct iovec            iov[1];
> -             struct pollfd           pfd;
> -             struct sockaddr_in      peer4;
> -             struct sockaddr_in6     peer6;
> -             ssize_t                 cc;
> -             int                     timeout;
> +             int     timeout;
>  
>               /* signal handling */
>               if (seenint)
> @@ -864,16 +903,6 @@ main(int argc, char *argv[])
>               if (poll(&pfd, 1, timeout) <= 0)
>                       continue;
>  
> -             if (v6flag) {
> -                     m.msg_name = &peer6;
> -                     m.msg_namelen = sizeof(peer6);
> -             } else {
> -                     m.msg_name = &peer4;
> -                     m.msg_namelen = sizeof(peer4);
> -             }
> -             memset(&iov, 0, sizeof(iov));
> -             iov[0].iov_base = (caddr_t)packet;
> -             iov[0].iov_len = packlen;
>               m.msg_iov = iov;
>               m.msg_iovlen = 1;
>               m.msg_control = (caddr_t)&cmsgbuf.buf;
> 
> 
> -- 
> I'm not entirely sure you are real.
> 

Reply via email to