]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Fixed client hang when server don't PUSH (aka the NO_SOUP_FOR_YOU patch)
authorDavid Sommerseth <dazo@users.sourceforge.net>
Sat, 12 Jun 2010 22:35:55 +0000 (00:35 +0200)
committerDavid Sommerseth <dazo@users.sourceforge.net>
Thu, 21 Oct 2010 09:40:36 +0000 (11:40 +0200)
Solves bug ticket 13
<https://community.openvpn.net/openvpn/ticket/13>

When the client sends PUSH_REQUESTS, it waits until the server sends PUSH_REPLY.
If the server do not have anything to push to the client nothing happens.  The
client will then regularly send new PUSH_REQUESTS until it gets an answer, which
results in not completing the connection negotiation.

This patch makes the server send an empty PUSH_REPLY when it has nothing to more
to push to the client.

Signed-off-by: David Sommerseth <dazo@users.sourceforge.net>
Acked-by: James Yonan <james@openvpn.net>
push.c

diff --git a/push.c b/push.c
index 9ddc90027a92210fd92db27a69fe5a91c9627199..1320bec5221399656fc34b1fe32583ca99d04720 100644 (file)
--- a/push.c
+++ b/push.c
@@ -177,6 +177,7 @@ send_push_reply (struct context *c)
   static char cmd[] = "PUSH_REPLY";
   const int extra = 64; /* extra space for possible trailing ifconfig and push-continuation */
   const int safe_cap = BCAP (&buf) - extra;
+  bool push_sent = false;
 
   buf_printf (&buf, cmd);
 
@@ -192,6 +193,7 @@ send_push_reply (struct context *c)
                const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
                if (!status)
                  goto fail;
+               push_sent = true;
                multi_push = true;
                buf_reset_len (&buf);
                buf_printf (&buf, cmd);
@@ -217,6 +219,21 @@ send_push_reply (struct context *c)
   if (BLEN (&buf) > sizeof(cmd)-1)
     {
       const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
+      if (!status)
+        goto fail;
+      push_sent = true;
+    }
+
+  /* If nothing have been pushed, send an empty push,
+   * as the client is expecting a response
+   */
+  if (!push_sent)
+    {
+      bool status = false;
+
+      buf_reset_len (&buf);
+      buf_printf (&buf, cmd);
+      status = send_control_channel_string (c, BSTR(&buf), D_PUSH);
       if (!status)
        goto fail;
     }