]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
svn merge -r 614:615 $SO/patches/openvpn-2-1_alpha3a-tcpbind
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Sat, 15 Oct 2005 09:43:36 +0000 (09:43 +0000)
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Sat, 15 Oct 2005 09:43:36 +0000 (09:43 +0000)
Added --bind option for TCP client connections (Ewan Bhamrah Harley).
Pre-2.1-beta3

git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@623 e7ae566f-a301-0410-adde-c780ea21d3b5

ChangeLog
openvpn.8
options.c
options.h
socket.c

index 04c8567a89cb718de218cfb4200bca6e551e8cc3..87abbff15f17cad1965a770ce800c0a305d012fb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,7 @@ $Id$
   contains a CA cert or not (Mathias Sundman).
 * Merged --capath patch (Thomas Noel).
 * Merged --multihome patch.
+* Added --bind option for TCP client connections (Ewan Bhamrah Harley).
 * NOTE TO PACKAGE MAINTAINERS: Moved "plugin" directory to "plugins".
   This is to work around a strange problem with the "make dist"
   target in the automake-generated makefile, where the target tries to
index 4e4c81c9502c25ce164db551f709c087dd7317c5..7655524a1696223c439538d6aed32c0d18f94f41 100644 (file)
--- a/openvpn.8
+++ b/openvpn.8
@@ -190,6 +190,7 @@ openvpn \- secure IP tunnel daemon.
 [\ \fB\-\-nice\fR\ \fIn\fR\ ]
 [\ \fB\-\-no\-iv\fR\ ]
 [\ \fB\-\-no\-replay\fR\ ]
+[\ \fB\-\-bind\fR\ ]
 [\ \fB\-\-nobind\fR\ ]
 [\ \fB\-\-ns\-cert\-type\fR\ \fIclient|server\fR\ ]
 [\ \fB\-\-passtos\fR\ ]
@@ -443,7 +444,7 @@ server capability.
 .\"*********************************************************
 .TP
 .B --local host
-Local host name or IP address.
+Local host name or IP address for bind.
 If specified, OpenVPN will bind to this address only.
 If unspecified, OpenVPN will bind to all interfaces.
 .\"*********************************************************
@@ -727,13 +728,23 @@ Previous versions used port 5000 as the default.
 .\"*********************************************************
 .TP
 .B --lport port
-TCP/UDP port number for local.
+TCP/UDP port number for bind.
 .\"*********************************************************
 .TP
 .B --rport port
 TCP/UDP port number for remote.
 .\"*********************************************************
 .TP
+.B --bind
+Bind to local address and port. This is the default unless any of 
+.B --proto tcp-client
+,
+.B --http-proxy
+or
+.B --socks-proxy
+are used.
+.\"*********************************************************
+.TP
 .B --nobind
 Do not bind to local address and port.  The IP stack will allocate
 a dynamic port for returning packets.  Since the value of the dynamic port
index c9ed15df8fe4d4f6a8a14c41fa750577e132fc5d..99e5cc0364c162f8d47dbbd679e317b179a89402 100644 (file)
--- a/options.c
+++ b/options.c
@@ -87,7 +87,7 @@ static const char usage_message[] =
   "--version       : Show copyright and version information.\n"
   "\n"
   "Tunnel Options:\n"
-  "--local host    : Local host name or ip address.\n"
+  "--local host    : Local host name or ip address. Implies --bind.\n"
   "--remote host [port] : Remote host name or ip address.\n"
   "--remote-random : If multiple --remote options specified, choose one randomly.\n"
   "--mode m        : Major mode, m = 'p2p' (default, point-to-point) or 'server'.\n"
@@ -121,8 +121,17 @@ static const char usage_message[] =
   "--ipchange cmd  : Execute shell command cmd on remote ip address initial\n"
   "                  setting or change -- execute as: cmd ip-address port#\n"
   "--port port     : TCP/UDP port # for both local and remote.\n"
-  "--lport port    : TCP/UDP port # for local (default=%d).\n"
+  "--lport port    : TCP/UDP port # for local (default=%d). Implies --bind.\n"
   "--rport port    : TCP/UDP port # for remote (default=%d).\n"
+  "--bind          : Bind to local address and port. (This is the default unless\n"
+  "                  --proto tcp-client"
+#ifdef ENABLE_HTTP_PROXY
+                   " or --http-proxy"
+#endif
+#ifdef ENABLE_SOCKS
+                   " or --socks-proxy"
+#endif
+                   " is used).\n"
   "--nobind        : Do not bind to local address and port.\n"
   "--dev tunX|tapX : tun/tap device (X can be omitted for dynamic device.\n"
   "--dev-type dt   : Which device type are we using? (dt = tun or tap) Use\n"
@@ -688,6 +697,20 @@ setenv_settings (struct env_set *es, const struct options *o)
          setenv_int (es, remote_port_string, o->remote_list->array[i].port);
        }
     }
+#ifdef ENABLE_HTTP_PROXY
+    if (o->http_proxy_options)
+      {
+        setenv_str (es, "http_proxy_server", o->http_proxy_options->server);
+        setenv_int (es, "http_proxy_port", o->http_proxy_options->port);
+      }
+#endif
+#ifdef ENABLE_SOCKS
+    if(o->socks_proxy_server)
+      {
+        setenv_str (es, "socks_proxy_server", o->socks_proxy_server);
+        setenv_int (es, "socks_proxy_port", o->socks_proxy_port);
+      }
+#endif
 }
 
 static in_addr_t
@@ -997,6 +1020,7 @@ show_settings (const struct options *o)
   SHOW_INT (remote_port);
   SHOW_BOOL (remote_float);
   SHOW_STR (ipchange);
+  SHOW_BOOL (bind_defined);
   SHOW_BOOL (bind_local);
   SHOW_STR (dev);
   SHOW_STR (dev_type);
@@ -1395,12 +1419,29 @@ options_postprocess (struct options *options, bool first_time)
   if (string_defined_equal (options->ifconfig_local, options->ifconfig_remote_netmask))
     msg (M_USAGE, "local and remote/netmask --ifconfig addresses must be different");
 
+  if (options->bind_defined && !options->bind_local)
+    msg (M_USAGE, "--bind and --nobind can't be used together");
+
+  if (options->local && !options->bind_local)
+    msg (M_USAGE, "--local and --nobind don't make sense when used together");
+
   if (options->local_port_defined && !options->bind_local)
     msg (M_USAGE, "--lport and --nobind don't make sense when used together");
 
   if (!options->remote_list && !options->bind_local)
     msg (M_USAGE, "--nobind doesn't make sense unless used with --remote");
 
+  if (options->proto == PROTO_TCPv4_CLIENT && !options->local && !options->local_port_defined && !options->bind_defined)
+    options->bind_local = false;
+
+#ifdef ENABLE_SOCKS
+  if (options->proto == PROTO_UDPv4 && options->socks_proxy_server && !options->local && !options->local_port_defined && !options->bind_defined)
+    options->bind_local = false;
+#endif
+
+  if (!options->bind_local)
+    options->local_port = 0;
+
   /*
    * Check for consistency of management options
    */
@@ -3521,6 +3562,11 @@ add_option (struct options *options,
       options->port_option_used = true;
       options->remote_port = port;
     }
+  else if (streq (p[0], "bind"))
+    {
+      VERIFY_PERMISSION (OPT_P_GENERAL);
+      options->bind_defined = true;
+    }
   else if (streq (p[0], "nobind"))
     {
       VERIFY_PERMISSION (OPT_P_GENERAL);
index bb4175974e55e94f8102c9e4950b0eae774d7eb1..69a2f0445af5dcbf6189045ecfaa82b635374359 100644 (file)
--- a/options.h
+++ b/options.h
@@ -120,6 +120,7 @@ struct options
   struct remote_list *remote_list;
   bool remote_random;
   const char *ipchange;
+  bool bind_defined;
   bool bind_local;
   const char *dev;
   const char *dev_type;
index 35d38a1bb58dc814272f29165bace051ab71aaf0..ce54cb86a1c3ed2594a51a4e6bc152aa3fa29e2c 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -685,8 +685,26 @@ socket_listen_accept (socket_descriptor_t sd,
   return new_sd;
 }
 
+static void
+socket_bind (socket_descriptor_t sd,
+             struct openvpn_sockaddr *local)
+{
+  struct gc_arena gc = gc_new ();
+
+  if (bind (sd, (struct sockaddr *) &local->sa, sizeof (local->sa)))
+    {
+      const int errnum = openvpn_errno_socket ();
+      msg (M_FATAL, "TCP/UDP: Socket bind failed on local address %s: %s",
+           print_sockaddr (local, &gc),
+           strerror_ts (errnum, &gc));
+    }
+  gc_free (&gc);
+}
+
 static void
 socket_connect (socket_descriptor_t *sd,
+                struct openvpn_sockaddr *local,
+                bool bind_local,
                struct openvpn_sockaddr *remote,
                struct remote_list *remote_list,
                const char *remote_dynamic,
@@ -727,6 +745,8 @@ socket_connect (socket_descriptor_t *sd,
        }
 
       *sd = create_socket_tcp ();
+      if (bind_local)
+        socket_bind (*sd, local);
       update_remote (remote_dynamic, remote, remote_changed);
     }
 
@@ -796,14 +816,12 @@ resolve_bind_local (struct link_socket *sock)
   /* bind to local address/port */
   if (sock->bind_local)
     {
-      if (bind (sock->sd, (struct sockaddr *) &sock->info.lsa->local.sa,
-               sizeof (sock->info.lsa->local.sa)))
-       {
-         const int errnum = openvpn_errno_socket ();
-         msg (M_FATAL, "TCP/UDP: Socket bind failed on local address %s: %s",
-              print_sockaddr (&sock->info.lsa->local, &gc),
-              strerror_ts (errnum, &gc));
-       }
+#ifdef ENABLE_SOCKS
+      if (sock->socks_proxy && sock->info.proto == PROTO_UDPv4)
+          socket_bind (sock->ctrl_sd, &sock->info.lsa->local);
+      else
+#endif
+          socket_bind (sock->sd, &sock->info.lsa->local);
     }
   gc_free (&gc);
 }
@@ -1070,10 +1088,6 @@ link_socket_init_phase1 (struct link_socket *sock,
       else
        sock->bind_local = true;
     }
-  else if (sock->info.proto == PROTO_TCPv4_CLIENT)
-    {
-      sock->bind_local = false;
-    }
 
   /* were we started by inetd or xinetd? */
   if (sock->inetd)
@@ -1176,6 +1190,8 @@ link_socket_init_phase2 (struct link_socket *sock,
       else if (sock->info.proto == PROTO_TCPv4_CLIENT)
        {
          socket_connect (&sock->sd,
+                          &sock->info.lsa->local,
+                          sock->bind_local,
                          &sock->info.lsa->actual.dest,
                          sock->remote_list,
                          remote_dynamic,
@@ -1214,6 +1230,8 @@ link_socket_init_phase2 (struct link_socket *sock,
       else if (sock->info.proto == PROTO_UDPv4 && sock->socks_proxy)
        {
          socket_connect (&sock->ctrl_sd,
+                          &sock->info.lsa->local,
+                          sock->bind_local,
                          &sock->info.lsa->actual.dest,
                          NULL,
                          remote_dynamic,