Skip to contentSkip to conversation

Patches from OpenVPN for Android

PATCH In review Arne Schwabe 2 participants 25 messages Mar 21, 2014 – Mar 26, 2014

lore
Share & tools
lore
#0 lore raw

cover Patches from OpenVPN for Android

To minimise the difference between my local ics-openvpn OpenVPN branch and the official master I am sending the patches which I think should be applied to master but are not yet applied yet.

Arne Schwabe (12):
Fix connecting to localhost on Android
Move the initialization of the environment to the top so c2.es is
initialized
Workaround broken Android 4.4 VpnService API for persist-tun mode Implement an easy parsable log output that allows access to flags of
the log message
Introduce an option to resolve dns names in advance for —remote,
—local and http-proxy
Fix for server selecting address family
Don’t show the connection profile store in options->ce if there is a
connection_list defined.
Add gateway and device to android control messages
Don’t redirect the gateway on Android even if requested Clean up of socket code.
Fix assert when using port-share
Fix client-nat only working is also mss-fix is specified.

 doc/openvpn.8         |   6 +
 src/openvpn/buffer.c  |  38 ++++
 src/openvpn/buffer.h  |  28 ++-
 src/openvpn/error.c   |  28 ++-
 src/openvpn/error.h   |   2 +
 src/openvpn/forward.c |  13 +-
 src/openvpn/init.c    |  60 +++--
 src/openvpn/manage.c  |  48 +++-
 src/openvpn/manage.h  |   5 +
 src/openvpn/openvpn.h |   3 +
 src/openvpn/options.c |  27 ++-
 src/openvpn/options.h |   5 +-
 src/openvpn/ps.c      |   2 +-
 src/openvpn/route.c   |  15 +-
 src/openvpn/socket.c  | 599 ++++++++++++++++++++++++++++++++------------------
 src/openvpn/socket.h  |  45 +++-
 src/openvpn/tun.c     |  29 ++-
 17 files changed, 681 insertions(+), 272 deletions(-)
Signature · 1 line
1.8.5.2 (Apple Git-48)
#1 lore raw

PATCH 1/12 Fix connecting to localhost on Android

Do not protect the link socket when connecting to localhost. Also only call the protect function on valid socket

---
 src/openvpn/socket.c | 21 ++++++++++++++++++---
 src/openvpn/socket.h | 17 +++++++++++++++++
 2 files changed, 35 insertions(+), 3 deletions(-)
src/openvpn/socket.c +18 -3
index 100eedd..91c6af0 100644
@@ -689,17 +689,24 @@ create_socket (struct link_socket *sock)
 
     /* set socket to --mark packets with given value */
     socket_set_mark (sock->sd, sock->mark);
+}
 
 #ifdef TARGET_ANDROID
+static void protect_fd_nonlocal (int fd, const struct sockaddr* addr)
+{
   /* pass socket FD to management interface to pass on to VPNService API
    * as "protected socket" (exempt from being routed into tunnel)
    */
+  if (addr_local (addr)) {
+    msg(M_DEBUG, "Address is local, not protecting socket fd %d", fd);
+    return;
+  }
 
-  management->connection.fdtosend = sock->sd;
+  msg(M_DEBUG, "Protecting socket fd %d", fd);
+  management->connection.fdtosend = fd;
   management_android_control (management, "PROTECTFD", __func__);
-#endif
-
 }
+#endif
 
 /*
  * Functions used for establishing a TCP stream connection.
@@ -935,6 +942,10 @@ openvpn_connect (socket_descriptor_t sd,
 {
   int status = 0;
 
+#ifdef TARGET_ANDROID
+  protect_fd_nonlocal(sd, remote);
+#endif
+
 #ifdef CONNECT_NONBLOCK
   set_nonblock (sd);
   status = connect (sd, remote, af_addr_size(remote->sa_family));
@@ -1788,6 +1799,10 @@ link_socket_init_phase2 (struct link_socket *sock,
 	  phase2_socks_client (sock, sig_info);
 #endif
 	}
+#ifdef TARGET_ANDROID
+      if (sock->sd != -1)
+	protect_fd_nonlocal (sock->sd, &sock->info.lsa->actual.dest.addr.sa);
+#endif
       if (sig_info && sig_info->signal_received)
 	goto done;
     }
src/openvpn/socket.h +17 -0
index e0e0fff..191668f 100644
@@ -598,6 +598,23 @@ addr_defined (const struct openvpn_sockaddr *addr)
     default: return 0;
   }
 }
+
+static inline bool
+addr_local (const struct sockaddr *addr)
+{
+    if (!addr)
+	return false;
+    switch (addr->sa_family) {
+	case AF_INET:
+	    return ((const struct sockaddr_in*)addr)->sin_addr.s_addr == htonl(INADDR_LOOPBACK);
+	case AF_INET6:
+	    return  IN6_IS_ADDR_LOOPBACK(&((const struct sockaddr_in6*)addr)->sin6_addr);
+	default:
+	    return false;
+    }
+}
+
+
 static inline bool
 addr_defined_ipi (const struct link_socket_actual *lsa)
 {
Signature · 1 line
1.8.5.2 (Apple Git-48)
#2 lore raw

[Openvpn-devel] [PATCH applied] Re: Fix connecting to localhost on Android

ACK.

Patch has been applied to the master branch.

(It's only affecting #ifdef ANDROID, and if you tell me it needs it, that's good enough for me)

commit 5118787158eb6fafa3bfef9cb87acb1c76264a90

Author: Arne Schwabe
Date:   Fri Mar 21 14:18:34 2014 +0100
     Fix connecting to localhost on Android

     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/8375
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#3 lore raw

PATCH 2/12 Move the initialization of the environment to the top so c2.es is initialized

In reply to Arne Schwabe
---
 src/openvpn/init.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
src/openvpn/init.c +4 -4
index 3b72b96..c50b5c2 100644
@@ -3339,6 +3339,10 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int
   /* init garbage collection level */
   gc_init (&c->c2.gc);
 
+  /* inherit environmental variables */
+  if (env)
+     do_inherit_env (c, env);
+
   /* signals caught here will abort */
   c->sig->signal_received = 0;
   c->sig->signal_text = NULL;
@@ -3390,10 +3394,6 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int
   if (c->mode == CM_P2P || c->mode == CM_TOP)
     do_option_warnings (c);
 
-  /* inherit environmental variables */
-  if (env)
-    do_inherit_env (c, env);
-
 #ifdef ENABLE_PLUGIN
   /* initialize plugins */
   if (c->mode == CM_P2P || c->mode == CM_TOP)
Signature · 1 line
1.8.5.2 (Apple Git-48)
#4 lore raw

[Openvpn-devel] [PATCH applied] Re: Move the initialization of the environment to the top so c2.es is initialized

ACK, with the explanation given on IRC:

13:54 <@plai> that patch is FOSDEM last year time
13:58 <@plai> Something could fail with an msg (M_FATAL, which calls then
openvpn_exit with calls the exit script hook, which fails if the env is not available

Your patch has been applied to the master branch.

commit ac1c2f259b44d1229a65a3e639b09d57a4e2a53b

Author: Arne Schwabe
Date:   Fri Mar 21 14:18:35 2014 +0100
     Move the initialization of the environment to the top so c2.es is initialized

     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/8372
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#5 lore raw

PATCH 3/12 Workaround broken Android 4.4 VpnService API for persist-tun mode

In reply to Arne Schwabe

In Android 4.4 it is not possible to open a new tun device and then close the old tun device without breaking the whole VPNService stack until the device is reported. This management method ask the UI what method should be taken to ensure the optimal solution for the situation.

---
 src/openvpn/init.c   | 19 +++++++++++--------
 src/openvpn/manage.c | 28 ++++++++++++++++++++++++++++
 src/openvpn/manage.h |  5 +++++
 src/openvpn/tun.c    | 29 ++++++++++++++++++++++++-----
 4 files changed, 68 insertions(+), 13 deletions(-)
src/openvpn/init.c +11 -8
index c50b5c2..21e3052 100644
@@ -1426,10 +1426,10 @@ do_open_tun (struct context *c)
 
 #ifdef TARGET_ANDROID
       /* If we emulate persist-tun on android we still have to open a new tun and
-         then close the old */
+       * then close the old */
       int oldtunfd=-1;
       if (c->c1.tuntap)
-          oldtunfd = c->c1.tuntap->fd;
+	oldtunfd = c->c1.tuntap->fd;
 #endif
 
       /* initialize (but do not open) tun/tap object */
@@ -1463,14 +1463,14 @@ do_open_tun (struct context *c)
         do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
                   c->c1.tuntap, c->plugins, c->c2.es);
       }
-
+#ifdef TARGET_ANDROID
+	/* Store the old fd inside the fd so open_tun can use it */
+	c->c1.tuntap->fd = oldtunfd;
+#endif
       /* open the tun device */
       open_tun (c->options.dev, c->options.dev_type, c->options.dev_node,
 		c->c1.tuntap);
-#ifdef TARGET_ANDROID
-      if (oldtunfd>=0)
-        close(oldtunfd);
-#endif
+
       /* set the hardware address */
       if (c->options.lladdr)
 	  set_lladdr(c->c1.tuntap->actual_name, c->options.lladdr, c->c2.es);
@@ -3767,7 +3767,10 @@ close_context (struct context *c, int sig, unsigned int flags)
     {
       if ((flags & CC_USR1_TO_HUP)
 	  || (c->sig->source == SIG_SOURCE_HARD && (flags & CC_HARD_USR1_TO_HUP)))
-	c->sig->signal_received = SIGHUP;
+        {
+          c->sig->signal_received = SIGHUP;
+          c->sig->signal_text = "close_context usr1 to hup";
+        }
     }
 
   if (!(flags & CC_NO_CLOSE))
src/openvpn/manage.c +28 -0
index 22dbe13..68ee37f 100644
@@ -1864,6 +1864,34 @@ bool management_android_control (struct management *man, const char *command, co
   management_query_user_pass(management, &up , command, GET_USER_PASS_NEED_OK,(void*) 0);
   return strcmp ("ok", up.password)==0;
 }
+
+/*
+ * In Android 4.4 it is not possible to open a new tun device and then close the
+ * old tun device without breaking the whole VPNService stack until the device
+ * is rebooted. This management method ask the UI what method should be taken to
+ * ensure the optimal solution for the situation
+ */
+int managment_android_persisttun_action (struct management *man)
+{
+  struct user_pass up;
+  CLEAR(up);
+  strcpy(up.username,"tunmethod");
+  management_query_user_pass(management, &up , "PERSIST_TUN_ACTION",
+			     GET_USER_PASS_NEED_OK,(void*) 0);
+  if (!strcmp("NOACTION", up.password))
+    return ANDROID_KEEP_OLD_TUN;
+  else if (!strcmp ("OPEN_AFTER_CLOSE", up.password))
+    return ANDROID_OPEN_AFTER_CLOSE;
+  else if (!strcmp ("OPEN_BEFORE_CLOSE", up.password))
+    return ANDROID_OPEN_BEFORE_CLOSE;
+  else
+    msg (M_ERR, "Got unrecognised '%s' from management for PERSIST_TUN_ACTION query", up.password);
+  
+  ASSERT(0);
+  return ANDROID_OPEN_AFTER_CLOSE;
+}
+
+
 #endif
 
 static int
src/openvpn/manage.h +5 -0
index 962b5bc..1c8dda6 100644
@@ -378,6 +378,11 @@ bool management_query_user_pass (struct management *man,
 
 #ifdef TARGET_ANDROID
 bool management_android_control (struct management *man, const char *command, const char *msg);
+
+#define ANDROID_KEEP_OLD_TUN 1
+#define ANDROID_OPEN_AFTER_CLOSE 2
+#define ANDROID_OPEN_BEFORE_CLOSE 3
+int managment_android_persisttun_action (struct management *man);
 #endif
 
 bool management_should_daemonize (struct management *man);
src/openvpn/tun.c +24 -5
index 672486e..4df271d 100644
@@ -1501,19 +1501,38 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
   struct gc_arena gc = gc_new ();
   bool opentun;
 
+  int oldtunfd = tt->fd;
+
   for (i = 0; i < tt->options.dns_len; ++i) {
     management_android_control (management, "DNSSERVER",
-                                print_in_addr_t(tt->options.dns[i], 0, &gc));
+				print_in_addr_t(tt->options.dns[i], 0, &gc));
   }
 
   if(tt->options.domain)
     management_android_control (management, "DNSDOMAIN", tt->options.domain);
 
-  opentun = management_android_control (management, "OPENTUN", dev);
+  int android_method = managment_android_persisttun_action (management);
+
+  /* Android 4.4 workaround */
+  if (oldtunfd >=0 && android_method == ANDROID_OPEN_AFTER_CLOSE)
+    {
+      close(oldtunfd);
+      openvpn_sleep(2);
+    }
+
+  if (oldtunfd >=0  && android_method == ANDROID_KEEP_OLD_TUN) {
+    /* keep the old fd */
+    opentun = true;
+  } else {
+    opentun = management_android_control (management, "OPENTUN", dev);
+    /* Pick up the fd from management interface after calling the
+     * OPENTUN command */
+    tt->fd = management->connection.lastfdreceived;
+    management->connection.lastfdreceived=-1;
+  }
 
-  /* Pick up the fd from management interface after calling the OPENTUN command */
-  tt->fd = management->connection.lastfdreceived;
-  management->connection.lastfdreceived=-1;
+  if (oldtunfd>=0 && android_method == ANDROID_OPEN_BEFORE_CLOSE)
+    close(oldtunfd);
 
   /* Set the actual name to a dummy name */
   tt->actual_name = string_alloc (ANDROID_TUNNAME, NULL);
Signature · 1 line
1.8.5.2 (Apple Git-48)
#6 lore raw

[Openvpn-devel] [PATCH applied] Re: Workaround broken Android 4.4 VpnService API for persist-tun mode

ACK. This has limited impact on "the core" as it's all #ifdef ANDROID only - and is obviously necessary changes, as well contained as possible.

I have amended the commit message somewhat to make it more clear what the patch does.

Patch has been applied to the master branch.

commit c058cbffc182b6618182a3ff8b13c66d01ce937d

Author: Arne Schwabe
Date:   Fri Mar 21 14:18:36 2014 +0100
     Workaround broken Android 4.4 VpnService API for persist-tun mode

     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/8373
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#7 lore raw

PATCH 4/12 Implement an easy parsable log output that allows access to flags of the log message

In reply to Arne Schwabe
---
 doc/openvpn.8         |  6 ++++++
 src/openvpn/error.c   | 28 +++++++++++++++++++++++++++-
 src/openvpn/error.h   |  2 ++
 src/openvpn/options.c |  8 ++++++++
 src/openvpn/options.h |  1 +
 5 files changed, 44 insertions(+), 1 deletion(-)
doc/openvpn.8 +6 -0
index d01c935..3a58317 100644
@@ -2283,6 +2283,12 @@ otherwise would be prepended. In particular, this applies to
 log messages sent to stdout.
 .\"*********************************************************
 .TP
+.B \-\-machine-readable-output
+Always write timestamps and message flags to log messages, even when they
+otherwise would not be prefixed. In particular, this applies to
+log messages sent to stdout.
+.\"*********************************************************
+.TP
 .B \-\-writepid file
 Write OpenVPN's main process ID to
 .B file.
src/openvpn/error.c +27 -1
index ebe9a52..fd9f19d 100644
@@ -82,6 +82,10 @@ static bool std_redir;      /* GLOBAL */
 /* Should messages be written to the syslog? */
 static bool use_syslog;     /* GLOBAL */
 
+/* Should stdout/stderr be be parsable and always be prefixed with time
+ * and message flags */
+static bool machine_readable_output;   /* GLOBAL */
+
 /* Should timestamps be included on messages to stdout/stderr? */
 static bool suppress_timestamps; /* GLOBAL */
 
@@ -155,10 +159,17 @@ set_suppress_timestamps (bool suppressed)
 }
 
 void
+set_machine_readable_output (bool parsable)
+{
+  machine_readable_output = parsable;
+}
+
+void
 error_reset ()
 {
   use_syslog = std_redir = false;
   suppress_timestamps = false;
+  machine_readable_output = false;
   x_debug_level = 1;
   mute_cutoff = 0;
   mute_count = 0;
@@ -330,7 +341,22 @@ void x_msg_va (const unsigned int flags, const char *format, va_list arglist)
 	  FILE *fp = msg_fp(flags);
 	  const bool show_usec = check_debug_level (DEBUG_LEVEL_USEC_TIME);
 
-	  if ((flags & M_NOPREFIX) || suppress_timestamps)
+	  if (machine_readable_output)
+	    {
+	      struct timeval tv;
+	      gettimeofday (&tv, NULL);
+
+	      fprintf (fp, "%lu.%06lu %x %s%s%s%s",
+		       tv.tv_sec,
+		       tv.tv_usec,
+		       flags,
+		       prefix,
+		       prefix_sep,
+		       m1,
+		       "\n");
+
+	    }
+	  else if ((flags & M_NOPREFIX) || suppress_timestamps)
 	    {
 	      fprintf (fp, "%s%s%s%s",
 		       prefix,
src/openvpn/error.h +2 -0
index 27c48b6..1e1f2ac 100644
@@ -194,6 +194,8 @@ void error_reset (void);
 void errors_to_stderr (void);
 
 void set_suppress_timestamps (bool suppressed);
+void set_machine_readable_output (bool parsable);
+
 
 #define SDL_CONSTRAIN (1<<0)
 bool set_debug_level (const int level, const unsigned int flags);
src/openvpn/options.c +8 -0
index c4d9e51..e7259f7 100644
@@ -343,6 +343,7 @@ static const char usage_message[] =
   "--log file      : Output log to file which is created/truncated on open.\n"
   "--log-append file : Append log to file, or create file if nonexistent.\n"
   "--suppress-timestamps : Don't log timestamps to stdout/stderr.\n"
+  "--machine-readable-output : Always log timestamp, message flags to stdout/stderr.\n"
   "--writepid file : Write main process ID to file.\n"
   "--nice n        : Change process priority (>0 = lower, <0 = higher).\n"
   "--echo [parms ...] : Echo parameters to log output.\n"
@@ -1511,6 +1512,7 @@ show_settings (const struct options *o)
   SHOW_INT (inetd);
   SHOW_BOOL (log);
   SHOW_BOOL (suppress_timestamps);
+  SHOW_BOOL (machine_readable_output);
   SHOW_INT (nice);
   SHOW_INT (verbosity);
   SHOW_INT (mute);
@@ -4722,6 +4724,12 @@ add_option (struct options *options,
       options->suppress_timestamps = true;
       set_suppress_timestamps(true);
     }
+  else if (streq (p[0], "machine-readable-output"))
+    {
+      VERIFY_PERMISSION (OPT_P_GENERAL);
+      options->machine_readable_output = true;
+      set_machine_readable_output(true);
+    }
   else if (streq (p[0], "log-append") && p[1])
     {
       VERIFY_PERMISSION (OPT_P_GENERAL);
src/openvpn/options.h +1 -0
index 27bbc14..175918e 100644
@@ -305,6 +305,7 @@ struct options
 
   bool log;
   bool suppress_timestamps;
+  bool machine_readable_output;
   int nice;
   int verbosity;
   int mute;
Signature · 1 line
1.8.5.2 (Apple Git-48)
#8 lore raw

[Openvpn-devel] [PATCH applied] Re: Implement an easy parsable log output that allows access to flags of the log message

ACK. Useful feature, limited side-effects, and has been lingering way too long on the list without anyone protesting it (=lazy ACK applies as well)

Patch has been applied to the master branch.

commit 8f7d5e671a49a316a5fd6392f480d51533fc2747

Author: Arne Schwabe
Date:   Fri Mar 21 14:18:37 2014 +0100
     Implement an easy parsable log output that allows access to flags of the log message

     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/8374
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#9 lore raw

PATCH 5/12 Introduce an option to resolve dns names in advance for —remote, —local and http-proxy

In reply to Arne Schwabe

Also introduce x_gc_addspeical function that allows to add objects with a custom free function to the gc.

Some additional addrinfo cleanup

Conflicts:
src/openvpn/socket.c

---
 src/openvpn/buffer.c  |  38 +++++
 src/openvpn/buffer.h  |  28 +++-
 src/openvpn/init.c    |  33 +++--
 src/openvpn/manage.c  |  18 ++-
 src/openvpn/openvpn.h |   3 +
 src/openvpn/options.c |  12 ++
 src/openvpn/options.h |   4 +-
 src/openvpn/route.c   |   2 +-
 src/openvpn/socket.c  | 395 +++++++++++++++++++++++++++++++++++---------------
 src/openvpn/socket.h  |  22 ++-
 10 files changed, 413 insertions(+), 142 deletions(-)
src/openvpn/buffer.c +38 -0
index fb3b52d..3661141 100644
@@ -372,6 +372,44 @@ x_gc_free (struct gc_arena *a)
 }
 
 /*
+ * Functions to handle special objects in gc_entries
+ */
+
+void
+x_gc_freespecial (struct gc_arena *a)
+{
+  struct gc_entry_special *e;
+  e = a->list_special;
+  a->list_special = NULL;
+
+  while (e != NULL)
+    {
+      struct gc_entry_special *next = e->next;
+      e->free_fnc (e->addr);
+      free(e);
+      e = next;
+    }
+}
+
+void gc_addspecial (void *addr, void (free_function)(void*), struct gc_arena *a)
+{
+  ASSERT(a);
+  struct gc_entry_special *e;
+#ifdef DMALLOC
+  e = (struct gc_entry_special *) openvpn_dmalloc (file, line, sizeof (struct gc_entry_special));
+#else
+  e = (struct gc_entry_special *) malloc (sizeof (struct gc_entry_special));
+#endif
+  check_malloc_return (e);
+  e->free_fnc = free_function;
+  e->addr = addr;
+
+  e->next = a->list_special;
+  a->list_special = e;
+}
+
+
+/*
  * Transfer src arena to dest, resetting src to an empty arena.
  */
 void
src/openvpn/buffer.h +26 -2
index 93efb09..0010c77 100644
@@ -91,6 +91,18 @@ struct gc_entry
                                  *   linked list. */
 };
 
+/**
+ * Gargabe collection entry for a specially allocated structure that needs
+ * a custom free function to be freed like struct addrinfo
+ *
+ */
+struct gc_entry_special
+{
+  struct gc_entry_special *next;
+  void (*free_fnc)(void*);
+  void *addr;
+};
+
 
 /**
  * Garbage collection arena used to keep track of dynamically allocated
@@ -106,6 +118,7 @@ struct gc_arena
 {
   struct gc_entry *list;        /**< First element of the linked list of
                                  *   \c gc_entry structures. */
+  struct gc_entry_special *list_special;
 };
 
 
@@ -153,7 +166,6 @@ char *string_alloc_debug (const char *str, struct gc_arena *gc, const char *file
 struct buffer string_alloc_buf_debug (const char *str, struct gc_arena *gc, const char *file, int line);
 
 #else
-
 struct buffer alloc_buf (size_t size);
 struct buffer alloc_buf_gc (size_t size, struct gc_arena *gc); /* allocate buffer with garbage collection */
 struct buffer clone_buf (const struct buffer* buf);
@@ -163,6 +175,9 @@ struct buffer string_alloc_buf (const char *str, struct gc_arena *gc);
 
 #endif
 
+void gc_addspecial (void *addr, void (*free_function)(void*), struct gc_arena *a);
+
+
 #ifdef BUF_INIT_TRACKING
 #define buf_init(buf, offset) buf_init_debug (buf, offset, __FILE__, __LINE__)
 bool buf_init_debug (struct buffer *buf, int offset, const char *file, int line);
@@ -172,6 +187,11 @@ bool buf_init_debug (struct buffer *buf, int offset, const char *file, int line)
 
 
 /* inline functions */
+inline static void
+gc_freeaddrinfo_callback (void *addr)
+{
+  freeaddrinfo((struct addrinfo*) addr);
+}
 
 static inline bool
 buf_defined (const struct buffer *buf)
@@ -778,6 +798,7 @@ void character_class_debug (void);
 void gc_transfer (struct gc_arena *dest, struct gc_arena *src);
 
 void x_gc_free (struct gc_arena *a);
+void x_gc_freespecial (struct gc_arena *a);
 
 static inline bool
 gc_defined (struct gc_arena *a)
@@ -789,6 +810,7 @@ static inline void
 gc_init (struct gc_arena *a)
 {
   a->list = NULL;
+  a->list_special = NULL;
 }
 
 static inline void
@@ -801,7 +823,7 @@ static inline struct gc_arena
 gc_new (void)
 {
   struct gc_arena ret;
-  ret.list = NULL;
+  gc_init (&ret);
   return ret;
 }
 
@@ -810,6 +832,8 @@ gc_free (struct gc_arena *a)
 {
   if (a->list)
     x_gc_free (a);
+  if (a->list_special)
+    x_gc_freespecial(a);
 }
 
 static inline void
src/openvpn/init.c +22 -11
index 21e3052..c39646d 100644
@@ -1,4 +1,4 @@
-/*
+    /*
  *  OpenVPN -- An application to securely tunnel IP networks
  *             over a single TCP/UDP port, with support for SSL/TLS-based
  *             session authentication and key exchange,
@@ -131,7 +131,7 @@ management_callback_proxy_cmd (void *arg, const char **p)
           msg (M_WARN, "HTTP proxy support is not available");
 #else
           struct http_proxy_options *ho;
-          if (ce->proto != PROTO_TCP && ce->proto != PROTO_TCP_CLIENT )            {
+         if (ce->proto != PROTO_TCP && ce->proto != PROTO_TCP_CLIENT )            {
               msg (M_WARN, "HTTP proxy support only works for TCP based connections");
               return false;
             }
@@ -306,11 +306,10 @@ init_connection_list (struct context *c)
 /*
  * Clear the remote address list
  */
-static void clear_remote_addrlist (struct link_socket_addr *lsa)
+static void clear_remote_addrlist (struct link_socket_addr *lsa, bool free)
 {
-    if (lsa->remote_list) {
-        freeaddrinfo(lsa->remote_list);
-    }
+    if (lsa->remote_list && free)
+      freeaddrinfo(lsa->remote_list);
     lsa->remote_list = NULL;
     lsa->current_remote = NULL;
 }
@@ -348,9 +347,12 @@ next_connection_entry (struct context *c)
              * this is broken probably ever since connection lists and multiple
              * remote existed
              */
-
             if (!c->options.persist_remote_ip)
-                clear_remote_addrlist (&c->c1.link_socket_addr);
+	      {
+		/* close_instance should have cleared the addrinfo objects */
+		ASSERT (c->c1.link_socket_addr.current_remote == NULL);
+		ASSERT (c->c1.link_socket_addr.remote_list == NULL);
+	      }
             else
                 c->c1.link_socket_addr.current_remote =
                 c->c1.link_socket_addr.remote_list;
@@ -2688,6 +2690,7 @@ do_init_socket_1 (struct context *c, const int mode)
 			   c->options.ce.local_port,
 			   c->options.ce.remote,
 			   c->options.ce.remote_port,
+			   c->c1.dns_cache,
 			   c->options.ce.proto,
 			   c->options.ce.af,
 			   c->options.ce.bind_ipv6_only,
@@ -2908,7 +2911,7 @@ do_close_link_socket (struct context *c)
            || c->options.no_advance))
          )))
     {
-      clear_remote_addrlist(&c->c1.link_socket_addr);
+      clear_remote_addrlist(&c->c1.link_socket_addr, !c->options.resolve_in_advance);
     }
 
     /* Clear the remote actual address when persist_remote_ip is not in use */
@@ -2916,8 +2919,9 @@ do_close_link_socket (struct context *c)
       CLEAR (c->c1.link_socket_addr.actual);
 
   if (!(c->sig->signal_received == SIGUSR1 && c->options.persist_local_ip)) {
-    if (c->c1.link_socket_addr.bind_local)
-        freeaddrinfo(c->c1.link_socket_addr.bind_local);
+    if (c->c1.link_socket_addr.bind_local && !c->options.resolve_in_advance)
+	freeaddrinfo(c->c1.link_socket_addr.bind_local);
+
     c->c1.link_socket_addr.bind_local=NULL;
   }
 }
@@ -3359,6 +3363,13 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int
 	goto sig;
     }
 
+  if (c->options.resolve_in_advance)
+    {
+      do_preresolve (c);
+      if (IS_SIG (c))
+	goto sig;
+    }
+
   /* map in current connection entry */
   next_connection_entry (c);
 
src/openvpn/manage.c +13 -5
index 68ee37f..0cc185b 100644
@@ -1568,9 +1568,9 @@ man_listen (struct management *man)
       else
 #endif
 	{
-	  man->connection.sd_top = create_socket_tcp (AF_INET);
+	  man->connection.sd_top = create_socket_tcp (man->settings.local->ai_family);
 	  socket_bind (man->connection.sd_top, man->settings.local,
-                       AF_INET, "MANAGEMENT", true);
+                       man->settings.local->ai_family, "MANAGEMENT", false);
 	}
 
       /*
@@ -2151,8 +2151,14 @@ man_settings_init (struct man_settings *ms,
 	    }
 	  else
 	    {
-              int status = openvpn_getaddrinfo(GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL,
-                                               addr, port, 0, NULL, AF_INET, &ms->local);
+	      int status;
+	      int resolve_flags = GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL;
+
+	      if (! (flags & MF_CONNECT_AS_CLIENT))
+		  resolve_flags |= GETADDR_PASSIVE;
+
+              status = openvpn_getaddrinfo (resolve_flags, addr, port, 0,
+					    NULL, AF_UNSPEC, &ms->local);
               ASSERT(status==0);
 	    }
 	}
@@ -2179,6 +2185,8 @@ man_settings_init (struct man_settings *ms,
 static void
 man_settings_close (struct man_settings *ms)
 {
+  if (ms->local)
+    freeaddrinfo(ms->local);
   free (ms->write_peer_info_file);
   CLEAR (*ms);
 }
@@ -2616,7 +2624,7 @@ management_post_tunnel_open (struct management *man, const in_addr_t tun_local_i
       int ret;
 
       ia.s_addr = htonl(tun_local_ip);
-      ret = openvpn_getaddrinfo(0, inet_ntoa(ia), NULL, 0, NULL,
+      ret = openvpn_getaddrinfo(GETADDR_PASSIVE, inet_ntoa(ia), NULL, 0, NULL,
                                 AF_INET, &man->settings.local);
       ASSERT (ret==0);
       man_connection_init (man);
src/openvpn/openvpn.h +3 -0
index 606a4f5..7ad6c55 100644
@@ -166,6 +166,9 @@ struct context_1
   /* tunnel session keys */
   struct key_schedule ks;
 
+  /* preresolved and cached host names */
+  struct cached_dns_entry *dns_cache;
+
   /* persist crypto sequence number to/from file */
   struct packet_id_persist pid_persist;
 
src/openvpn/options.c +12 -0
index e7259f7..cb2cf95 100644
@@ -796,6 +796,7 @@ init_options (struct options *o, const bool init_gc)
   o->ce.mssfix = MSSFIX_DEFAULT;
   o->route_delay_window = 30;
   o->resolve_retry_seconds = RESOLV_RETRY_INFINITE;
+  o->resolve_in_advance = false;
   o->proto_force = -1;
 #ifdef ENABLE_OCC
   o->occ = true;
@@ -1369,6 +1370,7 @@ show_connection_entry (const struct connection_entry *o)
   SHOW_BOOL (remote_float);
   SHOW_BOOL (bind_defined);
   SHOW_BOOL (bind_local);
+  SHOW_BOOL (bind_ipv6_only);
   SHOW_INT (connect_retry_seconds);
   SHOW_INT (connect_timeout);
 
@@ -1494,6 +1496,7 @@ show_settings (const struct options *o)
 #endif
 
   SHOW_INT (resolve_retry_seconds);
+  SHOW_BOOL (resolve_in_advance);
 
   SHOW_STR (username);
   SHOW_STR (groupname);
@@ -4540,6 +4543,15 @@ add_option (struct options *options,
       else
 	options->resolve_retry_seconds = positive_atoi (p[1]);
     }
+  else if (streq (p[0], "preresolve") || streq (p[0], "ip-remote-hint"))
+    {
+      VERIFY_PERMISSION (OPT_P_GENERAL);
+      options->resolve_in_advance = true;
+      /* Note the ip-remote-hint and the argument p[1] are for
+	 backward compatibility */
+      if (p[1])
+	options->ip_remote_hint=p[1];
+    }
   else if (streq (p[0], "connect-retry") && p[1])
     {
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
src/openvpn/options.h +3 -1
index 175918e..ec1d091 100644
@@ -90,7 +90,7 @@ struct connection_entry
   sa_family_t af;
   const char* local_port;
   bool local_port_defined;
-  const char* remote_port;
+  const char *remote_port;
   const char *local;
   const char *remote;
   bool remote_float;
@@ -278,6 +278,8 @@ struct options
 #endif
 
   int resolve_retry_seconds;    /* If hostname resolve fails, retry for n seconds */
+  bool resolve_in_advance;
+  const char *ip_remote_hint;
 
   struct tuntap_options tuntap_options;
 
src/openvpn/route.c +1 -1
index 392e248..1dd14fb 100644
@@ -638,6 +638,7 @@ init_route_list (struct route_list *rl,
 	else
 	  {
             struct addrinfo* curele;
+            gc_addspecial(netlist, &gc_freeaddrinfo_callback, &gc);
             for (curele	= netlist; curele; curele = curele->ai_next)
 	      {
                 struct route_ipv4 *new;
@@ -647,7 +648,6 @@ init_route_list (struct route_list *rl,
                 new->next = rl->routes;
                 rl->routes = new;
 	      }
-            freeaddrinfo(netlist);
 	  }
       }
   }
src/openvpn/socket.c +276 -119

486 lines not on this page · raw message

src/openvpn/socket.h +19 -3
index 191668f..8d4316b 100644
@@ -77,6 +77,16 @@ struct openvpn_sockaddr
   } addr;
 };
 
+/* struct to hold preresolved host names */
+struct cached_dns_entry {
+    const char *hostname;
+    const char *servname;
+    int ai_family;
+    int flags;
+    struct addrinfo *ai;
+    struct cached_dns_entry *next;
+};
+
 /* actual address of remote, based on source address of received packets */
 struct link_socket_actual
 {
@@ -188,6 +198,7 @@ struct link_socket
   const char *remote_port;
   const char *local_host;
   const char *local_port;
+  struct cached_dns_entry *dns_cache;
   bool bind_local;
 
 # define INETD_NONE   0
@@ -208,8 +219,6 @@ struct link_socket
 
   int mtu;                      /* OS discovered MTU, or 0 if unknown */
 
-  bool did_resolve_remote;
-
 # define SF_USE_IP_PKTINFO (1<<0)
 # define SF_TCP_NODELAY (1<<1)
 # define SF_PORT_SHARE (1<<2)
@@ -298,6 +307,8 @@ int openvpn_connect (socket_descriptor_t sd,
 		     int connect_timeout,
 		     volatile int *signal_received);
 
+
+
 /*
  * Initialize link_socket object.
  */
@@ -308,6 +319,7 @@ link_socket_init_phase1 (struct link_socket *sock,
 			 const char *local_port,
 			 const char *remote_host,
 			 const char *remote_port,
+			 struct cached_dns_entry *dns_cache,
 			 int proto,
 			 sa_family_t af,
 			 bool bind_ipv6_only,
@@ -340,6 +352,8 @@ void link_socket_init_phase2 (struct link_socket *sock,
 			      const struct frame *frame,
 			      struct signal_info *sig_info);
 
+void do_preresolve(struct context *c);
+
 void socket_adjust_frame_parameters (struct frame *frame, int proto);
 
 void frame_adjust_path_mtu (struct frame *frame, int pmtu, int proto);
@@ -514,6 +528,8 @@ bool unix_socket_get_peer_uid_gid (const socket_descriptor_t sd, int *uid, int *
 #define GETADDR_PASSIVE               (1<<10)
 #define GETADDR_DATAGRAM              (1<<11)
 
+#define GETADDR_CACHE_MASK		GETADDR_DATAGRAM|GETADDR_PASSIVE
+
 in_addr_t getaddr (unsigned int flags,
 		   const char *hostname,
 		   int resolve_retry_seconds,
@@ -905,7 +921,7 @@ link_socket_set_outgoing_addr (const struct buffer *buf,
 	   &&
 	   /* address undef or address == remote or --float */
 	   (info->remote_float ||
-	       (!lsa->remote_list || addrlist_match_proto (&act->dest, lsa->remote_list, info->proto))
+	    (!lsa->remote_list || addrlist_match_proto (&act->dest, lsa->remote_list, info->proto))
 	    )
 	  )
 	{
Signature · 1 line
1.8.5.2 (Apple Git-48)
#10 lore raw

PATCH v2 5/12 Introduce an option to resolve dns names in advance for —remote, —local and http-proxy

Also introduce x_gc_addspeical function that allows to add objects with a custom free function to the gc.

Some additional addrinfo cleanup

---
 src/openvpn/buffer.c  |  38 +++++
 src/openvpn/buffer.h  |  28 +++-
 src/openvpn/init.c    |  33 +++--
 src/openvpn/manage.c  |  18 ++-
 src/openvpn/openvpn.h |   3 +
 src/openvpn/options.c |  12 ++
 src/openvpn/options.h |   4 +-
 src/openvpn/route.c   |   2 +-
 src/openvpn/socket.c  | 401 +++++++++++++++++++++++++++++++++++---------------
 src/openvpn/socket.h  |  22 ++-
 10 files changed, 419 insertions(+), 142 deletions(-)
src/openvpn/buffer.c +38 -0
index fb3b52d..3661141 100644
@@ -372,6 +372,44 @@ x_gc_free (struct gc_arena *a)
 }
 
 /*
+ * Functions to handle special objects in gc_entries
+ */
+
+void
+x_gc_freespecial (struct gc_arena *a)
+{
+  struct gc_entry_special *e;
+  e = a->list_special;
+  a->list_special = NULL;
+
+  while (e != NULL)
+    {
+      struct gc_entry_special *next = e->next;
+      e->free_fnc (e->addr);
+      free(e);
+      e = next;
+    }
+}
+
+void gc_addspecial (void *addr, void (free_function)(void*), struct gc_arena *a)
+{
+  ASSERT(a);
+  struct gc_entry_special *e;
+#ifdef DMALLOC
+  e = (struct gc_entry_special *) openvpn_dmalloc (file, line, sizeof (struct gc_entry_special));
+#else
+  e = (struct gc_entry_special *) malloc (sizeof (struct gc_entry_special));
+#endif
+  check_malloc_return (e);
+  e->free_fnc = free_function;
+  e->addr = addr;
+
+  e->next = a->list_special;
+  a->list_special = e;
+}
+
+
+/*
  * Transfer src arena to dest, resetting src to an empty arena.
  */
 void
src/openvpn/buffer.h +26 -2
index 93efb09..0010c77 100644
@@ -91,6 +91,18 @@ struct gc_entry
                                  *   linked list. */
 };
 
+/**
+ * Gargabe collection entry for a specially allocated structure that needs
+ * a custom free function to be freed like struct addrinfo
+ *
+ */
+struct gc_entry_special
+{
+  struct gc_entry_special *next;
+  void (*free_fnc)(void*);
+  void *addr;
+};
+
 
 /**
  * Garbage collection arena used to keep track of dynamically allocated
@@ -106,6 +118,7 @@ struct gc_arena
 {
   struct gc_entry *list;        /**< First element of the linked list of
                                  *   \c gc_entry structures. */
+  struct gc_entry_special *list_special;
 };
 
 
@@ -153,7 +166,6 @@ char *string_alloc_debug (const char *str, struct gc_arena *gc, const char *file
 struct buffer string_alloc_buf_debug (const char *str, struct gc_arena *gc, const char *file, int line);
 
 #else
-
 struct buffer alloc_buf (size_t size);
 struct buffer alloc_buf_gc (size_t size, struct gc_arena *gc); /* allocate buffer with garbage collection */
 struct buffer clone_buf (const struct buffer* buf);
@@ -163,6 +175,9 @@ struct buffer string_alloc_buf (const char *str, struct gc_arena *gc);
 
 #endif
 
+void gc_addspecial (void *addr, void (*free_function)(void*), struct gc_arena *a);
+
+
 #ifdef BUF_INIT_TRACKING
 #define buf_init(buf, offset) buf_init_debug (buf, offset, __FILE__, __LINE__)
 bool buf_init_debug (struct buffer *buf, int offset, const char *file, int line);
@@ -172,6 +187,11 @@ bool buf_init_debug (struct buffer *buf, int offset, const char *file, int line)
 
 
 /* inline functions */
+inline static void
+gc_freeaddrinfo_callback (void *addr)
+{
+  freeaddrinfo((struct addrinfo*) addr);
+}
 
 static inline bool
 buf_defined (const struct buffer *buf)
@@ -778,6 +798,7 @@ void character_class_debug (void);
 void gc_transfer (struct gc_arena *dest, struct gc_arena *src);
 
 void x_gc_free (struct gc_arena *a);
+void x_gc_freespecial (struct gc_arena *a);
 
 static inline bool
 gc_defined (struct gc_arena *a)
@@ -789,6 +810,7 @@ static inline void
 gc_init (struct gc_arena *a)
 {
   a->list = NULL;
+  a->list_special = NULL;
 }
 
 static inline void
@@ -801,7 +823,7 @@ static inline struct gc_arena
 gc_new (void)
 {
   struct gc_arena ret;
-  ret.list = NULL;
+  gc_init (&ret);
   return ret;
 }
 
@@ -810,6 +832,8 @@ gc_free (struct gc_arena *a)
 {
   if (a->list)
     x_gc_free (a);
+  if (a->list_special)
+    x_gc_freespecial(a);
 }
 
 static inline void
src/openvpn/init.c +22 -11
index 21e3052..c39646d 100644
@@ -1,4 +1,4 @@
-/*
+    /*
  *  OpenVPN -- An application to securely tunnel IP networks
  *             over a single TCP/UDP port, with support for SSL/TLS-based
  *             session authentication and key exchange,
@@ -131,7 +131,7 @@ management_callback_proxy_cmd (void *arg, const char **p)
           msg (M_WARN, "HTTP proxy support is not available");
 #else
           struct http_proxy_options *ho;
-          if (ce->proto != PROTO_TCP && ce->proto != PROTO_TCP_CLIENT )            {
+         if (ce->proto != PROTO_TCP && ce->proto != PROTO_TCP_CLIENT )            {
               msg (M_WARN, "HTTP proxy support only works for TCP based connections");
               return false;
             }
@@ -306,11 +306,10 @@ init_connection_list (struct context *c)
 /*
  * Clear the remote address list
  */
-static void clear_remote_addrlist (struct link_socket_addr *lsa)
+static void clear_remote_addrlist (struct link_socket_addr *lsa, bool free)
 {
-    if (lsa->remote_list) {
-        freeaddrinfo(lsa->remote_list);
-    }
+    if (lsa->remote_list && free)
+      freeaddrinfo(lsa->remote_list);
     lsa->remote_list = NULL;
     lsa->current_remote = NULL;
 }
@@ -348,9 +347,12 @@ next_connection_entry (struct context *c)
              * this is broken probably ever since connection lists and multiple
              * remote existed
              */
-
             if (!c->options.persist_remote_ip)
-                clear_remote_addrlist (&c->c1.link_socket_addr);
+	      {
+		/* close_instance should have cleared the addrinfo objects */
+		ASSERT (c->c1.link_socket_addr.current_remote == NULL);
+		ASSERT (c->c1.link_socket_addr.remote_list == NULL);
+	      }
             else
                 c->c1.link_socket_addr.current_remote =
                 c->c1.link_socket_addr.remote_list;
@@ -2688,6 +2690,7 @@ do_init_socket_1 (struct context *c, const int mode)
 			   c->options.ce.local_port,
 			   c->options.ce.remote,
 			   c->options.ce.remote_port,
+			   c->c1.dns_cache,
 			   c->options.ce.proto,
 			   c->options.ce.af,
 			   c->options.ce.bind_ipv6_only,
@@ -2908,7 +2911,7 @@ do_close_link_socket (struct context *c)
            || c->options.no_advance))
          )))
     {
-      clear_remote_addrlist(&c->c1.link_socket_addr);
+      clear_remote_addrlist(&c->c1.link_socket_addr, !c->options.resolve_in_advance);
     }
 
     /* Clear the remote actual address when persist_remote_ip is not in use */
@@ -2916,8 +2919,9 @@ do_close_link_socket (struct context *c)
       CLEAR (c->c1.link_socket_addr.actual);
 
   if (!(c->sig->signal_received == SIGUSR1 && c->options.persist_local_ip)) {
-    if (c->c1.link_socket_addr.bind_local)
-        freeaddrinfo(c->c1.link_socket_addr.bind_local);
+    if (c->c1.link_socket_addr.bind_local && !c->options.resolve_in_advance)
+	freeaddrinfo(c->c1.link_socket_addr.bind_local);
+
     c->c1.link_socket_addr.bind_local=NULL;
   }
 }
@@ -3359,6 +3363,13 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int
 	goto sig;
     }
 
+  if (c->options.resolve_in_advance)
+    {
+      do_preresolve (c);
+      if (IS_SIG (c))
+	goto sig;
+    }
+
   /* map in current connection entry */
   next_connection_entry (c);
 
src/openvpn/manage.c +13 -5
index 8097905..7215caf 100644
@@ -1568,9 +1568,9 @@ man_listen (struct management *man)
       else
 #endif
 	{
-	  man->connection.sd_top = create_socket_tcp (AF_INET);
+	  man->connection.sd_top = create_socket_tcp (man->settings.local->ai_family);
 	  socket_bind (man->connection.sd_top, man->settings.local,
-                       AF_INET, "MANAGEMENT", true);
+                       man->settings.local->ai_family, "MANAGEMENT", false);
 	}
 
       /*
@@ -2151,8 +2151,14 @@ man_settings_init (struct man_settings *ms,
 	    }
 	  else
 	    {
-              int status = openvpn_getaddrinfo(GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL,
-                                               addr, port, 0, NULL, AF_INET, &ms->local);
+	      int status;
+	      int resolve_flags = GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL;
+
+	      if (! (flags & MF_CONNECT_AS_CLIENT))
+		  resolve_flags |= GETADDR_PASSIVE;
+
+              status = openvpn_getaddrinfo (resolve_flags, addr, port, 0,
+					    NULL, AF_UNSPEC, &ms->local);
               ASSERT(status==0);
 	    }
 	}
@@ -2179,6 +2185,8 @@ man_settings_init (struct man_settings *ms,
 static void
 man_settings_close (struct man_settings *ms)
 {
+  if (ms->local)
+    freeaddrinfo(ms->local);
   free (ms->write_peer_info_file);
   CLEAR (*ms);
 }
@@ -2616,7 +2624,7 @@ management_post_tunnel_open (struct management *man, const in_addr_t tun_local_i
       int ret;
 
       ia.s_addr = htonl(tun_local_ip);
-      ret = openvpn_getaddrinfo(0, inet_ntoa(ia), NULL, 0, NULL,
+      ret = openvpn_getaddrinfo(GETADDR_PASSIVE, inet_ntoa(ia), NULL, 0, NULL,
                                 AF_INET, &man->settings.local);
       ASSERT (ret==0);
       man_connection_init (man);
src/openvpn/openvpn.h +3 -0
index 606a4f5..7ad6c55 100644
@@ -166,6 +166,9 @@ struct context_1
   /* tunnel session keys */
   struct key_schedule ks;
 
+  /* preresolved and cached host names */
+  struct cached_dns_entry *dns_cache;
+
   /* persist crypto sequence number to/from file */
   struct packet_id_persist pid_persist;
 
src/openvpn/options.c +12 -0
index e7259f7..cb2cf95 100644
@@ -796,6 +796,7 @@ init_options (struct options *o, const bool init_gc)
   o->ce.mssfix = MSSFIX_DEFAULT;
   o->route_delay_window = 30;
   o->resolve_retry_seconds = RESOLV_RETRY_INFINITE;
+  o->resolve_in_advance = false;
   o->proto_force = -1;
 #ifdef ENABLE_OCC
   o->occ = true;
@@ -1369,6 +1370,7 @@ show_connection_entry (const struct connection_entry *o)
   SHOW_BOOL (remote_float);
   SHOW_BOOL (bind_defined);
   SHOW_BOOL (bind_local);
+  SHOW_BOOL (bind_ipv6_only);
   SHOW_INT (connect_retry_seconds);
   SHOW_INT (connect_timeout);
 
@@ -1494,6 +1496,7 @@ show_settings (const struct options *o)
 #endif
 
   SHOW_INT (resolve_retry_seconds);
+  SHOW_BOOL (resolve_in_advance);
 
   SHOW_STR (username);
   SHOW_STR (groupname);
@@ -4540,6 +4543,15 @@ add_option (struct options *options,
       else
 	options->resolve_retry_seconds = positive_atoi (p[1]);
     }
+  else if (streq (p[0], "preresolve") || streq (p[0], "ip-remote-hint"))
+    {
+      VERIFY_PERMISSION (OPT_P_GENERAL);
+      options->resolve_in_advance = true;
+      /* Note the ip-remote-hint and the argument p[1] are for
+	 backward compatibility */
+      if (p[1])
+	options->ip_remote_hint=p[1];
+    }
   else if (streq (p[0], "connect-retry") && p[1])
     {
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
src/openvpn/options.h +3 -1
index 175918e..ec1d091 100644
@@ -90,7 +90,7 @@ struct connection_entry
   sa_family_t af;
   const char* local_port;
   bool local_port_defined;
-  const char* remote_port;
+  const char *remote_port;
   const char *local;
   const char *remote;
   bool remote_float;
@@ -278,6 +278,8 @@ struct options
 #endif
 
   int resolve_retry_seconds;    /* If hostname resolve fails, retry for n seconds */
+  bool resolve_in_advance;
+  const char *ip_remote_hint;
 
   struct tuntap_options tuntap_options;
 
src/openvpn/route.c +1 -1
index 392e248..1dd14fb 100644
@@ -638,6 +638,7 @@ init_route_list (struct route_list *rl,
 	else
 	  {
             struct addrinfo* curele;
+            gc_addspecial(netlist, &gc_freeaddrinfo_callback, &gc);
             for (curele	= netlist; curele; curele = curele->ai_next)
 	      {
                 struct route_ipv4 *new;
@@ -647,7 +648,6 @@ init_route_list (struct route_list *rl,
                 new->next = rl->routes;
                 rl->routes = new;
 	      }
-            freeaddrinfo(netlist);
 	  }
       }
   }
src/openvpn/socket.c +282 -119

492 lines not on this page · raw message

src/openvpn/socket.h +19 -3
index 191668f..8d4316b 100644
@@ -77,6 +77,16 @@ struct openvpn_sockaddr
   } addr;
 };
 
+/* struct to hold preresolved host names */
+struct cached_dns_entry {
+    const char *hostname;
+    const char *servname;
+    int ai_family;
+    int flags;
+    struct addrinfo *ai;
+    struct cached_dns_entry *next;
+};
+
 /* actual address of remote, based on source address of received packets */
 struct link_socket_actual
 {
@@ -188,6 +198,7 @@ struct link_socket
   const char *remote_port;
   const char *local_host;
   const char *local_port;
+  struct cached_dns_entry *dns_cache;
   bool bind_local;
 
 # define INETD_NONE   0
@@ -208,8 +219,6 @@ struct link_socket
 
   int mtu;                      /* OS discovered MTU, or 0 if unknown */
 
-  bool did_resolve_remote;
-
 # define SF_USE_IP_PKTINFO (1<<0)
 # define SF_TCP_NODELAY (1<<1)
 # define SF_PORT_SHARE (1<<2)
@@ -298,6 +307,8 @@ int openvpn_connect (socket_descriptor_t sd,
 		     int connect_timeout,
 		     volatile int *signal_received);
 
+
+
 /*
  * Initialize link_socket object.
  */
@@ -308,6 +319,7 @@ link_socket_init_phase1 (struct link_socket *sock,
 			 const char *local_port,
 			 const char *remote_host,
 			 const char *remote_port,
+			 struct cached_dns_entry *dns_cache,
 			 int proto,
 			 sa_family_t af,
 			 bool bind_ipv6_only,
@@ -340,6 +352,8 @@ void link_socket_init_phase2 (struct link_socket *sock,
 			      const struct frame *frame,
 			      struct signal_info *sig_info);
 
+void do_preresolve(struct context *c);
+
 void socket_adjust_frame_parameters (struct frame *frame, int proto);
 
 void frame_adjust_path_mtu (struct frame *frame, int pmtu, int proto);
@@ -514,6 +528,8 @@ bool unix_socket_get_peer_uid_gid (const socket_descriptor_t sd, int *uid, int *
 #define GETADDR_PASSIVE               (1<<10)
 #define GETADDR_DATAGRAM              (1<<11)
 
+#define GETADDR_CACHE_MASK		GETADDR_DATAGRAM|GETADDR_PASSIVE
+
 in_addr_t getaddr (unsigned int flags,
 		   const char *hostname,
 		   int resolve_retry_seconds,
@@ -905,7 +921,7 @@ link_socket_set_outgoing_addr (const struct buffer *buf,
 	   &&
 	   /* address undef or address == remote or --float */
 	   (info->remote_float ||
-	       (!lsa->remote_list || addrlist_match_proto (&act->dest, lsa->remote_list, info->proto))
+	    (!lsa->remote_list || addrlist_match_proto (&act->dest, lsa->remote_list, info->proto))
 	    )
 	  )
 	{
Signature · 1 line
1.8.3.4 (Apple Git-47)
#11 lore raw

[PATCH applied] Re: Introduce an option to resolve dns names in advance for —remote, —local and http-proxy

ACK, with some whitespace fixes (undoing spurious changes, cleaning up others), and swapping the if/else branches in socket.c/do_preresolve_host() for easier readability (no functional change) as agreed on IRC.

t_client tested OK (without --preresolve).

Patch has been applied to the master branch.

commit e719a0535345db8f0781c0b80408ca5417597469

Author: Arne Schwabe
Date:   Sun Mar 23 13:13:06 2014 +0100
     Introduce an option to resolve dns names in advance for —remote, —local and http-proxy

     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/8386
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#12 lore raw

PATCH 6/12 Fix for server selecting address family

In reply to Arne Schwabe
---
 src/openvpn/socket.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)
src/openvpn/socket.c +12 -12
index bf793f4..97f6756 100644
@@ -1509,21 +1509,10 @@ create_new_socket (struct link_socket* sock)
       /* clear destination set by set_actual_address */
       CLEAR(sock->info.lsa->actual.dest);
     }
-
-  /*
-   * Create the socket early if socket should be bound
-   */
-  if (sock->bind_local)
-    {
-      create_socket (sock);
-
-      if (sock->bind_local)
-          bind_local(sock);
-    }
-
 }
 
 
+
 /* bind socket if necessary */
 void
 link_socket_init_phase1 (struct link_socket *sock,
@@ -1946,6 +1935,17 @@ link_socket_init_phase2 (struct link_socket *sock,
       /* If socket has not already been created create it now */
       if (sock->sd == SOCKET_UNDEFINED)
 	{
+          /* If we have no --remote and have still not figured out the
+           * protocol family to use we will use the first of the bind */
+          if (sock->bind_local && sock->info.lsa->bind_local
+              && !sock->info.lsa->actual.ai_family && !sock->remote_host)
+          {
+            msg (M_WARN, "Could not determine IPv4/IPv6 protocol. Using %s",
+                 addr_family_name(sock->info.lsa->bind_local->ai_family));
+            set_actual_address(&sock->info.lsa->actual, sock->info.lsa->bind_local);
+
+          }
+
 	  if (sock->info.lsa->actual.ai_family)
 	    {
 	      create_socket (sock);
Signature · 1 line
1.8.5.2 (Apple Git-48)
#13 lore raw

[Openvpn-devel] [PATCH applied] Re: Fix for server selecting address family

I take this as "fixes fallout of the of the grand socket.c restructuring", so ACK, even if I won't claim to truly understand under which conditions this makes a difference.

Patch has been applied to the master branch.

commit 45184804c477aed2ae91ce23d6606da1bfccbaa7

Author: Arne Schwabe
Date:   Fri Mar 21 14:18:39 2014 +0100
     Fix for server selecting address family

     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/8371
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#14 lore raw

PATCH 7/12 Don’t show the connection profile store in options->ce if there is a connection_list defined.

In reply to Arne Schwabe

Entries in options->ce are never used and overwritten by the first usable connection profile on initialisation.

---
 src/openvpn/options.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
src/openvpn/options.c +5 -2
index cb2cf95..c5746c5 100644
@@ -1406,8 +1406,6 @@ show_connection_entry (const struct connection_entry *o)
 static void
 show_connection_entries (const struct options *o)
 {
-  msg (D_SHOW_PARMS, "Connection profiles [default]:");
-  show_connection_entry (&o->ce);
  if (o->connection_list)
    {
      const struct connection_list *l = o->connection_list;
@@ -1418,6 +1416,11 @@ show_connection_entries (const struct options *o)
 	 show_connection_entry (l->array[i]);
        }
    }
+ else
+   {
+     msg (D_SHOW_PARMS, "Connection profiles [default]:");
+     show_connection_entry (&o->ce);
+   }
   msg (D_SHOW_PARMS, "Connection profiles END");
 }
 
Signature · 1 line
1.8.5.2 (Apple Git-48)
#15 lore raw

[PATCH applied] Re: Don’t show the connection profile store in options->ce if there is a connection_list defined.

ACK. "Makes sense" :-)

Your patch has been applied to the master branch.

commit 98e24cc7e8ce3dafada43e46aef32a3d6a7a4f27

Author: Arne Schwabe
Date:   Fri Mar 21 14:18:40 2014 +0100
     Don't show the connection profile store in options->ce if there is a connection_list defined.

     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/8377
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#16 lore raw

PATCH 8/12 Add gateway and device to android control messages

In reply to Arne Schwabe
---
 src/openvpn/route.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
src/openvpn/route.c +6 -3
index 1dd14fb..13eed5f 100644
@@ -1311,9 +1311,12 @@ add_route (struct route_ipv4 *r,
   status = openvpn_execve_check (&argv, es, 0, "ERROR: Linux route add command failed");
 
 #elif defined (TARGET_ANDROID)
-  struct buffer out = alloc_buf_gc (64, &gc);
+  struct buffer out = alloc_buf_gc (128, &gc);
 
-  buf_printf (&out, "%s %s", network, netmask);
+  if (rgi)
+    buf_printf (&out, "%s %s %s dev %s", network, netmask, gateway, rgi->iface);
+  else
+    buf_printf (&out, "%s %s %s", network, netmask, gateway);
   management_android_control (management, "ROUTE", buf_bptr(&out));
 
 #elif defined (WIN32)
@@ -1593,7 +1596,7 @@ add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int fla
 #elif defined (TARGET_ANDROID)
     struct buffer out = alloc_buf_gc (64, &gc);
 
-    buf_printf (&out, "%s/%d", network, r6->netbits);
+    buf_printf (&out, "%s/%d %s", network, r6->netbits, device);
 
     management_android_control (management, "ROUTE6", buf_bptr(&out));
 
Signature · 1 line
1.8.5.2 (Apple Git-48)
#17 lore raw

[Openvpn-devel] [PATCH applied] Re: Add gateway and device to android control messages

ACK, on the basis of "this is all happening inside #ifdef ANDROID, and from the description on IRC" (necessary to enable the GUI to properly exclude routes-to-eth0 by recognizing routes-to-eth0 in the first place, like the vpn gateway in the "redirect-gateway" case).

Patch has been applied to the master branch.

commit 928e341073cbe5aef4496e0b55aae5c6335b1fc3

Author: Arne Schwabe
Date:   Fri Mar 21 14:18:41 2014 +0100
     Add gateway and device to android control messages

     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/8368
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#18 lore raw

PATCH 9/12 Don’t redirect the gateway on Android even if requested

In reply to Arne Schwabe

Routing loops are avoided using the VPNService API

---
 src/openvpn/route.c | 4 ++++
 1 file changed, 4 insertions(+)
src/openvpn/route.c +4 -0
index 13eed5f..eb5fb46 100644
@@ -530,8 +530,10 @@ add_block_local (struct route_list *rl)
     {
       size_t i;
 
+#ifndef TARGET_ANDROID
       /* add bypass for gateway addr */
       add_bypass_address (&rl->spec.bypass, rl->rgi.gateway.addr);
+#endif
 
       /* block access to local subnet */
       add_block_local_item (rl, &rl->rgi.gateway, rl->spec.remote_endpoint);
@@ -822,6 +824,7 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u
 	}
       else
 	{
+#ifndef TARGET_ANDROID
 	  bool local = BOOL_CAST(rl->flags & RG_LOCAL);
 	  if (rl->flags & RG_AUTO_LOCAL) {
 	    const int tla = rl->spec.remote_host_local;
@@ -854,6 +857,7 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u
 		dmsg (D_ROUTE, "ROUTE remote_host protocol differs from tunneled");
 	      }
 	    }
+#endif
 
 	  /* route DHCP/DNS server traffic through original default gateway */
 	  add_bypass_routes (&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags, &rl->rgi, es);
Signature · 1 line
1.8.5.2 (Apple Git-48)
#19 lore raw

Re: [Openvpn-devel] [PATCH 09/12] Don???t redirect the gateway on Android even if requested

Hi,

as agreed on IRC, this is postponed for the time being, to see if a way can be found to handle this without more #if(n)def ANDROID in route.c (like, via options.c)

gert

Quoted 51 lines · Arne Schwabe

Routing loops are avoided using the VPNService API

---
 src/openvpn/route.c | 4 ++++
 1 file changed, 4 insertions(+)
src/openvpn/route.c +4 -0
index 13eed5f..eb5fb46 100644
@@ -530,8 +530,10 @@ add_block_local (struct route_list *rl)
     {
       size_t i;
 
+#ifndef TARGET_ANDROID
       /* add bypass for gateway addr */
       add_bypass_address (&rl->spec.bypass, rl->rgi.gateway.addr);
+#endif
 
       /* block access to local subnet */
       add_block_local_item (rl, &rl->rgi.gateway, rl->spec.remote_endpoint);
@@ -822,6 +824,7 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u
 	}
       else
 	{
+#ifndef TARGET_ANDROID
 	  bool local = BOOL_CAST(rl->flags & RG_LOCAL);
 	  if (rl->flags & RG_AUTO_LOCAL) {
 	    const int tla = rl->spec.remote_host_local;
@@ -854,6 +857,7 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u
 		dmsg (D_ROUTE, "ROUTE remote_host protocol differs from tunneled");
 	      }
 	    }
+#endif
 
 	  /* route DHCP/DNS server traffic through original default gateway */
 	  add_bypass_routes (&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags, &rl->rgi, es);
Signature · 13 lines
1.8.5.2 (Apple Git-48)


------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/13534_NeoTech
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel
Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#20 lore raw

PATCH 10/12 Clean up of socket code.

In reply to Arne Schwabe

Let socket_create take struct addrinfo as argument and use the entries of addrinfo to create the socket.

---
 src/openvpn/manage.c |   6 +-
 src/openvpn/socket.c | 187 +++++++++++++++++++++++++--------------------------
 src/openvpn/socket.h |   6 +-
 3 files changed, 95 insertions(+), 104 deletions(-)
src/openvpn/manage.c +3 -3
index 0cc185b..f5b3ad5 100644
@@ -1568,9 +1568,9 @@ man_listen (struct management *man)
       else
 #endif
 	{
-	  man->connection.sd_top = create_socket_tcp (man->settings.local->ai_family);
+	  man->connection.sd_top = create_socket_tcp (man->settings.local);
 	  socket_bind (man->connection.sd_top, man->settings.local,
-                       man->settings.local->ai_family, "MANAGEMENT", false);
+		       man->settings.local->ai_family, "MANAGEMENT", false);
 	}
 
       /*
@@ -1635,7 +1635,7 @@ man_connect (struct management *man)
   else
 #endif
     {
-      man->connection.sd_cli = create_socket_tcp (AF_INET);
+      man->connection.sd_cli = create_socket_tcp (man->settings.local);
       status = openvpn_connect (man->connection.sd_cli,
 				man->settings.local->ai_addr,
 				5,
src/openvpn/socket.c +91 -96

330 lines not on this page · raw message

src/openvpn/socket.h +1 -5
index 8d4316b..5132953 100644
@@ -91,10 +91,6 @@ struct cached_dns_entry {
 struct link_socket_actual
 {
   /*int dummy;*/ /* add offset to force a bug if dest not explicitly dereferenced */
- int ai_family;	/* PF_xxx */
- int ai_socktype;	/* SOCK_xxx */
- int ai_protocol;	/* 0 or IPPROTO_xxx for IPv4 and IPv6 */
-
 
   struct openvpn_sockaddr dest;
 #if ENABLE_IP_PKTINFO
@@ -473,7 +469,7 @@ bool ip_or_dns_addr_safe (const char *addr, const bool allow_fqdn);
 bool mac_addr_safe (const char *mac_addr);
 bool ipv6_addr_safe (const char *ipv6_text_addr);
 
-socket_descriptor_t create_socket_tcp (int af);
+socket_descriptor_t create_socket_tcp (struct addrinfo*);
 
 socket_descriptor_t socket_do_accept (socket_descriptor_t sd,
 				      struct link_socket_actual *act,
Signature · 1 line
1.8.5.2 (Apple Git-48)
#21 lore raw

[Openvpn-devel] [PATCH applied] Re: Clean up of socket code.

ACK. Stared at the code for a while, discussed on IRC, with this small change to bring "use TCP to talk to a socks proxy, then use UDP to connect to OpenVPN server" back to working state:

src/openvpn/socket.c +2 -1
index d2f8240..b769171 100644
@@ -872,7 +872,8 @@ create_socket (struct link_socket* sock, struct addrinfo* addr)
 	   * currently resolve two remote addresses is not supported,
 	   * TODO: Rewrite the whole resolve_remote */
 	  struct addrinfo addrinfo_tmp = *addr;
-	  addr->ai_protocol = IPPROTO_TCP;
+	  addrinfo_tmp.ai_socktype = SOCK_STREAM;
+	  addrinfo_tmp.ai_protocol = IPPROTO_TCP;
 	  sock->ctrl_sd = create_socket_tcp (&addrinfo_tmp);
 	}
 #endif

Patch has been applied to the master branch.

commit 7dbe04de74ea01bd77461ec82253dd769381c711

Author: Arne Schwabe
Date:   Fri Mar 21 14:18:43 2014 +0100
     Clean up of socket code.

     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/8370
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#22 lore raw

PATCH 11/12 Fix assert when using port-share

In reply to Arne Schwabe
---
 src/openvpn/ps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
src/openvpn/ps.c +1 -1
index 901a094..6807aac 100644
@@ -803,7 +803,7 @@ port_share_open (const char *host,
    * Get host's IP address
    */
 
-  status = openvpn_getaddrinfo (GETADDR_RESOLVE|GETADDR_HOST_ORDER|GETADDR_FATAL,
+  status = openvpn_getaddrinfo (GETADDR_RESOLVE|GETADDR_FATAL,
                                  host, port,  0, NULL, AF_INET, &ai);
   ASSERT (status==0);
   hostaddr = *((struct sockaddr_in*) ai->ai_addr);
Signature · 1 line
1.8.5.2 (Apple Git-48)
#23 lore raw

[Openvpn-devel] [PATCH applied] Re: Fix assert when using port-share

Your patch has been applied to the master branch.

commit f1da227574c6b2e3a75a38ac6f9a196be0ad3071

Author: Arne Schwabe
Date:   Fri Mar 21 14:18:44 2014 +0100
     Fix assert when using port-share

     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/8369
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#24 lore raw

PATCH 12/12 Fix client-nat only working is also mss-fix is specified.

In reply to Arne Schwabe

Also make sure that with this fix compiling without ENABLE_CLIENT_NAT does not result in always checking the ip header

---
 src/openvpn/forward.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
src/openvpn/forward.c +10 -3
index 0ec00f3..453ab3f 100644
@@ -1017,6 +1017,10 @@ process_ip_header (struct context *c, unsigned int flags, struct buffer *buf)
   if (!c->options.passtos)
     flags &= ~PIPV4_PASSTOS;
 #endif
+#ifdef ENABLE_CLIENT_NAT
+  if (!c->options.client_nat)
+    flags &= ~PIPV4_CLIENT_NAT;
+#endif
   if (!c->options.route_gateway_via_dhcp)
     flags &= ~PIPV4_EXTRACT_DHCP_ROUTER;
 
@@ -1026,11 +1030,14 @@ process_ip_header (struct context *c, unsigned int flags, struct buffer *buf)
        * The --passtos and --mssfix options require
        * us to examine the IPv4 header.
        */
+      if (flags & (PIP_MSSFIX|PIPV4_EXTRACT_DHCP_ROUTER
 #if PASSTOS_CAPABILITY
-      if (flags & (PIPV4_PASSTOS|PIP_MSSFIX))
-#else
-      if (flags & PIP_MSSFIX)
+                   | PIPV4_PASSTOS
+#endif
+#ifdef ENABLE_CLIENT_NAT
+                   | PIPV4_CLIENT_NAT
 #endif
+                   ))
 	{
 	  struct buffer ipbuf = *buf;
 	  if (is_ipv4 (TUNNEL_TYPE (c->c1.tuntap), &ipbuf))
Signature · 1 line
1.8.5.2 (Apple Git-48)