bin/176713: nc(1) closes network socket too soon

Ronald F.Guilmette rfg at tristatelogic.com
Thu Mar 7 02:50:02 UTC 2013


>Number:         176713
>Category:       bin
>Synopsis:       nc(1) closes network socket too soon
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Mar 07 02:50:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator:     Ronald F. Guilmette
>Release:        FreeBSD 9.1-RELEASE amd64
>Organization:
entr0py
>Environment:

System: FreeBSD 9.1-RELEASE FreeBSD amd64

>Description:

As described in this thread:

  https://bugs.launchpad.net/ubuntu/+source/netcat-openbsd/+bug/544935

numerous people have, like me, encountered a serious problem with nc(1),
specifically that it prematurely closes the connection to the remote network
server being accessed as soon as it senses EOF on its stdin channel.

As can been see by perusing the above web page, this problem can cause,
and has caused much gnashing of teeth and tearing of hair in many quarters.

It is certainly possible that some existing scripts and/or applications
may perhaps depend on the current/existing behavior, and thus, it may
perhaps not be considered wise to change the existing behavior at this
(late?) point in time.  However there are quite certainly many situations
in which the different behavior (of gathering and outputting all output
from the remote server before closing down) can be unambiguously useful,
if not to say utterly irreplacable.  For these reasons I propse the addition
of a new "-q" option (no arguments) for nc(1) which, when used would change
the program's behavior, causing it to wait for EOF from the remote network
server before closing down and exiting.

I provide implementation patches for exactly such a change below.

>How-To-Repeat:

echo 193.0.6.139 | nc whois.ripe.net 43

((note how the output produced by the above command pipeline gets chopped
off prematurely))

Fix:

Simple/trivial context diff patches (implementing -q) attached below.


*** netcat.c	2012-12-03 10:55:02.000000000 -0800
--- netcat.c	2013-03-06 18:10:10.000000000 -0800
***************
*** 82,87 ****
--- 82,88 ----
  int	FreeBSD_Oflag;				/* Do not use TCP options */
  char   *Pflag;					/* Proxy username */
  char   *pflag;					/* Localport flag */
+ int	qflag;					/* quit on remote EOF flag */
  int	rflag;					/* Random ports flag */
  char   *sflag;					/* Source Address */
  int	tflag;					/* Telnet Emulation */
***************
*** 153,159 ****
  	sv = NULL;
  
  	while ((ch = getopt_long(argc, argv,
! 	    "46DdEe:hI:i:jklnoO:P:p:rSs:tT:UuV:vw:X:x:z",
  	    longopts, NULL)) != -1) {
  		switch (ch) {
  		case '4':
--- 154,160 ----
  	sv = NULL;
  
  	while ((ch = getopt_long(argc, argv,
! 	    "46DdEe:hI:i:jklnoO:P:p:qrSs:tT:UuV:vw:X:x:z",
  	    longopts, NULL)) != -1) {
  		switch (ch) {
  		case '4':
***************
*** 224,229 ****
--- 225,233 ----
  		case 'p':
  			pflag = optarg;
  			break;
+ 		case 'q':
+ 			qflag = 1;
+ 			break;
  		case 'r':
  			rflag = 1;
  			break;
***************
*** 823,829 ****
  			if ((n = read(wfd, buf, plen)) < 0)
  				return;
  			else if (n == 0) {
! 				shutdown(nfd, SHUT_WR);
  				pfd[1].fd = -1;
  				pfd[1].events = 0;
  			} else {
--- 827,834 ----
  			if ((n = read(wfd, buf, plen)) < 0)
  				return;
  			else if (n == 0) {
! 				if (!qflag)
! 					shutdown(nfd, SHUT_WR);
  				pfd[1].fd = -1;
  				pfd[1].events = 0;
  			} else {
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list