Below is a patch against 2.0 that adds support for the local and lport
options on tcp-client connections (also udp connections via a socks proxy).

I'm not sure what the default should be if none of local, lport or nobind
are given. As posted, the patch assumes nobind in this case (consistent with
typical TCP client behaviour) but dropping the patch to options.c will cause
local binding to INADDR_ANY and the default port - nobind must specifically
be given to get nobind behaviour (consistent with current udp connection
behaviour).

I've tested this on linux and windows but it's all pretty generic so I
wouldn't expect any problems on other platforms.

Rgds
Ewan Bhamrah Harley

diff -Naur openvpn-2.0/options.c openvpn-2.0-ebh/options.c
--- openvpn-2.0/options.c       2005-04-16 23:03:15.000000000 +0100
+++ openvpn-2.0-ebh/options.c   2005-07-11 17:29:15.000000000 +0100
@@ -1330,6 +1330,14 @@
   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_local = false;
+
+#ifdef ENABLE_SOCKS
+  if (options->proto == PROTO_UDPv4 && options->socks_proxy_server &&
!options->local && !options->local_port_defined)
+    options->bind_local = false;
+#endif
+
   /*
    * Check for consistency of management options
    */
diff -Naur openvpn-2.0/socket.c openvpn-2.0-ebh/socket.c
--- openvpn-2.0/socket.c        2005-04-11 04:43:58.000000000 +0100
+++ openvpn-2.0-ebh/socket.c    2005-07-11 17:29:15.000000000 +0100
@@ -619,7 +619,26 @@
 }

 static void
+socket_bind (socket_descriptor_t sd,
+             struct sockaddr_in *local)
+{
+  struct gc_arena gc = gc_new ();
+
+  if (bind (sd, (struct sockaddr *) local,
+                sizeof (struct sockaddr_in)))
+    {
+      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 sockaddr_in *local,
+               bool bind_local,
                struct sockaddr_in *remote,
                struct remote_list *remote_list,
                const char *remote_dynamic,
@@ -660,6 +679,8 @@
        }

       *sd = create_socket_tcp ();
+      if (bind_local)
+        socket_bind (*sd, local);
       update_remote (remote_dynamic, remote, remote_changed);
     }

@@ -729,14 +750,12 @@
   /* bind to local address/port */
   if (sock->bind_local)
     {
-      if (bind (sock->sd, (struct sockaddr *) &sock->info.lsa->local,
-               sizeof (sock->info.lsa->local)))
-       {
-         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);
 }
@@ -990,10 +1009,12 @@
       else
        sock->bind_local = true;
     }
+#if 0
   else if (sock->info.proto == PROTO_TCPv4_CLIENT)
     {
       sock->bind_local = false;
     }
+#endif

   /* were we started by inetd or xinetd? */
   if (sock->inetd)
@@ -1096,6 +1117,8 @@
       else if (sock->info.proto == PROTO_TCPv4_CLIENT)
        {
          socket_connect (&sock->sd,
+                         &sock->info.lsa->local,
+                         sock->bind_local,
                          &sock->info.lsa->actual,
                          sock->remote_list,
                          remote_dynamic,
@@ -1134,6 +1157,8 @@
       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,
                          NULL,
                          remote_dynamic,

Reply via email to