Subject: ping suggestion.
To: None <tech-net@netbsd.org>
From: Sean Boudreau <seanb@qnx.com>
List: tech-net
Date: 04/25/2003 17:01:20
Since the 'sloop' socket is never read on, mbufs
Q in its recv buffer until full and remain until
the ping is terminated.  This is easy to see with
netstat -m.  Also, the knocking down / resetting
of IP_HDRINCL on 'sloop' isn't necessary.

Here's a suggested diff:

-seanb


Index: ping.c
===================================================================
RCS file: /cvsroot/src/sbin/ping/ping.c,v
retrieving revision 1.63
diff -c -r1.63 ping.c
*** ping.c	2001/12/20 20:10:38	1.63
--- ping.c	2003/04/25 20:54:36
***************
*** 258,263 ****
--- 258,264 ----
  	char *policy_in = NULL;
  	char *policy_out = NULL;
  #endif
+ 	int one = 1;
  #endif
    
  
***************
*** 468,486 ****
  			warn("SO_DONTROUTE");
  	}
  
- 	if ((sloop = cap_socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
- 		err(1, "Cannot create socket");
- 	if (options & SO_DEBUG) {
- 		if (setsockopt(sloop, SOL_SOCKET, SO_DEBUG,
- 			       (char *)&on, sizeof(on)) == -1)
- 			warn("Can't turn on socket debugging");
- 	}
- 	if (options & SO_DONTROUTE) {
- 		if (setsockopt(sloop, SOL_SOCKET, SO_DONTROUTE,
- 			       (char *)&on, sizeof(on)) == -1)
- 			warn("SO_DONTROUTE");
- 	}
- 
  	if (pingflags & F_SOURCE_ROUTE) {
  		optspace[IPOPT_OPTVAL] = IPOPT_LSRR;
  		optspace[IPOPT_OLEN] = optlen = 7;
--- 469,474 ----
***************
*** 539,544 ****
--- 527,551 ----
  			err(1, "Can't set source interface/address");
  	}
  #ifdef IPSEC
+ 	if ((sloop = cap_socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
+ 		err(1, "Cannot create socket");
+ 	if (options & SO_DEBUG) {
+ 		if (setsockopt(sloop, SOL_SOCKET, SO_DEBUG,
+ 			       (char *)&on, sizeof(on)) == -1)
+ 			warn("Can't turn on socket debugging");
+ 	}
+ 	if (options & SO_DONTROUTE) {
+ 		if (setsockopt(sloop, SOL_SOCKET, SO_DONTROUTE,
+ 			       (char *)&on, sizeof(on)) == -1)
+ 			warn("SO_DONTROUTE");
+ 	}
+ 	/*
+ 	 * Set to lowest value to prevent packets from filing
+ 	 * up the recv buffer as this socket is never read on.
+ 	 */
+ 	if (setsockopt(sloop, SOL_SOCKET, SO_RCVBUF, &one, sizeof(one)) == -1)
+ 		warn("SO_RCVBUF");
+ 
  #ifdef IPSEC_POLICY_IPSEC
      {
  	char *buf;
***************
*** 607,612 ****
--- 614,621 ----
  		(char *)&optval, sizeof(optval));
      }
  #endif /*IPSEC_POLICY_IPSEC*/
+ #else
+ 	sloop = s;
  #endif /*IPSEC*/
  
  	(void)printf("PING %s (%s): %d data bytes\n", hostname,
***************
*** 837,845 ****
--- 846,856 ----
  		opack_icmp.icmp_cksum = in_cksum((u_short*)&opack_icmp,
  						 PHDR_LEN);
  		sw = 0;
+ #ifndef IPSEC
  		if (setsockopt(sloop,IPPROTO_IP,IP_HDRINCL,
  			       (char *)&sw,sizeof(sw)) < 0)
  			err(1, "Can't turn off special IP header");
+ #endif
  		if (sendto(sloop, (char *) &opack_icmp, PHDR_LEN, MSG_DONTROUTE,
  			   (struct sockaddr *)&loc_addr,
  			   sizeof(struct sockaddr_in)) < 0) {
***************
*** 853,861 ****
--- 864,874 ----
  				warn("failed to clear cached route");
  		}
  		sw = 1;
+ #ifndef IPSEC
  		if (setsockopt(sloop,IPPROTO_IP,IP_HDRINCL,
  			       (char *)&sw, sizeof(sw)) < 0)
  			err(1, "Can't set special IP header");
+ #endif
  		
  		(void)gettimeofday(&clear_cache,0);
  	}