This delays error reporting from config parsing to resolving of host addresses. 
But it allows statements like

remote openvpn.example.org openvpn
port https
management localhost ntp

Signed-off-by: Arne Schwabe <a...@rfc2549.org>
---
 doc/openvpn.8         |    8 +--
 src/openvpn/init.c    |   20 +++-----
 src/openvpn/manage.c  |   19 ++++---
 src/openvpn/manage.h  |    2 +-
 src/openvpn/options.c |  128 +++++++++++------------------------------------
 src/openvpn/options.h |   14 +++---
 src/openvpn/proxy.c   |   12 ++---
 src/openvpn/proxy.h   |    6 +--
 src/openvpn/ps.c      |   29 ++++++-----
 src/openvpn/ps.h      |    2 +-
 src/openvpn/route.c   |    4 +-
 src/openvpn/socket.c  |  131 ++++++++++++++++++++++---------------------------
 src/openvpn/socket.h  |   20 +++-----
 src/openvpn/socks.c   |   30 +++++++++--
 src/openvpn/socks.h   |    6 +--
 15 files changed, 183 insertions(+), 248 deletions(-)

diff --git a/doc/openvpn.8 b/doc/openvpn.8
index b53d383..99b4d22 100644
--- a/doc/openvpn.8
+++ b/doc/openvpn.8
@@ -668,18 +668,18 @@ peer on its new IP address.
 .\"*********************************************************
 .TP
 .B \-\-port port
-TCP/UDP port number for both local and remote.  The current
+TCP/UDP port number or port name for both local and remote.  The current
 default of 1194 represents the official IANA port number
 assignment for OpenVPN and has been used since version 2.0-beta17.
 Previous versions used port 5000 as the default.
 .\"*********************************************************
 .TP
 .B \-\-lport port
-TCP/UDP port number for bind.
+TCP/UDP port number or name for bind.
 .\"*********************************************************
 .TP
 .B \-\-rport port
-TCP/UDP port number for remote.
+TCP/UDP port number or name for remote.
 .\"*********************************************************
 .TP
 .B \-\-bind
@@ -5859,7 +5859,7 @@ Set on program initiation and reset on SIGHUP.
 .\"*********************************************************
 .TP
 .B local_port
-The local port number, specified by
+The local port number or name, specified by
 .B \-\-port
 or
 .B \-\-lport.
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index ba15fe3..41ff038 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -125,13 +125,6 @@ management_callback_proxy_cmd (void *arg, const char **p)
     ret = true;
   else if (p[2] && p[3])
     {
-      const int port = atoi(p[3]);
-      if (!legal_ipv4_port (port))
-        {
-          msg (M_WARN, "Bad proxy port number: %s", p[3]);
-          return false;
-        }
-
       if (streq (p[1], "HTTP"))
         {
 #ifndef ENABLE_HTTP_PROXY
@@ -146,7 +139,7 @@ management_callback_proxy_cmd (void *arg, const char **p)
             }
           ho = init_http_proxy_options_once (&ce->http_proxy_options, gc);
           ho->server = string_alloc (p[2], gc);
-          ho->port = port;
+          ho->port = string_alloc (p[3], gc);
           ho->retry = true;
           ho->auth_retry = (p[4] && streq (p[4], "nct") ? PAR_NCT : PAR_ALL);
           ret = true;
@@ -158,7 +151,7 @@ management_callback_proxy_cmd (void *arg, const char **p)
           msg (M_WARN, "SOCKS proxy support is not available");
 #else
           ce->socks_proxy_server = string_alloc (p[2], gc);
-          ce->socks_proxy_port = port;
+          ce->socks_proxy_port = p[3];
           ret = true;
 #endif
         }
@@ -227,8 +220,7 @@ management_callback_remote_cmd (void *arg, const char **p)
        }
       else if (!strcmp(p[1], "MOD") && p[2] && p[3])
        {
-         const int port = atoi(p[3]);
-         if (strlen(p[2]) < RH_HOST_LEN && legal_ipv4_port(port))
+         if (strlen(p[2]) < RH_HOST_LEN && strlen(p[3]) < RH_PORT_LEN)
            {
              struct remote_host_store *rhs = c->options.rh_store;
              if (!rhs)
@@ -237,8 +229,10 @@ management_callback_remote_cmd (void *arg, const char **p)
                  c->options.rh_store = rhs;
                }
              strncpynt(rhs->host, p[2], RH_HOST_LEN);
+              strncpynt(rhs->port, p[3], RH_PORT_LEN);
+
              ce->remote = rhs->host;
-             ce->remote_port = port;
+             ce->remote_port = rhs->port;
              flags = CE_MAN_QUERY_REMOTE_MOD;
              ret = true;
            }
@@ -262,7 +256,7 @@ ce_management_query_remote (struct context *c, const char 
*remote_ip_hint)
   if (management)
     {
       struct buffer out = alloc_buf_gc (256, &gc);
-      buf_printf (&out, ">REMOTE:%s,%d,%s", np(ce->remote), ce->remote_port, 
proto2ascii(ce->proto, false));
+      buf_printf (&out, ">REMOTE:%s,%s,%s", np(ce->remote), ce->remote_port, 
proto2ascii(ce->proto, false));
       management_notify_generic(management, BSTR (&out));
       ce->flags &= ~(CE_MAN_QUERY_REMOTE_MASK<<CE_MAN_QUERY_REMOTE_SHIFT);
       ce->flags |= (CE_MAN_QUERY_REMOTE_QUERY<<CE_MAN_QUERY_REMOTE_SHIFT);
diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c
index 74de1e1..3816740 100644
--- a/src/openvpn/manage.c
+++ b/src/openvpn/manage.c
@@ -2058,7 +2058,7 @@ man_persist_close (struct man_persist *mp)
 static void
 man_settings_init (struct man_settings *ms,
                   const char *addr,
-                  const int port,
+                  const char *port,
                   const char *pass_file,
                   const char *client_user,
                   const char *client_group,
@@ -2111,12 +2111,6 @@ man_settings_init (struct man_settings *ms,
       else
 #endif
        {
-         /*
-          * Initialize socket address
-          */
-         ms->local.addr.in4.sin_family = AF_INET;
-         ms->local.addr.in4.sin_addr.s_addr = 0;
-         ms->local.addr.in4.sin_port = htons (port);

          /*
           * Run management over tunnel, or
@@ -2128,8 +2122,13 @@ man_settings_init (struct man_settings *ms,
            }
          else
            {
-             ms->local.addr.in4.sin_addr.s_addr = getaddr
-               (GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL, addr, 0, 
NULL, NULL);
+              struct addrinfo* ai;
+              int status = 
openvpn_getaddrinfo(GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL,
+                                               addr, port, 0, NULL, AF_INET, 
&ai);
+              ASSERT(status==0);
+              ms->local.addr.in4 = *((struct sockaddr_in*)ai->ai_addr);
+              freeaddrinfo(ai);
+
            }
        }

@@ -2248,7 +2247,7 @@ management_init (void)
 bool
 management_open (struct management *man,
                 const char *addr,
-                const int port,
+                const char *port,
                 const char *pass_file,
                 const char *client_user,
                 const char *client_group,
diff --git a/src/openvpn/manage.h b/src/openvpn/manage.h
index b08bb78..a54d0b6 100644
--- a/src/openvpn/manage.h
+++ b/src/openvpn/manage.h
@@ -341,7 +341,7 @@ struct management *management_init (void);

 bool management_open (struct management *man,
                      const char *addr,
-                     const int port,
+                     const char *port,
                      const char *pass_file,
                      const char *client_user,
                      const char *client_group,
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index e925397..3d711fa 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -169,8 +169,8 @@ static const char usage_message[] =
   "--ipchange cmd  : Run 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). Implies --bind.\n"
-  "--rport port    : TCP/UDP port # for remote (default=%d).\n"
+  "--lport port    : TCP/UDP port # for local (default=%s). Implies --bind.\n"
+  "--rport port    : TCP/UDP port # for remote (default=%s).\n"
   "--bind          : Bind to local address and port. (This is the default 
unless\n"
   "                  --proto tcp-client"
 #ifdef ENABLE_HTTP_PROXY
@@ -909,22 +909,22 @@ setenv_connection_entry (struct env_set *es,
 {
   setenv_str_i (es, "proto", proto2ascii (e->proto, false), i);
   setenv_str_i (es, "local", e->local, i);
-  setenv_int_i (es, "local_port", e->local_port, i);
+  setenv_str_i (es, "local_port", e->local_port, i);
   setenv_str_i (es, "remote", e->remote, i);
-  setenv_int_i (es, "remote_port", e->remote_port, i);
+  setenv_str_i (es, "remote_port", e->remote_port, i);

 #ifdef ENABLE_HTTP_PROXY
   if (e->http_proxy_options)
     {
       setenv_str_i (es, "http_proxy_server", e->http_proxy_options->server, i);
-      setenv_int_i (es, "http_proxy_port", e->http_proxy_options->port, i);
+      setenv_str_i (es, "http_proxy_port", e->http_proxy_options->port, i);
     }
 #endif
 #ifdef ENABLE_SOCKS
   if (e->socks_proxy_server)
     {
       setenv_str_i (es, "socks_proxy_server", e->socks_proxy_server, i);
-      setenv_int_i (es, "socks_proxy_port", e->socks_proxy_port, i);
+      setenv_str_i (es, "socks_proxy_port", e->socks_proxy_port, i);
     }
 #endif
 }
@@ -1226,7 +1226,7 @@ show_p2mp_parms (const struct options *o)
   SHOW_BOOL (auth_user_pass_verify_script_via_file);
 #if PORT_SHARE
   SHOW_STR (port_share_host);
-  SHOW_INT (port_share_port);
+  SHOW_STR (port_share_port);
 #endif
 #endif /* P2MP_SERVER */

@@ -1298,7 +1298,7 @@ show_http_proxy_options (const struct http_proxy_options 
*o)
   int i;
   msg (D_SHOW_PARMS, "BEGIN http_proxy");
   SHOW_STR (server);
-  SHOW_INT (port);
+  SHOW_STR (port);
   SHOW_STR (auth_method_string);
   SHOW_STR (auth_file);
   SHOW_BOOL (retry);
@@ -1360,9 +1360,9 @@ show_connection_entry (const struct connection_entry *o)
 {
   msg (D_SHOW_PARMS, "  proto = %s", proto2ascii (o->proto, false));
   SHOW_STR (local);
-  SHOW_INT (local_port);
+  SHOW_STR (local_port);
   SHOW_STR (remote);
-  SHOW_INT (remote_port);
+  SHOW_STR (remote_port);
   SHOW_BOOL (remote_float);
   SHOW_BOOL (bind_defined);
   SHOW_BOOL (bind_local);
@@ -1376,7 +1376,7 @@ show_connection_entry (const struct connection_entry *o)
 #endif
 #ifdef ENABLE_SOCKS
   SHOW_STR (socks_proxy_server);
-  SHOW_INT (socks_proxy_port);
+  SHOW_STR (socks_proxy_port);
   SHOW_BOOL (socks_proxy_retry);
 #endif
   SHOW_INT (tun_mtu);
@@ -1557,7 +1557,7 @@ show_settings (const struct options *o)

 #ifdef ENABLE_MANAGEMENT
   SHOW_STR (management_addr);
-  SHOW_INT (management_port);
+  SHOW_STR (management_port);
   SHOW_STR (management_user_pass);
   SHOW_INT (management_log_history_cache);
   SHOW_INT (management_echo_buffer_size);
@@ -1705,17 +1705,9 @@ parse_http_proxy_override (const char *server,
   if (server && port)
     {
       struct http_proxy_options *ho;
-      const int int_port = atoi(port);
-
-      if (!legal_ipv4_port (int_port))
-       {
-         msg (msglevel, "Bad http-proxy port number: %s", port);
-         return NULL;
-       }
-
       ALLOC_OBJ_CLEAR_GC (ho, struct http_proxy_options, gc);
       ho->server = string_alloc(server, gc);
-      ho->port = int_port;
+      ho->port = port;
       ho->retry = true;
       ho->timeout = 5;
       if (flags && !strcmp(flags, "nct"))
@@ -1818,7 +1810,7 @@ connection_entry_load_re (struct connection_entry *ce, 
const struct remote_entry
 {
   if (re->remote)
     ce->remote = re->remote;
-  if (re->remote_port >= 0)
+  if (re->remote_port)
     ce->remote_port = re->remote_port;
   if (re->proto >= 0)
     ce->proto = re->proto;
@@ -1922,7 +1914,7 @@ options_postprocess_verify_ce (const struct options 
*options, const struct conne

   if (proto_is_net(ce->proto)
       && string_defined_equal (ce->local, ce->remote)
-      && ce->local_port == ce->remote_port)
+      && string_defined_equal (ce->local_port, ce->remote_port))
     msg (M_USAGE, "--remote and --local addresses are the same");

   if (string_defined_equal (ce->remote, options->ifconfig_local)
@@ -2400,7 +2392,7 @@ options_postprocess_mutate_ce (struct options *o, struct 
connection_entry *ce)
 #endif

   if (!ce->bind_local)
-    ce->local_port = 0;
+    ce->local_port = NULL;

   /* if protocol forcing is enabled, disable all protocols except for the 
forced one */
   if (o->proto_force >= 0 && proto_is_tcp(o->proto_force) != 
proto_is_tcp(ce->proto))
@@ -4144,8 +4136,6 @@ add_option (struct options *options,
 #ifdef ENABLE_MANAGEMENT
   else if (streq (p[0], "management") && p[1] && p[2])
     {
-      int port = 0;
-
       VERIFY_PERMISSION (OPT_P_GENERAL);
       if (streq (p[2], "unix"))
        {
@@ -4156,18 +4146,9 @@ add_option (struct options *options,
          goto err;
 #endif
        }
-      else
-       {
-         port = atoi (p[2]);
-         if (!legal_ipv4_port (port))
-           {
-             msg (msglevel, "port number associated with --management 
directive is out of range");
-             goto err;
-           }
-       }

       options->management_addr = p[1];
-      options->management_port = port;
+      options->management_port = p[2];
       if (p[3])
        {
          options->management_user_pass = p[3];
@@ -4481,20 +4462,14 @@ add_option (struct options *options,
   else if (streq (p[0], "remote") && p[1])
     {
       struct remote_entry re;
-      re.remote = NULL;
-      re.remote_port = re.proto = -1;
+      re.remote = re.remote_port= NULL;
+      re.proto = -1;

       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
       re.remote = p[1];
       if (p[2])
        {
-         const int port = atoi (p[2]);
-         if (!legal_ipv4_port (port))
-           {
-             msg (msglevel, "remote: port number associated with host %s is 
out of range", p[1]);
-             goto err;
-           }
-         re.remote_port = port;
+         re.remote_port = p[2];
          if (p[3])
            {
              const int proto = ascii2proto (p[3]);
@@ -4902,43 +4877,19 @@ add_option (struct options *options,
     }
   else if (streq (p[0], "port") && p[1])
     {
-      int port;
-
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
-      port = atoi (p[1]);
-      if (!legal_ipv4_port (port))
-       {
-         msg (msglevel, "Bad port number: %s", p[1]);
-         goto err;
-       }
-      options->ce.local_port = options->ce.remote_port = port;
+      options->ce.local_port = options->ce.remote_port = p[1];
     }
   else if (streq (p[0], "lport") && p[1])
     {
-      int port;
-
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
-      port = atoi (p[1]);
-      if ((port != 0) && !legal_ipv4_port (port))
-       {
-         msg (msglevel, "Bad local port number: %s", p[1]);
-         goto err;
-       }
       options->ce.local_port_defined = true;
-      options->ce.local_port = port;
+      options->ce.local_port = p[1];
     }
   else if (streq (p[0], "rport") && p[1])
     {
-      int port;
-
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);
-      port = atoi (p[1]);
-      if (!legal_ipv4_port (port))
-       {
-         msg (msglevel, "Bad remote port number: %s", p[1]);
-         goto err;
-       }
-      options->ce.remote_port = port;
+      options->ce.remote_port = p[1];
     }
   else if (streq (p[0], "bind"))
     {
@@ -4997,23 +4948,16 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);

       {
-       int port;
        if (!p[2])
          {
            msg (msglevel, "http-proxy port number not defined");
            goto err;
          }
-       port = atoi (p[2]);
-       if (!legal_ipv4_port (port))
-         {
-           msg (msglevel, "Bad http-proxy port number: %s", p[2]);
-           goto err;
-         }

        ho = init_http_proxy_options_once (&options->ce.http_proxy_options, 
&options->gc);

        ho->server = p[1];
-       ho->port = port;
+       ho->port = p[2];
       }

       if (p[3])
@@ -5110,19 +5054,12 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_GENERAL|OPT_P_CONNECTION);

       if (p[2])
-       {
-         int port;
-          port = atoi (p[2]);
-          if (!legal_ipv4_port (port))
-           {
-             msg (msglevel, "Bad socks-proxy port number: %s", p[2]);
-             goto err;
-           }
-          options->ce.socks_proxy_port = port;
+        {
+          options->ce.socks_proxy_port = p[2];
        }
       else
        {
-         options->ce.socks_proxy_port = 1080;
+         options->ce.socks_proxy_port = "1080";
        }
       options->ce.socks_proxy_server = p[1];
       options->ce.socks_proxy_authfile = p[3]; /* might be NULL */
@@ -5755,18 +5692,9 @@ add_option (struct options *options,
 #if PORT_SHARE
   else if (streq (p[0], "port-share") && p[1] && p[2])
     {
-      int port;
-
       VERIFY_PERMISSION (OPT_P_GENERAL);
-      port = atoi (p[2]);
-      if (!legal_ipv4_port (port))
-       {
-         msg (msglevel, "port number associated with --port-share directive is 
out of range");
-         goto err;
-       }
-
       options->port_share_host = p[1];
-      options->port_share_port = port;
+      options->port_share_port = p[2];
       options->port_share_journal_dir = p[3];
     }
 #endif
diff --git a/src/openvpn/options.h b/src/openvpn/options.h
index 8e0e367..84a5910 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -87,9 +87,9 @@ struct options_pre_pull
 struct connection_entry
 {
   int proto;
-  int local_port;
+  const char* local_port;
   bool local_port_defined;
-  int remote_port;
+  const char* remote_port;
   const char *local;
   const char *remote;
   bool remote_float;
@@ -105,7 +105,7 @@ struct connection_entry
 #endif  
 #ifdef ENABLE_SOCKS
   const char *socks_proxy_server;
-  int socks_proxy_port;
+  const char *socks_proxy_port;
   const char *socks_proxy_authfile;
   bool socks_proxy_retry;
 #endif
@@ -143,7 +143,7 @@ struct connection_entry
 struct remote_entry
 {
   const char *remote;
-  int remote_port;
+  const char *remote_port;
   int proto;
 };

@@ -168,6 +168,8 @@ struct remote_host_store
 {
 # define RH_HOST_LEN 80
   char host[RH_HOST_LEN];
+#define RH_PORT_LEN 20
+  char port[RH_PORT_LEN];
 };

 /* Command line options */
@@ -356,7 +358,7 @@ struct options

 #ifdef ENABLE_MANAGEMENT
   const char *management_addr;
-  int management_port;
+  const char *management_port;
   const char *management_user_pass;
   int management_log_history_cache;
   int management_echo_buffer_size;
@@ -451,7 +453,7 @@ struct options
   bool auth_user_pass_verify_script_via_file;
 #if PORT_SHARE
   char *port_share_host;
-  int port_share_port;
+  char *port_share_port;
   const char *port_share_journal_dir;
 #endif
 #endif
diff --git a/src/openvpn/proxy.c b/src/openvpn/proxy.c
index c3496e2..f7f0648 100644
--- a/src/openvpn/proxy.c
+++ b/src/openvpn/proxy.c
@@ -443,7 +443,7 @@ http_proxy_new (const struct http_proxy_options *o)
   if (!o || !o->server)
     msg (M_FATAL, "HTTP_PROXY: server not specified");

-  ASSERT (legal_ipv4_port (o->port));
+  ASSERT ( o->port);

   ALLOC_OBJ_CLEAR (p, struct http_proxy_info);
   p->options = *o;
@@ -492,7 +492,7 @@ bool
 add_proxy_headers (struct http_proxy_info *p,
                  socket_descriptor_t sd, /* already open to proxy */
                  const char *host,       /* openvpn server remote */
-                 const int port          /* openvpn server port */
+                 const char* port        /* openvpn server port */
                  )
 {
   char buf[512];
@@ -553,7 +553,7 @@ bool
 establish_http_proxy_passthru (struct http_proxy_info *p,
                               socket_descriptor_t sd, /* already open to proxy 
*/
                               const char *host,       /* openvpn server remote 
*/
-                              const int port,         /* openvpn server port */
+                              const char *port,         /* openvpn server port 
*/
                               struct buffer *lookahead,
                               volatile int *signal_received)
 {
@@ -581,7 +581,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
   else
     {
       /* format HTTP CONNECT message */
-      openvpn_snprintf (buf, sizeof(buf), "CONNECT %s:%d HTTP/%s",
+      openvpn_snprintf (buf, sizeof(buf), "CONNECT %s:%s HTTP/%s",
                        host,
                        port,
                        p->options.http_version);
@@ -692,7 +692,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
           /* now send the phase 3 reply */

           /* format HTTP CONNECT message */
-          openvpn_snprintf (buf, sizeof(buf), "CONNECT %s:%d HTTP/%s",
+          openvpn_snprintf (buf, sizeof(buf), "CONNECT %s:%s HTTP/%s",
                            host,
                            port,
                            p->options.http_version);
@@ -777,7 +777,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p,


              /* build the digest response */
-             openvpn_snprintf (uri, sizeof(uri), "%s:%d",
+             openvpn_snprintf (uri, sizeof(uri), "%s:%s",
                                host,
                                port);

diff --git a/src/openvpn/proxy.h b/src/openvpn/proxy.h
index b72748f..0e7a6df 100644
--- a/src/openvpn/proxy.h
+++ b/src/openvpn/proxy.h
@@ -46,7 +46,7 @@ struct http_custom_header {
 #define MAX_CUSTOM_HTTP_HEADER 10
 struct http_proxy_options {
   const char *server;
-  int port;
+  const char *port;
   bool retry;
   int timeout;

@@ -64,7 +64,7 @@ struct http_proxy_options {

 struct http_proxy_options_simple {
   const char *server;
-  int port;
+  const char *port;
   int auth_retry;
 };

@@ -87,7 +87,7 @@ void http_proxy_close (struct http_proxy_info *hp);
 bool establish_http_proxy_passthru (struct http_proxy_info *p,
                                    socket_descriptor_t sd, /* already open to 
proxy */
                                    const char *host,       /* openvpn server 
remote */
-                                   const int port,         /* openvpn server 
port */
+                                   const char *port,         /* openvpn server 
port */
                                    struct buffer *lookahead,
                                    volatile int *signal_received);

diff --git a/src/openvpn/ps.c b/src/openvpn/ps.c
index 6495dc7..44eda89 100644
--- a/src/openvpn/ps.c
+++ b/src/openvpn/ps.c
@@ -403,8 +403,7 @@ proxy_connection_io_requeue (struct proxy_connection *pc, 
const int rwflags_new,
 static bool
 proxy_entry_new (struct proxy_connection **list,
                 struct event_set *es,
-                const in_addr_t server_addr,
-                const int server_port,
+                const struct sockaddr_in server_addr,
                 const socket_descriptor_t sd_client,
                 struct buffer *initial_data,
                 const char *journal_dir)
@@ -416,7 +415,7 @@ proxy_entry_new (struct proxy_connection **list,
   struct proxy_connection *cp;

   /* connect to port share server */
-  sock_addr_set (&osaddr, server_addr, server_port);
+  osaddr.addr.in4 = server_addr;
   if ((sd_server = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
     {
       msg (M_WARN|M_ERRNO, "PORT SHARE PROXY: cannot create socket");
@@ -482,8 +481,7 @@ static bool
 control_message_from_parent (const socket_descriptor_t sd_control,
                             struct proxy_connection **list,
                             struct event_set *es,
-                            const in_addr_t server_addr,
-                            const int server_port,
+                            const struct sockaddr_in server_addr,
                             const int max_initial_buf,
                             const char *journal_dir)
 {
@@ -539,7 +537,6 @@ control_message_from_parent (const socket_descriptor_t 
sd_control,
              if (proxy_entry_new (list,
                                   es,
                                   server_addr,
-                                  server_port,
                                   received_fd,
                                   &buf,
                                   journal_dir))
@@ -716,8 +713,7 @@ proxy_connection_io_dispatch (struct proxy_connection *pc,
  * This is the main function for the port share proxy background process.
  */
 static void
-port_share_proxy (const in_addr_t hostaddr,
-                 const int port,
+port_share_proxy (const struct sockaddr_in hostaddr,
                  const socket_descriptor_t sd_control,
                  const int max_initial_buf,
                  const char *journal_dir)
@@ -754,7 +750,7 @@ port_share_proxy (const in_addr_t hostaddr,
                  const struct event_set_return *e = &esr[i];
                  if (e->arg == sd_control_marker)
                    {
-                     if (!control_message_from_parent (sd_control, &list, es, 
hostaddr, port, max_initial_buf, journal_dir))
+                     if (!control_message_from_parent (sd_control, &list, es, 
hostaddr, max_initial_buf, journal_dir))
                        goto done;
                    }
                  else
@@ -789,14 +785,16 @@ port_share_proxy (const in_addr_t hostaddr,
  */
 struct port_share *
 port_share_open (const char *host,
-                const int port,
+                const char *port,
                 const int max_initial_buf,
                 const char *journal_dir)
 {
   pid_t pid;
   socket_descriptor_t fd[2];
-  in_addr_t hostaddr;
+  struct sockaddr_in hostaddr;
   struct port_share *ps;
+  int status;
+  struct addrinfo* ai;

   ALLOC_OBJ_CLEAR (ps, struct port_share);
   ps->foreground_fd = -1;
@@ -805,7 +803,12 @@ port_share_open (const char *host,
   /*
    * Get host's IP address
    */
-  hostaddr = getaddr (GETADDR_RESOLVE|GETADDR_HOST_ORDER|GETADDR_FATAL, host, 
0, NULL, NULL);
+  
+  status = openvpn_getaddrinfo 
(GETADDR_RESOLVE|GETADDR_HOST_ORDER|GETADDR_FATAL,
+                                 host, port,  0, NULL, AF_INET, &ai);
+  ASSERT (status==0);
+  hostaddr = *((struct sockaddr_in*) ai->ai_addr);
+  freeaddrinfo(ai);

   /*
    * Make a socket for foreground and background processes
@@ -881,7 +884,7 @@ port_share_open (const char *host,
       prng_init (NULL, 0);

       /* execute the event loop */
-      port_share_proxy (hostaddr, port, fd[1], max_initial_buf, journal_dir);
+      port_share_proxy (hostaddr, fd[1], max_initial_buf, journal_dir);

       openvpn_close_socket (fd[1]);

diff --git a/src/openvpn/ps.h b/src/openvpn/ps.h
index 4280635..e8919d4 100644
--- a/src/openvpn/ps.h
+++ b/src/openvpn/ps.h
@@ -44,7 +44,7 @@ struct port_share {
 extern struct port_share *port_share;

 struct port_share *port_share_open (const char *host,
-                                   const int port,
+                                   const char *port,
                                    const int max_initial_buf,
                                    const char *journal_dir);

diff --git a/src/openvpn/route.c b/src/openvpn/route.c
index 19b4bfe..f051dd3 100644
--- a/src/openvpn/route.c
+++ b/src/openvpn/route.c
@@ -294,12 +294,12 @@ init_route (struct route *r,
   if(get_special_addr (rl, ro->network, &special.s_addr, &status))
     {
       special.s_addr = htonl(special.s_addr);
-      ret = openvpn_getaddrinfo(0, inet_ntoa(special), 0, NULL,
+      ret = openvpn_getaddrinfo(0, inet_ntoa(special), NULL, 0, NULL,
                                 AF_INET, network_list);
     }
   else
     ret = openvpn_getaddrinfo(GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL,
-                              ro->network, 0, NULL, AF_INET, network_list);
+                              ro->network, NULL, 0, NULL, AF_INET, 
network_list);

   status = (ret == 0);

diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c
index 3c0a379..33ef3f4 100644
--- a/src/openvpn/socket.c
+++ b/src/openvpn/socket.c
@@ -101,8 +101,8 @@ getaddr (unsigned int flags,
 {
   struct addrinfo *ai;
   int status;
-  status = openvpn_getaddrinfo(flags, hostname, resolve_retry_seconds,
-                                                          signal_received, 
AF_INET, &ai);
+  status = openvpn_getaddrinfo (flags & ~GETADDR_HOST_ORDER, hostname, NULL,
+                                resolve_retry_seconds, signal_received, 
AF_INET, &ai);
   if(status==0) {
     struct in_addr ia;
     if(succeeded)
@@ -125,6 +125,7 @@ getaddr (unsigned int flags,
 int
 openvpn_getaddrinfo (unsigned int flags,
                      const char *hostname,
+                     const char *servname,
                      int resolve_retry_seconds,
                      volatile int *signal_received,
                      int ai_family,
@@ -135,6 +136,8 @@ openvpn_getaddrinfo (unsigned int flags,
   int sigrec = 0;
   int msglevel = (flags & GETADDR_FATAL) ? M_FATAL : D_RESOLVE_ERRORS;
   struct gc_arena gc = gc_new ();
+  const char *print_hostname;
+  const char *print_servname;

   ASSERT(res);

@@ -142,8 +145,19 @@ openvpn_getaddrinfo (unsigned int flags,
   res_init ();
 #endif

-  if (!hostname)
-    hostname = "::";
+  ASSERT (hostname || servname);
+  ASSERT (!(flags & GETADDR_HOST_ORDER));
+
+  if(hostname)
+    print_hostname = hostname;
+  else
+    print_hostname = "undefined";
+    
+  if(servname)
+    print_servname = servname;
+  else
+    print_servname = "";
+

   if (flags & GETADDR_RANDOMIZE)
     hostname = hostname_randomize(hostname, &gc);
@@ -160,8 +174,11 @@ openvpn_getaddrinfo (unsigned int flags,
   hints.ai_family = ai_family;
   hints.ai_flags = AI_NUMERICHOST;
   hints.ai_socktype = SOCK_STREAM;
+  
+  if(flags & GETADDR_PASSIVE)
+      hints.ai_flags |= AI_PASSIVE;

-  status = getaddrinfo(hostname, NULL, &hints, res);
+  status = getaddrinfo(hostname, servname, &hints, res);

   if (status != 0) /* parse as numeric address failed? */
     {
@@ -169,7 +186,7 @@ openvpn_getaddrinfo (unsigned int flags,
       int resolve_retries = (flags & GETADDR_TRY_ONCE) ? 1 : 
(resolve_retry_seconds / fail_wait_interval);
       const char *fmt;
       int level = 0;
-
+      
       fmt = "RESOLVE: Cannot resolve host address: %s: %s";
       if ((flags & GETADDR_MENTION_RESOLVE_RETRY)
           && !resolve_retry_seconds)
@@ -177,7 +194,8 @@ openvpn_getaddrinfo (unsigned int flags,

       if (!(flags & GETADDR_RESOLVE) || status == EAI_FAIL)
         {
-          msg (msglevel, "RESOLVE: Cannot parse IP address: %s", hostname);
+          msg (msglevel, "RESOLVE: Cannot parse IP address: %s:%s",
+               print_hostname,print_servname);
           goto done;
         }

@@ -199,10 +217,10 @@ openvpn_getaddrinfo (unsigned int flags,
       while (true)
         {
           /* try hostname lookup */
-          hints.ai_flags = 0;
+          hints.ai_flags &= ~AI_NUMERICHOST;
           dmsg (D_SOCKET_DEBUG, "GETADDRINFO flags=0x%04x ai_family=%d 
ai_socktype=%d",
                 flags, hints.ai_family, hints.ai_socktype);
-          status = getaddrinfo(hostname, NULL, &hints, res);
+          status = getaddrinfo(hostname, servname, &hints, res);

           if (signal_received)
             {
@@ -236,7 +254,8 @@ openvpn_getaddrinfo (unsigned int flags,

           msg (level,
                fmt,
-               hostname,
+               print_hostname,
+               print_servname,
                gai_strerror(status));

           if (--resolve_retries <= 0)
@@ -449,7 +468,8 @@ update_remote (const char* host,
           int status;
           struct addrinfo* ai;

-                 status = 
openvpn_getaddrinfo(sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, 
sockflags), host, 1, NULL, AF_INET6, &ai);
+          status = 
openvpn_getaddrinfo(sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, 
sockflags), 
+                                       host, NULL, 1, NULL, AF_INET6, &ai);

           if ( status ==0 )
             {
@@ -1141,53 +1161,30 @@ resolve_bind_local (struct link_socket *sock)
   /* resolve local address if undefined */
   if (!addr_defined (&sock->info.lsa->local))
     {
+      int status;
+      struct addrinfo *ai;
+ 
       /* may return AF_{INET|INET6} guessed from local_host */
-      switch(addr_guess_family(sock->info.proto, sock->local_host))
-       {
-       case AF_INET:
-         sock->info.lsa->local.addr.in4.sin_family = AF_INET;
-         sock->info.lsa->local.addr.in4.sin_addr.s_addr =
-           (sock->local_host ? getaddr (GETADDR_RESOLVE | 
GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL,
-                                        sock->local_host,
-                                        0,
-                                        NULL,
-                                        NULL)
-            : htonl (INADDR_ANY));
-         sock->info.lsa->local.addr.in4.sin_port = htons (sock->local_port);
-         break;
-       case AF_INET6:
-           {
-             int status;
-             CLEAR(sock->info.lsa->local.addr.in6);
-             if (sock->local_host)
-               {
-                 struct addrinfo *ai;
-
-                 status = openvpn_getaddrinfo(GETADDR_RESOLVE | 
GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL,
-                                                                          
sock->local_host, 0, NULL, AF_INET6, &ai);
-                 if(status ==0) {
-                         sock->info.lsa->local.addr.in6 = *((struct 
sockaddr_in6*)(ai->ai_addr));
-                         freeaddrinfo(ai);
-                 }
-               }
-             else
-               {
-                 sock->info.lsa->local.addr.in6.sin6_family = AF_INET6;
-                 sock->info.lsa->local.addr.in6.sin6_addr = in6addr_any;
-                 status = 0;
-               }
-             if (!status == 0)
-               {
-                 msg (M_FATAL, "getaddr6() failed for local \"%s\": %s",
-                      sock->local_host,
-                      gai_strerror(status));
-               }
-             sock->info.lsa->local.addr.in6.sin6_port = htons 
(sock->local_port);
-           }
-         break;
-       }
+      const int af = addr_guess_family(sock->info.proto, sock->local_host);
+      status = openvpn_getaddrinfo(GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL | 
GETADDR_FATAL | GETADDR_PASSIVE,
+                                   sock->local_host, sock->local_port, 0, 
NULL, af, &ai);
+      if(status ==0) {
+        switch(af) {
+        case AF_INET:
+          sock->info.lsa->local.addr.in4 =  *((struct 
sockaddr_in*)(ai->ai_addr));
+
+        case AF_INET6:
+          sock->info.lsa->local.addr.in6 = *((struct 
sockaddr_in6*)(ai->ai_addr));
+          break;
+          freeaddrinfo(ai);
+        }
+      } else {
+        msg (M_FATAL, "getaddrinfo() failed for local \"%s:%s\": %s",
+             sock->local_host, sock->local_port,
+             gai_strerror(status));
+      }
     }
-  
+
   /* bind to local address/port */
   if (sock->bind_local)
     {
@@ -1272,8 +1269,8 @@ resolve_remote (struct link_socket *sock,
                }

                  /* Temporary fix, this need to be changed for dual stack */
-                 status = openvpn_getaddrinfo(flags, sock->remote_host, retry,
-                                                                               
          signal_received, af, &ai);
+                 status = openvpn_getaddrinfo(flags, sock->remote_host, 
sock->remote_port,
+                                               retry, signal_received, af, 
&ai);
                  if(status == 0) {
                          sock->info.lsa->remote.addr.in6 = *((struct 
sockaddr_in6*)(ai->ai_addr));
                          freeaddrinfo(ai);
@@ -1297,15 +1294,6 @@ resolve_remote (struct link_socket *sock,
                  goto done;
                }
            }
-          switch(af)
-            {
-              case AF_INET:
-                sock->info.lsa->remote.addr.in4.sin_port = htons 
(sock->remote_port);
-                break;
-              case AF_INET6:
-                sock->info.lsa->remote.addr.in6.sin6_port = htons 
(sock->remote_port);
-                break;
-            }
        }

       /* should we re-use previous active remote address? */
@@ -1348,9 +1336,9 @@ void
 link_socket_init_phase1 (struct link_socket *sock,
                         const bool connection_profiles_defined,
                         const char *local_host,
-                        int local_port,
+                        const char *local_port,
                         const char *remote_host,
-                        int remote_port,
+                        const char *remote_port,
                         int proto,
                         int mode,
                         const struct link_socket *accept_from,
@@ -1496,8 +1484,9 @@ link_socket_init_phase1 (struct link_socket *sock,

       /* set socket to --mark packets with given value */
       socket_set_mark (sock->sd, mark);
-
-      resolve_bind_local (sock);
+      
+      if(sock->bind_local)
+          resolve_bind_local (sock);
       resolve_remote (sock, 1, NULL, NULL);
     }
 }
diff --git a/src/openvpn/socket.h b/src/openvpn/socket.h
index 793cd9f..549946e 100644
--- a/src/openvpn/socket.h
+++ b/src/openvpn/socket.h
@@ -39,7 +39,7 @@
 /*
  * OpenVPN's default port number as assigned by IANA.
  */
-#define OPENVPN_PORT 1194
+#define OPENVPN_PORT "1194"

 /*
  * Maximum size passed passed to setsockopt SNDBUF/RCVBUF
@@ -179,9 +179,9 @@ struct link_socket
   bool connection_profiles_defined;

   const char *remote_host;
-  int remote_port;
+  const char *remote_port;
   const char *local_host;
-  int local_port;
+  const char *local_port;
   bool bind_local;

 # define INETD_NONE   0
@@ -232,7 +232,7 @@ struct link_socket
 #if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_SOCKS)
   /* The OpenVPN server we will use the proxy to connect to */
   const char *proxy_dest_host;
-  int proxy_dest_port;
+  const char *proxy_dest_port;
 #endif

 #if PASSTOS_CAPABILITY
@@ -299,9 +299,9 @@ void
 link_socket_init_phase1 (struct link_socket *sock,
                         const bool connection_profiles_defined,
                         const char *local_host,
-                        int local_port,
+                        const char *local_port,
                         const char *remote_host,
-                        int remote_port,
+                        const char *remote_port,
                         int proto,
                         int mode,
                         const struct link_socket *accept_from,
@@ -481,6 +481,7 @@ bool unix_socket_get_peer_uid_gid (const 
socket_descriptor_t sd, int *uid, int *
 #define GETADDR_TRY_ONCE              (1<<7)
 #define GETADDR_UPDATE_MANAGEMENT_STATE (1<<8)
 #define GETADDR_RANDOMIZE             (1<<9)
+#define GETADDR_PASSIVE               (1<<10)

 in_addr_t getaddr (unsigned int flags,
                   const char *hostname,
@@ -490,6 +491,7 @@ in_addr_t getaddr (unsigned int flags,

 int openvpn_getaddrinfo (unsigned int flags,
                          const char *hostname,
+                         const char *servname,
                          int resolve_retry_seconds,
                          volatile int *signal_received,
                          int ai_family,
@@ -544,12 +546,6 @@ datagram_overhead (int proto)
  */

 static inline bool
-legal_ipv4_port (int port)
-{
-  return port > 0 && port < 65536;
-}
-
-static inline bool
 link_socket_proto_connection_oriented (int proto)
 {
   return !proto_is_dgram(proto);
diff --git a/src/openvpn/socks.c b/src/openvpn/socks.c
index 235982e..c2203c2 100644
--- a/src/openvpn/socks.c
+++ b/src/openvpn/socks.c
@@ -61,7 +61,7 @@ socks_adjust_frame_parameters (struct frame *frame, int proto)

 struct socks_proxy_info *
 socks_proxy_new (const char *server,
-                int port,
+                const char *port,
                 const char *authfile,
                 bool retry)
 {
@@ -70,7 +70,7 @@ socks_proxy_new (const char *server,
   ALLOC_OBJ_CLEAR (p, struct socks_proxy_info);

   ASSERT (server);
-  ASSERT (legal_ipv4_port (port));
+  ASSERT (port);

   strncpynt (p->server, server, sizeof (p->server));
   p->port = port;
@@ -389,11 +389,27 @@ recv_socks_reply (socket_descriptor_t sd,
   return true;
 }

+static int
+port_from_servname(const char* servname)
+{
+    int port =0;
+    port = atoi(servname);
+    if(port >0 && port < 65536)
+        return port;
+    
+    struct  servent* service;
+    service = getservbyname(servname, NULL);
+    if(service)
+        return service->s_port;
+
+    return 0;
+}
+
 void
 establish_socks_proxy_passthru (struct socks_proxy_info *p,
                                socket_descriptor_t sd, /* already open to 
proxy */
                                const char *host,       /* openvpn server 
remote */
-                               const int port,         /* openvpn server port 
*/
+                               const char *servname,   /* openvpn server port 
*/
                                volatile int *signal_received)
 {
   char buf[128];
@@ -414,6 +430,13 @@ establish_socks_proxy_passthru (struct socks_proxy_info *p,
   buf[4] = (char) len;
   memcpy(buf + 5, host, len);

+  int port = port_from_servname (servname);
+  if (port ==0)
+    {
+      msg (D_LINK_ERRORS, "establish_socks_proxy_passthrough: Cannot convert 
%s to port number", servname);
+      goto error;
+    }
+    
   buf[5 + len] = (char) (port >> 8);
   buf[5 + len + 1] = (char) (port & 0xff);

@@ -425,6 +448,7 @@ establish_socks_proxy_passthru (struct socks_proxy_info *p,
        goto error;
       }
   }
+    

   /* receive reply from Socks proxy and discard */
   if (!recv_socks_reply (sd, NULL, signal_received))
diff --git a/src/openvpn/socks.h b/src/openvpn/socks.h
index b55ff6f..30b957d 100644
--- a/src/openvpn/socks.h
+++ b/src/openvpn/socks.h
@@ -42,14 +42,14 @@ struct socks_proxy_info {
   bool retry;

   char server[128];
-  int port;
+  const char *port;
   char authfile[256];
 };

 void socks_adjust_frame_parameters (struct frame *frame, int proto);

 struct socks_proxy_info *socks_proxy_new (const char *server,
-                                         int port,
+                                         const char *port,
                                          const char *authfile,
                                          bool retry);

@@ -58,7 +58,7 @@ void socks_proxy_close (struct socks_proxy_info *sp);
 void establish_socks_proxy_passthru (struct socks_proxy_info *p,
                                     socket_descriptor_t sd, /* already open to 
proxy */
                                     const char *host,       /* openvpn server 
remote */
-                                    const int port,         /* openvpn server 
port */
+                                    const char *servname,         /* openvpn 
server port */
                                     volatile int *signal_received);

 void establish_socks_proxy_udpassoc (struct socks_proxy_info *p,
-- 
1.7.9.5


Reply via email to