Hi,

  this is simple patch implementing internal openvpn ping over OCC channel.
  Important difference of OCC ping (OCC_PING) to existing one is that
this one is replied on the other side of the channel (with
OCC_PING_REPLY),
  thus making it possible to configure clients and server ping and
ping-restart timeout differently.
  This might be usefull if someone is trying to combine mobile and
non-mobile clients on one openvpn server. Non-mobile clients might
want to have
  reliable link and ping more frequently compared to mobile clients
that might not want this (ie. to save battery on android ;-).

  OCC ping replaces 'normal' ping if activated via occ-ping directive,
and thus fully integrates with all ping/ping-restart/... directives.
  Additionaly I've implemented occ-ping-compat mode, that will send
OCC_REQUEST instread of OCC_PING. All OCC clients will then reply to
this
  request with OCC_REPLY message - it might be usefull to enable this
on server, to stay backward compatible with older non occ-ping
clients.

  Please review it ;)
  Thanks.

Sam


diff -ur openvpn-2.2.2/occ.c openvpn-2.2.2-dev/occ.c
--- openvpn-2.2.2/occ.c 2011-12-13 17:58:56.000000000 +0100
+++ openvpn-2.2.2-dev/occ.c     2012-05-27 19:23:15.000000000 +0200
@@ -302,6 +302,29 @@
       dmsg (D_PACKET_CONTENT, "SENT OCC_EXIT");
       doit = true;
       break;
+
+    case OCC_PING:
+      if (c->options.occ_ping_compat)
+        {
+          if (!buf_write_u8 (&c->c2.buf, OCC_REQUEST))
+           break;
+          dmsg (D_PACKET_CONTENT, "SENT OCC_REQUEST (compat OCC_PING)");
+        }
+      else
+        {
+          if (!buf_write_u8 (&c->c2.buf, OCC_PING))
+           break;
+          dmsg (D_PACKET_CONTENT, "SENT OCC_PING");
+        }
+      doit = true;
+      break;
+
+    case OCC_PING_REPLY:
+      if (!buf_write_u8 (&c->c2.buf, OCC_PING_REPLY))
+       break;
+      dmsg (D_PACKET_CONTENT, "SENT OCC_PING_REPLY");
+      doit = true;
+      break;
     }

   if (doit)
@@ -384,6 +407,14 @@
       c->sig->signal_received = SIGTERM;
       c->sig->signal_text = "remote-exit";
       break;
+
+    case OCC_PING:
+      dmsg (D_PACKET_CONTENT, "RECEIVED OCC_PING");
+      c->c2.occ_op = OCC_PING_REPLY;
+      break;
+    case OCC_PING_REPLY:
+      dmsg (D_PACKET_CONTENT, "RECEIVED OCC_PING_REPLY");
+      break;
     }
   c->c2.buf.len = 0; /* don't pass packet on */
 }
diff -ur openvpn-2.2.2/occ.h openvpn-2.2.2-dev/occ.h
--- openvpn-2.2.2/occ.h 2011-04-26 10:33:04.000000000 +0200
+++ openvpn-2.2.2-dev/occ.h     2012-05-25 23:07:18.000000000 +0200
@@ -70,6 +70,13 @@
 #define OCC_EXIT               6

 /*
+ * OCC based ping
+ */
+#define OCC_PING               7
+#define OCC_PING_REPLY         8
+
+
+/*
  * Used to conduct a load test command sequence
  * of UDP connection for empirical MTU measurement.
  */
diff -ur openvpn-2.2.2/options.c openvpn-2.2.2-dev/options.c
--- openvpn-2.2.2/options.c     2011-12-13 17:58:56.000000000 +0100
+++ openvpn-2.2.2-dev/options.c 2012-05-25 23:20:55.000000000 +0200
@@ -229,6 +229,11 @@
   "--ping-timer-rem: Run the --ping-exit/--ping-restart timer only if
we have a\n"
   "                  remote address.\n"
   "--ping n        : Ping remote once every n seconds over TCP/UDP port.\n"
+#ifdef ENABLE_OCC
+  "--occ-ping      : Ping using internal OCC protocol.\n"
+  "--occ-ping-compat : Use backward compatible OCC ping.\n"
+  "                  Use for clients without occ-ping support.\n"
+#endif
 #if ENABLE_IP_PKTINFO
   "--multihome     : Configure a multi-homed UDP server.\n"
 #endif
@@ -1235,8 +1240,11 @@
   SHOW_BOOL (ping_timer_remote);
   SHOW_INT (remap_sigusr1);
 #ifdef ENABLE_OCC
+  SHOW_BOOL (occ_ping);
+  SHOW_BOOL (occ_ping_compat);
   SHOW_INT (explicit_exit_notification);
 #endif
+
   SHOW_BOOL (persist_tun);
   SHOW_BOOL (persist_local_ip);
   SHOW_BOOL (persist_remote_ip);
@@ -4529,6 +4537,16 @@
       options->ping_timer_remote = true;
     }
 #ifdef ENABLE_OCC
+  else if (streq (p[0], "occ-ping"))
+    {
+      VERIFY_PERMISSION (OPT_P_TIMER);
+      options->occ_ping = true;
+    }
+  else if (streq (p[0], "occ-ping-compat"))
+    {
+      VERIFY_PERMISSION (OPT_P_TIMER);
+      options->occ_ping_compat = true;
+    }
   else if (streq (p[0], "explicit-exit-notify"))
     {
       VERIFY_PERMISSION (OPT_P_EXPLICIT_NOTIFY);
diff -ur openvpn-2.2.2/options.h openvpn-2.2.2-dev/options.h
--- openvpn-2.2.2/options.h     2011-12-13 17:58:56.000000000 +0100
+++ openvpn-2.2.2-dev/options.h 2012-05-25 23:04:14.000000000 +0200
@@ -239,6 +239,11 @@
   int ping_send_timeout;        /* Send a TCP/UDP ping to remote
every n seconds */
   int ping_rec_timeout;         /* Expect a TCP/UDP ping from remote
at least once every n seconds */
   bool ping_timer_remote;       /* Run ping timer only if we have a
remote address */
+#ifdef ENABLE_OCC
+  bool occ_ping;               /* Enable OCC ping */
+  bool occ_ping_compat;                /* Enable OCC ping compatibility mode */
+#endif
+
   bool tun_ipv6;                /* Build tun dev that supports IPv6 */

 # define PING_UNDEF   0
diff -ur openvpn-2.2.2/ping-inline.h openvpn-2.2.2-dev/ping-inline.h
--- openvpn-2.2.2/ping-inline.h 2011-04-26 10:33:04.000000000 +0200
+++ openvpn-2.2.2-dev/ping-inline.h     2012-05-27 18:50:40.000000000 +0200
@@ -53,7 +53,14 @@
       && event_timeout_trigger (&c->c2.ping_send_interval,
                                &c->c2.timeval,
                                !TO_LINK_DEF(c) ? ETT_DEFAULT : 1))
-    check_ping_send_dowork (c);
+    {
+#ifdef ENABLE_OCC
+      if(c->options.occ_ping)
+        c->c2.occ_op = OCC_PING;
+      else
+#endif
+        check_ping_send_dowork (c);
+    }
 }

 #endif

Reply via email to