On Fri, 23 Dec 2016 12:47:10 +0100 (CET) Cristian Ionescu-Idbohrn
<cristian.ionescu-idbo...@axis.com> wrote:
> Package: netcat-openbsd
> Version: 1.130-1

> 
>       $ echo 'ehlo itsme' | nc.openbsd host.example.com 25
> 
> There is _no_ output.
> 


This particular problem (along with the same no-output when using "nc -d -l")
seems to be caused by a Debian change which introduces the -q option[1]. This
causes the readwrite loop to exit before handling possible return data or the
received data in the listen case.
One draw back with the proposed fix: while this now allows to receive the data
sent back, it will hang there until stopped. That problem comes from upstream
changes. They added a -N flag to send shutdown messages to the remote socket
when the input stream was closed (which was the default in the old version of
nc). So:

    echo 'ehlo itsme' | nc.openbsd -N host.example.com 25

would then behave as expected. Not sure how to handle this. IMO it would have
been better if upstream kept the old behaviour as default and added an option to
*not* do the shutdown. But now that its done that way it might be confusing to
change it.

-Stefan



[1] 0005-quit-timer.patch

--- one possible fix ---

Description: Fix handling of delayed exit option
 The option for delayed exit (-q#) existed before but since upstream
 rewrote the readwrite call the patch adding it had to be adapted.
 However the current implementation causes the loop to exit too early.
 Move the exit handling to those places which do exit the loop in the
 original code. While on it also add some code to close the net_fd on
 delayed exit.
Author: Stefan Bader <stefan.ba...@canonical.com>

Index: netcat-openbsd-1.130/netcat.c
===================================================================
--- netcat-openbsd-1.130.orig/netcat.c
+++ netcat-openbsd-1.130/netcat.c
@@ -178,6 +178,8 @@ char    *proto_name(int uflag, int dccpf

 static int connect_with_timeout(int fd, const struct sockaddr *sa,
         socklen_t salen, int ctimeout);
+
+int    quit_fd = -1;
 static void quit();

 int
@@ -1028,19 +1030,31 @@ readwrite(int net_fd)
                /* both inputs are gone, buffers are empty, we are done */
                if (pfd[POLL_STDIN].fd == -1 && pfd[POLL_NETIN].fd == -1
                    && stdinbufpos == 0 && netinbufpos == 0) {
-                       close(net_fd);
-                       return;
+                       if (qflag == 0) {
+                               close(net_fd);
+                               return;
+                       }
+                       goto delay_exit;
                }
                /* both outputs are gone, we can't continue */
                if (pfd[POLL_NETOUT].fd == -1 && pfd[POLL_STDOUT].fd == -1) {
-                       close(net_fd);
-                       return;
+                       if (qflag == 0) {
+                               close(net_fd);
+                               return;
+                       }
+                       goto delay_exit;
                }
                /* listen and net in gone, queues empty, done */
                if (lflag && pfd[POLL_NETIN].fd == -1
                    && stdinbufpos == 0 && netinbufpos == 0) {
-                       close(net_fd);
-                       return;
+                       if (qflag == 0) {
+                               close(net_fd);
+                               return;
+                       }
+delay_exit:
+                       quit_fd = net_fd;
+                       signal(SIGALRM, quit);
+                       alarm(qflag);
                }

                /* poll */
@@ -1159,20 +1173,10 @@ readwrite(int net_fd)
                        if (pfd[POLL_NETOUT].fd != -1 && Nflag)
                                shutdown(pfd[POLL_NETOUT].fd, SHUT_WR);
                        pfd[POLL_NETOUT].fd = -1;
-                       goto exit_on_eof;
                }
                /* net in gone and queue empty? */
                if (pfd[POLL_NETIN].fd == -1 && netinbufpos == 0) {
                        pfd[POLL_STDOUT].fd = -1;
-                       exit_on_eof:
-                               /* if the user asked to exit on EOF, do it */
-                               if (qflag == 0)
-                                       return;
-                               /* if user asked to die after a while, arrange 
for it */
-                               else if (qflag > 0) {
-                                       signal(SIGALRM, quit);
-                                       alarm(qflag);
-                               }
                }
        }
 }
@@ -1615,6 +1619,8 @@ usage(int ret)
  */
 static void quit()
 {
-        /* XXX: should explicitly close fds here */
+        if (quit_fd >= 0)
+               close(quit_fd);
+
         exit(0);
 }

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to