diff options
| author | Arne Schwabe <arne@rfc2549.org> | 2013-12-05 07:07:51 +0100 | 
|---|---|---|
| committer | Arne Schwabe <arne@rfc2549.org> | 2013-12-05 07:07:51 +0100 | 
| commit | 137cc5c10327306f0dc15f063e069d2cbc497519 (patch) | |
| tree | 57951d2ac173a6738315fb422a6cefd4a2a1a9f4 | |
| parent | ac1934d9e06d72fbe5bdacd5c0c1a89a377e508d (diff) | |
Add pre resolve patch
| -rwxr-xr-x | openvpn/compile | 347 | ||||
| -rw-r--r-- | openvpn/doc/openvpn.8 | 16 | ||||
| -rw-r--r-- | openvpn/src/openvpn/init.c | 37 | ||||
| -rw-r--r-- | openvpn/src/openvpn/manage.c | 2 | ||||
| -rw-r--r-- | openvpn/src/openvpn/options.c | 23 | ||||
| -rw-r--r-- | openvpn/src/openvpn/options.h | 6 | ||||
| -rw-r--r-- | openvpn/src/openvpn/push.c | 3 | ||||
| -rw-r--r-- | openvpn/src/openvpn/socket.c | 360 | ||||
| -rw-r--r-- | openvpn/src/openvpn/socket.h | 98 | ||||
| -rw-r--r-- | openvpn/src/openvpn/ssl_openssl.c | 3 | ||||
| -rw-r--r-- | openvpn/src/openvpn/tun.c | 4 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/VpnProfile.java | 4 | 
12 files changed, 329 insertions, 574 deletions
| diff --git a/openvpn/compile b/openvpn/compile deleted file mode 100755 index 531136b0..00000000 --- a/openvpn/compile +++ /dev/null @@ -1,347 +0,0 @@ -#! /bin/sh -# Wrapper for compilers which do not understand '-c -o'. - -scriptversion=2012-10-14.11; # UTC - -# Copyright (C) 1999-2013 Free Software Foundation, Inc. -# Written by Tom Tromey <tromey@cygnus.com>. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program.  If not, see <http://www.gnu.org/licenses/>. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# This file is maintained in Automake, please report -# bugs to <bug-automake@gnu.org> or send patches to -# <automake-patches@gnu.org>. - -nl=' -' - -# We need space, tab and new line, in precisely that order.  Quoting is -# there to prevent tools from complaining about whitespace usage. -IFS=" ""	$nl" - -file_conv= - -# func_file_conv build_file lazy -# Convert a $build file to $host form and store it in $file -# Currently only supports Windows hosts. If the determined conversion -# type is listed in (the comma separated) LAZY, no conversion will -# take place. -func_file_conv () -{ -  file=$1 -  case $file in -    / | /[!/]*) # absolute file, and not a UNC file -      if test -z "$file_conv"; then -	# lazily determine how to convert abs files -	case `uname -s` in -	  MINGW*) -	    file_conv=mingw -	    ;; -	  CYGWIN*) -	    file_conv=cygwin -	    ;; -	  *) -	    file_conv=wine -	    ;; -	esac -      fi -      case $file_conv/,$2, in -	*,$file_conv,*) -	  ;; -	mingw/*) -	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` -	  ;; -	cygwin/*) -	  file=`cygpath -m "$file" || echo "$file"` -	  ;; -	wine/*) -	  file=`winepath -w "$file" || echo "$file"` -	  ;; -      esac -      ;; -  esac -} - -# func_cl_dashL linkdir -# Make cl look for libraries in LINKDIR -func_cl_dashL () -{ -  func_file_conv "$1" -  if test -z "$lib_path"; then -    lib_path=$file -  else -    lib_path="$lib_path;$file" -  fi -  linker_opts="$linker_opts -LIBPATH:$file" -} - -# func_cl_dashl library -# Do a library search-path lookup for cl -func_cl_dashl () -{ -  lib=$1 -  found=no -  save_IFS=$IFS -  IFS=';' -  for dir in $lib_path $LIB -  do -    IFS=$save_IFS -    if $shared && test -f "$dir/$lib.dll.lib"; then -      found=yes -      lib=$dir/$lib.dll.lib -      break -    fi -    if test -f "$dir/$lib.lib"; then -      found=yes -      lib=$dir/$lib.lib -      break -    fi -    if test -f "$dir/lib$lib.a"; then -      found=yes -      lib=$dir/lib$lib.a -      break -    fi -  done -  IFS=$save_IFS - -  if test "$found" != yes; then -    lib=$lib.lib -  fi -} - -# func_cl_wrapper cl arg... -# Adjust compile command to suit cl -func_cl_wrapper () -{ -  # Assume a capable shell -  lib_path= -  shared=: -  linker_opts= -  for arg -  do -    if test -n "$eat"; then -      eat= -    else -      case $1 in -	-o) -	  # configure might choose to run compile as 'compile cc -o foo foo.c'. -	  eat=1 -	  case $2 in -	    *.o | *.[oO][bB][jJ]) -	      func_file_conv "$2" -	      set x "$@" -Fo"$file" -	      shift -	      ;; -	    *) -	      func_file_conv "$2" -	      set x "$@" -Fe"$file" -	      shift -	      ;; -	  esac -	  ;; -	-I) -	  eat=1 -	  func_file_conv "$2" mingw -	  set x "$@" -I"$file" -	  shift -	  ;; -	-I*) -	  func_file_conv "${1#-I}" mingw -	  set x "$@" -I"$file" -	  shift -	  ;; -	-l) -	  eat=1 -	  func_cl_dashl "$2" -	  set x "$@" "$lib" -	  shift -	  ;; -	-l*) -	  func_cl_dashl "${1#-l}" -	  set x "$@" "$lib" -	  shift -	  ;; -	-L) -	  eat=1 -	  func_cl_dashL "$2" -	  ;; -	-L*) -	  func_cl_dashL "${1#-L}" -	  ;; -	-static) -	  shared=false -	  ;; -	-Wl,*) -	  arg=${1#-Wl,} -	  save_ifs="$IFS"; IFS=',' -	  for flag in $arg; do -	    IFS="$save_ifs" -	    linker_opts="$linker_opts $flag" -	  done -	  IFS="$save_ifs" -	  ;; -	-Xlinker) -	  eat=1 -	  linker_opts="$linker_opts $2" -	  ;; -	-*) -	  set x "$@" "$1" -	  shift -	  ;; -	*.cc | *.CC | *.cxx | *.CXX | *.[cC]++) -	  func_file_conv "$1" -	  set x "$@" -Tp"$file" -	  shift -	  ;; -	*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) -	  func_file_conv "$1" mingw -	  set x "$@" "$file" -	  shift -	  ;; -	*) -	  set x "$@" "$1" -	  shift -	  ;; -      esac -    fi -    shift -  done -  if test -n "$linker_opts"; then -    linker_opts="-link$linker_opts" -  fi -  exec "$@" $linker_opts -  exit 1 -} - -eat= - -case $1 in -  '') -     echo "$0: No command.  Try '$0 --help' for more information." 1>&2 -     exit 1; -     ;; -  -h | --h*) -    cat <<\EOF -Usage: compile [--help] [--version] PROGRAM [ARGS] - -Wrapper for compilers which do not understand '-c -o'. -Remove '-o dest.o' from ARGS, run PROGRAM with the remaining -arguments, and rename the output as expected. - -If you are trying to build a whole package this is not the -right script to run: please start by reading the file 'INSTALL'. - -Report bugs to <bug-automake@gnu.org>. -EOF -    exit $? -    ;; -  -v | --v*) -    echo "compile $scriptversion" -    exit $? -    ;; -  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) -    func_cl_wrapper "$@"      # Doesn't return... -    ;; -esac - -ofile= -cfile= - -for arg -do -  if test -n "$eat"; then -    eat= -  else -    case $1 in -      -o) -	# configure might choose to run compile as 'compile cc -o foo foo.c'. -	# So we strip '-o arg' only if arg is an object. -	eat=1 -	case $2 in -	  *.o | *.obj) -	    ofile=$2 -	    ;; -	  *) -	    set x "$@" -o "$2" -	    shift -	    ;; -	esac -	;; -      *.c) -	cfile=$1 -	set x "$@" "$1" -	shift -	;; -      *) -	set x "$@" "$1" -	shift -	;; -    esac -  fi -  shift -done - -if test -z "$ofile" || test -z "$cfile"; then -  # If no '-o' option was seen then we might have been invoked from a -  # pattern rule where we don't need one.  That is ok -- this is a -  # normal compilation that the losing compiler can handle.  If no -  # '.c' file was seen then we are probably linking.  That is also -  # ok. -  exec "$@" -fi - -# Name of file we expect compiler to create. -cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` - -# Create the lock directory. -# Note: use '[/\\:.-]' here to ensure that we don't use the same name -# that we are using for the .o file.  Also, base the name on the expected -# object file name, since that is what matters with a parallel build. -lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d -while true; do -  if mkdir "$lockdir" >/dev/null 2>&1; then -    break -  fi -  sleep 1 -done -# FIXME: race condition here if user kills between mkdir and trap. -trap "rmdir '$lockdir'; exit 1" 1 2 15 - -# Run the compile. -"$@" -ret=$? - -if test -f "$cofile"; then -  test "$cofile" = "$ofile" || mv "$cofile" "$ofile" -elif test -f "${cofile}bj"; then -  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" -fi - -rmdir "$lockdir" -exit $ret - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/openvpn/doc/openvpn.8 b/openvpn/doc/openvpn.8 index e351fff0..48a88647 100644 --- a/openvpn/doc/openvpn.8 +++ b/openvpn/doc/openvpn.8 @@ -221,7 +221,7 @@ options.  indicates the protocol to use when connecting with the  remote, and may be "tcp" or "udp". -For forcing IPv4 or IPv6 connection suffix tcp or udp  +For forcing IPv4 or IPv6 connection suffix tcp or udp  with 4/6 like udp4/udp6/tcp4/tcp6.  The client will move on to the next host in the list, @@ -481,13 +481,13 @@ seconds (default=10).  .TP  .B \-\-connect-retry-max n  .B n -specifies the number of times all  -.B \-\-remote  -respectively  +specifies the number of times all +.B \-\-remote +respectively  .B <connection> -statements are tried. Specifiying  +statements are tried. Specifiying  .B n -as one would try each entry exactly once. A sucessful connection  +as one would try each entry exactly once. A sucessful connection  resets the counter. (default=umlimited).  .\"*********************************************************  .TP @@ -693,8 +693,8 @@ or  .B \-\-socks-proxy  are used. -If the  -.B \-\-ipv6only +If the +.B ipv6only  keyword is present OpenVPN will bind only to IPv6 (as oposed  to IPv6 and IPv4) when a IPv6 socket is opened. diff --git a/openvpn/src/openvpn/init.c b/openvpn/src/openvpn/init.c index 1beca959..5979e0bb 100644 --- a/openvpn/src/openvpn/init.c +++ b/openvpn/src/openvpn/init.c @@ -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, @@ -306,9 +306,9 @@ 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 freeaddr)  { -    if (lsa->remote_list) { +    if (lsa->remote_list && freeaddr) {          freeaddrinfo(lsa->remote_list);      }      lsa->remote_list = NULL; @@ -325,7 +325,7 @@ next_connection_entry (struct context *c)    bool ce_defined;    struct connection_entry *ce;    int n_cycles = 0; -   +    do {      ce_defined = true;      if (c->options.no_advance && l->current >= 0) @@ -348,19 +348,18 @@ 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); +                clear_remote_addrlist (&c->c1.link_socket_addr, !c->options.resolve_in_advance);              else                  c->c1.link_socket_addr.current_remote =                  c->c1.link_socket_addr.remote_list; - +                          /*               * Increase the number of connection attempts               * If this is connect-retry-max * size(l)               * OpenVPN will quit               */ -             +              c->options.unsuccessful_attempts++;              if (++l->current >= l->len) @@ -399,7 +398,7 @@ next_connection_entry (struct context *c)          }  #endif    } while (!ce_defined); -   +    /* Check if this connection attempt would bring us over the limit */    if (c->options.connect_retry_max > 0 &&        c->options.unsuccessful_attempts > (l->len  * c->options.connect_retry_max)) @@ -560,6 +559,8 @@ context_init_1 (struct context *c)   }  #endif +  if (c->options.resolve_in_advance) +      do_preresolve(c);  }  void @@ -1254,7 +1255,7 @@ void  initialization_sequence_completed (struct context *c, const unsigned int flags)  {    static const char message[] = "Initialization Sequence Completed"; -     +    /* Reset the unsuccessful connection counter on complete initialisation */    c->options.unsuccessful_attempts=0; @@ -2686,8 +2687,10 @@ do_init_socket_1 (struct context *c, const int mode)    link_socket_init_phase1 (c->c2.link_socket,  			   c->options.ce.local,  			   c->options.ce.local_port, +			   c->options.ce.preresolved_local,  			   c->options.ce.remote,  			   c->options.ce.remote_port, +			   c->options.ce.preresolved_remote,  			   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,7 +2919,7 @@ 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) +    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 +3362,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); @@ -3433,7 +3443,7 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int    /* allocate our socket object */    if (c->mode == CM_P2P || c->mode == CM_TOP || c->mode == CM_CHILD_TCP)      do_link_socket_new (c); - +      #ifdef ENABLE_FRAGMENT    /* initialize internal fragmentation object */    if (options->ce.fragment && (c->mode == CM_P2P || child)) @@ -3795,6 +3805,7 @@ test_crypto_thread (void *arg)    ASSERT (options->test_crypto);    init_verb_mute (c, IVM_LEVEL_1);    context_init_1 (c); +  next_connection_entry(c);    do_init_crypto_static (c, 0);    frame_finalize_options (c, options); diff --git a/openvpn/src/openvpn/manage.c b/openvpn/src/openvpn/manage.c index 8217ead2..352021bd 100644 --- a/openvpn/src/openvpn/manage.c +++ b/openvpn/src/openvpn/manage.c @@ -2611,7 +2611,7 @@ management_post_tunnel_open (struct management *man, const in_addr_t tun_local_i        /* listen on our local TUN/TAP IP address */        struct in_addr ia;        int ret; -       +        ia.s_addr = htonl(tun_local_ip);        ret = openvpn_getaddrinfo(0, inet_ntoa(ia), NULL, 0, NULL,                                  AF_INET, &man->settings.local); diff --git a/openvpn/src/openvpn/options.c b/openvpn/src/openvpn/options.c index cfbbfb4f..07a9b896 100644 --- a/openvpn/src/openvpn/options.c +++ b/openvpn/src/openvpn/options.c @@ -780,7 +780,7 @@ init_options (struct options *o, const bool init_gc)    o->topology = TOP_NET30;    o->ce.proto = PROTO_UDP;    o->ce.af = AF_UNSPEC; -  o->ce.bind_local=false; +  o->ce.bind_ipv6_only = false;    o->ce.connect_retry_seconds = 5;    o->ce.connect_timeout = 10;    o->connect_retry_max = 0; @@ -796,6 +796,7 @@ init_options (struct options *o, const bool init_gc)    o->route_delay_window = 30;    o->max_routes = MAX_ROUTES_DEFAULT;    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); @@ -2038,7 +2041,7 @@ options_postprocess_verify_ce (const struct options *options, const struct conne        if (ce->socks_proxy_server)  	msg (M_USAGE, "--socks-proxy cannot be used with --mode server");  #endif -      /* <connection> blocks force to have a remote embedded, so we check for the  +      /* <connection> blocks force to have a remote embedded, so we check for the         * --remote and bail out if it  is present */         if (options->connection_list->len >1 ||                    options->connection_list->array[0]->remote) @@ -2486,6 +2489,7 @@ options_postprocess_verify (const struct options *o)  static void  options_postprocess_mutate (struct options *o)  { +  int i;    /*     * Process helper-type options which map to other, more complex     * sequences of options. @@ -2502,13 +2506,12 @@ options_postprocess_mutate (struct options *o)         * Convert remotes into connection list         */        const struct remote_list *rl = o->remote_list; -      int i;        for (i = 0; i < rl->len; ++i)          {            const struct remote_entry *re = rl->array[i];            struct connection_entry ce = o->ce;            struct connection_entry *ace; -           +            ASSERT (re->remote);            connection_entry_load_re (&ce, re);            ace = alloc_connection_entry (o, M_USAGE); @@ -2525,10 +2528,9 @@ options_postprocess_mutate (struct options *o)      }    ASSERT (o->connection_list); -  int i;    for (i = 0; i < o->connection_list->len; ++i)  	options_postprocess_mutate_ce (o, o->connection_list->array[i]); -   +  #if HTTP_PROXY_OVERRIDE    if (o->http_proxy_override)  	options_postprocess_http_proxy_override(o); @@ -4481,6 +4483,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); diff --git a/openvpn/src/openvpn/options.h b/openvpn/src/openvpn/options.h index dda9658a..ddeb8b38 100644 --- a/openvpn/src/openvpn/options.h +++ b/openvpn/src/openvpn/options.h @@ -90,9 +90,11 @@ 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; +  struct addrinfo *preresolved_remote; +  struct addrinfo *preresolved_local;    bool remote_float;    bool bind_defined;    bool bind_ipv6_only; @@ -278,6 +280,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; diff --git a/openvpn/src/openvpn/push.c b/openvpn/src/openvpn/push.c index 994b7ba7..bd08cff7 100644 --- a/openvpn/src/openvpn/push.c +++ b/openvpn/src/openvpn/push.c @@ -49,7 +49,8 @@ void  receive_auth_failed (struct context *c, const struct buffer *buffer)  {    msg (M_VERB0, "AUTH: Received control message: %s", BSTR(buffer)); -    c->options.no_advance=true; +  c->options.no_advance=true; +    if (c->options.pull)      {        switch (auth_retry_get ()) diff --git a/openvpn/src/openvpn/socket.c b/openvpn/src/openvpn/socket.c index 2605f854..05ae9e91 100644 --- a/openvpn/src/openvpn/socket.c +++ b/openvpn/src/openvpn/socket.c @@ -39,6 +39,7 @@  #include "manage.h"  #include "misc.h"  #include "manage.h" +#include "openvpn.h"  #include "memdbg.h" @@ -118,6 +119,59 @@ getaddr (unsigned int flags,  } +void +do_preresolve(struct context *c) +{ +  int i; +  struct connection_list *l = c->options.connection_list; + + +  for (i = 0; i < l->len; ++i) { +    int status; +    const char *remote; +    struct connection_entry* ce = c->options.connection_list->array[i]; +    unsigned int flags = GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE| +      GETADDR_MENTION_RESOLVE_RETRY|GETADDR_FATAL; + +    if (proto_is_dgram(ce->proto)) +      flags |= GETADDR_DATAGRAM; + +    if (c->options.sockflags & SF_HOST_RANDOMIZE) +      flags |= GETADDR_RANDOMIZE; + +    if (c->options.ip_remote_hint) +      remote = c->options.ip_remote_hint; +    else +      remote = ce->remote; + +    if (! ce->preresolved_remote) +      { +        status = openvpn_getaddrinfo (flags, remote, ce->remote_port, +				  c->options.resolve_retry_seconds, NULL, +				  ce->af, &ce->preresolved_remote); + +    if (status != 0) +      goto err; +      } + +    flags |= GETADDR_PASSIVE; +      if (ce->bind_local && !ce->preresolved_local) +        { +        status = openvpn_getaddrinfo (flags, ce->local, ce->local_port, +                                      c->options.resolve_retry_seconds, NULL, +                                      ce->af, &ce->preresolved_local); + +    if (status != 0) +      goto err; +      } + +  } +  return; + +  err: +    throw_signal_soft (SIGUSR1, "Preresolving failed"); +} +  /*   * Translate IPv4/IPv6 addr or hostname into struct addrinfo   * If resolve error, try again for resolve_retry_seconds seconds. @@ -275,8 +329,8 @@ openvpn_getaddrinfo (unsigned int flags,        /* hostname resolve succeeded */ -      /*  -       * Do not chose an IP Addresse by random or change the order * +      /* +       * Do not choose an IP Addresse by random or change the order *         * of IP addresses, doing so will break RFC 3484 address selection *         */      } @@ -627,7 +681,7 @@ create_socket_udp (const int af, const unsigned int flags)    else if (flags & SF_USE_IP_PKTINFO)      {        int pad = 1; -      if(af == AF_INET)  +      if(af == AF_INET)          {  #ifdef IP_PKTINFO            if (setsockopt (sd, SOL_IP, IP_PKTINFO, @@ -640,8 +694,8 @@ create_socket_udp (const int af, const unsigned int flags)  #else  #error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h)  #endif -        }  -      else if (af == AF_INET6 )  +        } +      else if (af == AF_INET6 )          {  #ifndef IPV6_RECVPKTINFO /* Some older Darwin platforms require this */            if (setsockopt (sd, IPPROTO_IPV6, IPV6_PKTINFO, @@ -665,7 +719,7 @@ create_socket (struct link_socket *sock)    int ai_family = sock->info.lsa->actual.ai_family;    ASSERT (sock->info.af == AF_UNSPEC  || sock->info.af == ai_family); -     +    if (ai_proto == IPPROTO_UDP)      {        sock->sd = create_socket_udp (ai_family, sock->sockflags); @@ -686,10 +740,9 @@ create_socket (struct link_socket *sock)      }      /* set socket buffers based on --sndbuf and --rcvbuf options */      socket_set_buffers (sock->sd, &sock->socket_buffer_sizes); -     +      /* set socket to --mark packets with given value */      socket_set_mark (sock->sd, sock->mark); -      }  #ifdef TARGET_ANDROID @@ -898,13 +951,12 @@ socket_bind (socket_descriptor_t sd,     * For example if an address has multiple A records     * What is the correct way to deal with it?     */ -   +    struct addrinfo* cur; -  int v6only= ipv6only ? 0: 1; -   +    ASSERT(local); -  -     + +    /* find the first addrinfo with correct ai_family */    for (cur = local; cur; cur=cur->ai_next)      { @@ -917,9 +969,11 @@ socket_bind (socket_descriptor_t sd,    if (ai_family == AF_INET6)      { +      int v6only = ipv6only ? 0: 1;	/* setsockopt must have an "int" */ +        if (setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)))  	{ -	  msg (M_NONFATAL|M_ERRNO, "Setting IPV6_V6ONLY failed"); +	  msg (M_NONFATAL|M_ERRNO, "Setting IPV6_V6ONLY=%d failed", v6only);  	}      }    if (bind (sd, cur->ai_addr, cur->ai_addrlen)) @@ -1023,7 +1077,7 @@ void set_actual_address (struct link_socket_actual* actual, struct addrinfo* ai)  {      CLEAR (*actual);      ASSERT (ai); -     +      if (ai->ai_family == AF_INET)          actual->dest.addr.in4 =          *((struct sockaddr_in*) ai->ai_addr); @@ -1032,7 +1086,7 @@ void set_actual_address (struct link_socket_actual* actual, struct addrinfo* ai)          *((struct sockaddr_in6*) ai->ai_addr);      else          ASSERT(0); -     +      /* Copy addrinfo sock parameters for socket creating */      actual->ai_family = ai->ai_family;      actual->ai_protocol = ai->ai_protocol; @@ -1047,9 +1101,9 @@ socket_connect (socket_descriptor_t *sd,  {    struct gc_arena gc = gc_new ();    const struct sockaddr *dest = &lsa->actual.dest.addr.sa; -     +    int status; -       +  #ifdef CONNECT_NONBLOCK    msg (M_INFO, "Attempting to establish TCP connection with %s [nonblock]",         print_sockaddr (dest, &gc)); @@ -1057,14 +1111,14 @@ socket_connect (socket_descriptor_t *sd,    msg (M_INFO, "Attempting to establish TCP connection with %s",         print_sockaddr (dest, &gc));  #endif -       +  #ifdef ENABLE_MANAGEMENT    if (management)  	management_set_state (management, -                          OPENVPN_STATE_TCP_CONNECT, -                          NULL, -                          (in_addr_t)0, -                          (in_addr_t)0); +			      OPENVPN_STATE_TCP_CONNECT, +			      NULL, +			      (in_addr_t)0, +			      (in_addr_t)0);  #endif    /* Set the actual address */ @@ -1154,7 +1208,13 @@ resolve_bind_local (struct link_socket *sock, const sa_family_t af)  	flags |= GETADDR_DATAGRAM;        /* will return AF_{INET|INET6}from local_host */ -      status = openvpn_getaddrinfo(flags, sock->local_host, sock->local_port, 0, +      if (sock->preresolved_local) +	{ +	  status=0; +	  sock->info.lsa->bind_local=sock->preresolved_local; +	} +      else +	status = openvpn_getaddrinfo(flags, sock->local_host, sock->local_port, 0,  				   NULL, af, &sock->info.lsa->bind_local);        if(status !=0) { @@ -1192,104 +1252,104 @@ resolve_remote (struct link_socket *sock,  {    struct gc_arena gc = gc_new (); -  if (!sock->did_resolve_remote) +  /* resolve remote address if undefined */ +  if (!sock->info.lsa->remote_list)      { -      /* resolve remote address if undefined */ -      if (!sock->info.lsa->remote_list) +      if (sock->remote_host)  	{ -	  if (sock->remote_host) +	  unsigned int flags = sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sock->sockflags); +	  int retry = 0; +	  int status = -1; +	  struct addrinfo* ai; +	  if (proto_is_dgram(sock->info.proto)) +	    flags |= GETADDR_DATAGRAM; + +	  if (sock->resolve_retry_seconds == RESOLV_RETRY_INFINITE) +	    { +	      if (phase == 2) +		flags |= (GETADDR_TRY_ONCE | GETADDR_FATAL); +	      retry = 0; +	    } +	  else if (phase == 1)  	    { -	      unsigned int flags = sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sock->sockflags); -	      int retry = 0; -	      int status = -1; -              struct addrinfo* ai; -              if (proto_is_dgram(sock->info.proto)) -                  flags |= GETADDR_DATAGRAM; - -	      if (sock->resolve_retry_seconds == RESOLV_RETRY_INFINITE) +	      if (sock->resolve_retry_seconds)  		{ -		  if (phase == 2) -		    flags |= (GETADDR_TRY_ONCE | GETADDR_FATAL);  		  retry = 0;  		} -	      else if (phase == 1) +	      else  		{ -		  if (sock->resolve_retry_seconds) -		    { -		      retry = 0; -		    } -		  else -		    { -		      flags |= (GETADDR_FATAL | GETADDR_MENTION_RESOLVE_RETRY); -		      retry = 0; -		    } +		  flags |= (GETADDR_FATAL | GETADDR_MENTION_RESOLVE_RETRY); +		  retry = 0;  		} -	      else if (phase == 2) +	    } +	  else if (phase == 2) +	    { +	      if (sock->resolve_retry_seconds)  		{ -		  if (sock->resolve_retry_seconds) -		    { -		      flags |= GETADDR_FATAL; -		      retry = sock->resolve_retry_seconds; -		    } -		  else -		    { -		      ASSERT (0); -		    } +		  flags |= GETADDR_FATAL; +		  retry = sock->resolve_retry_seconds;  		}  	      else  		{  		  ASSERT (0);  		} +	    } +	  else +	    { +	      ASSERT (0); +	    } -	      status = openvpn_getaddrinfo (flags, sock->remote_host, sock->remote_port, -					    retry, signal_received, sock->info.af, &ai); - -	      if(status == 0) { -		sock->info.lsa->remote_list = ai; -		sock->info.lsa->current_remote = ai; - -		dmsg (D_SOCKET_DEBUG, "RESOLVE_REMOTE flags=0x%04x phase=%d rrs=%d sig=%d status=%d", -		      flags, -		      phase, -		      retry, -		      signal_received ? *signal_received : -1, -		      status); -	      } +	  if (sock->preresolved_remote) +	    { +	      status = 0; +	      ai = sock->preresolved_remote; +	    } +	  else +	    status = openvpn_getaddrinfo (flags, sock->remote_host, sock->remote_port, +					  retry, signal_received, sock->info.af, &ai); + +	  if(status == 0) { +	    sock->info.lsa->remote_list = ai; +	    sock->info.lsa->current_remote = ai; + +	    dmsg (D_SOCKET_DEBUG, "RESOLVE_REMOTE flags=0x%04x phase=%d rrs=%d sig=%d status=%d", +		  flags, +		  phase, +		  retry, +		  signal_received ? *signal_received : -1, +		  status); +	  } +	  if (signal_received) +	    { +	      if (*signal_received) +		goto done; +	    } +	  if (status!=0) +	    {  	      if (signal_received) -		{ -		  if (*signal_received) -		    goto done; -		} -	      if (status!=0) -		{ -		  if (signal_received) -		    *signal_received = SIGUSR1; -		  goto done; -		} +		*signal_received = SIGUSR1; +	      goto done;  	    }  	} +    } -      /* should we re-use previous active remote address? */ -      if (link_socket_actual_defined (&sock->info.lsa->actual)) -	{ -	  msg (M_INFO, "TCP/UDP: Preserving recently used remote address: %s", -	       print_link_socket_actual (&sock->info.lsa->actual, &gc)); -	  if (remote_dynamic) -	    *remote_dynamic = NULL; -	} -      /*      else, quick hack to fix persistent-remote ....*/ -	{ -          CLEAR (sock->info.lsa->actual); -          if(sock->info.lsa->current_remote) -            { -              set_actual_address (&sock->info.lsa->actual, -                                  sock->info.lsa->current_remote); -            } -	} - -      /* remember that we finished */ -      sock->did_resolve_remote = true; +  /* should we re-use previous active remote address? */ +  if (link_socket_actual_defined (&sock->info.lsa->actual)) +    { +      msg (M_INFO, "TCP/UDP: Preserving recently used remote address: %s", +	   print_link_socket_actual (&sock->info.lsa->actual, &gc)); +      if (remote_dynamic) +	*remote_dynamic = NULL;      } +  /*      else, quick hack to fix persistent-remote ....*/ +  { +    CLEAR (sock->info.lsa->actual); +    if(sock->info.lsa->current_remote) +      { +	set_actual_address (&sock->info.lsa->actual, +			    sock->info.lsa->current_remote); +      } +  }   done:    gc_free (&gc); @@ -1317,11 +1377,11 @@ create_new_socket (struct link_socket* sock)        resolve_bind_local (sock, sock->info.af);    }    resolve_remote (sock, 1, NULL, NULL); -   +    /*     * In P2P or server mode we must create the socket even when resolving     * the remote site fails/is not specified. */ -     +    if (sock->info.lsa->actual.ai_family==0 && sock->bind_local)      {        /* Copy sock parameters from bind addr */ @@ -1329,8 +1389,8 @@ 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) @@ -1340,6 +1400,7 @@ create_new_socket (struct link_socket* sock)        if (sock->bind_local)            bind_local(sock);      } +  } @@ -1348,8 +1409,10 @@ void  link_socket_init_phase1 (struct link_socket *sock,  			 const char *local_host,  			 const char *local_port, +			 struct addrinfo *local_preresolved,  			 const char *remote_host,  			 const char *remote_port, +			 struct addrinfo *remote_preresolved,  			 int proto,  			 sa_family_t af,  			 bool bind_ipv6_only, @@ -1382,8 +1445,10 @@ link_socket_init_phase1 (struct link_socket *sock,    sock->local_host = local_host;    sock->local_port = local_port; +  sock->preresolved_local = local_preresolved;    sock->remote_host = remote_host;    sock->remote_port = remote_port; +  sock->preresolved_remote = remote_preresolved;  #ifdef ENABLE_HTTP_PROXY    sock->http_proxy = http_proxy; @@ -1425,7 +1490,7 @@ link_socket_init_phase1 (struct link_socket *sock,        ASSERT (!sock->inetd);        sock->sd = accept_from->sd;      } -     +    if (false)      ;  #ifdef ENABLE_HTTP_PROXY @@ -1560,39 +1625,35 @@ static void  linksock_print_addr (struct link_socket *sock)  {    struct gc_arena gc = gc_new (); +  const int msglevel = (sock->mode == LS_MODE_TCP_ACCEPT_FROM) ? D_INIT_MEDIUM : M_INFO; -  /* print local address */ -  { -    const int msglevel = (sock->mode == LS_MODE_TCP_ACCEPT_FROM) ? D_INIT_MEDIUM : M_INFO; - -    if (sock->inetd) -      msg (msglevel, "%s link local: [inetd]", proto2ascii (sock->info.proto, sock->info.af, true)); -    else if (sock->bind_local) -      { -	/* Socket is always bound on the first matching address */ -	struct addrinfo *cur; -	for (cur = sock->info.lsa->bind_local; cur; cur=cur->ai_next) -	  { -	    if(cur->ai_family == sock->info.lsa->actual.ai_family) -		break; -	  } -	ASSERT (cur); -	msg (msglevel, "%s link local (bound): %s", + if (sock->inetd) +    msg (msglevel, "%s link local: [inetd]", proto2ascii (sock->info.proto, sock->info.af, true)); +  else if (sock->bind_local) +    { +      /* Socket is always bound on the first matching address */ +      struct addrinfo *cur; +      for (cur = sock->info.lsa->bind_local; cur; cur=cur->ai_next) +	{ +	  if(cur->ai_family == sock->info.lsa->actual.ai_family) +	    break; +	} +      ASSERT (cur); +      msg (msglevel, "%s link local (bound): %s",  	   proto2ascii (sock->info.proto, sock->info.af, true),  	   print_sockaddr(cur->ai_addr,&gc)); -      } -    else -	msg (msglevel, "%s link local: (not bound)", -	     proto2ascii (sock->info.proto, sock->info.af, true)); - -    /* print active remote address */ -    msg (msglevel, "%s link remote: %s", -	 proto2ascii (sock->info.proto, sock->info.af, true), -	 print_link_socket_actual_ex (&sock->info.lsa->actual, -				      ":", -				      PS_SHOW_PORT_IF_DEFINED, -				      &gc)); -  } +    } +  else +    msg (msglevel, "%s link local: (not bound)", +	 proto2ascii (sock->info.proto, sock->info.af, true)); + +  /* print active remote address */ +  msg (msglevel, "%s link remote: %s", +       proto2ascii (sock->info.proto, sock->info.af, true), +       print_link_socket_actual_ex (&sock->info.lsa->actual, +				    ":", +				    PS_SHOW_PORT_IF_DEFINED, +				    &gc));    gc_free(&gc);  } @@ -1631,7 +1692,6 @@ phase2_tcp_server (struct link_socket *sock, const char *remote_dynamic,      default:        ASSERT (0);      } -  } @@ -1645,9 +1705,9 @@ phase2_tcp_client (struct link_socket *sock, struct signal_info *sig_info)  #endif    do {      socket_connect (&sock->sd, -		    sock->info.lsa, -		    sock->connect_timeout, -		    sig_info); +                   sock->info.lsa, +                   sock->connect_timeout, +                   sig_info);      if (sig_info->signal_received)        return; @@ -1678,7 +1738,7 @@ phase2_tcp_client (struct link_socket *sock, struct signal_info *sig_info)      if (proxy_retry)        {  	/* TODO (schwabe): This code assumes AF_INET for the proxy socket -	 * when retrying a connection */ +         * when retrying a connection */  	openvpn_close_socket (sock->sd);  	sock->sd = create_socket_tcp (AF_INET);        } @@ -1698,7 +1758,7 @@ phase2_socks_client (struct link_socket *sock, struct signal_info *sig_info)      if (sig_info->signal_received)  	return; -  +      establish_socks_proxy_udpassoc (sock->socks_proxy,  				    sock->ctrl_sd,  				    sock->sd, @@ -1710,7 +1770,6 @@ phase2_socks_client (struct link_socket *sock, struct signal_info *sig_info)      sock->remote_host = sock->proxy_dest_host;      sock->remote_port = sock->proxy_dest_port; -    sock->did_resolve_remote = false;      addr_zero_host(&sock->info.lsa->actual.dest);      if (sock->info.lsa->remote_list) @@ -2482,12 +2541,17 @@ struct proto_names {  /* Indexed by PROTO_x */  static const struct proto_names proto_names[] = {    {"proto-uninitialized",        "proto-NONE", AF_UNSPEC, PROTO_NONE}, +  /* try IPv4 and IPv6 (client), bind dual-stack (server) */    {"udp",        "UDP", AF_UNSPEC, PROTO_UDP}, -  {"udp4",        "UDPv4", AF_INET, PROTO_UDP}, -  {"tcp-server", "TCPv4_SERVER", AF_INET, PROTO_TCP_SERVER}, -  {"tcp-client", "TCPv4_CLIENT", AF_INET, PROTO_TCP_CLIENT}, +  {"tcp-server", "TCP_SERVER", AF_UNSPEC, PROTO_TCP_SERVER}, +  {"tcp-client", "TCP_CLIENT", AF_UNSPEC, PROTO_TCP_CLIENT},    {"tcp",        "TCP", AF_UNSPEC, PROTO_TCP}, -  {"tcp4",        "TCPv4", AF_INET, PROTO_TCP}, +  /* force IPv4 */ +  {"udp4",       "UDPv4", AF_INET, PROTO_UDP}, +  {"tcp4-server","TCPv4_SERVER", AF_INET, PROTO_TCP_SERVER}, +  {"tcp4-client","TCPv4_CLIENT", AF_INET, PROTO_TCP_CLIENT}, +  {"tcp4",       "TCPv4", AF_INET, PROTO_TCP}, +  /* force IPv6 */    {"udp6"       ,"UDPv6", AF_INET6, PROTO_UDP},    {"tcp6-server","TCPv6_SERVER", AF_INET6, PROTO_TCP_SERVER},    {"tcp6-client","TCPv6_CLIENT", AF_INET6, PROTO_TCP_CLIENT}, diff --git a/openvpn/src/openvpn/socket.h b/openvpn/src/openvpn/socket.h index 3f8318f5..8a118cd1 100644 --- a/openvpn/src/openvpn/socket.h +++ b/openvpn/src/openvpn/socket.h @@ -85,7 +85,7 @@ struct link_socket_actual   int ai_socktype;	/* SOCK_xxx */   int ai_protocol;	/* 0 or IPPROTO_xxx for IPv4 and IPv6 */ -     +    struct openvpn_sockaddr dest;  #if ENABLE_IP_PKTINFO    union { @@ -104,7 +104,7 @@ struct link_socket_addr  {    struct addrinfo* bind_local;    struct addrinfo* remote_list;   /* complete remote list */ -  struct addrinfo* current_remote;  /* remote used in the  +  struct addrinfo* current_remote;  /* remote used in the                                       current connection attempt */    struct link_socket_actual actual; /* reply to this address */  }; @@ -186,8 +186,10 @@ struct link_socket    const char *remote_host;    const char *remote_port; +  struct addrinfo *preresolved_remote;    const char *local_host;    const char *local_port; +  struct addrinfo *preresolved_local;    bool bind_local;  # define INETD_NONE   0 @@ -208,8 +210,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 +298,8 @@ int openvpn_connect (socket_descriptor_t sd,  		     int connect_timeout,  		     volatile int *signal_received); + +  /*   * Initialize link_socket object.   */ @@ -306,8 +308,10 @@ void  link_socket_init_phase1 (struct link_socket *sock,  			 const char *local_host,  			 const char *local_port, +			 struct addrinfo *local_preresolved,  			 const char *remote_host,  			 const char *remote_port, +			 struct addrinfo *remote_preresolved,  			 int proto,  			 sa_family_t af,  			 bool bind_ipv6_only, @@ -340,6 +344,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); @@ -644,35 +650,36 @@ link_socket_actual_defined (const struct link_socket_actual *act)  static inline bool  addr_match (const struct openvpn_sockaddr *a1, const struct openvpn_sockaddr *a2)  { -    switch(a1->addr.sa.sa_family) { -        case AF_INET: -            return a1->addr.in4.sin_addr.s_addr == a2->addr.in4.sin_addr.s_addr; -        case AF_INET6: -            return IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &a2->addr.in6.sin6_addr); -    } -    ASSERT(0); -    return false; +  switch(a1->addr.sa.sa_family) { +    case AF_INET: +      return a1->addr.in4.sin_addr.s_addr == a2->addr.in4.sin_addr.s_addr; +    case AF_INET6: +      return IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &a2->addr.in6.sin6_addr); +  } +  ASSERT(0); +  return false;  }  static inline bool  addrlist_match (const struct openvpn_sockaddr *a1, const struct addrinfo *addrlist)  {    const struct addrinfo *curele; -  for (curele = addrlist; curele; curele=curele->ai_next) { - -    switch(a1->addr.sa.sa_family) { -    case AF_INET: -      if (a1->addr.in4.sin_addr.s_addr == ((struct sockaddr_in*)curele->ai_addr)->sin_addr.s_addr) -        return true; -      break; -    case AF_INET6: -      if (IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &((struct sockaddr_in6*) curele->ai_addr)->sin6_addr)) -        return true; -      break; -    default: -      ASSERT(0); +  for (curele = addrlist; curele; curele=curele->ai_next) +    { +      switch(a1->addr.sa.sa_family) +        { +	  case AF_INET: +	    if (a1->addr.in4.sin_addr.s_addr == ((struct sockaddr_in*)curele->ai_addr)->sin_addr.s_addr) +	      return true; +	    break; +	  case AF_INET6: +	    if (IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &((struct sockaddr_in6*) curele->ai_addr)->sin6_addr)) +	      return true; +	    break; +	  default: +	    ASSERT(0); +        }      } -  }    return false;  } @@ -693,26 +700,28 @@ addr_host (const struct openvpn_sockaddr *addr)  static inline bool  addrlist_port_match (const struct openvpn_sockaddr *a1, const struct addrinfo *a2)  { -    const struct addrinfo *curele; -    for(curele=a2;curele;curele = curele->ai_next) { -        switch(a1->addr.sa.sa_family) { -            case AF_INET: +  const struct addrinfo *curele; +  for(curele=a2;curele;curele = curele->ai_next) +    { +      switch(a1->addr.sa.sa_family) +        { +          case AF_INET:              if (curele->ai_family == AF_INET                  && a1->addr.in4.sin_addr.s_addr == ((struct sockaddr_in*)curele->ai_addr)->sin_addr.s_addr                  && a1->addr.in4.sin_port == ((struct sockaddr_in*)curele->ai_addr)->sin_port)                  return true;                  break; -            case AF_INET6: +          case AF_INET6:                  if (curele->ai_family == AF_INET6                  && IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &((struct sockaddr_in6*) curele->ai_addr)->sin6_addr)                  && a1->addr.in6.sin6_port == ((struct sockaddr_in6*) curele->ai_addr)->sin6_port)                      return true;                  break; -            default: +          default:                  ASSERT(0);          }      } -    return false; +  return false;  } @@ -725,7 +734,7 @@ addr_port_match (const struct openvpn_sockaddr *a1, const struct openvpn_sockadd        return a1->addr.in4.sin_addr.s_addr == a2->addr.in4.sin_addr.s_addr  	&& a1->addr.in4.sin_port == a2->addr.in4.sin_port;      case AF_INET6: -      return IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &a2->addr.in6.sin6_addr)  +      return IN6_ARE_ADDR_EQUAL(&a1->addr.in6.sin6_addr, &a2->addr.in6.sin6_addr)  	&& a1->addr.in6.sin6_port == a2->addr.in6.sin6_port;    }    ASSERT(0); @@ -734,10 +743,10 @@ addr_port_match (const struct openvpn_sockaddr *a1, const struct openvpn_sockadd  static inline bool  addr_match_proto (const struct openvpn_sockaddr *a1, -                      const struct openvpn_sockaddr *a2, -                      const int proto) +		  const struct openvpn_sockaddr *a2, +		  const int proto)  { -    return link_socket_proto_connection_oriented (proto) +  return link_socket_proto_connection_oriented (proto)      ? addr_match (a1, a2)      : addr_port_match (a1, a2);  } @@ -745,8 +754,8 @@ addr_match_proto (const struct openvpn_sockaddr *a1,  static inline bool  addrlist_match_proto (const struct openvpn_sockaddr *a1, -		  struct addrinfo *addr_list, -		  const int proto) +		      struct addrinfo *addr_list, +		      const int proto)  {    return link_socket_proto_connection_oriented (proto)      ? addrlist_match (a1, addr_list) @@ -895,14 +904,15 @@ link_socket_set_outgoing_addr (const struct buffer *buf,      {        struct link_socket_addr *lsa = info->lsa;        if ( -	  (  	   /* new or changed address? */  	   (!info->connection_established -	    || !addr_match_proto (&act->dest, &lsa->actual.dest, info->proto)) +	    || !addr_match_proto (&act->dest, &lsa->actual.dest, info->proto) +	    ) +	   &&  	   /* address undef or address == remote or --float */ -	   && (info->remote_float -	       || !lsa->remote_list)) -	  || addrlist_match_proto (&act->dest, lsa->remote_list, info->proto) +	   (info->remote_float || +	    (!lsa->remote_list || addrlist_match_proto (&act->dest, lsa->remote_list, info->proto)) +	    )  	  )  	{  	  link_socket_connection_initiated (buf, info, act, common_name, es); diff --git a/openvpn/src/openvpn/ssl_openssl.c b/openvpn/src/openvpn/ssl_openssl.c index 120aa666..f41bb711 100644 --- a/openvpn/src/openvpn/ssl_openssl.c +++ b/openvpn/src/openvpn/ssl_openssl.c @@ -682,10 +682,11 @@ tls_ctx_use_external_private_key (struct tls_root_ctx *ctx,    X509 *cert = NULL;    ASSERT (NULL != ctx); -  ASSERT (NULL != cert);    tls_ctx_load_cert_file_and_copy (ctx, cert_file, cert_file_inline, &cert); +  ASSERT (NULL != cert); +    /* allocate custom RSA method object */    ALLOC_OBJ_CLEAR (rsa_meth, RSA_METHOD);    rsa_meth->name = "OpenVPN external private key RSA Method"; diff --git a/openvpn/src/openvpn/tun.c b/openvpn/src/openvpn/tun.c index c1dcc5e2..9e3e8b9e 100644 --- a/openvpn/src/openvpn/tun.c +++ b/openvpn/src/openvpn/tun.c @@ -473,8 +473,8 @@ init_tun (const char *dev,       /* --dev option */  	   * If local_public or remote_public addresses are defined,  	   * make sure they do not clash with our virtual subnet.  	   */ -           -          for(curele=remote_public;curele;curele=curele->ai_next) { + +          for(curele=local_public;curele;curele=curele->ai_next) {              if(curele->ai_family == AF_INET)                check_addr_clash ("local",  			    tt->type, diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java index f4771bc1..a9232eee 100644 --- a/src/de/blinkt/openvpn/VpnProfile.java +++ b/src/de/blinkt/openvpn/VpnProfile.java @@ -391,8 +391,8 @@ public class VpnProfile implements Serializable {          if (mPersistTun) {              cfg += "persist-tun\n"; -            cfg += "# persist-tun also sets persist-remote-ip to avoid DNS resolve problem\n"; -            cfg += "persist-remote-ip\n"; +            cfg += "# persist-tun also enables pre resolving to avoid DNS resolve problem\n"; +            cfg += "preresolve\n";          }          SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); | 
