diff -pruN 3:5.44-1/build-android.sh 3:5.49-1/build-android.sh
--- 3:5.44-1/build-android.sh	2017-11-14 14:01:47.000000000 +0000
+++ 3:5.49-1/build-android.sh	2018-08-09 05:43:52.000000000 +0000
@@ -1,6 +1,6 @@
 #!/bin/sh
 set -ev
-VERSION=5.44
+VERSION=5.49
 DST=stunnel-$VERSION-android
 
 # to build OpenSSL:
diff -pruN 3:5.44-1/ChangeLog 3:5.49-1/ChangeLog
--- 3:5.44-1/ChangeLog	2017-11-26 22:03:02.000000000 +0000
+++ 3:5.49-1/ChangeLog	2018-09-03 20:15:38.000000000 +0000
@@ -1,5 +1,74 @@
 stunnel change log
 
+Version 5.49, 2018.09.03, urgency: MEDIUM
+* New features
+  - Performance optimizations.
+  - Logging of negotiated or resumed TLS session IDs (thx
+    to ANSSI - National Cybersecurity Agency of France).
+  - Merged Debian 10-enabled.patch and 11-killproc.patch
+    (thx to Peter Pentchev).
+  - OpenSSL DLLs updated to version 1.0.2p.
+  - PKCS#11 engine DLL updated to version 0.4.9.
+* Bugfixes
+  - Fixed a crash in the session persistence implementation.
+  - Fixed syslog identifier after configuration file reload.
+  - Fixed non-interactive "make check" invocations.
+  - Fixed reloading syslog configuration.
+  - stunnel.pem created with SHA-256 instead of SHA-1.
+  - SHA-256 "make check" certificates.
+
+Version 5.48, 2018.07.02, urgency: HIGH
+* Security bugfixes
+  - Fixed requesting client certificate when specified
+    as a global option.
+* New features
+  - Certificate subject checks modified to accept certificates
+    if at least one of the specified checks matches.
+
+Version 5.47, 2018.06.23, urgency: HIGH
+* New features
+  - Fast add_lock_callback for OpenSSL < 1.1.0.
+    This largely improves performance on heavy load.
+  - Automatic detection of Homebrew OpenSSL.
+  - Clarified port binding error logs.
+  - Various "make test" improvements.
+* Bugfixes
+  - Fixed a crash on switching to SNI slave sections.
+
+Version 5.46, 2018.05.28, urgency: MEDIUM
+* New features
+  - The default cipher list was updated to a safer value:
+    "HIGH:!aNULL:!SSLv2:!DH:!kDHEPSK".
+* Bugfixes
+  - Default accept address restored to INADDR_ANY.
+
+Version 5.45, 2018.05.21, urgency: MEDIUM
+* New feature sponsored by https://loadbalancer.org/
+  - Implemented delayed deallocation of service sections
+    after configuration file reload.
+* Other new features
+  - OpenSSL DLLs updated to version 1.0.2o.
+  - Deprecated the sslVersion option.
+  - The "socket" option is now also available in service sections.
+  - Implemented try-restart in the SysV init script (thx to
+    Peter Pentchev).
+  - TLS 1.3 compliant session handling for OpenSSL 1.1.1.
+  - Default "failover" value changed from "rr" to "prio".
+  - New "make check" tests.
+* Bugfixes
+  - A service no longer refuses to start if binding fails for
+    some (but not all) addresses:ports.
+  - Fixed compression handling with OpenSSL 1.1.0 and later.
+  - _beginthread() replaced with safer _beginthreadex().
+  - Fixed exception handling in libwrap.
+  - Fixed exec+connect services.
+  - Fixed automatic resolver delaying.
+  - Fixed a Gentoo cross-compilation bug (thx to Joe Harvell).
+  - A number of "make check" framework fixes.
+  - Fixed false postive memory leak logs.
+  - Build fixes for OpenSSL versions down to 0.9.7.
+  - Fixed (again) round-robin failover in the FORK threading model.
+
 Version 5.44, 2017.11.26, urgency: MEDIUM
 * New features
   - Signed Win32 executables, libraries, and installer.
diff -pruN 3:5.44-1/configure 3:5.49-1/configure
--- 3:5.44-1/configure	2017-11-14 14:07:50.000000000 +0000
+++ 3:5.49-1/configure	2018-08-31 14:51:17.000000000 +0000
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for stunnel 5.44.
+# Generated by GNU Autoconf 2.69 for stunnel 5.49.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='stunnel'
 PACKAGE_TARNAME='stunnel'
-PACKAGE_VERSION='5.44'
-PACKAGE_STRING='stunnel 5.44'
+PACKAGE_VERSION='5.49'
+PACKAGE_STRING='stunnel 5.49'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1340,7 +1340,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures stunnel 5.44 to adapt to many kinds of systems.
+\`configure' configures stunnel 5.49 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1411,7 +1411,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of stunnel 5.44:";;
+     short | recursive ) echo "Configuration of stunnel 5.49:";;
    esac
   cat <<\_ACEOF
 
@@ -1530,7 +1530,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-stunnel configure 5.44
+stunnel configure 5.49
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2136,7 +2136,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by stunnel $as_me 5.44, which was
+It was created by stunnel $as_me 5.49, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3005,7 +3005,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='stunnel'
- VERSION='5.44'
+ VERSION='5.49'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -16266,6 +16266,7 @@ if test -z "$sysroot" -o "x$sysroot" = "
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: /" >&5
 $as_echo "/" >&6; }
 else
+    SYSROOT="$sysroot"
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sysroot" >&5
 $as_echo "$sysroot" >&6; }
 fi
@@ -16277,7 +16278,13 @@ check_ssl_dir() { :
 find_ssl_dir() { :
     stunnel_prefix="$prefix"
     test "x$stunnel_prefix" = "xNONE" && stunnel_prefix=$ac_default_prefix
-    for main_dir in "$stunnel_prefix" "/usr/local" "/usr/lib" "/usr/pkg" "/opt/local" "/opt" "/opt/csw" "/usr" ""; do
+    # OpenSSL directory search order:
+    # - the user-specified prefix
+    # - common locations for packages built from sources
+    # - common locations for non-OS-default package managers
+    # - common locations for OS-default package managers
+    # - empty prefix
+    for main_dir in "$stunnel_prefix" "/usr/local" "/opt" "/opt/local" "/usr/local/opt" "/opt/csw" "/usr/pkg" "/usr/lib" "/usr" ""; do
         for sub_dir in "/ssl" "/openssl" "/ossl" ""; do
             check_ssl_dir "$sysroot$main_dir$sub_dir" && return
         done
@@ -16351,7 +16358,7 @@ LIBS="$valid_LIBS"
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: **************************************** write the results" >&5
 $as_echo "$as_me: **************************************** write the results" >&6;}
-ac_config_files="$ac_config_files Makefile src/Makefile doc/Makefile tools/Makefile tests/Makefile"
+ac_config_files="$ac_config_files Makefile src/Makefile doc/Makefile tools/Makefile tests/Makefile tests/certs/Makefile"
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -16887,7 +16894,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_wri
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by stunnel $as_me 5.44, which was
+This file was extended by stunnel $as_me 5.49, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -16953,7 +16960,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-stunnel config.status 5.44
+stunnel config.status 5.49
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -17373,6 +17380,7 @@ do
     "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
     "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;;
     "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
+    "tests/certs/Makefile") CONFIG_FILES="$CONFIG_FILES tests/certs/Makefile" ;;
 
   *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac
diff -pruN 3:5.44-1/configure.ac 3:5.49-1/configure.ac
--- 3:5.44-1/configure.ac	2017-11-14 14:01:47.000000000 +0000
+++ 3:5.49-1/configure.ac	2018-08-31 14:49:02.000000000 +0000
@@ -1,6 +1,6 @@
 # Process this file with autoconf to produce a configure script.
 
-AC_INIT([stunnel],[5.44])
+AC_INIT([stunnel],[5.49])
 AC_MSG_NOTICE([**************************************** initialization])
 AC_CONFIG_AUX_DIR(auto)
 AC_CONFIG_MACRO_DIR([m4])
@@ -405,6 +405,7 @@ if test -z "$sysroot" -o "x$sysroot" = "
     sysroot=""
     AC_MSG_RESULT([/])
 else
+    SYSROOT="$sysroot"
     AC_MSG_RESULT([$sysroot])
 fi
 
@@ -415,7 +416,13 @@ check_ssl_dir() { :
 find_ssl_dir() { :
     stunnel_prefix="$prefix"
     test "x$stunnel_prefix" = "xNONE" && stunnel_prefix=$ac_default_prefix
-    for main_dir in "$stunnel_prefix" "/usr/local" "/usr/lib" "/usr/pkg" "/opt/local" "/opt" "/opt/csw" "/usr" ""; do
+    # OpenSSL directory search order:
+    # - the user-specified prefix
+    # - common locations for packages built from sources
+    # - common locations for non-OS-default package managers
+    # - common locations for OS-default package managers
+    # - empty prefix
+    for main_dir in "$stunnel_prefix" "/usr/local" "/opt" "/opt/local" "/usr/local/opt" "/opt/csw" "/usr/pkg" "/usr/lib" "/usr" ""; do
         for sub_dir in "/ssl" "/openssl" "/ossl" ""; do
             check_ssl_dir "$sysroot$main_dir$sub_dir" && return
         done
@@ -461,7 +468,7 @@ CPPFLAGS="$valid_CPPFLAGS"
 LIBS="$valid_LIBS"
 
 AC_MSG_NOTICE([**************************************** write the results])
-AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile tools/Makefile tests/Makefile])
+AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile tools/Makefile tests/Makefile tests/certs/Makefile])
 AC_OUTPUT
 
 AC_MSG_NOTICE([**************************************** success])
diff -pruN 3:5.44-1/COPYING 3:5.49-1/COPYING
--- 3:5.44-1/COPYING	2017-01-02 14:27:26.000000000 +0000
+++ 3:5.49-1/COPYING	2018-04-06 14:25:10.000000000 +0000
@@ -1,6 +1,6 @@
 stunnel license (see COPYRIGHT.GPL for detailed GPL conditions)
 
-Copyright (C) 1998-2017 Michal Trojnara
+Copyright (C) 1998-2018 Michal Trojnara
 
 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
diff -pruN 3:5.44-1/debian/changelog 3:5.49-1/debian/changelog
--- 3:5.44-1/debian/changelog	2017-11-27 12:12:39.000000000 +0000
+++ 3:5.49-1/debian/changelog	2018-09-10 09:05:18.000000000 +0000
@@ -1,3 +1,83 @@
+stunnel4 (3:5.49-1) unstable; urgency=medium
+
+  * Declare compliance with Debian Policy 4.2.1 with no changes.
+  * Use the B-D: debhelper-compat (= 11) mechanism.
+  * New upstream version:
+    - drop the 10-enabled and 11-killproc patches, integrated upstream
+    - refresh patch line numbers
+    - reenable the upstream test suite, both at build time and as
+      an autopkgtest, since this upstream version Closes: #906981
+
+ -- Peter Pentchev <roam@debian.org>  Mon, 10 Sep 2018 12:05:18 +0300
+
+stunnel4 (3:5.48-2) unstable; urgency=medium
+
+  * Bring up to compliance with Debian Policy 4.2.0: install
+    the upstream release notes as "NEWS" instead of "changelog".
+  * Temporarily disable the upstream test suite, both during the build
+    and as an autopkgtest, until #906981 is fixed.  Add the requisite
+    Perl module build dependencies.
+  * Also add Unicode::UTF8 as a dependency for our test program.
+
+ -- Peter Pentchev <roam@debian.org>  Fri, 24 Aug 2018 23:47:08 +0300
+
+stunnel4 (3:5.48-1) unstable; urgency=high
+
+  * Declare compliance with Debian Policy 4.1.5 with no changes.
+  * New upstream version.
+
+ -- Peter Pentchev <roam@debian.org>  Fri, 13 Jul 2018 17:18:17 +0300
+
+stunnel4 (3:5.47-1) unstable; urgency=high
+
+  * New upstream release with a fix for a SNI mode crash,
+    add a build and test dependency on net-tools now needed for
+    the upstream test suite.
+
+ -- Peter Pentchev <roam@debian.org>  Mon, 25 Jun 2018 11:28:17 +0300
+
+stunnel4 (3:5.46-1) unstable; urgency=medium
+
+  * New upstream release.
+
+ -- Peter Pentchev <roam@debian.org>  Tue, 29 May 2018 02:04:44 +0300
+
+stunnel4 (3:5.45-1) unstable; urgency=medium
+
+  * New upstream version:
+    - drop the 09-try-restart patch, integrated upstream
+    - drop the 12-disable-tests patch, no longer needed
+    - refresh patch line numbers
+    - update the upstream copyright years
+
+ -- Peter Pentchev <roam@debian.org>  Thu, 24 May 2018 17:15:06 +0300
+
+stunnel4 (3:5.44-2) unstable; urgency=medium
+
+  * Declare compliance with Debian Policy 4.1.4 with no changes.
+  * Add procps to the build dependencies for the upstream test suite.
+  * Bump the debhelper compat level to 11 with no changes.
+  * Bump the year on my debian/* copyright notice.
+  * Change the way the service handles the lack of default configuration:
+    - drop the ENABLED option from /etc/defaults/stunnel4
+    - let debhelper take care of not starting the service immediately
+      after installation (when there are no valid config files yet)
+    - add a NEWS blurb pointing out how to disable the service if it
+      is indeed meant to only be started on demand
+  * Let the init script actually wait for the old stunnel instances to
+    stop before starting the new ones or even reporting that the old
+    ones are dead.  Closes: #782030
+  * Use my Debian e-mail address.
+  * Point the Vcs-* URLs to salsa.debian.org.
+  * Temporarily drop two tests that rely on an expired certificate and
+    an expired CRL.  Closes: #895954, #899130
+  * Drop an empty line at the end of the Debian changelog file.
+  * Drop the "CAs" spelling error override, since recent versions of
+    Lintian do not consider it an error any more.
+  * Add a trivial autopkgtest running adequate on the installed package.
+
+ -- Peter Pentchev <roam@debian.org>  Mon, 21 May 2018 18:23:00 +0300
+
 stunnel4 (3:5.44-1) unstable; urgency=medium
 
   * New upstream release, drop the 10-accept patch taken from upstream.
@@ -1321,4 +1401,3 @@ stunnel (2.1-1) unstable; urgency=low
   * Initial release.
 
  -- Paolo Molaro <lupus@debian.org>  Mon, 30 Nov 1998 11:41:29 +0100
-
diff -pruN 3:5.44-1/debian/compat 3:5.49-1/debian/compat
--- 3:5.44-1/debian/compat	2016-06-27 08:17:21.000000000 +0000
+++ 3:5.49-1/debian/compat	1970-01-01 00:00:00.000000000 +0000
@@ -1 +0,0 @@
-10
diff -pruN 3:5.44-1/debian/control 3:5.49-1/debian/control
--- 3:5.44-1/debian/control	2017-11-13 13:04:54.000000000 +0000
+++ 3:5.49-1/debian/control	2018-08-26 20:29:02.000000000 +0000
@@ -2,18 +2,24 @@ Source: stunnel4
 Section: net
 Priority: optional
 Build-Depends:
- debhelper (>= 10),
+ debhelper-compat (= 11),
  autoconf-archive,
+ libanyevent-perl,
+ libnet-ssleay-perl,
+ libpath-tiny-perl,
  libssl-dev,
  libsystemd-dev [linux-any],
+ libunicode-utf8-perl,
  libwrap0-dev,
  netcat-traditional,
- openssl
-Maintainer: Peter Pentchev <roam@ringlet.net>
+ net-tools,
+ openssl,
+ procps
+Maintainer: Peter Pentchev <roam@debian.org>
 Uploaders: Laszlo Boszormenyi (GCS) <gcs@debian.org>
-Standards-Version: 4.1.1
-Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/stunnel.git
-Vcs-Git: https://anonscm.debian.org/git/collab-maint/stunnel.git
+Standards-Version: 4.2.1
+Vcs-Browser: https://salsa.debian.org/debian/stunnel/
+Vcs-Git: https://salsa.debian.org/debian/stunnel.git
 Homepage: https://www.stunnel.org/
 Rules-Requires-Root: no
 
diff -pruN 3:5.44-1/debian/copyright 3:5.49-1/debian/copyright
--- 3:5.44-1/debian/copyright	2017-09-23 15:59:40.000000000 +0000
+++ 3:5.49-1/debian/copyright	2018-05-23 10:39:48.000000000 +0000
@@ -6,12 +6,12 @@ License: GPL-2+-openssl
 
 Files: *
 Copyright:
-  (C) 1998-2017  Michal Trojnara <Michal.Trojnara@stunnel.org>
+  (C) 1998-2018  Michal Trojnara <Michal.Trojnara@stunnel.org>
   (c) 2014 Mark Theunissen
 License: GPL-2+-openssl
 
 Files: src/stunnel3.in
-Copyright: (C) 2004-2012 Michal Trojnara <Michal.Trojnara@stunnel.org>
+Copyright: (C) 1998-2018  Michal Trojnara <Michal.Trojnara@stunnel.org>
 License: GPL-2+
 
 Files: debian/*
@@ -20,7 +20,7 @@ Copyright:
  (C) 2003-2007  Julien Lemoine <speedblue@debian.org>
  (C) 2007-2012  Luis Rodrigo Gallardo Cruz <rodrigo@debian.org>
  (C) 2013       Salvatore Bonaccorso <carnil@debian.org>
- (C) 2014-2017  Peter Pentchev <roam@ringlet.net>
+ (C) 2014-2018  Peter Pentchev <roam@debian.org>
 License: GPL-2+-openssl
 
 License: GPL-2+-openssl
diff -pruN 3:5.44-1/debian/patches/02-rename-binary.patch 3:5.49-1/debian/patches/02-rename-binary.patch
--- 3:5.44-1/debian/patches/02-rename-binary.patch	2017-09-23 12:33:22.000000000 +0000
+++ 3:5.49-1/debian/patches/02-rename-binary.patch	2018-09-10 08:47:12.000000000 +0000
@@ -2,7 +2,7 @@ Description: Change references to the bi
 Forwarded: not-needed
 Author: Julien Lemoine <speedblue@debian.org>
 Author: Luis Rodrigo Gallardo Cruz <rodrigo@debian.org>
-Last-Update: 2017-09-23
+Last-Update: 2018-09-10
 
 --- a/src/stunnel3.in
 +++ b/src/stunnel3.in
@@ -36,7 +36,7 @@ Last-Update: 2017-09-23
  NAME=stunnel
  DESC="TLS tunnels"
  OPTIONS=""
-@@ -49,9 +49,9 @@
+@@ -48,9 +48,9 @@
  startdaemons() {
    local res file args pidfile warn status
  
@@ -49,18 +49,15 @@ Last-Update: 2017-09-23
    fi
    if [ -n "$RLIMITS" ]; then
      ulimit $RLIMITS
-@@ -141,9 +141,9 @@
+@@ -181,7 +181,7 @@
    OPTIONS="-- $OPTIONS"
  fi
  
 -[ -f @sysconfdir@/default/stunnel ] && . @sysconfdir@/default/stunnel
 +[ -f @sysconfdir@/default/stunnel4 ] && . @sysconfdir@/default/stunnel4
- if [ "$ENABLED" = "0" ] ; then
--  echo "$DESC disabled, see @sysconfdir@/default/stunnel"
-+  echo "$DESC disabled, see @sysconfdir@/default/stunnel4"
-   exit 0
- fi
  
+ # If the user want to manage a single tunnel, the conf file's name
+ # is in $2. Otherwise, respect @sysconfdir@/default/stunnel4 setting.
 --- a/tools/script.sh
 +++ b/tools/script.sh
 @@ -2,7 +2,7 @@
@@ -90,14 +87,14 @@ Last-Update: 2017-09-23
  edit = sed \
 --- a/doc/stunnel.pl.8.in
 +++ b/doc/stunnel.pl.8.in
-@@ -70,8 +70,8 @@
- .rr rF
+@@ -66,8 +66,8 @@
+ .\}
  .\" ========================================================================
  .\"
 -.IX Title "stunnel 8"
--.TH stunnel 8 "2017.04.01" "5.42" "stunnel TLS Proxy"
+-.TH stunnel 8 "2018.07.02" "5.48" "stunnel TLS Proxy"
 +.IX Title "stunnel4 8"
-+.TH stunnel 8 "2017.04.01" "5.42" "stunnel4 TLS Proxy"
++.TH stunnel 8 "2018.07.02" "5.48" "stunnel4 TLS Proxy"
  .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
  .\" way too many mistakes in technical documents.
  .if n .ad l
diff -pruN 3:5.44-1/debian/patches/04-restore-pidfile-default.patch 3:5.49-1/debian/patches/04-restore-pidfile-default.patch
--- 3:5.44-1/debian/patches/04-restore-pidfile-default.patch	2017-09-23 12:33:22.000000000 +0000
+++ 3:5.49-1/debian/patches/04-restore-pidfile-default.patch	2018-09-10 08:47:48.000000000 +0000
@@ -21,7 +21,7 @@ Last-Update: 2017-07-03
  stunnel_LDFLAGS = -L$(SSLDIR)/lib64 -L$(SSLDIR)/lib -lssl -lcrypto
 --- a/src/options.c
 +++ b/src/options.c
-@@ -917,7 +917,7 @@
+@@ -1028,7 +1028,7 @@
  #ifndef USE_WIN32
      switch(cmd) {
      case CMD_BEGIN:
@@ -30,8 +30,8 @@ Last-Update: 2017-07-03
          break;
      case CMD_EXEC:
          if(strcasecmp(opt, "pid"))
-@@ -932,9 +932,10 @@
-     case CMD_FREE:
+@@ -1048,9 +1048,10 @@
+         str_free(tmp);
          break;
      case CMD_DEFAULT:
 +        s_log(LOG_NOTICE, "%-22s = %s", "pid", PIDFILE);
diff -pruN 3:5.44-1/debian/patches/07-path-max.patch 3:5.49-1/debian/patches/07-path-max.patch
--- 3:5.44-1/debian/patches/07-path-max.patch	2017-11-27 10:11:51.000000000 +0000
+++ 3:5.49-1/debian/patches/07-path-max.patch	2018-06-25 08:12:58.000000000 +0000
@@ -6,7 +6,7 @@ Last-Update: 2017-07-03
 
 --- a/src/common.h
 +++ b/src/common.h
-@@ -94,7 +94,6 @@
+@@ -102,7 +102,6 @@
  typedef int                 ssize_t;
  #endif /* _WIN64 */
  #endif /* !__MINGW32__ */
@@ -16,8 +16,8 @@ Last-Update: 2017-07-03
  #define _CRT_NONSTDC_NO_DEPRECATE
 --- a/src/options.c
 +++ b/src/options.c
-@@ -211,7 +211,7 @@
- NOEXPORT char **argalloc(char *);
+@@ -244,7 +244,7 @@
+ NOEXPORT void arg_free(char **arg);
  #endif
  
 -char configuration_file[PATH_MAX];
@@ -25,7 +25,7 @@ Last-Update: 2017-07-03
  
  GLOBAL_OPTIONS global_options;
  SERVICE_OPTIONS service_options;
-@@ -289,17 +289,27 @@
+@@ -322,17 +322,27 @@
      }
  
  #ifdef HAVE_REALPATH
@@ -60,7 +60,7 @@ Last-Update: 2017-07-03
  
 --- a/src/prototypes.h
 +++ b/src/prototypes.h
-@@ -430,7 +430,7 @@
+@@ -435,7 +435,7 @@
  
  /**************************************** prototypes for options.c */
  
diff -pruN 3:5.44-1/debian/patches/09-try-restart.patch 3:5.49-1/debian/patches/09-try-restart.patch
--- 3:5.44-1/debian/patches/09-try-restart.patch	2017-09-23 12:33:22.000000000 +0000
+++ 3:5.49-1/debian/patches/09-try-restart.patch	1970-01-01 00:00:00.000000000 +0000
@@ -1,76 +0,0 @@
-Description: Implement try-restart in the SysV init script.
-Forwarded: not-yet
-Author: Peter Pentchev <roam@ringlet.net>
-Last-Update: 2017-07-03
-
---- a/tools/stunnel.init.in
-+++ b/tools/stunnel.init.in
-@@ -137,6 +137,47 @@
-   exit "$res"
- }
- 
-+restartrunningdaemons()
-+{
-+  local res file pidfile status args
-+
-+  res=0
-+  for file in $FILES; do
-+    echo -n " $file: "
-+    pidfile=`get_pidfile "$file"`
-+    if [ ! -e "$pidfile" ]; then
-+      echo -n 'no pid file'
-+    else
-+      status=0
-+      pidofproc -p "$pidfile" "$DAEMON" >/dev/null || status="$?"
-+      if [ "$status" = 0 ]; then
-+        echo -n 'stopping'
-+        killproc -p "$pidfile" "$DAEMON" "$sig" || status="$?"
-+        if [ "$status" -eq 0 ]; then
-+          echo -n ' starting'
-+          args="$file $OPTIONS"
-+          start_daemon -p "$pidfile" "$DAEMON" $args || status="$?"
-+          if [ "$status" -eq 0 ]; then
-+            echo -n ' started'
-+          else
-+            echo ' failed'
-+            res=1
-+          fi
-+        else
-+          echo -n ' failed'
-+          res=1
-+        fi
-+      elif [ "$status" = 4 ]; then
-+        echo "cannot access the pid file $pidfile"
-+      else
-+        echo -n 'stopped'
-+      fi
-+    fi
-+  done
-+  echo ''
-+  exit "$res"
-+}
-+
- if [ "x$OPTIONS" != "x" ]; then
-   OPTIONS="-- $OPTIONS"
- fi
-@@ -194,6 +235,11 @@
-     killdaemons && startdaemons
-     res=$?
-     ;;
-+  try-restart)
-+    echo -n "Restarting $DESC if running:"
-+    restartrunningdaemons
-+    res=$?
-+    ;;
-   status)
-     echo -n "$DESC status:"
-     querydaemons
-@@ -201,7 +247,7 @@
-     ;;
-   *)
-     N=@sysconfdir@/init.d/$NAME
--    echo "Usage: $N {start|stop|status|reload|reopen-logs|restart} [<stunnel instance>]" >&2
-+    echo "Usage: $N {start|stop|status|reload|reopen-logs|restart|try-restart} [<stunnel instance>]" >&2
-     res=1
-     ;;
- esac
diff -pruN 3:5.44-1/debian/patches/series 3:5.49-1/debian/patches/series
--- 3:5.44-1/debian/patches/series	2017-11-27 10:11:36.000000000 +0000
+++ 3:5.49-1/debian/patches/series	2018-09-10 08:47:37.000000000 +0000
@@ -4,4 +4,3 @@
 04-restore-pidfile-default.patch
 05-author-tests.patch
 07-path-max.patch
-09-try-restart.patch
diff -pruN 3:5.44-1/debian/rules 3:5.49-1/debian/rules
--- 3:5.44-1/debian/rules	2017-11-14 09:14:40.000000000 +0000
+++ 3:5.49-1/debian/rules	2018-09-10 08:50:47.000000000 +0000
@@ -23,6 +23,12 @@ override_dh_auto_configure:
 	dh_auto_configure -- \
 	  --enable-ipv6 --with-threads=pthread
 
+override_dh_auto_test:
+ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
+	env TEST_STUNNEL=$(CURDIR)/src/stunnel debian/tests/runtime
+	dh_auto_test
+endif
+
 override_dh_auto_install:
 	dh_auto_install -- -C src
 ifeq ($(DEB_NODOC),0)
@@ -69,6 +75,13 @@ override_dh_link:
 	rmdir $(CURDIR)/debian/stunnel4/usr/share/man
 endif
 
+override_dh_installchangelogs:
+	dh_installchangelogs -X ChangeLog
+	install -m 644 ChangeLog $(CURDIR)/debian/stunnel4/usr/share/doc/stunnel4/NEWS
+
+override_dh_installinit:
+	dh_installinit --no-start
+
 override_dh_installppp:
 	dh_installppp --name=0stunnel4
 
diff -pruN 3:5.44-1/debian/stunnel4.conf.README 3:5.49-1/debian/stunnel4.conf.README
--- 3:5.44-1/debian/stunnel4.conf.README	2016-12-09 08:41:36.000000000 +0000
+++ 3:5.49-1/debian/stunnel4.conf.README	2018-05-23 10:34:48.000000000 +0000
@@ -6,8 +6,5 @@ used to start a daemon process setting u
 configuration. Note that this directory is initially empty, as the
 settings you may want for your tunnels are completely system dependent.
 
-In order to have the tunnels start up automatically on system boot you
-must *also* set ENABLED to 1 in /etc/default/stunnel4
-
 A sample configuration file with defaults may be found at
  /usr/share/doc/stunnel4/examples/stunnel.conf-sample
diff -pruN 3:5.44-1/debian/stunnel4.default 3:5.49-1/debian/stunnel4.default
--- 3:5.44-1/debian/stunnel4.default	2015-11-12 16:30:31.000000000 +0000
+++ 3:5.49-1/debian/stunnel4.default	2018-05-23 10:34:48.000000000 +0000
@@ -2,8 +2,6 @@
 # Julien LEMOINE <speedblue@debian.org>
 # September 2003
 
-# Change to one to enable stunnel automatic startup
-ENABLED=0
 FILES="/etc/stunnel/*.conf"
 OPTIONS=""
 
diff -pruN 3:5.44-1/debian/stunnel4.lintian-overrides 3:5.49-1/debian/stunnel4.lintian-overrides
--- 3:5.44-1/debian/stunnel4.lintian-overrides	2017-09-23 12:33:22.000000000 +0000
+++ 3:5.49-1/debian/stunnel4.lintian-overrides	2018-05-23 10:34:48.000000000 +0000
@@ -1,5 +1,2 @@
 # No character arrays anywhere in this .so
 stunnel4: hardening-no-stackprotector usr/lib/stunnel/libstunnel.so
-
-# Not a typo at all.
-stunnel4: spelling-error-in-manpage usr/share/man/man8/stunnel4.8.gz CAs Case
diff -pruN 3:5.44-1/debian/stunnel4.NEWS 3:5.49-1/debian/stunnel4.NEWS
--- 3:5.44-1/debian/stunnel4.NEWS	2016-12-09 08:41:36.000000000 +0000
+++ 3:5.49-1/debian/stunnel4.NEWS	2018-05-23 10:34:48.000000000 +0000
@@ -1,3 +1,19 @@
+stunnel4 (3:5.44-2) unstable; urgency=medium
+
+  The ENABLED option has been removed from the /etc/default/stunnel4
+  file and the stunnel4 init script no longer checks for it.  Instead,
+  new installations of the stunnel4 package will not attempt to start
+  the service immediately after installation, because there are no
+  valid configuration files yet.
+  
+  For existing installations where ENABLED=0 was specified and stunnel
+  was e.g. only started on demand for certain tunnels, the service will
+  now need to be explicitly disabled by the following command:
+
+    update-rc.d stunnel4 defaults-disabled
+
+ -- Peter Pentchev <roam@debian.org>  Mon, 21 May 2018 18:23:00 +0300
+
 stunnel4 (3:5.06-1) unstable; urgency=medium
 
   There are two major changes in this version of stunnel.
diff -pruN 3:5.44-1/debian/tests/control 3:5.49-1/debian/tests/control
--- 3:5.44-1/debian/tests/control	2017-11-15 10:02:20.000000000 +0000
+++ 3:5.49-1/debian/tests/control	2018-09-10 08:50:59.000000000 +0000
@@ -1,6 +1,9 @@
 Test-Command: env TEST_STUNNEL=/usr/bin/stunnel4 debian/tests/runtime
-Depends: @, perl, libanyevent-perl, libnet-ssleay-perl, libpath-tiny-perl
+Depends: @, perl, libanyevent-perl, libnet-ssleay-perl, libpath-tiny-perl, libunicode-utf8-perl
 Restrictions: allow-stderr
 
 Test-Command: debian/tests/upstream
-Depends: @, netcat-traditional
+Depends: @, netcat-traditional, net-tools
+
+Test-Command: adequate stunnel4
+Depends: @, adequate
diff -pruN 3:5.44-1/doc/Makefile.am 3:5.49-1/doc/Makefile.am
--- 3:5.44-1/doc/Makefile.am	2017-01-02 14:27:26.000000000 +0000
+++ 3:5.49-1/doc/Makefile.am	2018-06-08 17:30:06.000000000 +0000
@@ -1,5 +1,5 @@
 ## Process this file with automake to produce Makefile.in
-# by Michal Trojnara 2015-2017
+# by Michal Trojnara 1998-2018
 
 EXTRA_DIST = stunnel.pod.in stunnel.8.in stunnel.html.in en
 EXTRA_DIST += stunnel.pl.pod.in stunnel.pl.8.in stunnel.pl.html.in pl
@@ -24,7 +24,8 @@ SUFFIXES = .pod.in .8.in .html.in
 
 edit = sed \
 	-e 's|@bindir[@]|$(bindir)|g' \
-	-e 's|@sysconfdir[@]|$(sysconfdir)|g'
+	-e 's|@sysconfdir[@]|$(sysconfdir)|g' \
+	-e '\|^<link rev="made" href="|d'
 
 $(man_MANS) $(doc_DATA): Makefile
 	$(edit) '$(srcdir)/$@.in' >$@
diff -pruN 3:5.44-1/doc/Makefile.in 3:5.49-1/doc/Makefile.in
--- 3:5.44-1/doc/Makefile.in	2017-11-14 14:07:50.000000000 +0000
+++ 3:5.49-1/doc/Makefile.in	2018-08-31 14:51:16.000000000 +0000
@@ -14,7 +14,7 @@
 
 @SET_MAKE@
 
-# by Michal Trojnara 2015-2017
+# by Michal Trojnara 1998-2018
 
 VPATH = @srcdir@
 am__is_gnu_make = { \
@@ -289,7 +289,8 @@ CLEANFILES = $(man_MANS) $(doc_DATA)
 SUFFIXES = .pod.in .8.in .html.in
 edit = sed \
 	-e 's|@bindir[@]|$(bindir)|g' \
-	-e 's|@sysconfdir[@]|$(sysconfdir)|g'
+	-e 's|@sysconfdir[@]|$(sysconfdir)|g' \
+	-e '\|^<link rev="made" href="|d'
 
 all: all-am
 
diff -pruN 3:5.44-1/doc/stunnel.8.in 3:5.49-1/doc/stunnel.8.in
--- 3:5.44-1/doc/stunnel.8.in	2017-04-01 12:21:27.000000000 +0000
+++ 3:5.49-1/doc/stunnel.8.in	2018-07-02 21:31:41.000000000 +0000
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.28)
+.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
@@ -46,7 +46,7 @@
 .ie \n(.g .ds Aq \(aq
 .el       .ds Aq '
 .\"
-.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" If the F register is >0, we'll generate index entries on stderr for
 .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
 .\" entries marked with X<> in POD.  Of course, you'll have to process the
 .\" output yourself in some meaningful fashion.
@@ -54,24 +54,20 @@
 .\" Avoid warning from groff about undefined register 'F'.
 .de IX
 ..
-.nr rF 0
-.if \n(.g .if rF .nr rF 1
-.if (\n(rF:(\n(.g==0)) \{
-.    if \nF \{
-.        de IX
-.        tm Index:\\$1\t\\n%\t"\\$2"
+.if !\nF .nr F 0
+.if \nF>0 \{\
+.    de IX
+.    tm Index:\\$1\t\\n%\t"\\$2"
 ..
-.        if !\nF==2 \{
-.            nr % 0
-.            nr F 2
-.        \}
+.    if !\nF==2 \{\
+.        nr % 0
+.        nr F 2
 .    \}
 .\}
-.rr rF
 .\" ========================================================================
 .\"
 .IX Title "stunnel 8"
-.TH stunnel 8 "2017.04.01" "5.42" "stunnel TLS Proxy"
+.TH stunnel 8 "2018.07.02" "5.48" "stunnel TLS Proxy"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -313,26 +309,6 @@ name for \s-1TCP\s0 Wrappers.  While thi
 service sections, it is only useful in global options.
 .Sp
 default: stunnel
-.IP "\fBsocket\fR = a|l|r:OPTION=VALUE[:VALUE]" 4
-.IX Item "socket = a|l|r:OPTION=VALUE[:VALUE]"
-Set an option on the accept/local/remote socket
-.Sp
-The values for the linger option are l_onof:l_linger.
-The values for the time are tv_sec:tv_usec.
-.Sp
-Examples:
-.Sp
-.Vb 9
-\&    socket = l:SO_LINGER=1:60
-\&        set one minute timeout for closing local socket
-\&    socket = r:SO_OOBINLINE=yes
-\&        place out\-of\-band data directly into the
-\&        receive data stream for remote sockets
-\&    socket = a:SO_REUSEADDR=no
-\&        disable address reuse (enabled by default)
-\&    socket = a:SO_BINDTODEVICE=lo
-\&        only accept connections on loopback interface
-.Ve
 .IP "\fBsyslog\fR = yes | no (Unix only)" 4
 .IX Item "syslog = yes | no (Unix only)"
 enable logging via syslog
@@ -402,9 +378,9 @@ engine is enabled.
 email address of the peer certificate subject
 .Sp
 Multiple \fIcheckEmail\fR options are allowed in a single service section.
-Certificates are accepted if no \fIcheckEmail\fR option was specified, or the
-email address of the peer certificate matches any of the email addresses
-specified with \fIcheckEmail\fR.
+Certificates are accepted if no subject checks were specified, or the email
+address of the peer certificate matches any of the email addresses specified
+with \fIcheckEmail\fR.
 .Sp
 This option requires OpenSSL 1.0.2 or later.
 .IP "\fBcheckHost\fR = \s-1HOST\s0" 4
@@ -412,9 +388,8 @@ This option requires OpenSSL 1.0.2 or la
 host of the peer certificate subject
 .Sp
 Multiple \fIcheckHost\fR options are allowed in a single service section.
-Certificates are accepted if no \fIcheckHost\fR option was specified, or the host
-name of the peer certificate matches any of the hosts specified with
-\&\fIcheckHost\fR.
+Certificates are accepted if no subject checks were specified, or the host name
+of the peer certificate matches any of the hosts specified with \fIcheckHost\fR.
 .Sp
 This option requires OpenSSL 1.0.2 or later.
 .IP "\fBcheckIP\fR = \s-1IP\s0" 4
@@ -422,7 +397,7 @@ This option requires OpenSSL 1.0.2 or la
 \&\s-1IP\s0 address of the peer certificate subject
 .Sp
 Multiple \fIcheckIP\fR options are allowed in a single service section.
-Certificates are accepted if no \fIcheckIP\fR option was specified, or the \s-1IP\s0
+Certificates are accepted if no subject checks were specified, or the \s-1IP\s0
 address of the peer certificate matches any of the \s-1IP\s0 addresses specified with
 \&\fIcheckIP\fR.
 .Sp
@@ -578,7 +553,7 @@ priority \- use the order specified in c
 .RE
 .RS 4
 .Sp
-default: rr
+default: prio
 .RE
 .IP "\fBident\fR = \s-1USERNAME\s0" 4
 .IX Item "ident = USERNAME"
@@ -587,7 +562,21 @@ use \s-1IDENT \s0(\s-1RFC 1413\s0) usern
 .IX Item "include = DIRECTORY"
 include all configuration file parts located in \s-1DIRECTORY\s0
 .Sp
-The files are included in the ascending alphabetical order of their names.
+The files are included in the ascending alphabetical order of their names. The recommended filename convention is
+.Sp
+for global options:
+.Sp
+.Vb 1
+\&        00\-global.conf
+.Ve
+.Sp
+for local service-level options:
+.Sp
+.Vb 1
+\&        01\-service.conf
+\&
+\&        02\-service.conf
+.Ve
 .IP "\fBkey\fR = \s-1KEY_FILE\s0" 4
 .IX Item "key = KEY_FILE"
 private key for the certificate specified with \fIcert\fR option
@@ -894,11 +883,43 @@ Empty \s-1SERVER_NAME\s0 disables sendin
 .Sp
 The \fIsni\fR option is only available when compiled with \fBOpenSSL 1.0.0\fR and
 later.
+.IP "\fBsocket\fR = a|l|r:OPTION=VALUE[:VALUE]" 4
+.IX Item "socket = a|l|r:OPTION=VALUE[:VALUE]"
+Set an option on the accept/local/remote socket
+.Sp
+The values for the linger option are l_onof:l_linger.
+The values for the time are tv_sec:tv_usec.
+.Sp
+Examples:
+.Sp
+.Vb 9
+\&    socket = l:SO_LINGER=1:60
+\&        set one minute timeout for closing local socket
+\&    socket = r:SO_OOBINLINE=yes
+\&        place out\-of\-band data directly into the
+\&        receive data stream for remote sockets
+\&    socket = a:SO_REUSEADDR=no
+\&        disable address reuse (enabled by default)
+\&    socket = a:SO_BINDTODEVICE=lo
+\&        only accept connections on loopback interface
+.Ve
 .IP "\fBsslVersion\fR = \s-1SSL_VERSION\s0" 4
 .IX Item "sslVersion = SSL_VERSION"
 select the \s-1TLS\s0 protocol version
 .Sp
-Supported values: all, SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2
+Supported versions: all, SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2
+.Sp
+sslVersion is obsolete and it will be removed in future releases of stunnel.
+Use the following options instead:
+.Sp
+.Vb 6
+\&    options = NO_SSLv2
+\&    options = NO_SSLv3
+\&    options = NO_TLSv1
+\&    options = NO_TLSv1.1
+\&    options = NO_TLSv1.2
+\&    options = NO_TLSv1.3
+.Ve
 .Sp
 Availability of specific protocols depends on the linked OpenSSL library.
 Older versions of OpenSSL do not support TLSv1.1 and TLSv1.2.
@@ -1367,8 +1388,7 @@ certificate file, which disables generat
 .Ve
 .SH "FILES"
 .IX Header "FILES"
-.ie n .IP "\fI\fI@sysconfdir\fI@/stunnel/stunnel.conf\fR" 4
-.el .IP "\fI\f(CI@sysconfdir\fI@/stunnel/stunnel.conf\fR" 4
+.IP "\fI\f(CI@sysconfdir\fI@/stunnel/stunnel.conf\fR" 4
 .IX Item "@sysconfdir@/stunnel/stunnel.conf"
 \&\fBstunnel\fR configuration file
 .SH "BUGS"
diff -pruN 3:5.44-1/doc/stunnel.html.in 3:5.49-1/doc/stunnel.html.in
--- 3:5.44-1/doc/stunnel.html.in	2017-04-01 12:21:27.000000000 +0000
+++ 3:5.49-1/doc/stunnel.html.in	2018-07-02 21:31:41.000000000 +0000
@@ -389,26 +389,6 @@
 <p>default: stunnel</p>
 
 </dd>
-<dt id="socket-a-l-r:OPTION-VALUE-:VALUE"><b>socket</b> = a|l|r:OPTION=VALUE[:VALUE]</dt>
-<dd>
-
-<p>Set an option on the accept/local/remote socket</p>
-
-<p>The values for the linger option are l_onof:l_linger. The values for the time are tv_sec:tv_usec.</p>
-
-<p>Examples:</p>
-
-<pre><code>    socket = l:SO_LINGER=1:60
-        set one minute timeout for closing local socket
-    socket = r:SO_OOBINLINE=yes
-        place out-of-band data directly into the
-        receive data stream for remote sockets
-    socket = a:SO_REUSEADDR=no
-        disable address reuse (enabled by default)
-    socket = a:SO_BINDTODEVICE=lo
-        only accept connections on loopback interface</code></pre>
-
-</dd>
 <dt id="syslog-yes-no-Unix-only"><b>syslog</b> = yes | no (Unix only)</dt>
 <dd>
 
@@ -484,7 +464,7 @@
 
 <p>email address of the peer certificate subject</p>
 
-<p>Multiple <i>checkEmail</i> options are allowed in a single service section. Certificates are accepted if no <i>checkEmail</i> option was specified, or the email address of the peer certificate matches any of the email addresses specified with <i>checkEmail</i>.</p>
+<p>Multiple <i>checkEmail</i> options are allowed in a single service section. Certificates are accepted if no subject checks were specified, or the email address of the peer certificate matches any of the email addresses specified with <i>checkEmail</i>.</p>
 
 <p>This option requires OpenSSL 1.0.2 or later.</p>
 
@@ -494,7 +474,7 @@
 
 <p>host of the peer certificate subject</p>
 
-<p>Multiple <i>checkHost</i> options are allowed in a single service section. Certificates are accepted if no <i>checkHost</i> option was specified, or the host name of the peer certificate matches any of the hosts specified with <i>checkHost</i>.</p>
+<p>Multiple <i>checkHost</i> options are allowed in a single service section. Certificates are accepted if no subject checks were specified, or the host name of the peer certificate matches any of the hosts specified with <i>checkHost</i>.</p>
 
 <p>This option requires OpenSSL 1.0.2 or later.</p>
 
@@ -504,7 +484,7 @@
 
 <p>IP address of the peer certificate subject</p>
 
-<p>Multiple <i>checkIP</i> options are allowed in a single service section. Certificates are accepted if no <i>checkIP</i> option was specified, or the IP address of the peer certificate matches any of the IP addresses specified with <i>checkIP</i>.</p>
+<p>Multiple <i>checkIP</i> options are allowed in a single service section. Certificates are accepted if no subject checks were specified, or the IP address of the peer certificate matches any of the IP addresses specified with <i>checkIP</i>.</p>
 
 <p>This option requires OpenSSL 1.0.2 or later.</p>
 
@@ -696,7 +676,7 @@
 </dd>
 </dl>
 
-<p>default: rr</p>
+<p>default: prio</p>
 
 </dd>
 <dt id="ident-USERNAME"><b>ident</b> = USERNAME</dt>
@@ -710,7 +690,17 @@
 
 <p>include all configuration file parts located in DIRECTORY</p>
 
-<p>The files are included in the ascending alphabetical order of their names.</p>
+<p>The files are included in the ascending alphabetical order of their names. The recommended filename convention is</p>
+
+<p>for global options:</p>
+
+<pre><code>        00-global.conf</code></pre>
+
+<p>for local service-level options:</p>
+
+<pre><code>        01-service.conf
+
+        02-service.conf</code></pre>
 
 </dd>
 <dt id="key-KEY_FILE"><b>key</b> = KEY_FILE</dt>
@@ -1070,12 +1060,41 @@
 <p>The <i>sni</i> option is only available when compiled with <b>OpenSSL 1.0.0</b> and later.</p>
 
 </dd>
+<dt id="socket-a-l-r:OPTION-VALUE-:VALUE"><b>socket</b> = a|l|r:OPTION=VALUE[:VALUE]</dt>
+<dd>
+
+<p>Set an option on the accept/local/remote socket</p>
+
+<p>The values for the linger option are l_onof:l_linger. The values for the time are tv_sec:tv_usec.</p>
+
+<p>Examples:</p>
+
+<pre><code>    socket = l:SO_LINGER=1:60
+        set one minute timeout for closing local socket
+    socket = r:SO_OOBINLINE=yes
+        place out-of-band data directly into the
+        receive data stream for remote sockets
+    socket = a:SO_REUSEADDR=no
+        disable address reuse (enabled by default)
+    socket = a:SO_BINDTODEVICE=lo
+        only accept connections on loopback interface</code></pre>
+
+</dd>
 <dt id="sslVersion-SSL_VERSION"><b>sslVersion</b> = SSL_VERSION</dt>
 <dd>
 
 <p>select the TLS protocol version</p>
 
-<p>Supported values: all, SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2</p>
+<p>Supported versions: all, SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2</p>
+
+<p>sslVersion is obsolete and it will be removed in future releases of stunnel. Use the following options instead:</p>
+
+<pre><code>    options = NO_SSLv2
+    options = NO_SSLv3
+    options = NO_TLSv1
+    options = NO_TLSv1.1
+    options = NO_TLSv1.2
+    options = NO_TLSv1.3</code></pre>
 
 <p>Availability of specific protocols depends on the linked OpenSSL library. Older versions of OpenSSL do not support TLSv1.1 and TLSv1.2. Newer versions of OpenSSL do not support SSLv2.</p>
 
diff -pruN 3:5.44-1/doc/stunnel.pl.8.in 3:5.49-1/doc/stunnel.pl.8.in
--- 3:5.44-1/doc/stunnel.pl.8.in	2017-04-01 12:21:27.000000000 +0000
+++ 3:5.49-1/doc/stunnel.pl.8.in	2018-07-02 21:31:41.000000000 +0000
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.28)
+.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
@@ -46,7 +46,7 @@
 .ie \n(.g .ds Aq \(aq
 .el       .ds Aq '
 .\"
-.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" If the F register is >0, we'll generate index entries on stderr for
 .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
 .\" entries marked with X<> in POD.  Of course, you'll have to process the
 .\" output yourself in some meaningful fashion.
@@ -54,24 +54,20 @@
 .\" Avoid warning from groff about undefined register 'F'.
 .de IX
 ..
-.nr rF 0
-.if \n(.g .if rF .nr rF 1
-.if (\n(rF:(\n(.g==0)) \{
-.    if \nF \{
-.        de IX
-.        tm Index:\\$1\t\\n%\t"\\$2"
+.if !\nF .nr F 0
+.if \nF>0 \{\
+.    de IX
+.    tm Index:\\$1\t\\n%\t"\\$2"
 ..
-.        if !\nF==2 \{
-.            nr % 0
-.            nr F 2
-.        \}
+.    if !\nF==2 \{\
+.        nr % 0
+.        nr F 2
 .    \}
 .\}
-.rr rF
 .\" ========================================================================
 .\"
 .IX Title "stunnel 8"
-.TH stunnel 8 "2017.04.01" "5.42" "stunnel TLS Proxy"
+.TH stunnel 8 "2018.07.02" "5.48" "stunnel TLS Proxy"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -318,30 +314,6 @@ użyć tej opcji w trybie w sekcji usłu
 globalnych.
 .Sp
 domyślnie: stunnel
-.IP "\fBsocket\fR = a|l|r:OPCJA=WARTOŚĆ[:WARTOŚĆ]" 4
-.IX Item "socket = a|l|r:OPCJA=WARTOŚĆ[:WARTOŚĆ]"
-ustaw opcję na akceptującym/lokalnym/zdalnym gnieździe
-.Sp
-Dla opcji linger wartości mają postać l_onof:l_linger.
-Dla opcji time wartości mają postać tv_sec:tv_usec.
-.Sp
-Przykłady:
-.Sp
-.Vb 10
-\&    socket = l:SO_LINGER=1:60
-\&        ustaw jednominutowe przeterminowanie
-\&        przy zamykaniu lokalnego gniazda
-\&    socket = r:SO_OOBINLINE=yes
-\&        umieść dane pozapasmowe (out\-of\-band)
-\&        bezpośrednio w strumieniu danych
-\&        wejściowych dla zdalnych gniazd
-\&    socket = a:SO_REUSEADDR=no
-\&        zablokuj ponowne używanie portu
-\&        (domyślnie włączone)
-\&    socket = a:SO_BINDTODEVICE=lo
-\&        przyjmuj połączenia wyłącznie na
-\&        interfejsie zwrotnym (ang. loopback)
-.Ve
 .IP "\fBsyslog\fR = yes | no (tylko Unix)" 4
 .IX Item "syslog = yes | no (tylko Unix)"
 włącz logowanie poprzez mechanizm syslog
@@ -411,31 +383,31 @@ Jeżeli używane jest sprzętowe urządz
 pozwala wybrać identyfikator używanego certyfikatu.
 .IP "\fBcheckEmail\fR = \s-1EMAIL\s0" 4
 .IX Item "checkEmail = EMAIL"
-adres email przedstawionego certyfikatu
+adres email podmiotu przedstawionego certyfikatu
 .Sp
 Pojedyncza sekcja może zawierać wiele wystąpień opcji \fBcheckEmail\fR.
-Certyfikaty są akceptowane, jeżeli sekcja nie zawiera opcji \fBcheckEmail\fR,
-albo adres email przedstawionego certyfikatu pasuje do jednego z adresów
-email określonych przy pomocy \fBcheckEmail\fR.
+Certyfikaty są akceptowane, jeżeli sekcja nie weryfikuje podmiotu certyfikatu,
+albo adres email przedstawionego certyfikatu pasuje do jednego z adresów email
+określonych przy pomocy \fBcheckEmail\fR.
 .Sp
 Opcja ta wymaga biblioteki OpenSSL w wersji 1.0.2 lub nowszej.
 .IP "\fBcheckHost\fR = \s-1NAZWA_SERWERA\s0" 4
 .IX Item "checkHost = NAZWA_SERWERA"
-nazwa serwera przedstawionego certyfikatu
+nazwa serwera podmiotu przedstawionego certyfikatu
 .Sp
 Pojedyncza sekcja może zawierać wiele wystąpień opcji \fBcheckHost\fR.
-Certyfikaty są akceptowane, jeżeli sekcja nie zawiera opcji \fBcheckHost\fR, albo
-nazwa serwera przedstawionego certyfikatu pasuje do jednego nazw określonych
-przy pomocy \fBcheckHost\fR.
+Certyfikaty są akceptowane, jeżeli sekcja nie weryfikuje podmiotu certyfikatu,
+albo nazwa serwera przedstawionego certyfikatu pasuje do jednego nazw
+określonych przy pomocy \fBcheckHost\fR.
 .Sp
 Opcja ta wymaga biblioteki OpenSSL w wersji 1.0.2 lub nowszej.
 .IP "\fBcheckIP\fR = \s-1IP\s0" 4
 .IX Item "checkIP = IP"
-adres \s-1IP\s0 przedstawionego certyfikatu
+adres \s-1IP\s0 podmiotu przedstawionego certyfikatu
 .Sp
 Pojedyncza sekcja może zawierać wiele wystąpień opcji \fBcheckIP\fR.  Certyfikaty
-są akceptowane, jeżeli sekcja nie zawiera opcji \fBcheckIP\fR, albo adres \s-1IP\s0
-przedstawionego certyfikatu pasuje do jednego z adresów \s-1IP\s0 określonych przy
+są akceptowane, jeżeli sekcja nie weryfikuje podmiotu certyfikatu, albo adres
+\&\s-1IP\s0 przedstawionego certyfikatu pasuje do jednego z adresów \s-1IP\s0 określonych przy
 pomocy \fBcheckIP\fR.
 .Sp
 Opcja ta wymaga biblioteki OpenSSL w wersji 1.0.2 lub nowszej.
@@ -596,7 +568,7 @@ priority \- użyj kolejności opcji w pl
 .RE
 .RS 4
 .Sp
-domyślnie: rr
+domyślnie: prio
 .RE
 .IP "\fBident\fR = NAZWA_UŻYTKOWNIKA" 4
 .IX Item "ident = NAZWA_UŻYTKOWNIKA"
@@ -605,7 +577,21 @@ weryfikuj nazwę zdalnego użytkownika k
 .IX Item "include = KATALOG"
 wczytaj fragmenty plików konfiguracyjnych z podanego katalogu
 .Sp
-Pliki są wczytywane w rosnącej kolejności alfabetycznej ich nazw.
+Pliki są wczytywane w rosnącej kolejności alfabetycznej ich nazw. Rekomendowana konwencja nazewnictwa plików
+.Sp
+dla opcji globalnych:
+.Sp
+.Vb 1
+\&        00\-global.conf
+.Ve
+.Sp
+dla lokalnych opcji usług:
+.Sp
+.Vb 1
+\&        01\-service.conf
+\&
+\&        02\-service.conf
+.Ve
 .IP "\fBkey\fR = \s-1PLIK_KLUCZA\s0" 4
 .IX Item "key = PLIK_KLUCZA"
 klucz prywatny do certyfikatu podanego w opcji \fIcert\fR
@@ -910,11 +896,47 @@ Użyj parametru jako wartości rozszerze
 Pusta wartość parametru \s-1NAZWA_SERWERA\s0 wyłącza wysyłanie rozszerzenia \s-1SNI.\s0
 .Sp
 Opcja \fIsni\fR jest dostępna począwszy od \fBOpenSSL 1.0.0\fR.
+.IP "\fBsocket\fR = a|l|r:OPCJA=WARTOŚĆ[:WARTOŚĆ]" 4
+.IX Item "socket = a|l|r:OPCJA=WARTOŚĆ[:WARTOŚĆ]"
+ustaw opcję na akceptującym/lokalnym/zdalnym gnieździe
+.Sp
+Dla opcji linger wartości mają postać l_onof:l_linger.
+Dla opcji time wartości mają postać tv_sec:tv_usec.
+.Sp
+Przykłady:
+.Sp
+.Vb 10
+\&    socket = l:SO_LINGER=1:60
+\&        ustaw jednominutowe przeterminowanie
+\&        przy zamykaniu lokalnego gniazda
+\&    socket = r:SO_OOBINLINE=yes
+\&        umieść dane pozapasmowe (out\-of\-band)
+\&        bezpośrednio w strumieniu danych
+\&        wejściowych dla zdalnych gniazd
+\&    socket = a:SO_REUSEADDR=no
+\&        zablokuj ponowne używanie portu
+\&        (domyślnie włączone)
+\&    socket = a:SO_BINDTODEVICE=lo
+\&        przyjmuj połączenia wyłącznie na
+\&        interfejsie zwrotnym (ang. loopback)
+.Ve
 .IP "\fBsslVersion\fR = \s-1WERSJA_SSL\s0" 4
 .IX Item "sslVersion = WERSJA_SSL"
 wersja protokołu \s-1TLS\s0
 .Sp
-Wspierane opcje: all, SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2
+Wspierane wersje: all, SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2
+.Sp
+Ocja \fIsslVersion\fR jest przestarzała i zostanie usunięta w przyszłych wersjach stunnela.
+Zamiast niej należy używać następujących opcji:
+.Sp
+.Vb 6
+\&    options = NO_SSLv2
+\&    options = NO_SSLv3
+\&    options = NO_TLSv1
+\&    options = NO_TLSv1.1
+\&    options = NO_TLSv1.2
+\&    options = NO_TLSv1.3
+.Ve
 .Sp
 Dostępność konkretnych protokołów zależy od użytej wersji OpenSSL.
 Starsze wersje OpenSSL nie wspierają TLSv1.1 i TLSv1.2.
@@ -941,7 +963,7 @@ maksymalny czas utrzymywania bezczynnego
 .IX Item "transparent = none | source | destination | both (tylko Unix)"
 tryb przezroczystego proxy na wspieranych platformach
 .Sp
-Wspierane opcje:
+Wspierane wartości:
 .RS 4
 .IP "\fBnone\fR" 4
 .IX Item "none"
@@ -1397,8 +1419,7 @@ co wyłącza generowanie parametrów tym
 .Ve
 .SH "PLIKI"
 .IX Header "PLIKI"
-.ie n .IP "\fI\fI@sysconfdir\fI@/stunnel/stunnel.conf\fR" 4
-.el .IP "\fI\f(CI@sysconfdir\fI@/stunnel/stunnel.conf\fR" 4
+.IP "\fI\f(CI@sysconfdir\fI@/stunnel/stunnel.conf\fR" 4
 .IX Item "@sysconfdir@/stunnel/stunnel.conf"
 plik konfiguracyjny programu
 .SH "BŁĘDY"
diff -pruN 3:5.44-1/doc/stunnel.pl.html.in 3:5.49-1/doc/stunnel.pl.html.in
--- 3:5.44-1/doc/stunnel.pl.html.in	2017-04-01 12:21:28.000000000 +0000
+++ 3:5.49-1/doc/stunnel.pl.html.in	2018-07-02 21:31:41.000000000 +0000
@@ -387,30 +387,6 @@
 <p>domy&#x15B;lnie: stunnel</p>
 
 </dd>
-<dt id="socket-a-l-r:OPCJA-WARTO-:WARTO"><b>socket</b> = a|l|r:OPCJA=WARTO&#x15A;&#x106;[:WARTO&#x15A;&#x106;]</dt>
-<dd>
-
-<p>ustaw opcj&#x119; na akceptuj&#x105;cym/lokalnym/zdalnym gnie&#x17A;dzie</p>
-
-<p>Dla opcji linger warto&#x15B;ci maj&#x105; posta&#x107; l_onof:l_linger. Dla opcji time warto&#x15B;ci maj&#x105; posta&#x107; tv_sec:tv_usec.</p>
-
-<p>Przyk&#x142;ady:</p>
-
-<pre><code>    socket = l:SO_LINGER=1:60
-        ustaw jednominutowe przeterminowanie
-        przy zamykaniu lokalnego gniazda
-    socket = r:SO_OOBINLINE=yes
-        umie&#x15B;&#x107; dane pozapasmowe (out-of-band)
-        bezpo&#x15B;rednio w strumieniu danych
-        wej&#x15B;ciowych dla zdalnych gniazd
-    socket = a:SO_REUSEADDR=no
-        zablokuj ponowne u&#x17C;ywanie portu
-        (domy&#x15B;lnie w&#x142;&#x105;czone)
-    socket = a:SO_BINDTODEVICE=lo
-        przyjmuj po&#x142;&#x105;czenia wy&#x142;&#x105;cznie na
-        interfejsie zwrotnym (ang. loopback)</code></pre>
-
-</dd>
 <dt id="syslog-yes-no-tylko-Unix"><b>syslog</b> = yes | no (tylko Unix)</dt>
 <dd>
 
@@ -484,9 +460,9 @@
 <dt id="checkEmail-EMAIL"><b>checkEmail</b> = EMAIL</dt>
 <dd>
 
-<p>adres email przedstawionego certyfikatu</p>
+<p>adres email podmiotu przedstawionego certyfikatu</p>
 
-<p>Pojedyncza sekcja mo&#x17C;e zawiera&#x107; wiele wyst&#x105;pie&#x144; opcji <b>checkEmail</b>. Certyfikaty s&#x105; akceptowane, je&#x17C;eli sekcja nie zawiera opcji <b>checkEmail</b>, albo adres email przedstawionego certyfikatu pasuje do jednego z adres&oacute;w email okre&#x15B;lonych przy pomocy <b>checkEmail</b>.</p>
+<p>Pojedyncza sekcja mo&#x17C;e zawiera&#x107; wiele wyst&#x105;pie&#x144; opcji <b>checkEmail</b>. Certyfikaty s&#x105; akceptowane, je&#x17C;eli sekcja nie weryfikuje podmiotu certyfikatu, albo adres email przedstawionego certyfikatu pasuje do jednego z adres&oacute;w email okre&#x15B;lonych przy pomocy <b>checkEmail</b>.</p>
 
 <p>Opcja ta wymaga biblioteki OpenSSL w wersji 1.0.2 lub nowszej.</p>
 
@@ -494,9 +470,9 @@
 <dt id="checkHost-NAZWA_SERWERA"><b>checkHost</b> = NAZWA_SERWERA</dt>
 <dd>
 
-<p>nazwa serwera przedstawionego certyfikatu</p>
+<p>nazwa serwera podmiotu przedstawionego certyfikatu</p>
 
-<p>Pojedyncza sekcja mo&#x17C;e zawiera&#x107; wiele wyst&#x105;pie&#x144; opcji <b>checkHost</b>. Certyfikaty s&#x105; akceptowane, je&#x17C;eli sekcja nie zawiera opcji <b>checkHost</b>, albo nazwa serwera przedstawionego certyfikatu pasuje do jednego nazw okre&#x15B;lonych przy pomocy <b>checkHost</b>.</p>
+<p>Pojedyncza sekcja mo&#x17C;e zawiera&#x107; wiele wyst&#x105;pie&#x144; opcji <b>checkHost</b>. Certyfikaty s&#x105; akceptowane, je&#x17C;eli sekcja nie weryfikuje podmiotu certyfikatu, albo nazwa serwera przedstawionego certyfikatu pasuje do jednego nazw okre&#x15B;lonych przy pomocy <b>checkHost</b>.</p>
 
 <p>Opcja ta wymaga biblioteki OpenSSL w wersji 1.0.2 lub nowszej.</p>
 
@@ -504,9 +480,9 @@
 <dt id="checkIP-IP"><b>checkIP</b> = IP</dt>
 <dd>
 
-<p>adres IP przedstawionego certyfikatu</p>
+<p>adres IP podmiotu przedstawionego certyfikatu</p>
 
-<p>Pojedyncza sekcja mo&#x17C;e zawiera&#x107; wiele wyst&#x105;pie&#x144; opcji <b>checkIP</b>. Certyfikaty s&#x105; akceptowane, je&#x17C;eli sekcja nie zawiera opcji <b>checkIP</b>, albo adres IP przedstawionego certyfikatu pasuje do jednego z adres&oacute;w IP okre&#x15B;lonych przy pomocy <b>checkIP</b>.</p>
+<p>Pojedyncza sekcja mo&#x17C;e zawiera&#x107; wiele wyst&#x105;pie&#x144; opcji <b>checkIP</b>. Certyfikaty s&#x105; akceptowane, je&#x17C;eli sekcja nie weryfikuje podmiotu certyfikatu, albo adres IP przedstawionego certyfikatu pasuje do jednego z adres&oacute;w IP okre&#x15B;lonych przy pomocy <b>checkIP</b>.</p>
 
 <p>Opcja ta wymaga biblioteki OpenSSL w wersji 1.0.2 lub nowszej.</p>
 
@@ -696,7 +672,7 @@
 </dd>
 </dl>
 
-<p>domy&#x15B;lnie: rr</p>
+<p>domy&#x15B;lnie: prio</p>
 
 </dd>
 <dt id="ident-NAZWA_UYTKOWNIKA"><b>ident</b> = NAZWA_U&#x17B;YTKOWNIKA</dt>
@@ -710,7 +686,17 @@
 
 <p>wczytaj fragmenty plik&oacute;w konfiguracyjnych z podanego katalogu</p>
 
-<p>Pliki s&#x105; wczytywane w rosn&#x105;cej kolejno&#x15B;ci alfabetycznej ich nazw.</p>
+<p>Pliki s&#x105; wczytywane w rosn&#x105;cej kolejno&#x15B;ci alfabetycznej ich nazw. Rekomendowana konwencja nazewnictwa plik&oacute;w</p>
+
+<p>dla opcji globalnych:</p>
+
+<pre><code>        00-global.conf</code></pre>
+
+<p>dla lokalnych opcji us&#x142;ug:</p>
+
+<pre><code>        01-service.conf
+
+        02-service.conf</code></pre>
 
 </dd>
 <dt id="key-PLIK_KLUCZA"><b>key</b> = PLIK_KLUCZA</dt>
@@ -1072,12 +1058,45 @@
 <p>Opcja <i>sni</i> jest dost&#x119;pna pocz&#x105;wszy od <b>OpenSSL 1.0.0</b>.</p>
 
 </dd>
+<dt id="socket-a-l-r:OPCJA-WARTO-:WARTO"><b>socket</b> = a|l|r:OPCJA=WARTO&#x15A;&#x106;[:WARTO&#x15A;&#x106;]</dt>
+<dd>
+
+<p>ustaw opcj&#x119; na akceptuj&#x105;cym/lokalnym/zdalnym gnie&#x17A;dzie</p>
+
+<p>Dla opcji linger warto&#x15B;ci maj&#x105; posta&#x107; l_onof:l_linger. Dla opcji time warto&#x15B;ci maj&#x105; posta&#x107; tv_sec:tv_usec.</p>
+
+<p>Przyk&#x142;ady:</p>
+
+<pre><code>    socket = l:SO_LINGER=1:60
+        ustaw jednominutowe przeterminowanie
+        przy zamykaniu lokalnego gniazda
+    socket = r:SO_OOBINLINE=yes
+        umie&#x15B;&#x107; dane pozapasmowe (out-of-band)
+        bezpo&#x15B;rednio w strumieniu danych
+        wej&#x15B;ciowych dla zdalnych gniazd
+    socket = a:SO_REUSEADDR=no
+        zablokuj ponowne u&#x17C;ywanie portu
+        (domy&#x15B;lnie w&#x142;&#x105;czone)
+    socket = a:SO_BINDTODEVICE=lo
+        przyjmuj po&#x142;&#x105;czenia wy&#x142;&#x105;cznie na
+        interfejsie zwrotnym (ang. loopback)</code></pre>
+
+</dd>
 <dt id="sslVersion-WERSJA_SSL"><b>sslVersion</b> = WERSJA_SSL</dt>
 <dd>
 
 <p>wersja protoko&#x142;u TLS</p>
 
-<p>Wspierane opcje: all, SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2</p>
+<p>Wspierane wersje: all, SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2</p>
+
+<p>Ocja <i>sslVersion</i> jest przestarza&#x142;a i zostanie usuni&#x119;ta w przysz&#x142;ych wersjach stunnela. Zamiast niej nale&#x17C;y u&#x17C;ywa&#x107; nast&#x119;puj&#x105;cych opcji:</p>
+
+<pre><code>    options = NO_SSLv2
+    options = NO_SSLv3
+    options = NO_TLSv1
+    options = NO_TLSv1.1
+    options = NO_TLSv1.2
+    options = NO_TLSv1.3</code></pre>
 
 <p>Dost&#x119;pno&#x15B;&#x107; konkretnych protoko&#x142;&oacute;w zale&#x17C;y od u&#x17C;ytej wersji OpenSSL. Starsze wersje OpenSSL nie wspieraj&#x105; TLSv1.1 i TLSv1.2. Nowsze wersje OpenSSL nie wspieraj&#x105; SSLv2.</p>
 
@@ -1119,7 +1138,7 @@
 
 <p>tryb przezroczystego proxy na wspieranych platformach</p>
 
-<p>Wspierane opcje:</p>
+<p>Wspierane warto&#x15B;ci:</p>
 
 <dl>
 
diff -pruN 3:5.44-1/doc/stunnel.pl.pod.in 3:5.49-1/doc/stunnel.pl.pod.in
--- 3:5.44-1/doc/stunnel.pl.pod.in	2017-04-01 12:21:18.000000000 +0000
+++ 3:5.49-1/doc/stunnel.pl.pod.in	2018-07-02 21:30:10.000000000 +0000
@@ -322,29 +322,6 @@ globalnych.
 
 domyślnie: stunnel
 
-=item B<socket> = a|l|r:OPCJA=WARTOŚĆ[:WARTOŚĆ]
-
-ustaw opcję na akceptującym/lokalnym/zdalnym gnieździe
-
-Dla opcji linger wartości mają postać l_onof:l_linger.
-Dla opcji time wartości mają postać tv_sec:tv_usec.
-
-Przykłady:
-
-    socket = l:SO_LINGER=1:60
-        ustaw jednominutowe przeterminowanie
-        przy zamykaniu lokalnego gniazda
-    socket = r:SO_OOBINLINE=yes
-        umieść dane pozapasmowe (out-of-band)
-        bezpośrednio w strumieniu danych
-        wejściowych dla zdalnych gniazd
-    socket = a:SO_REUSEADDR=no
-        zablokuj ponowne używanie portu
-        (domyślnie włączone)
-    socket = a:SO_BINDTODEVICE=lo
-        przyjmuj połączenia wyłącznie na
-        interfejsie zwrotnym (ang. loopback)
-
 =item B<syslog> = yes | no (tylko Unix)
 
 włącz logowanie poprzez mechanizm syslog
@@ -424,33 +401,33 @@ pozwala wybrać identyfikator używanego
 
 =item B<checkEmail> = EMAIL
 
-adres email przedstawionego certyfikatu
+adres email podmiotu przedstawionego certyfikatu
 
 Pojedyncza sekcja może zawierać wiele wystąpień opcji B<checkEmail>.
-Certyfikaty są akceptowane, jeżeli sekcja nie zawiera opcji B<checkEmail>,
-albo adres email przedstawionego certyfikatu pasuje do jednego z adresów
-email określonych przy pomocy B<checkEmail>.
+Certyfikaty są akceptowane, jeżeli sekcja nie weryfikuje podmiotu certyfikatu,
+albo adres email przedstawionego certyfikatu pasuje do jednego z adresów email
+określonych przy pomocy B<checkEmail>.
 
 Opcja ta wymaga biblioteki OpenSSL w wersji 1.0.2 lub nowszej.
 
 =item B<checkHost> = NAZWA_SERWERA
 
-nazwa serwera przedstawionego certyfikatu
+nazwa serwera podmiotu przedstawionego certyfikatu
 
 Pojedyncza sekcja może zawierać wiele wystąpień opcji B<checkHost>.
-Certyfikaty są akceptowane, jeżeli sekcja nie zawiera opcji B<checkHost>, albo
-nazwa serwera przedstawionego certyfikatu pasuje do jednego nazw określonych
-przy pomocy B<checkHost>.
+Certyfikaty są akceptowane, jeżeli sekcja nie weryfikuje podmiotu certyfikatu,
+albo nazwa serwera przedstawionego certyfikatu pasuje do jednego nazw
+określonych przy pomocy B<checkHost>.
 
 Opcja ta wymaga biblioteki OpenSSL w wersji 1.0.2 lub nowszej.
 
 =item B<checkIP> = IP
 
-adres IP przedstawionego certyfikatu
+adres IP podmiotu przedstawionego certyfikatu
 
 Pojedyncza sekcja może zawierać wiele wystąpień opcji B<checkIP>.  Certyfikaty
-są akceptowane, jeżeli sekcja nie zawiera opcji B<checkIP>, albo adres IP
-przedstawionego certyfikatu pasuje do jednego z adresów IP określonych przy
+są akceptowane, jeżeli sekcja nie weryfikuje podmiotu certyfikatu, albo adres
+IP przedstawionego certyfikatu pasuje do jednego z adresów IP określonych przy
 pomocy B<checkIP>.
 
 Opcja ta wymaga biblioteki OpenSSL w wersji 1.0.2 lub nowszej.
@@ -630,7 +607,7 @@ priority - użyj kolejności opcji w pli
 
 =back
 
-domyślnie: rr
+domyślnie: prio
 
 =item B<ident> = NAZWA_UŻYTKOWNIKA
 
@@ -640,7 +617,17 @@ weryfikuj nazwę zdalnego użytkownika k
 
 wczytaj fragmenty plików konfiguracyjnych z podanego katalogu
 
-Pliki są wczytywane w rosnącej kolejności alfabetycznej ich nazw.
+Pliki są wczytywane w rosnącej kolejności alfabetycznej ich nazw. Rekomendowana konwencja nazewnictwa plików
+
+dla opcji globalnych:
+
+	00-global.conf
+
+dla lokalnych opcji usług:
+
+	01-service.conf
+
+	02-service.conf
 
 =item B<key> = PLIK_KLUCZA
 
@@ -976,11 +963,44 @@ Pusta wartość parametru NAZWA_SERWERA
 
 Opcja I<sni> jest dostępna począwszy od B<OpenSSL 1.0.0>.
 
+=item B<socket> = a|l|r:OPCJA=WARTOŚĆ[:WARTOŚĆ]
+
+ustaw opcję na akceptującym/lokalnym/zdalnym gnieździe
+
+Dla opcji linger wartości mają postać l_onof:l_linger.
+Dla opcji time wartości mają postać tv_sec:tv_usec.
+
+Przykłady:
+
+    socket = l:SO_LINGER=1:60
+        ustaw jednominutowe przeterminowanie
+        przy zamykaniu lokalnego gniazda
+    socket = r:SO_OOBINLINE=yes
+        umieść dane pozapasmowe (out-of-band)
+        bezpośrednio w strumieniu danych
+        wejściowych dla zdalnych gniazd
+    socket = a:SO_REUSEADDR=no
+        zablokuj ponowne używanie portu
+        (domyślnie włączone)
+    socket = a:SO_BINDTODEVICE=lo
+        przyjmuj połączenia wyłącznie na
+        interfejsie zwrotnym (ang. loopback)
+
 =item B<sslVersion> = WERSJA_SSL
 
 wersja protokołu TLS
 
-Wspierane opcje: all, SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2
+Wspierane wersje: all, SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2
+
+Ocja I<sslVersion> jest przestarzała i zostanie usunięta w przyszłych wersjach stunnela.
+Zamiast niej należy używać następujących opcji:
+
+    options = NO_SSLv2
+    options = NO_SSLv3
+    options = NO_TLSv1
+    options = NO_TLSv1.1
+    options = NO_TLSv1.2
+    options = NO_TLSv1.3
 
 Dostępność konkretnych protokołów zależy od użytej wersji OpenSSL.
 Starsze wersje OpenSSL nie wspierają TLSv1.1 i TLSv1.2.
@@ -1013,7 +1033,7 @@ maksymalny czas utrzymywania bezczynnego
 
 tryb przezroczystego proxy na wspieranych platformach
 
-Wspierane opcje:
+Wspierane wartości:
 
 =over 4
 
diff -pruN 3:5.44-1/doc/stunnel.pod.in 3:5.49-1/doc/stunnel.pod.in
--- 3:5.44-1/doc/stunnel.pod.in	2017-04-01 12:21:24.000000000 +0000
+++ 3:5.49-1/doc/stunnel.pod.in	2018-07-02 21:30:10.000000000 +0000
@@ -318,25 +318,6 @@ service sections, it is only useful in g
 
 default: stunnel
 
-=item B<socket> = a|l|r:OPTION=VALUE[:VALUE]
-
-Set an option on the accept/local/remote socket
-
-The values for the linger option are l_onof:l_linger.
-The values for the time are tv_sec:tv_usec.
-
-Examples:
-
-    socket = l:SO_LINGER=1:60
-        set one minute timeout for closing local socket
-    socket = r:SO_OOBINLINE=yes
-        place out-of-band data directly into the
-        receive data stream for remote sockets
-    socket = a:SO_REUSEADDR=no
-        disable address reuse (enabled by default)
-    socket = a:SO_BINDTODEVICE=lo
-        only accept connections on loopback interface
-
 =item B<syslog> = yes | no (Unix only)
 
 enable logging via syslog
@@ -417,9 +398,9 @@ engine is enabled.
 email address of the peer certificate subject
 
 Multiple I<checkEmail> options are allowed in a single service section.
-Certificates are accepted if no I<checkEmail> option was specified, or the
-email address of the peer certificate matches any of the email addresses
-specified with I<checkEmail>.
+Certificates are accepted if no subject checks were specified, or the email
+address of the peer certificate matches any of the email addresses specified
+with I<checkEmail>.
 
 This option requires OpenSSL 1.0.2 or later.
 
@@ -428,9 +409,8 @@ This option requires OpenSSL 1.0.2 or la
 host of the peer certificate subject
 
 Multiple I<checkHost> options are allowed in a single service section.
-Certificates are accepted if no I<checkHost> option was specified, or the host
-name of the peer certificate matches any of the hosts specified with
-I<checkHost>.
+Certificates are accepted if no subject checks were specified, or the host name
+of the peer certificate matches any of the hosts specified with I<checkHost>.
 
 This option requires OpenSSL 1.0.2 or later.
 
@@ -439,7 +419,7 @@ This option requires OpenSSL 1.0.2 or la
 IP address of the peer certificate subject
 
 Multiple I<checkIP> options are allowed in a single service section.
-Certificates are accepted if no I<checkIP> option was specified, or the IP
+Certificates are accepted if no subject checks were specified, or the IP
 address of the peer certificate matches any of the IP addresses specified with
 I<checkIP>.
 
@@ -614,7 +594,7 @@ priority - use the order specified in co
 
 =back
 
-default: rr
+default: prio
 
 =item B<ident> = USERNAME
 
@@ -624,7 +604,17 @@ use IDENT (RFC 1413) username checking
 
 include all configuration file parts located in DIRECTORY
 
-The files are included in the ascending alphabetical order of their names.
+The files are included in the ascending alphabetical order of their names. The recommended filename convention is
+
+for global options:
+
+	00-global.conf
+
+for local service-level options:
+
+	01-service.conf
+
+	02-service.conf
 
 =item B<key> = KEY_FILE
 
@@ -962,11 +952,40 @@ Empty SERVER_NAME disables sending the S
 The I<sni> option is only available when compiled with B<OpenSSL 1.0.0> and
 later.
 
+=item B<socket> = a|l|r:OPTION=VALUE[:VALUE]
+
+Set an option on the accept/local/remote socket
+
+The values for the linger option are l_onof:l_linger.
+The values for the time are tv_sec:tv_usec.
+
+Examples:
+
+    socket = l:SO_LINGER=1:60
+        set one minute timeout for closing local socket
+    socket = r:SO_OOBINLINE=yes
+        place out-of-band data directly into the
+        receive data stream for remote sockets
+    socket = a:SO_REUSEADDR=no
+        disable address reuse (enabled by default)
+    socket = a:SO_BINDTODEVICE=lo
+        only accept connections on loopback interface
+
 =item B<sslVersion> = SSL_VERSION
 
 select the TLS protocol version
 
-Supported values: all, SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2
+Supported versions: all, SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2
+
+sslVersion is obsolete and it will be removed in future releases of stunnel.
+Use the following options instead:
+
+    options = NO_SSLv2
+    options = NO_SSLv3
+    options = NO_TLSv1
+    options = NO_TLSv1.1
+    options = NO_TLSv1.2
+    options = NO_TLSv1.3
 
 Availability of specific protocols depends on the linked OpenSSL library.
 Older versions of OpenSSL do not support TLSv1.1 and TLSv1.2.
diff -pruN 3:5.44-1/INSTALL.W32 3:5.49-1/INSTALL.W32
--- 3:5.44-1/INSTALL.W32	2017-01-16 20:10:16.000000000 +0000
+++ 3:5.49-1/INSTALL.W32	2018-04-06 14:25:10.000000000 +0000
@@ -14,29 +14,29 @@ Cross-compiling stunnel from source with
       mv openssl-(version) openssl-(version)-i686
       cd openssl-(version)-i686/
 
- 3) Build OpenSSL.
+ 3) Build and install OpenSSL.
     For 32-bit Windows:
       ./Configure \
         --cross-compile-prefix=i686-w64-mingw32- \
-        --openssldir=/opt/openssl-mingw mingw shared
+        --prefix=/opt/openssl-mingw mingw shared
       make
       sudo make install
       sudo cp ms/applink.c /opt/openssl-mingw/include/openssl/
     For 64-bit Windows:
       ./Configure \
         --cross-compile-prefix=x86_64-w64-mingw32- \
-        --openssldir=/opt/openssl-mingw64 mingw64 shared
+        --prefix=/opt/openssl-mingw64 mingw64 shared
       make
       sudo make install
       sudo cp ms/applink.c /opt/openssl-mingw64/include/openssl/
 
  4) Download and unpack stunnel-(version).tar.gz.
 
- 5) Configure stunnel:
+ 5) Configure stunnel.
       cd stunnel-(version)
       ./configure
 
- 6) Build Windows 32-bit and/or 64-bit executables:
+ 6) Build Windows 32-bit and/or 64-bit executables.
       cd src
       make mingw
       make mingw64
@@ -44,22 +44,32 @@ Cross-compiling stunnel from source with
 
 Building stunnel from source with MinGW (optional):
 
- Building on a Windows machine is possible, but not currently supported.
+ Building stunnel with MinGW on a Windows machine is possible,
+ but not currently supported.
 
 
 Building stunnel from source with Visual Studio (optional):
 
- TODO
+ 1) Build your own or download pre-built OpenSSL library and headers.
+    TODO
+
+ 2) Configure path to your OpenSSL in the src\vc.mak file.
+
+ 3) Build stunnel in Visual Studio Command Prompt.
+      cd src
+      nmake -f vc.mak
 
 
 Installing stunnel:
 
- 1) Run installer to install the precompiled binaries, or
-    copy the stunnel.exe or tstunnel.exe executable located in the
-      /stunnel-(version)/bin/mingw/ directory into the destination
-      directory on a Windows machine, and
-    copy OpenSSL DLLs: libeay32.dll, libssp-0.dll and ssleay32.dll
-      into the same directory, if necessary.
+ 1) Install stunnel.
+    Run installer to install the precompiled binaries.
+    Alternatively, copy the stunnel.exe and/or tstunnel.exe executable located in
+    /stunnel-(version)/bin/mingw/ or /stunnel-(version)/bin/mingw64/ directory
+    into the destination directory on a Windows machine.
+    Copy OpenSSL DLLs into the same directory if necessary.
+    For a MinGW build also copy libssp-0.dll.
+    For a Visual Studio build also install Microsoft Visual C++ Redistributable.
 
  2) Read the manual (stunnel.html).
 
diff -pruN 3:5.44-1/Makefile.am 3:5.49-1/Makefile.am
--- 3:5.44-1/Makefile.am	2017-08-23 05:03:13.000000000 +0000
+++ 3:5.49-1/Makefile.am	2018-06-08 17:30:06.000000000 +0000
@@ -1,5 +1,5 @@
 ## Process this file with automake to produce Makefile.in
-# by Michal Trojnara 2015-2017
+# by Michal Trojnara 1998-2018
 
 ACLOCAL_AMFLAGS = -I m4
 
@@ -47,12 +47,3 @@ install-data-hook:
 	@echo "*********************************************************"
 	@echo "* Type 'make cert' to also install a sample certificate *"
 	@echo "*********************************************************"
-
-edit = sed \
-	-e 's|@bindir[@]|$(bindir)|g' \
-	-e 's|@sysconfdir[@]|$(sysconfdir)|g'
-
-stunnel.pod: Makefile
-	$(edit) '$(srcdir)/$@.in' >$@
-
-stunnel.pod: $(srcdir)/stunnel.pod
diff -pruN 3:5.44-1/Makefile.in 3:5.49-1/Makefile.in
--- 3:5.44-1/Makefile.in	2017-11-14 14:07:50.000000000 +0000
+++ 3:5.49-1/Makefile.in	2018-08-31 14:51:16.000000000 +0000
@@ -14,7 +14,7 @@
 
 @SET_MAKE@
 
-# by Michal Trojnara 2015-2017
+# by Michal Trojnara 1998-2018
 
 VPATH = @srcdir@
 am__is_gnu_make = { \
@@ -370,10 +370,6 @@ EXTRA_DIST = PORTS BUGS COPYRIGHT.GPL CR
 doc_DATA = INSTALL README TODO COPYING AUTHORS ChangeLog PORTS BUGS \
 	COPYRIGHT.GPL CREDITS INSTALL.W32 INSTALL.WCE INSTALL.FIPS
 distcleancheck_listfiles = find -type f -exec sh -c 'test -f $(srcdir)/{} || echo {}' ';'
-edit = sed \
-	-e 's|@bindir[@]|$(bindir)|g' \
-	-e 's|@sysconfdir[@]|$(sysconfdir)|g'
-
 all: all-recursive
 
 .SUFFIXES:
@@ -897,11 +893,6 @@ install-data-hook:
 	@echo "* Type 'make cert' to also install a sample certificate *"
 	@echo "*********************************************************"
 
-stunnel.pod: Makefile
-	$(edit) '$(srcdir)/$@.in' >$@
-
-stunnel.pod: $(srcdir)/stunnel.pod
-
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
diff -pruN 3:5.44-1/src/client.c 3:5.49-1/src/client.c
--- 3:5.44-1/src/client.c	2017-11-14 14:01:47.000000000 +0000
+++ 3:5.49-1/src/client.c	2018-08-26 17:36:09.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -49,18 +49,18 @@
 #endif
 
 NOEXPORT void client_try(CLI *);
+NOEXPORT void exec_connect_loop(CLI *);
+NOEXPORT void exec_connect_once(CLI *);
 NOEXPORT void client_run(CLI *);
 NOEXPORT void local_start(CLI *);
 NOEXPORT void remote_start(CLI *);
 NOEXPORT void ssl_start(CLI *);
-NOEXPORT void session_cache_save(CLI *);
 NOEXPORT void session_cache_retrieve(CLI *);
-NOEXPORT void new_chain(CLI *);
+NOEXPORT void print_cipher(CLI *);
 NOEXPORT void transfer(CLI *);
 NOEXPORT int parse_socket_error(CLI *, const char *);
 
-NOEXPORT void print_cipher(CLI *);
-NOEXPORT void auth_user(CLI *, char *);
+NOEXPORT void auth_user(CLI *);
 NOEXPORT SOCKET connect_local(CLI *);
 #if !defined(USE_WIN32) && !defined(__vms)
 NOEXPORT char **env_alloc(CLI *);
@@ -85,78 +85,147 @@ CLI *alloc_client_session(SERVICE_OPTION
     c->local_rfd.fd=rfd;
     c->local_wfd.fd=wfd;
     c->seq=seq++;
-    c->opt->seq++;
+    c->rr=c->opt->rr++;
     return c;
 }
 
-void *client_thread(void *arg) {
+#if defined(USE_WIN32) || defined(USE_OS2)
+unsigned __stdcall
+#else
+void *
+#endif
+client_thread(void *arg) {
     CLI *c=arg;
 
+    /* initialize */
     c->tls=NULL; /* do not reuse */
     tls_alloc(c, NULL, NULL);
 #ifdef DEBUG_STACK_SIZE
     stack_info(1); /* initialize */
 #endif
+
+    /* execute */
     client_main(c);
+
+    /* cleanup */
 #ifdef DEBUG_STACK_SIZE
     stack_info(0); /* display computed value */
 #endif
     str_stats(); /* client thread allocation tracking */
     tls_cleanup();
     /* s_log() is not allowed after tls_cleanup() */
-#if defined(USE_WIN32) && !defined(_WIN32_WCE)
-    _endthread();
+
+    /* terminate */
+#if defined(USE_WIN32) || defined(USE_OS2)
+#if !defined(_WIN32_WCE)
+    _endthreadex(0);
 #endif
+    return 0;
+#else
 #ifdef USE_UCONTEXT
     s_poll_wait(NULL, 0, 0); /* wait on poll() */
 #endif
     return NULL;
+#endif
 }
 
 void client_main(CLI *c) {
     s_log(LOG_DEBUG, "Service [%s] started", c->opt->servname);
     if(c->opt->exec_name && c->opt->connect_addr.names) {
-            /* exec+connect options specified together
-             * -> spawn a local program instead of stdio */
-        for(;;) {
-            SERVICE_OPTIONS *opt=c->opt;
-            memset(c, 0, sizeof(CLI)); /* connect_local needs clean c */
-            c->opt=opt;
-            if(!setjmp(c->err))
-                c->local_rfd.fd=c->local_wfd.fd=connect_local(c);
-            else
-                break;
-            client_run(c);
-            if(!c->opt->option.retry)
-                break;
-            sleep(1); /* FIXME: not a good idea in ucontext threading */
-            s_poll_free(c->fds);
-            c->fds=NULL;
+        if(c->opt->option.retry)
+            exec_connect_loop(c);
+        else
+            exec_connect_once(c);
+    } else {
+        client_run(c);
+    }
+#ifndef USE_FORK
+    service_free(c->opt);
+#endif
+    str_free(c);
+}
+
+#ifdef __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+#pragma GCC diagnostic push
+#endif /* __GNUC__>=4.6 */
+#pragma GCC diagnostic ignored "-Wformat"
+#pragma GCC diagnostic ignored "-Wformat-extra-args"
+#endif /* __GNUC__ */
+NOEXPORT void exec_connect_loop(CLI *c) {
+    unsigned long long seq=0;
+    char *fresh_id=c->tls->id;
+    unsigned retry;
+
+    do {
+        /* make sure c->tls->id is valid in str_printf() */
+        char *id=str_printf("%s_%llu", fresh_id, seq++);
+        str_detach(id);
+        c->tls->id=id;
+
+        exec_connect_once(c);
+        /* retry is asynchronously changed in the main thread,
+         * so we make sure to use the same value for both checks */
+        retry=c->opt->option.retry;
+        if(retry) {
+            s_log(LOG_INFO, "Retrying an exec+connect section");
+            /* c and id are detached, so it is safe to call str_stats() */
             str_stats(); /* client thread allocation tracking */
-            /* c allocation is detached, so it is safe to call str_stats() */
-            if(service_options.next) /* no tls_cleanup() in inetd mode */
-                tls_cleanup();
+            sleep(1); /* FIXME: not a good idea in ucontext threading */
+            c->rr++;
         }
-    } else
+
+        /* make sure c->tls->id is valid in str_free() */
+        c->tls->id=fresh_id;
+        str_free(id);
+    } while(retry); /* retry is disabled on config reload */
+}
+#ifdef __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+#pragma GCC diagnostic pop
+#endif /* __GNUC__>=4.6 */
+#endif /* __GNUC__ */
+
+/* exec+connect options specified together
+ * -> spawn a local program instead of stdio */
+NOEXPORT void exec_connect_once(CLI *fresh_c) {
+    jmp_buf exception_buffer, *exception_backup;
+    /* connect_local() needs an unmodified copy of c each time */
+    CLI *c=str_alloc(sizeof(CLI));
+    memcpy(c, fresh_c, sizeof(CLI));
+
+    exception_backup=c->exception_pointer;
+    c->exception_pointer=&exception_buffer;
+    if(!setjmp(exception_buffer)) {
+        c->local_rfd.fd=c->local_wfd.fd=connect_local(c);
         client_run(c);
+    }
+    c->exception_pointer=exception_backup;
+
     str_free(c);
 }
 
 #ifdef __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 #pragma GCC diagnostic push
+#endif /* __GNUC__>=4.6 */
 #pragma GCC diagnostic ignored "-Wformat"
 #pragma GCC diagnostic ignored "-Wformat-extra-args"
 #endif /* __GNUC__ */
 NOEXPORT void client_run(CLI *c) {
+    jmp_buf exception_buffer, *exception_backup;
     int err, rst;
 #ifndef USE_FORK
-    long num_clients_copy;
+    int num;
 #endif
 
 #ifndef USE_FORK
-    stunnel_write_lock(&stunnel_locks[LOCK_CLIENTS]);
-    ui_clients(++num_clients);
-    stunnel_write_unlock(&stunnel_locks[LOCK_CLIENTS]);
+#ifdef USE_OS_THREADS
+    CRYPTO_atomic_add(&num_clients, 1, &num, stunnel_locks[LOCK_CLIENTS]);
+#else
+    num=++num_clients;
+#endif
+    ui_clients(num);
 #endif
 
         /* initialize the client context */
@@ -177,9 +246,14 @@ NOEXPORT void client_run(CLI *c) {
     addrlist_clear(&c->connect_addr, 0);
 
         /* try to process the request */
-    err=setjmp(c->err);
-    if(!err)
+    exception_backup=c->exception_pointer;
+    c->exception_pointer=&exception_buffer;
+    err=setjmp(exception_buffer);
+    if(!err) {
         client_try(c);
+    }
+    c->exception_pointer=exception_backup;
+
     rst=err==1 && c->opt->option.reset;
     s_log(LOG_NOTICE,
         "Connection %s: %llu byte(s) sent to TLS, %llu byte(s) sent to socket",
@@ -242,15 +316,16 @@ NOEXPORT void client_run(CLI *c) {
     /* display child return code if it managed to arrive on time */
     /* otherwise it will be retrieved by the init process and ignored */
     if(c->opt->exec_name) /* 'exec' specified */
-        child_status(); /* null SIGCHLD handler was used */
+        pid_status_hang("Child process"); /* null SIGCHLD handler was used */
     s_log(LOG_DEBUG, "Service [%s] finished", c->opt->servname);
 #else
-    stunnel_write_lock(&stunnel_locks[LOCK_CLIENTS]);
-    ui_clients(--num_clients);
-    num_clients_copy=num_clients; /* to move s_log() away from CRIT_CLIENTS */
-    stunnel_write_unlock(&stunnel_locks[LOCK_CLIENTS]);
-    s_log(LOG_DEBUG, "Service [%s] finished (%ld left)",
-        c->opt->servname, num_clients_copy);
+#ifdef USE_OS_THREADS
+    CRYPTO_atomic_add(&num_clients, -1, &num, stunnel_locks[LOCK_CLIENTS]);
+#else
+    num=--num_clients;
+#endif
+    ui_clients(num);
+    s_log(LOG_DEBUG, "Service [%s] finished (%ld left)", c->opt->servname, num);
 #endif
 
         /* free the client context */
@@ -258,10 +333,12 @@ NOEXPORT void client_run(CLI *c) {
     /* a client does not have its own local copy of
        c->connect_addr.session and c->connect_addr.fd */
     s_poll_free(c->fds);
-    c->fds=NULL;
+    str_free(c->accepted_address);
 }
 #ifdef __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 #pragma GCC diagnostic pop
+#endif /* __GNUC__>=4.6 */
 #endif /* __GNUC__ */
 
 NOEXPORT void client_try(CLI *c) {
@@ -283,7 +360,6 @@ NOEXPORT void client_try(CLI *c) {
 NOEXPORT void local_start(CLI *c) {
     SOCKADDR_UNION addr;
     socklen_t addr_len;
-    char *accepted_address;
 
     /* check if local_rfd is a socket and get peer address */
     addr_len=sizeof(SOCKADDR_UNION);
@@ -291,12 +367,12 @@ NOEXPORT void local_start(CLI *c) {
     if(c->local_rfd.is_socket) {
         memcpy(&c->peer_addr.sa, &addr.sa, (size_t)addr_len);
         c->peer_addr_len=addr_len;
-        if(set_socket_options(c->local_rfd.fd, 1))
+        if(socket_options_set(c->opt, c->local_rfd.fd, 1))
             s_log(LOG_WARNING, "Failed to set local socket options");
     } else {
         if(get_last_socket_error()!=S_ENOTSOCK) {
             sockerror("getpeerbyname (local_rfd)");
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
         }
     }
 
@@ -311,12 +387,12 @@ NOEXPORT void local_start(CLI *c) {
                 memcpy(&c->peer_addr.sa, &addr.sa, (size_t)addr_len);
                 c->peer_addr_len=addr_len;
             }
-            if(set_socket_options(c->local_wfd.fd, 1))
+            if(socket_options_set(c->opt, c->local_wfd.fd, 1))
                 s_log(LOG_WARNING, "Failed to set local socket options");
         } else {
             if(get_last_socket_error()!=S_ENOTSOCK) {
                 sockerror("getpeerbyname (local_wfd)");
-                longjmp(c->err, 1);
+                throw_exception(c, 1);
             }
         }
     }
@@ -326,7 +402,7 @@ NOEXPORT void local_start(CLI *c) {
 #ifndef USE_WIN32
         if(c->opt->option.transparent_src) {
             s_log(LOG_ERR, "Transparent source needs a socket");
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
         }
 #endif
         s_log(LOG_NOTICE, "Service [%s] accepted connection", c->opt->servname);
@@ -334,14 +410,13 @@ NOEXPORT void local_start(CLI *c) {
     }
 
     /* authenticate based on retrieved IP address of the client */
-    accepted_address=s_ntop(&c->peer_addr, c->peer_addr_len);
+    c->accepted_address=s_ntop(&c->peer_addr, c->peer_addr_len);
 #ifdef USE_LIBWRAP
-    libwrap_auth(c, accepted_address);
+    libwrap_auth(c);
 #endif /* USE_LIBWRAP */
-    auth_user(c, accepted_address);
+    auth_user(c);
     s_log(LOG_NOTICE, "Service [%s] accepted connection from %s",
-        c->opt->servname, accepted_address);
-    str_free(accepted_address);
+        c->opt->servname, c->accepted_address);
 }
 
 NOEXPORT void remote_start(CLI *c) {
@@ -368,7 +443,7 @@ NOEXPORT void remote_start(CLI *c) {
 #endif
     {
         c->remote_fd.is_socket=1;
-        if(set_socket_options(c->remote_fd.fd, 2))
+        if(socket_options_set(c->opt, c->remote_fd.fd, 2))
             s_log(LOG_WARNING, "Failed to set remote socket options");
     }
     s_log(LOG_DEBUG, "Remote descriptor (FD=%ld) initialized",
@@ -382,21 +457,26 @@ NOEXPORT void ssl_start(CLI *c) {
     c->ssl=SSL_new(c->opt->ctx);
     if(!c->ssl) {
         sslerror("SSL_new");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     /* for callbacks */
     if(!SSL_set_ex_data(c->ssl, index_ssl_cli, c)) {
         sslerror("SSL_set_ex_data");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     if(c->opt->option.client) {
 #ifndef OPENSSL_NO_TLSEXT
+        /* c->opt->sni should always be initialized at this point,
+         * either explicitly with "sni"
+         * or implicitly with "protocolHost" or "connect" */
         if(c->opt->sni && *c->opt->sni) {
             s_log(LOG_INFO, "SNI: sending servername: %s", c->opt->sni);
             if(!SSL_set_tlsext_host_name(c->ssl, c->opt->sni)) {
                 sslerror("SSL_set_tlsext_host_name");
-                longjmp(c->err, 1);
+                throw_exception(c, 1);
             }
+        } else { /* c->opt->sni was set to an empty value */
+            s_log(LOG_INFO, "SNI: extension disabled");
         }
 #endif
         session_cache_retrieve(c);
@@ -428,7 +508,7 @@ NOEXPORT void ssl_start(CLI *c) {
          * alternative solution is to disable internal session caching     *
          * NOTE: this critical section also covers callbacks (e.g. OCSP)   */
         if(unsafe_openssl)
-            stunnel_write_lock(&stunnel_locks[LOCK_SSL]);
+            CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_SSL]);
 
         if(c->opt->option.client)
             i=SSL_connect(c->ssl);
@@ -436,7 +516,7 @@ NOEXPORT void ssl_start(CLI *c) {
             i=SSL_accept(c->ssl);
 
         if(unsafe_openssl)
-            stunnel_write_unlock(&stunnel_locks[LOCK_SSL]);
+            CRYPTO_THREAD_unlock(stunnel_locks[LOCK_SSL]);
 
         err=SSL_get_error(c->ssl, i);
         if(err==SSL_ERROR_NONE)
@@ -449,16 +529,17 @@ NOEXPORT void ssl_start(CLI *c) {
             switch(s_poll_wait(c->fds, c->opt->timeout_busy, 0)) {
             case -1:
                 sockerror("ssl_start: s_poll_wait");
-                longjmp(c->err, 1);
+                throw_exception(c, 1);
             case 0:
                 s_log(LOG_INFO, "ssl_start: s_poll_wait:"
                     " TIMEOUTbusy exceeded: sending reset");
-                longjmp(c->err, 1);
+                s_poll_dump(c->fds, LOG_DEBUG);
+                throw_exception(c, 1);
             case 1:
                 break; /* OK */
             default:
                 s_log(LOG_ERR, "ssl_start: s_poll_wait: unknown result");
-                longjmp(c->err, 1);
+                throw_exception(c, 1);
             }
             continue; /* ok -> retry */
         }
@@ -476,94 +557,59 @@ NOEXPORT void ssl_start(CLI *c) {
             sslerror("SSL_connect");
         else
             sslerror("SSL_accept");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
-    s_log(LOG_INFO, "TLS %s: %s",
-        c->opt->option.client ? "connected" : "accepted",
-        SSL_session_reused(c->ssl) ?
-            "previous session reused" : "new session negotiated");
-    if(!SSL_session_reused(c->ssl)) { /* a new session was negotiated */
-        new_chain(c);
-        if(c->opt->option.client)
-            session_cache_save(c);
-        print_cipher(c);
-    }
-}
-
-/* cache client sessions */
-NOEXPORT void session_cache_save(CLI *c) {
-    SSL_SESSION *old1, *old2;
-
-    stunnel_write_lock(&stunnel_locks[LOCK_SESSION]);
-    /* per-destination client cache */
-    /* "parent->" part is added for future use (not currently needed) */
-    old1=c->connect_addr.parent->session[c->idx];
-    c->connect_addr.parent->session[c->idx]=SSL_get1_session(c->ssl);
-    /* per-section client cache (for delayed resolver) */
-    old2=c->opt->session;
-    c->opt->session=SSL_get1_session(c->ssl);
-    stunnel_write_unlock(&stunnel_locks[LOCK_SESSION]);
-    if(old1)
-        SSL_SESSION_free(old1);
-    if(old2)
-        SSL_SESSION_free(old2);
+    print_cipher(c);
+    if(SSL_session_reused(c->ssl))
+        print_session_id(SSL_get_session(c->ssl));
 }
 
 NOEXPORT void session_cache_retrieve(CLI *c) {
-    stunnel_read_lock(&stunnel_locks[LOCK_SESSION]);
-    /* try per-destination cache first */
-    /* "parent->" part is added for future use (not currently needed) */
-    if(c->connect_addr.parent->session[c->idx])
-        SSL_set_session(c->ssl, c->connect_addr.parent->session[c->idx]);
-    else if(c->opt->session)
-        SSL_set_session(c->ssl, c->opt->session);
-    stunnel_read_unlock(&stunnel_locks[LOCK_SESSION]);
-}
-
-NOEXPORT void new_chain(CLI *c) {
-    BIO *bio;
-    int i, len;
-    X509 *peer_cert;
-    STACK_OF(X509) *sk;
-    char *chain;
+    SSL_SESSION *sess;
 
-    if(c->opt->chain) /* already cached */
-        return; /* this race condition is safe to ignore */
-    bio=BIO_new(BIO_s_mem());
-    if(!bio)
-        return;
-    sk=SSL_get_peer_cert_chain(c->ssl);
-    for(i=0; sk && i<sk_X509_num(sk); i++) {
-        peer_cert=sk_X509_value(sk, i);
-        PEM_write_bio_X509(bio, peer_cert);
-    }
-    if(!sk || !c->opt->option.client) {
-        peer_cert=SSL_get_peer_certificate(c->ssl);
-        if(peer_cert) {
-            PEM_write_bio_X509(bio, peer_cert);
-            X509_free(peer_cert);
+    CRYPTO_THREAD_read_lock(stunnel_locks[LOCK_SESSION]);
+    if(c->opt->option.delayed_lookup) {
+        sess=c->opt->session;
+    } else { /* per-destination client cache */
+        if(c->opt->connect_session) {
+            sess=c->opt->connect_session[c->idx];
+        } else {
+            s_log(LOG_ERR, "INTERNAL ERROR: Uninitialized client session cache");
+            sess=NULL;
         }
     }
-    len=BIO_pending(bio);
-    if(len<=0) {
-        s_log(LOG_INFO, "No peer certificate received");
-        BIO_free(bio);
-        return;
-    }
-    /* prevent automatic deallocation of the cached value */
-    chain=str_alloc_detached((size_t)len+1);
-    len=BIO_read(bio, chain, len);
-    if(len<0) {
-        s_log(LOG_ERR, "BIO_read failed");
-        BIO_free(bio);
-        str_free(chain);
+    if(sess)
+        SSL_set_session(c->ssl, sess);
+    CRYPTO_THREAD_unlock(stunnel_locks[LOCK_SESSION]);
+}
+
+NOEXPORT void print_cipher(CLI *c) { /* print negotiated cipher */
+    SSL_CIPHER *cipher;
+#ifndef OPENSSL_NO_COMP
+    const COMP_METHOD *compression, *expansion;
+#endif
+
+    if(c->opt->log_level<LOG_INFO) /* performance optimization */
         return;
-    }
-    chain[len]='\0';
-    BIO_free(bio);
-    c->opt->chain=chain; /* this race condition is safe to ignore */
-    ui_new_chain(c->opt->section_number);
-    s_log(LOG_DEBUG, "Peer certificate was cached (%d bytes)", len);
+
+    s_log(LOG_INFO, "TLS %s: %s",
+        c->opt->option.client ? "connected" : "accepted",
+        SSL_session_reused(c->ssl) ?
+            "previous session reused" : "new session negotiated");
+
+    cipher=(SSL_CIPHER *)SSL_get_current_cipher(c->ssl);
+    s_log(LOG_INFO, "%s ciphersuite: %s (%d-bit encryption)",
+        SSL_get_version(c->ssl), SSL_CIPHER_get_name(cipher),
+        SSL_CIPHER_get_bits(cipher, NULL));
+
+#ifndef OPENSSL_NO_COMP
+    compression=SSL_get_current_compression(c->ssl);
+    expansion=SSL_get_current_expansion(c->ssl);
+    s_log(compression||expansion ? LOG_INFO : LOG_DEBUG,
+        "Compression: %s, expansion: %s",
+        compression ? SSL_COMP_get_name(compression) : "null",
+        expansion ? SSL_COMP_get_name(expansion) : "null");
+#endif
 }
 
 /****************************** transfer data */
@@ -621,17 +667,19 @@ NOEXPORT void transfer(CLI *c) {
         switch(err) {
         case -1:
             sockerror("transfer: s_poll_wait");
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
         case 0: /* timeout */
             if((sock_open_rd &&
                     !(SSL_get_shutdown(c->ssl)&SSL_RECEIVED_SHUTDOWN)) ||
                     c->ssl_ptr || c->sock_ptr) {
                 s_log(LOG_INFO, "transfer: s_poll_wait:"
                     " TIMEOUTidle exceeded: sending reset");
-                longjmp(c->err, 1);
+                s_poll_dump(c->fds, LOG_DEBUG);
+                throw_exception(c, 1);
             } else { /* already closing connection */
                 s_log(LOG_ERR, "transfer: s_poll_wait:"
                     " TIMEOUTclose exceeded: closing");
+                s_poll_dump(c->fds, LOG_DEBUG);
                 return; /* OK */
             }
         }
@@ -691,7 +739,7 @@ NOEXPORT void transfer(CLI *c) {
                     s_log(LOG_ERR,
                         "Socket closed (HUP) with %ld unsent byte(s)",
                         (long)c->ssl_ptr);
-                    longjmp(c->err, 1); /* reset the sockets */
+                    throw_exception(c, 1); /* reset the sockets */
                 }
                 s_log(LOG_INFO, "Socket closed (HUP)");
                 sock_open_rd=sock_open_wr=0;
@@ -701,7 +749,7 @@ NOEXPORT void transfer(CLI *c) {
                     s_log(LOG_ERR,
                         "TLS socket closed (HUP) with %ld unsent byte(s)",
                         (long)c->sock_ptr);
-                    longjmp(c->err, 1); /* reset the sockets */
+                    throw_exception(c, 1); /* reset the sockets */
                 }
                 s_log(LOG_INFO, "TLS socket closed (HUP)");
                 SSL_set_shutdown(c->ssl,
@@ -711,7 +759,7 @@ NOEXPORT void transfer(CLI *c) {
 
         if(c->reneg_state==RENEG_DETECTED && !c->opt->option.renegotiation) {
             s_log(LOG_ERR, "Aborting due to renegotiation request");
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
         }
 
         /****************************** send TLS close_notify alert */
@@ -748,10 +796,10 @@ NOEXPORT void transfer(CLI *c) {
                 break;
             case SSL_ERROR_SSL: /* TLS error */
                 sslerror("SSL_shutdown");
-                longjmp(c->err, 1);
+                throw_exception(c, 1);
             default:
                 s_log(LOG_ERR, "SSL_shutdown/SSL_get_error returned %d", err);
-                longjmp(c->err, 1);
+                throw_exception(c, 1);
             }
         }
 
@@ -843,7 +891,7 @@ NOEXPORT void transfer(CLI *c) {
                     s_log(LOG_ERR,
                         "TLS socket closed (SSL_write) with %ld unsent byte(s)",
                         (long)c->sock_ptr);
-                    longjmp(c->err, 1); /* reset the sockets */
+                    throw_exception(c, 1); /* reset the sockets */
                 }
                 s_log(LOG_INFO, "TLS socket closed (SSL_write)");
                 SSL_set_shutdown(c->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
@@ -855,10 +903,10 @@ NOEXPORT void transfer(CLI *c) {
                 break;
             case SSL_ERROR_SSL:
                 sslerror("SSL_write");
-                longjmp(c->err, 1);
+                throw_exception(c, 1);
             default:
                 s_log(LOG_ERR, "SSL_write/SSL_get_error returned %d", err);
-                longjmp(c->err, 1);
+                throw_exception(c, 1);
             }
         }
 
@@ -902,7 +950,7 @@ NOEXPORT void transfer(CLI *c) {
                     s_log(LOG_ERR,
                         "TLS socket closed (SSL_read) with %ld unsent byte(s)",
                         (long)c->sock_ptr);
-                    longjmp(c->err, 1); /* reset the sockets */
+                    throw_exception(c, 1); /* reset the sockets */
                 }
                 s_log(LOG_INFO, "TLS socket closed (SSL_read)");
                 SSL_set_shutdown(c->ssl,
@@ -916,10 +964,10 @@ NOEXPORT void transfer(CLI *c) {
                 break;
             case SSL_ERROR_SSL:
                 sslerror("SSL_read");
-                longjmp(c->err, 1);
+                throw_exception(c, 1);
             default:
                 s_log(LOG_ERR, "SSL_read/SSL_get_error returned %d", err);
-                longjmp(c->err, 1);
+                throw_exception(c, 1);
             }
         }
 
@@ -936,7 +984,7 @@ NOEXPORT void transfer(CLI *c) {
                 s_log(LOG_ERR,
                     "Write socket closed (write hangup) with %ld unsent byte(s)",
                     (long)c->ssl_ptr);
-                longjmp(c->err, 1); /* reset the sockets */
+                throw_exception(c, 1); /* reset the sockets */
             }
             s_log(LOG_INFO, "Write socket closed (write hangup)");
             sock_open_wr=0;
@@ -957,7 +1005,7 @@ NOEXPORT void transfer(CLI *c) {
                 s_log(LOG_ERR,
                     "TLS socket closed (write hangup) with %ld unsent byte(s)",
                     (long)c->sock_ptr);
-                longjmp(c->err, 1); /* reset the sockets */
+                throw_exception(c, 1); /* reset the sockets */
             }
             s_log(LOG_INFO, "TLS socket closed (write hangup)");
             SSL_set_shutdown(c->ssl,
@@ -1022,7 +1070,7 @@ NOEXPORT void transfer(CLI *c) {
             s_log(LOG_ERR, "socket input buffer: %ld byte(s), "
                 "TLS input buffer: %ld byte(s)",
                 (long)c->sock_ptr, (long)c->ssl_ptr);
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
         }
 
     } while(sock_open_wr || !(SSL_get_shutdown(c->ssl)&SSL_SENT_SHUTDOWN) ||
@@ -1030,10 +1078,12 @@ NOEXPORT void transfer(CLI *c) {
 }
 
 #ifdef __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 #pragma GCC diagnostic push
+#endif /* __GNUC__>=4.6 */
 #if __GNUC__ >= 7
 #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
-#endif
+#endif /* __GNUC__>=7 */
 #endif /* __GNUC__ */
 
     /* returns 0 on close and 1 on non-critical errors */
@@ -1071,39 +1121,18 @@ NOEXPORT int parse_socket_error(CLI *c,
 #endif
     default:
         sockerror(text);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
         return -1; /* some C compilers require a return value */
     }
 }
 
 #ifdef __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 #pragma GCC diagnostic pop
+#endif /* __GNUC__>=4.6 */
 #endif /* __GNUC__ */
 
-NOEXPORT void print_cipher(CLI *c) { /* print negotiated cipher */
-    SSL_CIPHER *cipher;
-#ifndef OPENSSL_NO_COMP
-    const COMP_METHOD *compression, *expansion;
-#endif
-
-    if(c->opt->log_level<LOG_INFO) /* performance optimization */
-        return;
-    cipher=(SSL_CIPHER *)SSL_get_current_cipher(c->ssl);
-    s_log(LOG_INFO, "Negotiated %s ciphersuite %s (%d-bit encryption)",
-        SSL_get_version(c->ssl), SSL_CIPHER_get_name(cipher),
-        SSL_CIPHER_get_bits(cipher, NULL));
-
-#ifndef OPENSSL_NO_COMP
-    compression=SSL_get_current_compression(c->ssl);
-    expansion=SSL_get_current_expansion(c->ssl);
-    s_log(compression||expansion ? LOG_INFO : LOG_DEBUG,
-        "Compression: %s, expansion: %s",
-        compression ? SSL_COMP_get_name(compression) : "null",
-        expansion ? SSL_COMP_get_name(expansion) : "null");
-#endif
-}
-
-NOEXPORT void auth_user(CLI *c, char *accepted_address) {
+NOEXPORT void auth_user(CLI *c) {
 #ifndef _WIN32_WCE
     struct servent *s_ent;    /* structure for getservbyname */
 #endif
@@ -1122,7 +1151,7 @@ NOEXPORT void auth_user(CLI *c, char *ac
     c->fd=s_socket(c->peer_addr.sa.sa_family, SOCK_STREAM,
         0, 1, "socket (auth_user)");
     if(c->fd==INVALID_SOCKET)
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     memcpy(&ident, &c->peer_addr, (size_t)c->peer_addr_len);
 #ifndef _WIN32_WCE
     s_ent=getservbyname("auth", "tcp");
@@ -1135,7 +1164,7 @@ NOEXPORT void auth_user(CLI *c, char *ac
         ident.in.sin_port=htons(113);
     }
     if(s_connect(c, &ident, addr_len(&ident)))
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     s_log(LOG_DEBUG, "IDENT server connected");
     remote_port=ntohs(c->peer_addr.in.sin_port);
     local_port=(unsigned)(c->opt->local_addr.addr ?
@@ -1148,35 +1177,35 @@ NOEXPORT void auth_user(CLI *c, char *ac
     if(!type) {
         s_log(LOG_ERR, "Malformed IDENT response");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     *type++='\0';
     system=strchr(type, ':');
     if(!system) {
         s_log(LOG_ERR, "Malformed IDENT response");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     *system++='\0';
     if(strcmp(type, " USERID ")) {
         s_log(LOG_ERR, "Incorrect INETD response type");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     user=strchr(system, ':');
     if(!user) {
         s_log(LOG_ERR, "Malformed IDENT response");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     *user++='\0';
     while(*user==' ') /* skip leading spaces */
         ++user;
     if(strcmp(user, c->opt->username)) {
         s_log(LOG_WARNING, "Connection from %s REFUSED by IDENT (user \"%s\")",
-            accepted_address, user);
+            c->accepted_address, user);
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     s_log(LOG_INFO, "IDENT authentication passed");
     str_free(line);
@@ -1186,7 +1215,7 @@ NOEXPORT void auth_user(CLI *c, char *ac
 
 NOEXPORT int connect_local(CLI *c) { /* spawn local process */
     s_log(LOG_ERR, "Local mode is not supported on this platform");
-    longjmp(c->err, 1);
+    throw_exception(c, 1);
     return -1; /* some C compilers require a return value */
 }
 
@@ -1199,7 +1228,7 @@ NOEXPORT SOCKET connect_local(CLI *c) {
     LPTSTR name, args;
 
     if(make_sockets(fd))
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     memset(&si, 0, sizeof si);
     si.cb=sizeof si;
     si.dwFlags=STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
@@ -1234,11 +1263,11 @@ NOEXPORT SOCKET connect_local(CLI *c) {
         char tty[64];
 
         if(pty_allocate(fd, fd+1, tty))
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
         s_log(LOG_DEBUG, "TTY=%s allocated", tty);
     } else
         if(make_sockets(fd))
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
     set_nonblock(fd[1], 0); /* switch back to the blocking mode */
 
     env=env_alloc(c);
@@ -1250,7 +1279,7 @@ NOEXPORT SOCKET connect_local(CLI *c) {
         closesocket(fd[1]);
         env_free(env);
         ioerror("fork");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     case  0:    /* child */
         /* the child is not allowed to play with thread-local storage */
         /* see http://linux.die.net/man/3/pthread_atfork for details */
@@ -1356,7 +1385,7 @@ NOEXPORT SOCKET connect_remote(CLI *c) {
     switch(c->connect_addr.num) {
     case 0:
         s_log(LOG_ERR, "No remote host resolved");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     case 1:
         idx_start=0;
         break;
@@ -1384,7 +1413,7 @@ NOEXPORT SOCKET connect_remote(CLI *c) {
         }
     }
     s_log(LOG_ERR, "No more addresses to connect");
-    longjmp(c->err, 1);
+    throw_exception(c, 1);
     return INVALID_SOCKET; /* some C compilers require a return value */
 }
 
@@ -1402,12 +1431,16 @@ NOEXPORT void idx_cache_save(SSL_SESSION
     s_log(LOG_INFO, "persistence: %s cached", addr_txt);
     str_free(addr_txt);
 
-    stunnel_write_lock(&stunnel_locks[LOCK_ADDR]);
+    CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_ADDR]);
     old_addr=SSL_SESSION_get_ex_data(sess, index_session_connect_address);
-    /* we can safely ignore the SSL_SESSION_set_ex_data() failure */
-    SSL_SESSION_set_ex_data(sess, index_session_connect_address, new_addr);
-    stunnel_write_unlock(&stunnel_locks[LOCK_ADDR]);
-    str_free(old_addr); /* NULL pointers are ignored */
+    if(SSL_SESSION_set_ex_data(sess, index_session_connect_address, new_addr)) {
+        CRYPTO_THREAD_unlock(stunnel_locks[LOCK_ADDR]);
+        str_free(old_addr); /* NULL pointers are ignored */
+    } else { /* failed to store new_addr -> remove it */
+        sslerror("SSL_SESSION_set_ex_data");
+        CRYPTO_THREAD_unlock(stunnel_locks[LOCK_ADDR]);
+        str_free(new_addr); /* NULL pointers are ignored */
+    }
 }
 
 NOEXPORT unsigned idx_cache_retrieve(CLI *c) {
@@ -1417,13 +1450,13 @@ NOEXPORT unsigned idx_cache_retrieve(CLI
     char *addr_txt;
 
     if(c->ssl && SSL_session_reused(c->ssl)) {
-        stunnel_read_lock(&stunnel_locks[LOCK_ADDR]);
+        CRYPTO_THREAD_read_lock(stunnel_locks[LOCK_ADDR]);
         ptr=SSL_SESSION_get_ex_data(SSL_get_session(c->ssl),
             index_session_connect_address);
         if(ptr) {
             len=addr_len(ptr);
             memcpy(&addr, ptr, (size_t)len);
-            stunnel_read_unlock(&stunnel_locks[LOCK_ADDR]);
+            CRYPTO_THREAD_unlock(stunnel_locks[LOCK_ADDR]);
             /* address was copied, ptr itself is no longer valid */
             for(i=0; i<c->connect_addr.num; ++i) {
                 if(addr_len(&c->connect_addr.addr[i])==len &&
@@ -1439,13 +1472,13 @@ NOEXPORT unsigned idx_cache_retrieve(CLI
             s_log(LOG_INFO, "persistence: %s not available", addr_txt);
             str_free(addr_txt);
         } else {
-            stunnel_read_unlock(&stunnel_locks[LOCK_ADDR]);
+            CRYPTO_THREAD_unlock(stunnel_locks[LOCK_ADDR]);
             s_log(LOG_NOTICE, "persistence: No cached address found");
         }
     }
 
     if(c->opt->failover==FAILOVER_RR) {
-        i=(c->connect_addr.start+c->opt->seq)%c->connect_addr.num;
+        i=(c->connect_addr.start+c->rr)%c->connect_addr.num;
         s_log(LOG_INFO, "failover: round-robin, starting at entry #%d", i);
     } else {
         i=0;
@@ -1473,7 +1506,7 @@ NOEXPORT void connect_setup(CLI *c) {
         c->connect_addr.num=1;
         c->connect_addr.addr=str_alloc(sizeof(SOCKADDR_UNION));
         if(original_dst(c->local_rfd.fd, c->connect_addr.addr))
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
         return;
     }
 
@@ -1552,7 +1585,7 @@ NOEXPORT int connect_init(CLI *c, int do
         /* FIXME: move this check to options.c */
         s_log(LOG_ERR, "Transparent proxy in remote mode is not supported"
             " on this platform");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
 #endif
     }
 #endif /* !defined(USE_WIN32) */
@@ -1616,4 +1649,10 @@ NOEXPORT void reset(SOCKET fd, char *txt
         log_error(LOG_DEBUG, get_last_socket_error(), txt);
 }
 
+void throw_exception(CLI *c, int v) {
+    if(!c || !c->exception_pointer)
+        fatal("No exception handler");
+    longjmp(*c->exception_pointer, v);
+}
+
 /* end of client.c */
diff -pruN 3:5.44-1/src/common.h 3:5.49-1/src/common.h
--- 3:5.44-1/src/common.h	2017-01-02 14:27:26.000000000 +0000
+++ 3:5.49-1/src/common.h	2018-06-08 17:30:15.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -52,8 +52,10 @@
 #define BUFFSIZE 18432
 
 /* how many bytes of random input to read from files for PRNG */
-/* OpenSSL likes at least 128 bits, so 64 bytes seems plenty. */
-#define RANDOM_BYTES 64
+/* security margin is huge to compensate for flawed entropy */
+#define RANDOM_BYTES 1024
+
+/**************************************** debugging */
 
 /* for FormatGuard */
 /* #define __NO_FORMATGUARD_ */
@@ -67,6 +69,12 @@
 #define NOEXPORT static
 #endif
 
+#ifdef __GNUC__
+#define NORETURN __attribute__((noreturn))
+#else
+#define NORETURN
+#endif /* __GNUC__ */
+
 /**************************************** platform */
 
 #ifdef _WIN32
@@ -355,16 +363,6 @@ typedef int SOCKET;
 #define INADDR_LOOPBACK  (u32)0x7F000001
 #endif
 
-#if defined(HAVE_WAITPID)
-/* for SYSV systems */
-#define wait_for_pid(a, b, c) waitpid((a), (b), (c))
-#define HAVE_WAIT_FOR_PID 1
-#elif defined(HAVE_WAIT4)
-/* for BSD systems */
-#define wait_for_pid(a, b, c) wait4((a), (b), (c), NULL)
-#define HAVE_WAIT_FOR_PID 1
-#endif
-
 /* SunOS 4 */
 #if defined(sun) && !defined(__svr4__) && !defined(__SVR4)
 #define atexit(a) on_exit((a), NULL)
@@ -460,6 +458,7 @@ extern char *sys_errlist[];
 #define USE_FIPS
 #endif
 
+#include <openssl/conf.h>
 #include <openssl/lhash.h>
 #include <openssl/ssl.h>
 #include <openssl/ui.h>
diff -pruN 3:5.44-1/src/cron.c 3:5.49-1/src/cron.c
--- 3:5.44-1/src/cron.c	2017-08-17 09:18:53.000000000 +0000
+++ 3:5.49-1/src/cron.c	2018-07-02 21:30:10.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -42,9 +42,9 @@
 NOEXPORT void *cron_thread(void *arg);
 #endif
 #ifdef USE_WIN32
-NOEXPORT void cron_thread(void *arg);
+NOEXPORT unsigned __stdcall cron_thread(void *arg);
 #endif
-#if defined(USE_PTHREAD) || defined(USE_WIN32)
+#ifdef USE_OS_THREADS
 NOEXPORT void cron_worker(void);
 NOEXPORT void cron_dh_param(void);
 #endif
@@ -92,21 +92,28 @@ NOEXPORT void *cron_thread(void *arg) {
 #elif defined(USE_WIN32)
 
 int cron_init() {
-    if((long)_beginthread(cron_thread, 0, NULL)==-1)
-        ioerror("_beginthread");
+    HANDLE handle;
+
+    handle=(HANDLE)_beginthreadex(NULL, 0, cron_thread, NULL, 0, NULL);
+    if(!handle) {
+        ioerror("_beginthreadex");
+        return 1;
+    }
+    CloseHandle(handle);
     return 0;
 }
 
-NOEXPORT void cron_thread(void *arg) {
+NOEXPORT unsigned __stdcall cron_thread(void *arg) {
     (void)arg; /* squash the unused parameter warning */
     tls_alloc(NULL, NULL, "cron");
     if(!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST))
         ioerror("SetThreadPriority");
     cron_worker();
-    _endthread(); /* it should never be executed */
+    _endthreadex(0); /* it should never be executed */
+    return 0;
 }
 
-#else /* !defined(USE_PTHREAD) && !defined(USE_WIN32) */
+#else /* USE_OS_THREADS */
 
 int cron_init() {
     /* not implemented for now */
@@ -118,7 +125,7 @@ int cron_init() {
 /* run the cron job every 24 hours */
 #define CRON_PERIOD (24*60*60)
 
-#if defined(USE_PTHREAD) || defined(USE_WIN32)
+#ifdef USE_OS_THREADS
 
 NOEXPORT void cron_worker(void) {
     time_t now, then;
@@ -183,10 +190,10 @@ NOEXPORT void cron_dh_param(void) {
 #endif
 
     /* update global dh_params for future configuration reloads */
-    stunnel_write_lock(&stunnel_locks[LOCK_DH]);
+    CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_DH]);
     DH_free(dh_params);
     dh_params=dh;
-    stunnel_write_unlock(&stunnel_locks[LOCK_DH]);
+    CRYPTO_THREAD_unlock(stunnel_locks[LOCK_DH]);
 
     /* set for all sections that require it */
     for(opt=service_options.next; opt; opt=opt->next)
@@ -196,6 +203,6 @@ NOEXPORT void cron_dh_param(void) {
 }
 #endif /* OPENSSL_NO_DH */
 
-#endif /* USE_PTHREAD || USE_WIN32 */
+#endif /* USE_OS_THREADS */
 
 /* end of cron.c */
diff -pruN 3:5.44-1/src/ctx.c 3:5.49-1/src/ctx.c
--- 3:5.44-1/src/ctx.c	2017-08-17 09:18:53.000000000 +0000
+++ 3:5.49-1/src/ctx.c	2018-08-09 05:43:52.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -54,7 +54,7 @@ int dh_needed=0;
 /* SNI */
 #ifndef OPENSSL_NO_TLSEXT
 NOEXPORT int servername_cb(SSL *, int *, void *);
-NOEXPORT int matches_wildcard(char *, char *);
+NOEXPORT int matches_wildcard(const char *, const char *);
 #endif
 
 /* DH/ECDH */
@@ -92,6 +92,8 @@ NOEXPORT int ui_retry();
 
 /* session callbacks */
 NOEXPORT int sess_new_cb(SSL *, SSL_SESSION *);
+NOEXPORT void new_chain(CLI *);
+NOEXPORT void session_cache_save(CLI *, SSL_SESSION *);
 NOEXPORT SSL_SESSION *sess_get_cb(SSL *,
 #if OPENSSL_VERSION_NUMBER>=0x10100000L
     const
@@ -148,19 +150,29 @@ int context_init(SERVICE_OPTIONS *sectio
         }
     }
 
-    /* options */
+    /* TLS options: configure the stunnel defaults first */
+    SSL_CTX_set_options(section->ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
+#ifdef SSL_OP_NO_COMPRESSION
+    /* we implemented a better way to disable compression if needed */
+    SSL_CTX_clear_options(section->ctx, SSL_OP_NO_COMPRESSION);
+#endif /* SSL_OP_NO_COMPRESSION */
+
+    /* TLS options: configure the user-specified values */
     SSL_CTX_set_options(section->ctx,
         (SSL_OPTIONS_TYPE)(section->ssl_options_set));
 #if OPENSSL_VERSION_NUMBER>=0x009080dfL
     SSL_CTX_clear_options(section->ctx,
         (SSL_OPTIONS_TYPE)(section->ssl_options_clear));
+#endif /* OpenSSL 0.9.8m or later */
+
+    /* TLS options: log the configured values */
+#if OPENSSL_VERSION_NUMBER>=0x009080dfL
     s_log(LOG_DEBUG, "TLS options: 0x%08lX (+0x%08lX, -0x%08lX)",
         SSL_CTX_get_options(section->ctx),
         section->ssl_options_set, section->ssl_options_clear);
 #else /* OpenSSL older than 0.9.8m */
     s_log(LOG_DEBUG, "TLS options: 0x%08lX (+0x%08lX)",
-        SSL_CTX_get_options(section->ctx),
-        section->ssl_options_set);
+        SSL_CTX_get_options(section->ctx), section->ssl_options_set);
 #endif /* OpenSSL 0.9.8m or later */
 
     /* initialize OpenSSL CONF options */
@@ -190,6 +202,8 @@ int context_init(SERVICE_OPTIONS *sectio
             return 1; /* FAILED */
         }
     }
+    SSL_CTX_set_session_cache_mode(section->ctx,
+        SSL_SESS_CACHE_BOTH | SSL_SESS_CACHE_NO_INTERNAL_STORE);
     SSL_CTX_sess_set_cache_size(section->ctx, section->session_size);
     SSL_CTX_set_timeout(section->ctx, section->session_timeout);
     SSL_CTX_sess_set_new_cb(section->ctx, sess_new_cb);
@@ -210,7 +224,6 @@ int context_init(SERVICE_OPTIONS *sectio
     /* initialize the DH/ECDH key agreement in the server mode */
     if(!section->option.client) {
 #ifndef OPENSSL_NO_TLSEXT
-        SSL_CTX_set_tlsext_servername_arg(section->ctx, section);
         SSL_CTX_set_tlsext_servername_callback(section->ctx, servername_cb);
 #endif /* OPENSSL_NO_TLSEXT */
 #ifndef OPENSSL_NO_DH
@@ -229,17 +242,16 @@ int context_init(SERVICE_OPTIONS *sectio
 #ifndef OPENSSL_NO_TLSEXT
 
 NOEXPORT int servername_cb(SSL *ssl, int *ad, void *arg) {
-    SERVICE_OPTIONS *section=(SERVICE_OPTIONS *)arg;
     const char *servername=SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
+    CLI *c=SSL_get_ex_data(ssl, index_ssl_cli);
     SERVERNAME_LIST *list;
-    CLI *c;
-#ifdef USE_LIBWRAP
-    char *accepted_address;
-#endif /* USE_LIBWRAP */
 
     /* leave the alert type at SSL_AD_UNRECOGNIZED_NAME */
     (void)ad; /* squash the unused parameter warning */
-    if(!section->servername_list_head) {
+    (void)arg; /* squash the unused parameter warning */
+
+    /* handle trivial cases first */
+    if(!c->opt->servername_list_head) {
         s_log(LOG_DEBUG, "SNI: no virtual services defined");
         return SSL_TLSEXT_ERR_OK;
     }
@@ -247,26 +259,31 @@ NOEXPORT int servername_cb(SSL *ssl, int
         s_log(LOG_NOTICE, "SNI: no servername received");
         return SSL_TLSEXT_ERR_NOACK;
     }
+
+    /* find a matching section */
     s_log(LOG_INFO, "SNI: requested servername: %s", servername);
+    for(list=c->opt->servername_list_head; list; list=list->next)
+        if(matches_wildcard(servername, list->servername))
+            break;
+    if(!list) {
+        s_log(LOG_ERR, "SNI: no pattern matched servername: %s", servername);
+        return SSL_TLSEXT_ERR_OK;
+    }
+    s_log(LOG_DEBUG, "SNI: matched pattern: %s", list->servername);
 
-    for(list=section->servername_list_head; list; list=list->next)
-        if(matches_wildcard((char *)servername, list->servername)) {
-            s_log(LOG_DEBUG, "SNI: matched pattern: %s", list->servername);
-            c=SSL_get_ex_data(ssl, index_ssl_cli);
-            c->opt=list->opt;
-            SSL_set_SSL_CTX(ssl, c->opt->ctx);
-            SSL_set_verify(ssl, SSL_CTX_get_verify_mode(c->opt->ctx),
-                SSL_CTX_get_verify_callback(c->opt->ctx));
-            s_log(LOG_NOTICE, "SNI: switched to service [%s]",
-                c->opt->servname);
+    /* switch to the new section */
+#ifndef USE_FORK
+    service_up_ref(list->opt);
+    service_free(c->opt);
+#endif
+    c->opt=list->opt;
+    SSL_set_SSL_CTX(ssl, c->opt->ctx);
+    SSL_set_verify(ssl, SSL_CTX_get_verify_mode(c->opt->ctx),
+        SSL_CTX_get_verify_callback(c->opt->ctx));
+    s_log(LOG_NOTICE, "SNI: switched to service [%s]", c->opt->servname);
 #ifdef USE_LIBWRAP
-            accepted_address=s_ntop(&c->peer_addr, c->peer_addr_len);
-            libwrap_auth(c, accepted_address); /* retry on a service switch */
-            str_free(accepted_address);
+    libwrap_auth(c); /* retry on a service switch */
 #endif /* USE_LIBWRAP */
-            return SSL_TLSEXT_ERR_OK;
-        }
-    s_log(LOG_ERR, "SNI: no pattern matched servername: %s", servername);
     return SSL_TLSEXT_ERR_OK;
 }
 /* TLSEXT callback return codes:
@@ -275,18 +292,17 @@ NOEXPORT int servername_cb(SSL *ssl, int
  *  - SSL_TLSEXT_ERR_ALERT_FATAL
  *  - SSL_TLSEXT_ERR_NOACK */
 
-NOEXPORT int matches_wildcard(char *servername, char *pattern) {
-    ssize_t diff;
-
+NOEXPORT int matches_wildcard(const char *servername, const char *pattern) {
     if(!servername || !pattern)
         return 0;
     if(*pattern=='*') { /* wildcard comparison */
-        diff=(ssize_t)strlen(servername)-(ssize_t)strlen(++pattern);
+        ssize_t diff=(ssize_t)strlen(servername)-((ssize_t)strlen(pattern)-1);
         if(diff<0) /* pattern longer than servername */
             return 0;
-        servername+=diff;
+        return !strcasecmp(servername+diff, pattern+1);
+    } else { /* string comparison */
+        return !strcasecmp(servername, pattern);
     }
-    return !strcasecmp(servername, pattern);
 }
 
 #endif /* OPENSSL_NO_TLSEXT */
@@ -337,9 +353,9 @@ NOEXPORT int dh_init(SERVICE_OPTIONS *se
         DH_free(dh);
         return 0; /* OK */
     }
-    stunnel_read_lock(&stunnel_locks[LOCK_DH]);
+    CRYPTO_THREAD_read_lock(stunnel_locks[LOCK_DH]);
     SSL_CTX_set_tmp_dh(section->ctx, dh_params);
-    stunnel_read_unlock(&stunnel_locks[LOCK_DH]);
+    CRYPTO_THREAD_unlock(stunnel_locks[LOCK_DH]);
     dh_needed=1; /* generate temporary DH parameters in cron */
     section->option.dh_needed=1; /* update this context */
     s_log(LOG_INFO, "Using dynamic DH parameters");
@@ -608,7 +624,7 @@ void psk_sort(PSK_TABLE *table, PSK_KEYS
         ++table->num;
     s_log(LOG_INFO, "PSK identities: %lu retrieved",
         (long unsigned)table->num);
-    table->val=str_alloc(table->num*sizeof(PSK_KEYS *));
+    table->val=str_alloc_detached(table->num*sizeof(PSK_KEYS *));
     for(curr=head, i=0; i<table->num; ++i) {
         table->val[i]=curr;
         curr=curr->next;
@@ -901,11 +917,116 @@ NOEXPORT int sess_new_cb(SSL *ssl, SSL_S
 
     s_log(LOG_DEBUG, "New session callback");
     c=SSL_get_ex_data(ssl, index_ssl_cli);
+
+    new_chain(c); /* new session -> we may have a new peer certificate chain */
+
+    if(c->opt->option.client)
+        session_cache_save(c, sess);
+    else /* SSL_SESS_CACHE_NO_INTERNAL_STORE prevented automatic caching */
+        SSL_CTX_add_session(SSL_get_SSL_CTX(ssl), sess);
     if(c->opt->option.sessiond)
         cache_new(ssl, sess);
+
+    print_session_id(sess);
+
     return 0; /* the OpenSSL's manual is really bad -> use the source here */
 }
 
+#if OPENSSL_VERSION_NUMBER<0x0090800fL
+NOEXPORT const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
+        unsigned int *len) {
+    if(len)
+        *len=s->session_id_length;
+    return (const unsigned char *)s->session_id;
+}
+#endif
+
+void print_session_id(SSL_SESSION *sess) {
+    const unsigned char *session_id;
+    unsigned int session_id_length;
+    char session_id_txt[2*SSL_MAX_SSL_SESSION_ID_LENGTH+1];
+
+    session_id=SSL_SESSION_get_id(sess, &session_id_length);
+    bin2hexstring(session_id, session_id_length,
+        session_id_txt, sizeof session_id_txt);
+    s_log(LOG_INFO, "Session id: %s", session_id_txt);
+}
+
+NOEXPORT void new_chain(CLI *c) {
+    BIO *bio;
+    int i, len;
+    X509 *peer_cert;
+    STACK_OF(X509) *sk;
+    char *chain;
+
+    if(c->opt->chain) /* already cached */
+        return; /* this race condition is safe to ignore */
+    bio=BIO_new(BIO_s_mem());
+    if(!bio)
+        return;
+    sk=SSL_get_peer_cert_chain(c->ssl);
+    for(i=0; sk && i<sk_X509_num(sk); i++) {
+        peer_cert=sk_X509_value(sk, i);
+        PEM_write_bio_X509(bio, peer_cert);
+    }
+    if(!sk || !c->opt->option.client) {
+        peer_cert=SSL_get_peer_certificate(c->ssl);
+        if(peer_cert) {
+            PEM_write_bio_X509(bio, peer_cert);
+            X509_free(peer_cert);
+        }
+    }
+    len=BIO_pending(bio);
+    if(len<=0) {
+        s_log(LOG_INFO, "No peer certificate received");
+        BIO_free(bio);
+        return;
+    }
+    /* prevent automatic deallocation of the cached value */
+    chain=str_alloc_detached((size_t)len+1);
+    len=BIO_read(bio, chain, len);
+    if(len<0) {
+        s_log(LOG_ERR, "BIO_read failed");
+        BIO_free(bio);
+        str_free(chain);
+        return;
+    }
+    chain[len]='\0';
+    BIO_free(bio);
+    c->opt->chain=chain; /* this race condition is safe to ignore */
+    ui_new_chain(c->opt->section_number);
+    s_log(LOG_DEBUG, "Peer certificate was cached (%d bytes)", len);
+}
+
+/* cache client sessions */
+NOEXPORT void session_cache_save(CLI *c, SSL_SESSION *sess) {
+    SSL_SESSION *old;
+
+#if OPENSSL_VERSION_NUMBER>=0x10100000L
+    SSL_SESSION_up_ref(sess);
+#else
+    sess=SSL_get1_session(c->ssl);
+#endif
+
+    CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_SESSION]);
+    if(c->opt->option.delayed_lookup) {
+        old=c->opt->session;
+        c->opt->session=sess;
+    } else { /* per-destination client cache */
+        if(c->opt->connect_session) {
+            old=c->opt->connect_session[c->idx];
+            c->opt->connect_session[c->idx]=sess;
+        } else {
+            s_log(LOG_ERR, "INTERNAL ERROR: Uninitialized client session cache");
+            old=NULL;
+        }
+    }
+    CRYPTO_THREAD_unlock(stunnel_locks[LOCK_SESSION]);
+
+    if(old)
+        SSL_SESSION_free(old);
+}
+
 NOEXPORT SSL_SESSION *sess_get_cb(SSL *ssl,
 #if OPENSSL_VERSION_NUMBER>=0x10100000L
         const
@@ -948,12 +1069,7 @@ NOEXPORT void cache_new(SSL *ssl, SSL_SE
     val_tmp=val=str_alloc((size_t)val_len);
     i2d_SSL_SESSION(sess, &val_tmp);
 
-#if OPENSSL_VERSION_NUMBER>=0x0090800fL
     session_id=SSL_SESSION_get_id(sess, &session_id_length);
-#else
-    session_id=(const unsigned char *)sess->session_id;
-    session_id_length=sess->session_id_length;
-#endif
     cache_transfer(SSL_get_SSL_CTX(ssl), CACHE_CMD_NEW,
         SSL_SESSION_get_timeout(sess),
         session_id, session_id_length, val, (size_t)val_len, NULL, NULL);
@@ -972,9 +1088,9 @@ NOEXPORT SSL_SESSION *cache_get(SSL *ssl
         return NULL;
     val_tmp=val;
     sess=d2i_SSL_SESSION(NULL,
-#if OPENSSL_VERSION_NUMBER>=0x0090800fL
+#if OPENSSL_VERSION_NUMBER>=0x0090707fL
         (const unsigned char **)
-#endif /* OpenSSL version >= 0.8.0 */
+#endif /* OpenSSL version >= 0.9.7g */
         &val_tmp, (long)val_len);
     str_free(val);
     return sess;
@@ -984,12 +1100,7 @@ NOEXPORT void cache_remove(SSL_CTX *ctx,
     const unsigned char *session_id;
     unsigned int session_id_length;
 
-#if OPENSSL_VERSION_NUMBER>=0x0090800fL
     session_id=SSL_SESSION_get_id(sess, &session_id_length);
-#else
-    session_id=(const unsigned char *)sess->session_id;
-    session_id_length=sess->session_id_length;
-#endif
     cache_transfer(ctx, CACHE_CMD_REMOVE, 0,
         session_id, session_id_length, NULL, 0, NULL, NULL);
 }
@@ -1008,9 +1119,7 @@ NOEXPORT void cache_transfer(SSL_CTX *ct
         const u_char *val, const size_t val_len,
         unsigned char **ret, size_t *ret_len) {
     char session_id_txt[2*SSL_MAX_SSL_SESSION_ID_LENGTH+1];
-    const char hex[16]="0123456789ABCDEF";
     const char *type_description[]={"new", "get", "remove"};
-    unsigned i;
     SOCKET s;
     ssize_t len;
     struct timeval t;
@@ -1021,11 +1130,7 @@ NOEXPORT void cache_transfer(SSL_CTX *ct
         *ret=NULL;
 
     /* log the request information */
-    for(i=0; i<key_len && i<SSL_MAX_SSL_SESSION_ID_LENGTH; ++i) {
-        session_id_txt[2*i]=hex[key[i]>>4];
-        session_id_txt[2*i+1]=hex[key[i]&0x0f];
-    }
-    session_id_txt[2*i]='\0';
+    bin2hexstring(key, key_len, session_id_txt, sizeof session_id_txt);
     s_log(LOG_INFO,
         "cache_transfer: request=%s, timeout=%ld, id=%s, length=%lu",
         type_description[type], timeout, session_id_txt, (long unsigned)val_len);
@@ -1131,7 +1236,11 @@ NOEXPORT void info_callback(const SSL *s
 
     c=SSL_get_ex_data((SSL *)ssl, index_ssl_cli);
     if(c) {
+#if OPENSSL_VERSION_NUMBER>=0x10100000L
+        OSSL_HANDSHAKE_STATE state=SSL_get_state(ssl);
+#else
         int state=SSL_get_state((SSL *)ssl);
+#endif
 
 #if 0
         s_log(LOG_DEBUG, "state = %x", state);
@@ -1143,13 +1252,13 @@ NOEXPORT void info_callback(const SSL *s
 #else
         if(state==SSL3_ST_CR_CERT_REQ_A)
 #endif
-            print_client_CA_list(SSL_get_client_CA_list(ssl));
+            print_client_CA_list(SSL_get_client_CA_list((SSL *)ssl));
 #ifndef SSL3_ST_CR_SRVR_DONE_A
         if(state==TLS_ST_CR_SRVR_DONE)
 #else
         if(state==SSL3_ST_CR_SRVR_DONE_A)
 #endif
-            if(!SSL_get_client_CA_list(ssl))
+            if(!SSL_get_client_CA_list((SSL *)ssl))
                 s_log(LOG_INFO, "Client certificate not requested");
 
         /* prevent renegotiation DoS attack */
diff -pruN 3:5.44-1/src/dhparam.c 3:5.49-1/src/dhparam.c
--- 3:5.44-1/src/dhparam.c	2017-11-14 14:01:47.000000000 +0000
+++ 3:5.49-1/src/dhparam.c	2018-08-09 05:43:52.000000000 +0000
@@ -8,32 +8,32 @@
 DH *get_dh2048()
 {
     static unsigned char dhp_2048[] = {
-	0xEF, 0xED, 0x5C, 0xA2, 0x8E, 0x37, 0xD8, 0xF4, 0xD1, 0xE9, 
-	0x85, 0x06, 0x79, 0x0E, 0xC0, 0xBC, 0xD2, 0xF3, 0xBC, 0x26, 
-	0xAE, 0x63, 0xB9, 0x06, 0xDF, 0x16, 0xDB, 0xE5, 0x76, 0x76, 
-	0xD5, 0xBC, 0x4F, 0xC1, 0x55, 0x28, 0xC9, 0x7A, 0xC8, 0xD6, 
-	0x1E, 0xB0, 0x5D, 0x85, 0x12, 0x39, 0x62, 0x06, 0x9D, 0x99, 
-	0x4D, 0xCF, 0x79, 0x27, 0x94, 0xB6, 0xE1, 0xC2, 0x92, 0x06, 
-	0xA3, 0xCF, 0x10, 0x25, 0xC4, 0x3D, 0x01, 0xD2, 0x34, 0x0C, 
-	0x1F, 0xB2, 0xA3, 0x0D, 0xA8, 0xDC, 0xB6, 0x5F, 0xDB, 0x8C, 
-	0xF6, 0x73, 0xC2, 0x07, 0x70, 0x4D, 0x01, 0x85, 0xE8, 0x49, 
-	0xBC, 0xC1, 0x80, 0x6C, 0x77, 0x71, 0xFF, 0x5D, 0x25, 0x2F, 
-	0x64, 0x5F, 0x0D, 0x33, 0xB3, 0x43, 0x24, 0xC0, 0xFC, 0xB3, 
-	0x94, 0xEA, 0xF2, 0xB7, 0x24, 0x08, 0x12, 0x74, 0x9D, 0xEA, 
-	0x20, 0x31, 0xD7, 0x0C, 0x0A, 0x84, 0x37, 0xCF, 0x34, 0x56, 
-	0x85, 0xFB, 0xF4, 0x7C, 0xF4, 0x4E, 0x67, 0x0E, 0x63, 0xB2, 
-	0x49, 0xAF, 0xA6, 0x43, 0xD3, 0x6E, 0x60, 0xA9, 0x96, 0xD6, 
-	0xE8, 0x63, 0x7E, 0x23, 0x39, 0x91, 0xE1, 0xF6, 0xC3, 0x8B, 
-	0x60, 0x92, 0x73, 0xB9, 0x5A, 0x69, 0xDF, 0x8A, 0xD4, 0x0E, 
-	0x1C, 0x95, 0x82, 0x59, 0xE4, 0x3B, 0xA8, 0xAC, 0x46, 0x47, 
-	0xE2, 0xFE, 0x98, 0xD7, 0xC2, 0xD4, 0xC6, 0x0A, 0xC5, 0x23, 
-	0x98, 0xCA, 0x0C, 0x5A, 0x82, 0xE1, 0x17, 0xC8, 0xA4, 0x5C, 
-	0x43, 0x2A, 0xE5, 0x5B, 0x20, 0x7C, 0x36, 0x90, 0x71, 0xB6, 
-	0x02, 0x55, 0xF5, 0x26, 0x13, 0xCF, 0xB3, 0x4C, 0xB7, 0x89, 
-	0x57, 0xC8, 0x27, 0x28, 0x72, 0x04, 0xF1, 0x78, 0x4B, 0xFF, 
-	0xB3, 0x78, 0x60, 0x79, 0xEF, 0xDD, 0xDE, 0x34, 0x88, 0xE2, 
-	0x00, 0x13, 0xED, 0x4B, 0x9F, 0xE7, 0x71, 0xBA, 0x68, 0xF6, 
-	0xD2, 0x9E, 0xF3, 0x3B, 0x2D, 0x2B
+	0xAB, 0xF7, 0x30, 0x6D, 0xD2, 0x87, 0x0A, 0x6D, 0x5F, 0x2D, 
+	0x95, 0xED, 0xC5, 0x32, 0x8C, 0x0D, 0x59, 0x14, 0x18, 0x14, 
+	0xFD, 0x49, 0xCD, 0x1A, 0x83, 0x2D, 0xBA, 0xF3, 0xD3, 0xBE, 
+	0x7B, 0x7B, 0x22, 0xE8, 0xD1, 0x73, 0x8D, 0x39, 0x74, 0x5E, 
+	0x74, 0x94, 0xD3, 0x4D, 0xA6, 0x69, 0x70, 0xB4, 0x6E, 0xAA, 
+	0xD7, 0x58, 0x8B, 0xEF, 0x79, 0xCC, 0x8B, 0xB0, 0x35, 0xCB, 
+	0x49, 0xDB, 0x31, 0xE4, 0x8E, 0x12, 0x65, 0x0C, 0x42, 0x28, 
+	0x29, 0x41, 0xAB, 0x2E, 0xE7, 0x36, 0x24, 0x32, 0x2F, 0xFA, 
+	0x44, 0x6A, 0x2A, 0x93, 0x73, 0x66, 0xE9, 0x65, 0x98, 0x9C, 
+	0xE7, 0xB6, 0x52, 0xD9, 0xEA, 0x96, 0xF9, 0x66, 0x46, 0x5A, 
+	0x88, 0x5A, 0x3F, 0x8C, 0xEE, 0xBB, 0x71, 0xCC, 0x6E, 0xCC, 
+	0x6A, 0x21, 0xDF, 0xDA, 0x5E, 0xB1, 0x5D, 0x1E, 0x3B, 0x40, 
+	0x68, 0xD8, 0xEF, 0x38, 0xFC, 0x42, 0x19, 0x46, 0x8E, 0x13, 
+	0x9B, 0x3F, 0x2D, 0x49, 0x13, 0xC6, 0xA7, 0x2D, 0x97, 0x4A, 
+	0x05, 0x58, 0xCF, 0xC7, 0xEB, 0xC6, 0x29, 0x50, 0x99, 0xF4, 
+	0x6D, 0x61, 0x0D, 0x4D, 0x43, 0xC6, 0xEA, 0x86, 0x4B, 0xB4, 
+	0x16, 0x10, 0x13, 0xAD, 0xBC, 0x48, 0x3B, 0x8F, 0x10, 0x25, 
+	0xFA, 0x53, 0xA5, 0x3C, 0xDE, 0x85, 0xDB, 0x9B, 0x79, 0xDC, 
+	0x32, 0xA6, 0xFD, 0x19, 0x2E, 0x7C, 0xAE, 0x32, 0x9D, 0x72, 
+	0xAD, 0x03, 0x14, 0x9C, 0x04, 0x61, 0x83, 0x20, 0x9C, 0x07, 
+	0x5A, 0x0E, 0x91, 0xC7, 0xED, 0xDB, 0x60, 0xE2, 0xC9, 0x0B, 
+	0x21, 0xD9, 0xDF, 0xA7, 0x14, 0x4A, 0x5E, 0x6B, 0xD6, 0xE6, 
+	0xEB, 0x5A, 0x14, 0xE6, 0xD4, 0x13, 0x8E, 0x9D, 0x26, 0x88, 
+	0x1F, 0x3B, 0x65, 0x01, 0x0F, 0x66, 0xC6, 0x45, 0xE2, 0xBD, 
+	0x51, 0x41, 0x43, 0x92, 0xE2, 0x38, 0x5C, 0x56, 0x6B, 0x79, 
+	0x92, 0xD9, 0xA0, 0x09, 0x0D, 0x3B
     };
     static unsigned char dhg_2048[] = {
 	0x02
@@ -43,8 +43,8 @@ DH *get_dh2048()
 
     if (dh == NULL)
         return NULL;
-    dhp_bn = BN_bin2bn(dhp_2048, sizeof (dhp_2048), NULL);
-    dhg_bn = BN_bin2bn(dhg_2048, sizeof (dhg_2048), NULL);
+    dhp_bn = BN_bin2bn(dhp_2048, sizeof(dhp_2048), NULL);
+    dhg_bn = BN_bin2bn(dhg_2048, sizeof(dhg_2048), NULL);
     if (dhp_bn == NULL || dhg_bn == NULL
             || !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) {
         DH_free(dh);
diff -pruN 3:5.44-1/src/env.c 3:5.49-1/src/env.c
--- 3:5.44-1/src/env.c	2017-01-02 14:27:26.000000000 +0000
+++ 3:5.49-1/src/env.c	2018-04-06 14:25:10.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
diff -pruN 3:5.44-1/src/evc.mak 3:5.49-1/src/evc.mak
--- 3:5.44-1/src/evc.mak	2015-05-23 16:55:47.000000000 +0000
+++ 3:5.49-1/src/evc.mak	2018-04-06 14:25:10.000000000 +0000
@@ -1,4 +1,4 @@
-# wce.mak for stunnel.exe by Michal Trojnara 2006-2012
+# wce.mak for stunnel.exe by Michal Trojnara 1998-2018
 # with help of Pierre Delaage <delaage.pierre@free.fr>
 # pdelaage 20140610 : added UNICODE optional FLAG, always ACTIVE on WCE because of poor ANSI support
 # pdelaage 20140610 : added _WIN32_WCE flag for RC compilation, to preprocess out "HELP" unsupported menu flag on WCE
diff -pruN 3:5.44-1/src/fd.c 3:5.49-1/src/fd.c
--- 3:5.44-1/src/fd.c	2017-01-02 14:27:26.000000000 +0000
+++ 3:5.49-1/src/fd.c	2018-07-02 21:30:10.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -89,8 +89,8 @@ void get_limits(void) { /* set max_fds a
         max_fds=16;
 
     if(max_fds) {
-        max_clients=(long)(max_fds>=256 ? max_fds*125/256 : (max_fds-6)/2);
-        s_log(LOG_DEBUG, "Clients allowed=%ld", max_clients);
+        max_clients=(int)(max_fds>=256 ? max_fds*125/256 : (max_fds-6)/2);
+        s_log(LOG_DEBUG, "Clients allowed=%d", max_clients);
     } else {
         max_clients=0;
         s_log(LOG_DEBUG, "No limit detected for the number of clients");
@@ -197,8 +197,8 @@ NOEXPORT SOCKET setup_fd(SOCKET fd, int
     }
 #ifndef USE_FORK
     if(max_fds && fd>=max_fds) {
-        s_log(LOG_ERR, "%s: FD=%d out of range (max %d)",
-            msg, (int)fd, (int)max_fds);
+        s_log(LOG_ERR, "%s: FD=%ld out of range (max %d)",
+            msg, (long)fd, (int)max_fds);
         closesocket(fd);
         return INVALID_SOCKET;
     }
@@ -218,8 +218,8 @@ NOEXPORT SOCKET setup_fd(SOCKET fd, int
 #endif /* USE_NEW_LINUX_API */
 
 #ifdef DEBUG_FD_ALLOC
-    s_log(LOG_DEBUG, "%s: FD=%d allocated (%sblocking mode)",
-        msg, fd, nonblock?"non-":"");
+    s_log(LOG_DEBUG, "%s: FD=%ld allocated (%sblocking mode)",
+        msg, (long)fd, nonblock?"non-":"");
 #endif /* DEBUG_FD_ALLOC */
 
     return fd;
diff -pruN 3:5.44-1/src/file.c 3:5.49-1/src/file.c
--- 3:5.44-1/src/file.c	2017-01-02 14:27:26.000000000 +0000
+++ 3:5.49-1/src/file.c	2018-04-06 14:25:10.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
diff -pruN 3:5.44-1/src/libwrap.c 3:5.49-1/src/libwrap.c
--- 3:5.44-1/src/libwrap.c	2017-08-17 09:18:53.000000000 +0000
+++ 3:5.49-1/src/libwrap.c	2018-07-02 21:30:10.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -47,7 +47,7 @@
 #define USE_LIBWRAP_POOL
 #endif /* USE_PTHREAD && !__CYGWIN__ */
 
-NOEXPORT int check(char *, int);
+NOEXPORT uint8_t check(char *, int);
 
 int allow_severity=LOG_NOTICE, deny_severity=LOG_WARNING;
 
@@ -68,7 +68,8 @@ static int *ipc_socket, *busy;
 int libwrap_init() {
 #ifdef USE_LIBWRAP_POOL
     unsigned i, j;
-    int rfd, result;
+    int rfd;
+    uint8_t result;
     char servname[SERVNAME_LEN];
     static int initialized=0;
     SERVICE_OPTIONS *opt;
@@ -104,7 +105,7 @@ int libwrap_init() {
                 if(read_fd(ipc_socket[2*i+1], servname, SERVNAME_LEN, &rfd)<=0)
                     _exit(0);
                 result=check(servname, rfd);
-                write(ipc_socket[2*i+1], (uint8_t *)&result, sizeof result);
+                write(ipc_socket[2*i+1], &result, sizeof result);
                 if(rfd>=0)
                     close(rfd);
             }
@@ -120,9 +121,10 @@ int libwrap_init() {
 #pragma GCC diagnostic pop
 #endif /* __GNUC__ */
 
-void libwrap_auth(CLI *c, char *accepted_address) {
-    int result=0; /* deny by default */
+void libwrap_auth(CLI *c) {
+    uint8_t result=0; /* deny by default */
 #ifdef USE_LIBWRAP_POOL
+    jmp_buf exception_buffer, *exception_backup;
     static volatile unsigned num_busy=0, roundrobin=0;
     unsigned my_process;
     int retval;
@@ -146,14 +148,12 @@ void libwrap_auth(CLI *c, char *accepted
         if(retval) {
             errno=retval;
             ioerror("pthread_mutex_lock");
-            longjmp(c->err, 1);
         }
         while(num_busy==num_processes) { /* all child processes are busy */
             retval=pthread_cond_wait(&cond, &mutex);
             if(retval) {
                 errno=retval;
                 ioerror("pthread_cond_wait");
-                longjmp(c->err, 1);
             }
         }
         while(busy[roundrobin]) /* find a free child process */
@@ -165,21 +165,23 @@ void libwrap_auth(CLI *c, char *accepted
         if(retval) {
             errno=retval;
             ioerror("pthread_mutex_unlock");
-            longjmp(c->err, 1);
         }
 
         s_log(LOG_DEBUG, "Acquired libwrap process #%d", my_process);
-        write_fd(ipc_socket[2*my_process], c->opt->servname,
-            strlen(c->opt->servname)+1, c->local_rfd.fd);
-        s_read(c, ipc_socket[2*my_process],
-            (uint8_t *)&result, sizeof result);
+        exception_backup=c->exception_pointer;
+        c->exception_pointer=&exception_buffer;
+        if(!setjmp(exception_buffer)) {
+            write_fd(ipc_socket[2*my_process], c->opt->servname,
+                strlen(c->opt->servname)+1, c->local_rfd.fd);
+            s_read(c, ipc_socket[2*my_process], &result, sizeof result);
+        }
+        c->exception_pointer=exception_backup;
         s_log(LOG_DEBUG, "Releasing libwrap process #%d", my_process);
 
         retval=pthread_mutex_lock(&mutex);
         if(retval) {
             errno=retval;
             ioerror("pthread_mutex_lock");
-            longjmp(c->err, 1);
         }
         busy[my_process]=0; /* mark the child process as free */
         --num_busy; /* the child process has been released */
@@ -187,39 +189,37 @@ void libwrap_auth(CLI *c, char *accepted
         if(retval) {
             errno=retval;
             ioerror("pthread_cond_signal");
-            longjmp(c->err, 1);
         }
         retval=pthread_mutex_unlock(&mutex);
         if(retval) {
             errno=retval;
             ioerror("pthread_mutex_unlock");
-            longjmp(c->err, 1);
         }
 
         s_log(LOG_DEBUG, "Released libwrap process #%d", my_process);
     } else
 #endif /* USE_LIBWRAP_POOL */
     { /* use original, synchronous libwrap calls */
-        stunnel_write_lock(&stunnel_locks[LOCK_LIBWRAP]);
+        CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_LIBWRAP]);
         result=check(c->opt->servname, c->local_rfd.fd);
-        stunnel_write_unlock(&stunnel_locks[LOCK_LIBWRAP]);
+        CRYPTO_THREAD_unlock(stunnel_locks[LOCK_LIBWRAP]);
     }
     if(!result) {
         s_log(LOG_WARNING, "Service [%s] REFUSED by libwrap from %s",
-            c->opt->servname, accepted_address);
+            c->opt->servname, c->accepted_address);
         s_log(LOG_DEBUG, "See hosts_access(5) manual for details");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     s_log(LOG_DEBUG, "Service [%s] permitted by libwrap from %s",
-        c->opt->servname, accepted_address);
+        c->opt->servname, c->accepted_address);
 }
 
-NOEXPORT int check(char *name, int fd) {
+NOEXPORT uint8_t check(char *name, int fd) {
     struct request_info request;
 
     request_init(&request, RQ_DAEMON, name, RQ_FILE, fd, 0);
     fromhost(&request);
-    return hosts_access(&request);
+    return hosts_access(&request)!=0;
 }
 
 #ifdef USE_LIBWRAP_POOL
diff -pruN 3:5.44-1/src/log.c 3:5.49-1/src/log.c
--- 3:5.44-1/src/log.c	2017-08-23 05:05:15.000000000 +0000
+++ 3:5.49-1/src/log.c	2018-08-20 12:40:35.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -55,19 +55,25 @@ static LOG_MODE log_mode=LOG_MODE_BUFFER
 
 static int syslog_opened=0;
 
-void syslog_open(void) {
-    syslog_close();
-    if(global_options.option.log_syslog)
+NOEXPORT void syslog_open(void) {
+    if(global_options.option.log_syslog) {
+        static char *servname=NULL;
+        char *servname_old;
+
+        /* openlog(3) requires a persistent copy of the "ident" parameter */
+        servname_old=servname;
+        servname=str_dup(service_options.servname);
 #ifdef __ultrix__
-        openlog(service_options.servname, 0);
+        openlog(servname, 0);
 #else
-        openlog(service_options.servname,
-            LOG_CONS|LOG_NDELAY, global_options.log_facility);
+        openlog(servname, LOG_CONS|LOG_NDELAY, global_options.log_facility);
 #endif /* __ultrix__ */
+        str_free(servname_old);
+    }
     syslog_opened=1;
 }
 
-void syslog_close(void) {
+NOEXPORT void syslog_close(void) {
     if(syslog_opened) {
         if(global_options.option.log_syslog)
             closelog();
@@ -77,7 +83,7 @@ void syslog_close(void) {
 
 #endif /* !defined(USE_WIN32) && !defined(__vms) */
 
-int log_open(void) {
+NOEXPORT int outfile_open(void) {
     if(global_options.output_file) { /* 'output' option specified */
         outfile=file_open(global_options.output_file,
             global_options.log_file_mode);
@@ -100,19 +106,36 @@ int log_open(void) {
             return 1;
         }
     }
-    log_flush(LOG_MODE_CONFIGURED);
     return 0;
 }
 
-void log_close(void) {
-    /* prevent changing the mode while logging */
-    stunnel_write_lock(&stunnel_locks[LOCK_LOG_MODE]);
-    log_mode=LOG_MODE_BUFFER;
+NOEXPORT void outfile_close(void) {
     if(outfile) {
         file_close(outfile);
         outfile=NULL;
     }
-    stunnel_write_unlock(&stunnel_locks[LOCK_LOG_MODE]);
+}
+
+int log_open(int sink) {
+#if !defined(USE_WIN32) && !defined(__vms)
+    if(sink&SINK_SYSLOG)
+        syslog_open();
+#endif
+    if(sink&SINK_OUTFILE && outfile_open())
+        return 1;
+    return 0;
+}
+
+void log_close(int sink) {
+    /* prevent changing the mode while logging */
+    CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_LOG_MODE]);
+#if !defined(USE_WIN32) && !defined(__vms)
+    if(sink&SINK_SYSLOG)
+        syslog_close();
+#endif
+    if(sink&SINK_OUTFILE)
+        outfile_close();
+    CRYPTO_THREAD_unlock(stunnel_locks[LOCK_LOG_MODE]);
 }
 
 void s_log(int level, const char *format, ...) {
@@ -162,12 +185,12 @@ void s_log(int level, const char *format
         safestring(text);
 
         /* either log or queue for logging */
-        stunnel_read_lock(&stunnel_locks[LOCK_LOG_MODE]);
+        CRYPTO_THREAD_read_lock(stunnel_locks[LOCK_LOG_MODE]);
         if(log_mode==LOG_MODE_BUFFER)
             log_queue(tls_data->opt, level, stamp, id, text);
         else
             log_raw(tls_data->opt, level, stamp, id, text);
-        stunnel_read_unlock(&stunnel_locks[LOCK_LOG_MODE]);
+        CRYPTO_THREAD_unlock(stunnel_locks[LOCK_LOG_MODE]);
     }
 
     set_last_error(libc_error);
@@ -191,32 +214,39 @@ NOEXPORT void log_queue(SERVICE_OPTIONS
     str_detach(tmp->text);
 
     /* append the new element to the list */
-    stunnel_write_lock(&stunnel_locks[LOCK_LOG_BUFFER]);
+    CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_LOG_BUFFER]);
     if(tail)
         tail->next=tmp;
     else
         head=tmp;
     tail=tmp;
-    stunnel_write_unlock(&stunnel_locks[LOCK_LOG_BUFFER]);
+    if(stunnel_locks[LOCK_LOG_BUFFER])
+    CRYPTO_THREAD_unlock(stunnel_locks[LOCK_LOG_BUFFER]);
 }
 
 void log_flush(LOG_MODE new_mode) {
-    stunnel_write_lock(&stunnel_locks[LOCK_LOG_MODE]);
+    CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_LOG_MODE]);
+
     /* prevent changing LOG_MODE_CONFIGURED to LOG_MODE_ERROR
      * once stderr file descriptor is closed */
-    if(log_mode!=LOG_MODE_CONFIGURED)
+    if(log_mode!=LOG_MODE_CONFIGURED || new_mode!=LOG_MODE_ERROR)
         log_mode=new_mode;
-    /* log_raw() will use the new value of log_mode */
-    stunnel_write_lock(&stunnel_locks[LOCK_LOG_BUFFER]);
-    while(head) {
-        struct LIST *tmp=head;
-        head=head->next;
-        log_raw(tmp->opt, tmp->level, tmp->stamp, tmp->id, tmp->text);
-        str_free(tmp);
-    }
-    head=tail=NULL;
-    stunnel_write_unlock(&stunnel_locks[LOCK_LOG_BUFFER]);
-    stunnel_write_unlock(&stunnel_locks[LOCK_LOG_MODE]);
+
+    /* emit the buffered logs (unless we just started buffering) */
+    if(new_mode!=LOG_MODE_BUFFER) {
+        /* log_raw() will use the new value of log_mode */
+        CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_LOG_BUFFER]);
+        while(head) {
+            struct LIST *tmp=head;
+            head=head->next;
+            log_raw(tmp->opt, tmp->level, tmp->stamp, tmp->id, tmp->text);
+            str_free(tmp);
+        }
+        head=tail=NULL;
+        CRYPTO_THREAD_unlock(stunnel_locks[LOCK_LOG_BUFFER]);
+    }
+
+    CRYPTO_THREAD_unlock(stunnel_locks[LOCK_LOG_MODE]);
 }
 
 NOEXPORT void log_raw(SERVICE_OPTIONS *opt,
@@ -272,7 +302,9 @@ NOEXPORT void log_raw(SERVICE_OPTIONS *o
 }
 
 #ifdef __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 #pragma GCC diagnostic push
+#endif /* __GNUC__>=4.6 */
 #pragma GCC diagnostic ignored "-Wformat"
 #pragma GCC diagnostic ignored "-Wformat-extra-args"
 #endif /* __GNUC__ */
@@ -314,14 +346,18 @@ char *log_id(CLI *c) {
     return str_dup("error");
 }
 #ifdef __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 #pragma GCC diagnostic pop
+#endif /* __GNUC__>=4.6 */
 #endif /* __GNUC__ */
 
 /* critical problem handling */
 /* str.c functions are not safe to use here */
 #ifdef __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || defined(__clang__)
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wunused-result"
+#endif /* __GNUC__>=4.6 */
 #endif /* __GNUC__ */
 void fatal_debug(char *txt, const char *file, int line) {
     char msg[80];
@@ -372,7 +408,9 @@ void fatal_debug(char *txt, const char *
     abort();
 }
 #ifdef __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 #pragma GCC diagnostic pop
+#endif /* __GNUC__>=4.6 */
 #endif /* __GNUC__ */
 
 void ioerror(const char *txt) { /* input/output error */
@@ -507,4 +545,17 @@ NOEXPORT void safestring(char *c) {
             *c='.';
 }
 
+/* provide hex string corresponding to the input string
+ * will be NULL terminated */
+void bin2hexstring(const unsigned char *in_data, size_t in_size, char *out_data, size_t out_size) {
+    const char hex[16]="0123456789ABCDEF";
+    size_t i;
+
+    for(i=0; i<in_size && 2*i+2<out_size; ++i) {
+        out_data[2*i]=hex[in_data[i]>>4];
+        out_data[2*i+1]=hex[in_data[i]&0x0f];
+    }
+    out_data[2*i]='\0';
+}
+
 /* end of log.c */
diff -pruN 3:5.44-1/src/Makefile.am 3:5.49-1/src/Makefile.am
--- 3:5.44-1/src/Makefile.am	2017-08-23 05:03:13.000000000 +0000
+++ 3:5.49-1/src/Makefile.am	2018-06-08 17:30:06.000000000 +0000
@@ -1,5 +1,5 @@
 ## Process this file with automake to produce Makefile.in
-# by Michal Trojnara 2015-2017
+# by Michal Trojnara 1998-2018
 
 ###############################################################################
 # File lists                                                                  #
@@ -38,7 +38,7 @@ EXTRA_DIST = stunnel3.in
 CLEANFILES = stunnel3
 
 # Red Hat "by design" bug #82369
-stunnel_CPPFLAGS = -I/usr/kerberos/include
+stunnel_CPPFLAGS = -I$(SYSROOT)/usr/kerberos/include
 
 # Additional preprocesor definitions
 stunnel_CPPFLAGS += -I$(SSLDIR)/include
diff -pruN 3:5.44-1/src/Makefile.in 3:5.49-1/src/Makefile.in
--- 3:5.44-1/src/Makefile.in	2017-11-14 14:07:50.000000000 +0000
+++ 3:5.49-1/src/Makefile.in	2018-08-31 14:51:16.000000000 +0000
@@ -14,7 +14,7 @@
 
 @SET_MAKE@
 
-# by Michal Trojnara 2015-2017
+# by Michal Trojnara 1998-2018
 
 ###############################################################################
 # File lists                                                                  #
@@ -381,8 +381,9 @@ CLEANFILES = stunnel3
 # Red Hat "by design" bug #82369
 
 # Additional preprocesor definitions
-stunnel_CPPFLAGS = -I/usr/kerberos/include -I$(SSLDIR)/include \
-	-DLIBDIR='"$(pkglibdir)"' -DCONFDIR='"$(sysconfdir)/stunnel"'
+stunnel_CPPFLAGS = -I$(SYSROOT)/usr/kerberos/include \
+	-I$(SSLDIR)/include -DLIBDIR='"$(pkglibdir)"' \
+	-DCONFDIR='"$(sysconfdir)/stunnel"'
 
 # TLS library
 stunnel_LDFLAGS = -L$(SSLDIR)/lib64 -L$(SSLDIR)/lib -lssl -lcrypto
diff -pruN 3:5.44-1/src/mingw.mak 3:5.49-1/src/mingw.mak
--- 3:5.44-1/src/mingw.mak	2017-01-02 14:27:26.000000000 +0000
+++ 3:5.49-1/src/mingw.mak	2018-04-06 14:25:10.000000000 +0000
@@ -1,4 +1,4 @@
-# Simple Makefile.w32 for stunnel.exe by Michal Trojnara 1998-2017
+# Simple Makefile.w32 for stunnel.exe by Michal Trojnara 1998-2018
 #
 # Modified by Brian Hatch  (bri@stunnel.org)
 # 20101030 pdelaage:
diff -pruN 3:5.44-1/src/mingw.mk 3:5.49-1/src/mingw.mk
--- 3:5.44-1/src/mingw.mk	2017-01-02 14:27:26.000000000 +0000
+++ 3:5.49-1/src/mingw.mk	2018-04-06 14:25:10.000000000 +0000
@@ -1,5 +1,5 @@
 ## mingw/mingw64 Makefile
-# by Michal Trojnara 2015-2017
+# by Michal Trojnara 1998-2018
 
 # 32-bit Windows
 #win32_targetcpu=i686
diff -pruN 3:5.44-1/src/network.c 3:5.49-1/src/network.c
--- 3:5.44-1/src/network.c	2017-01-19 08:51:32.000000000 +0000
+++ 3:5.49-1/src/network.c	2018-06-08 17:30:06.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -222,8 +222,8 @@ NOEXPORT void scan_waiting_queue(void) {
         for(i=0; i<context->fds->nfds; i++) {
             context->fds->ufds[i].revents=ufds[nfds].revents;
 #ifdef DEBUG_UCONTEXT
-            s_log(LOG_DEBUG, "CONTEXT %ld, FD=%d,%s%s ->%s%s%s%s%s",
-                context->id, ufds[nfds].fd,
+            s_log(LOG_DEBUG, "CONTEXT %ld, FD=%ld,%s%s ->%s%s%s%s%s",
+                context->id, (long)ufds[nfds].fd,
                 (ufds[nfds].events & POLLIN) ? " IN" : "",
                 (ufds[nfds].events & POLLOUT) ? " OUT" : "",
                 (ufds[nfds].revents & POLLIN) ? " IN" : "",
@@ -483,14 +483,15 @@ void s_poll_dump(s_poll_set *fds, int le
 
 /**************************************** fd management */
 
-int set_socket_options(SOCKET s, int type) {
+int socket_options_set(SERVICE_OPTIONS *service, SOCKET s, int type) {
     SOCK_OPT *ptr;
-    extern SOCK_OPT *sock_opts;
     static char *type_str[3]={"accept", "local", "remote"};
     socklen_t opt_size;
     int retval=0; /* no error found */
 
-    for(ptr=sock_opts; ptr->opt_str; ptr++) {
+    s_log(LOG_DEBUG, "Setting %s socket options (FD=%ld)",
+        type_str[type], (long)s);
+    for(ptr=service->sock_opts; ptr->opt_str; ptr++) {
         if(!ptr->opt_val[type])
             continue; /* default */
         switch(ptr->opt_type) {
@@ -605,21 +606,21 @@ void s_write(CLI *c, SOCKET fd, const vo
         switch(s_poll_wait(c->fds, c->opt->timeout_busy, 0)) {
         case -1:
             sockerror("s_write: s_poll_wait");
-            longjmp(c->err, 1); /* error */
+            throw_exception(c, 1); /* error */
         case 0:
             s_log(LOG_INFO, "s_write: s_poll_wait:"
                 " TIMEOUTbusy exceeded: sending reset");
-            longjmp(c->err, 1); /* timeout */
+            throw_exception(c, 1); /* timeout */
         case 1:
             break; /* OK */
         default:
             s_log(LOG_ERR, "s_write: s_poll_wait: unknown result");
-            longjmp(c->err, 1); /* error */
+            throw_exception(c, 1); /* error */
         }
         num=writesocket(fd, (void *)ptr, len);
         if(num==-1) { /* error */
             sockerror("writesocket (s_write)");
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
         }
         ptr+=(size_t)num;
         len-=(size_t)num;
@@ -636,25 +637,25 @@ void s_read(CLI *c, SOCKET fd, void *ptr
         switch(s_poll_wait(c->fds, c->opt->timeout_busy, 0)) {
         case -1:
             sockerror("s_read: s_poll_wait");
-            longjmp(c->err, 1); /* error */
+            throw_exception(c, 1); /* error */
         case 0:
             s_log(LOG_INFO, "s_read: s_poll_wait:"
                 " TIMEOUTbusy exceeded: sending reset");
-            longjmp(c->err, 1); /* timeout */
+            throw_exception(c, 1); /* timeout */
         case 1:
             break; /* OK */
         default:
             s_log(LOG_ERR, "s_read: s_poll_wait: unknown result");
-            longjmp(c->err, 1); /* error */
+            throw_exception(c, 1); /* error */
         }
         num=readsocket(fd, ptr, len);
         switch(num) {
         case -1: /* error */
             sockerror("readsocket (s_read)");
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
         case 0: /* EOF */
             s_log(LOG_ERR, "Unexpected socket close (s_read)");
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
         }
         ptr=(uint8_t *)ptr+num;
         len-=(size_t)num;
@@ -682,7 +683,7 @@ char *fd_getline(CLI *c, SOCKET fd) {
         if(ptr>65536) { /* >64KB --> DoS protection */
             s_log(LOG_ERR, "fd_getline: Line too long");
             str_free(line);
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
         }
         if(allocated<ptr+1) {
             allocated*=2;
@@ -711,7 +712,7 @@ void fd_printf(CLI *c, SOCKET fd, const
     va_end(ap);
     if(!line) {
         s_log(LOG_ERR, "fd_printf: str_vprintf failed");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     fd_putline(c, fd, line);
     str_free(line);
@@ -728,21 +729,21 @@ void s_ssl_write(CLI *c, const void *buf
         switch(s_poll_wait(c->fds, c->opt->timeout_busy, 0)) {
         case -1:
             sockerror("s_write: s_poll_wait");
-            longjmp(c->err, 1); /* error */
+            throw_exception(c, 1); /* error */
         case 0:
             s_log(LOG_INFO, "s_write: s_poll_wait:"
                 " TIMEOUTbusy exceeded: sending reset");
-            longjmp(c->err, 1); /* timeout */
+            throw_exception(c, 1); /* timeout */
         case 1:
             break; /* OK */
         default:
             s_log(LOG_ERR, "s_write: s_poll_wait: unknown result");
-            longjmp(c->err, 1); /* error */
+            throw_exception(c, 1); /* error */
         }
         num=SSL_write(c->ssl, (void *)ptr, len);
         if(num==-1) { /* error */
             sockerror("SSL_write (s_ssl_write)");
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
         }
         ptr+=num;
         len-=num;
@@ -760,26 +761,26 @@ void s_ssl_read(CLI *c, void *ptr, int l
             switch(s_poll_wait(c->fds, c->opt->timeout_busy, 0)) {
             case -1:
                 sockerror("s_read: s_poll_wait");
-                longjmp(c->err, 1); /* error */
+                throw_exception(c, 1); /* error */
             case 0:
                 s_log(LOG_INFO, "s_read: s_poll_wait:"
                     " TIMEOUTbusy exceeded: sending reset");
-                longjmp(c->err, 1); /* timeout */
+                throw_exception(c, 1); /* timeout */
             case 1:
                 break; /* OK */
             default:
                 s_log(LOG_ERR, "s_read: s_poll_wait: unknown result");
-                longjmp(c->err, 1); /* error */
+                throw_exception(c, 1); /* error */
             }
         }
         num=SSL_read(c->ssl, ptr, len);
         switch(num) {
         case -1: /* error */
             sockerror("SSL_read (s_ssl_read)");
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
         case 0: /* EOF */
             s_log(LOG_ERR, "Unexpected socket close (s_ssl_read)");
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
         }
         ptr=(uint8_t *)ptr+num;
         len-=num;
@@ -795,7 +796,7 @@ char *ssl_getstring(CLI *c) { /* get nul
         if(ptr>65536) { /* >64KB --> DoS protection */
             s_log(LOG_ERR, "ssl_getstring: Line too long");
             str_free(line);
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
         }
         if(allocated<ptr+1) {
             allocated*=2;
@@ -818,7 +819,7 @@ char *ssl_getline(CLI *c) { /* get newli
         if(ptr>65536) { /* >64KB --> DoS protection */
             s_log(LOG_ERR, "ssl_getline: Line too long");
             str_free(line);
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
         }
         if(allocated<ptr+1) {
             allocated*=2;
@@ -848,7 +849,7 @@ void ssl_putline(CLI *c, const char *lin
     if(len>INT_MAX) { /* paranoia */
         s_log(LOG_ERR, "ssl_putline: Line too long");
         str_free(tmpline);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     s_ssl_write(c, tmpline, (int)len);
     str_free(tmpline);
diff -pruN 3:5.44-1/src/options.c 3:5.49-1/src/options.c
--- 3:5.44-1/src/options.c	2017-11-15 07:06:12.000000000 +0000
+++ 3:5.49-1/src/options.c	2018-08-19 07:10:47.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -48,7 +48,8 @@ typedef enum {
     CMD_BEGIN,      /* initialize defaults */
     CMD_EXEC,       /* process command */
     CMD_END,        /* end of section */
-    CMD_FREE,       /* TODO: deallocate memory */
+    CMD_DUP,        /* duplicate new_service_options */
+    CMD_FREE,       /* deallocate memory */
     CMD_DEFAULT,    /* print default value */
     CMD_HELP        /* print help */
 } CMD;
@@ -69,12 +70,17 @@ NOEXPORT char *parse_service_option(CMD,
 
 #ifndef OPENSSL_NO_TLSEXT
 NOEXPORT char *sni_init(SERVICE_OPTIONS *);
+NOEXPORT void sni_free(SERVICE_OPTIONS *);
 #endif /* !defined(OPENSSL_NO_TLSEXT) */
 
+NOEXPORT char *tls_methods_set(SERVICE_OPTIONS *, const char *);
+NOEXPORT char *tls_methods_check(SERVICE_OPTIONS *);
+
 NOEXPORT char *parse_debug_level(char *, SERVICE_OPTIONS *);
 
 #ifndef OPENSSL_NO_PSK
 NOEXPORT PSK_KEYS *psk_read(char *);
+NOEXPORT PSK_KEYS *psk_dup(PSK_KEYS *);
 NOEXPORT void psk_free(PSK_KEYS *);
 #endif /* !defined(OPENSSL_NO_PSK) */
 
@@ -146,9 +152,20 @@ static const SSL_OPTION ssl_opts[] = {
     {"NO_TLSv1", SSL_OP_NO_TLSv1},
 #ifdef SSL_OP_NO_TLSv1_1
     {"NO_TLSv1.1", SSL_OP_NO_TLSv1_1},
+#else /* ignore if unsupported by OpenSSL */
+    {"NO_TLSv1.1", 0},
 #endif
 #ifdef SSL_OP_NO_TLSv1_2
     {"NO_TLSv1.2", SSL_OP_NO_TLSv1_2},
+#else /* ignore if unsupported by OpenSSL */
+    {"NO_TLSv1.2", 0},
+#endif
+#ifdef SSL_OP_NO_TLSv1_3
+    {"NO_TLSv1.3", SSL_OP_NO_TLSv1_3},
+    {"NO_TLSv1_3", SSL_OP_NO_TLSv1_3}, /* keep compatibility with our typo */
+#else /* ignore if unsupported by OpenSSL */
+    {"NO_TLSv1.3", 0},
+    {"NO_TLSv1_3", 0}, /* keep compatibility with our typo */
 #endif
     {"PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1},
     {"PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2},
@@ -175,8 +192,17 @@ static const SSL_OPTION ssl_opts[] = {
 #ifdef SSL_OP_NO_ENCRYPT_THEN_MAC
     {"NO_ENCRYPT_THEN_MAC", SSL_OP_NO_ENCRYPT_THEN_MAC},
 #endif
-#ifdef SSL_OP_NO_TLSv1_3
-    {"NO_TLSv1_3", SSL_OP_NO_TLSv1_3},
+#ifdef SSL_OP_ALLOW_NO_DHE_KEX
+    {"ALLOW_NO_DHE_KEX", SSL_OP_ALLOW_NO_DHE_KEX},
+#endif
+#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT
+    {"ENABLE_MIDDLEBOX_COMPAT", SSL_OP_ENABLE_MIDDLEBOX_COMPAT},
+#endif
+#ifdef SSL_OP_NO_RENEGOTIATION
+    {"NO_RENEGOTIATION", SSL_OP_NO_RENEGOTIATION},
+#endif
+#ifdef SSL_OP_PRIORITIZE_CHACHA
+    {"PRIORITIZE_CHACHA", SSL_OP_PRIORITIZE_CHACHA},
 #endif
     {NULL, 0}
 };
@@ -184,10 +210,13 @@ static const SSL_OPTION ssl_opts[] = {
 NOEXPORT long unsigned parse_ssl_option(char *);
 NOEXPORT void print_ssl_options(void);
 
-NOEXPORT void init_socket_options(void);
-NOEXPORT int print_socket_options(void);
-NOEXPORT char *print_option(int, OPT_UNION *);
-NOEXPORT int parse_socket_option(char *);
+NOEXPORT SOCK_OPT *socket_options_init(void);
+NOEXPORT void socket_option_set_int(SOCK_OPT *, char *, int, int);
+NOEXPORT SOCK_OPT *socket_options_dup(SOCK_OPT *);
+NOEXPORT void socket_options_free(SOCK_OPT *);
+NOEXPORT int socket_options_print(void);
+NOEXPORT char *socket_option_text(VAL_TYPE, OPT_UNION *);
+NOEXPORT int socket_option_parse(SOCK_OPT *, char *);
 
 #ifndef OPENSSL_NO_OCSP
 NOEXPORT unsigned long parse_ocsp_flag(char *);
@@ -207,8 +236,12 @@ NOEXPORT ENGINE *engine_get_by_num(const
 NOEXPORT void print_syntax(void);
 
 NOEXPORT void name_list_append(NAME_LIST **, char *);
+NOEXPORT void name_list_dup(NAME_LIST **, NAME_LIST *);
+NOEXPORT void name_list_free(NAME_LIST *);
 #ifndef USE_WIN32
-NOEXPORT char **argalloc(char *);
+NOEXPORT char **arg_alloc(char *);
+NOEXPORT char **arg_dup(char **);
+NOEXPORT void arg_free(char **arg);
 #endif
 
 char configuration_file[PATH_MAX];
@@ -224,7 +257,7 @@ static char *option_not_found=
     "Specified option name is not valid here";
 
 static char *stunnel_cipher_list=
-    "HIGH:!DH:!aNULL:!SSLv2";
+    "HIGH:!aNULL:!SSLv2:!DH:!kDHEPSK";
 
 /**************************************** parse commandline parameters */
 
@@ -264,7 +297,7 @@ int options_cmdline(char *arg1, char *ar
         log_flush(LOG_MODE_INFO);
         return 2;
     } else if(!strcasecmp(arg1, "-sockets")) {
-        print_socket_options();
+        socket_options_print();
         log_flush(LOG_MODE_INFO);
         return 2;
     } else if(!strcasecmp(arg1, "-options")) {
@@ -394,9 +427,8 @@ NOEXPORT int options_file(char *path, CO
             continue;
 
         if(config_opt[0]=='[' && config_opt[strlen(config_opt)-1]==']') { /* new section */
-            SERVICE_OPTIONS *new_section;
-
-            if(!new_service_options.next) { /* initialize global options */
+            /* initialize global options */
+            if(!new_service_options.next) {
                 errstr=parse_global_option(CMD_END, NULL, NULL);
                 if(errstr) {
                     s_log(LOG_ERR, "%s:%d: \"%s\": %s",
@@ -405,15 +437,22 @@ NOEXPORT int options_file(char *path, CO
                     return 1;
                 }
             }
+
+            /* append a new SERVICE_OPTIONS structure to the list */
+            {
+                SERVICE_OPTIONS *new_section;
+                new_section=str_alloc_detached(sizeof(SERVICE_OPTIONS));
+                new_section->next=NULL;
+                (*section)->next=new_section;
+                *section=new_section;
+            }
+
+            /* initialize the newly allocated section */
             ++config_opt;
             config_opt[strlen(config_opt)-1]='\0';
-            new_section=str_alloc(sizeof(SERVICE_OPTIONS));
-            memcpy(new_section, &new_service_options, sizeof(SERVICE_OPTIONS));
-            new_section->servname=str_dup(config_opt);
-            new_section->session=NULL;
-            new_section->next=NULL;
-            (*section)->next=new_section;
-            *section=new_section;
+            (*section)->servname=str_dup_detached(config_opt);
+            (*section)->session=NULL;
+            parse_service_option(CMD_DUP, *section, NULL, NULL);
             continue;
         }
 
@@ -476,8 +515,7 @@ NOEXPORT int options_include(char *direc
                 "%s/%s",
 #endif
                 directory, namelist[i]->d_name);
-            stat(name, &sb);
-            if(S_ISREG(sb.st_mode))
+            if(!stat(name, &sb) && S_ISREG(sb.st_mode))
                 err=options_file(name, CONF_FILE, section);
             else
                 s_log(LOG_DEBUG, "\"%s\" is not a file", name);
@@ -542,9 +580,10 @@ int alphasort(const struct dirent **a, c
 
 void options_defaults() {
     /* initialize globals *before* opening the config file */
-    memset(&new_global_options, 0, sizeof(GLOBAL_OPTIONS)); /* reset global options */
-    memset(&new_service_options, 0, sizeof(SERVICE_OPTIONS)); /* reset local options */
+    memset(&new_global_options, 0, sizeof(GLOBAL_OPTIONS));
+    memset(&new_service_options, 0, sizeof(SERVICE_OPTIONS));
     new_service_options.next=NULL;
+
     parse_global_option(CMD_BEGIN, NULL, NULL);
     parse_service_option(CMD_BEGIN, &new_service_options, NULL, NULL);
 }
@@ -553,18 +592,47 @@ void options_apply() { /* apply default/
     unsigned num=0;
     SERVICE_OPTIONS *section;
 
-    for(section=new_service_options.next; section; section=section->next)
-        section->section_number=num++;
-    /* FIXME: this operation may be unsafe, as client() threads use it */
     memcpy(&global_options, &new_global_options, sizeof(GLOBAL_OPTIONS));
+
     /* service_options are used for inetd mode and to enumerate services */
+    for(section=new_service_options.next; section; section=section->next)
+        section->section_number=num++;
     memcpy(&service_options, &new_service_options, sizeof(SERVICE_OPTIONS));
     number_of_sections=num;
 }
 
+void options_free() {
+    /* FIXME: this operation may be unsafe, as client() threads use it */
+    parse_global_option(CMD_FREE, NULL, NULL);
+}
+
+void service_up_ref(SERVICE_OPTIONS *section) {
+#ifdef USE_OS_THREADS
+    int ref;
+
+    CRYPTO_atomic_add(&section->ref, 1, &ref, stunnel_locks[LOCK_REF]);
+#else
+    ++(section->ref);
+#endif
+}
+
+void service_free(SERVICE_OPTIONS *section) {
+    int ref;
+
+#ifdef USE_OS_THREADS
+    CRYPTO_atomic_add(&section->ref, -1, &ref, stunnel_locks[LOCK_REF]);
+#else
+    ref=--(section->ref);
+#endif
+    if(ref==0)
+        parse_service_option(CMD_FREE, section, NULL, NULL);
+}
+
 /**************************************** global options */
 
 NOEXPORT char *parse_global_option(CMD cmd, char *opt, char *arg) {
+    void *tmp;
+
     if(cmd==CMD_DEFAULT || cmd==CMD_HELP) {
         s_log(LOG_NOTICE, " ");
         s_log(LOG_NOTICE, "Global options:");
@@ -583,7 +651,12 @@ NOEXPORT char *parse_global_option(CMD c
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
+        tmp=global_options.chroot_dir;
+        global_options.chroot_dir=NULL;
+        str_free(tmp);
         break;
     case CMD_DEFAULT:
         break;
@@ -602,7 +675,11 @@ NOEXPORT char *parse_global_option(CMD c
     case CMD_EXEC:
         if(strcasecmp(opt, "compression"))
             break;
-        if(OpenSSL_version_num()>=0x00908051L && !strcasecmp(arg, "deflate"))
+        /* only allow compression with OpenSSL 0.9.8 or later
+         * with OpenSSL #1468 zlib memory leak fixed */
+        if(OpenSSL_version_num()<0x00908051L) /* 0.9.8e-beta1 */
+            return "Compression unsupported due to a memory leak";
+        if(!strcasecmp(arg, "deflate"))
             new_global_options.compression=COMP_DEFLATE;
         else if(!strcasecmp(arg, "zlib"))
             new_global_options.compression=COMP_ZLIB;
@@ -611,6 +688,8 @@ NOEXPORT char *parse_global_option(CMD c
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -638,7 +717,12 @@ NOEXPORT char *parse_global_option(CMD c
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
+        tmp=global_options.egd_sock;
+        global_options.egd_sock=NULL;
+        str_free(tmp);
         break;
     case CMD_DEFAULT:
 #ifdef EGD_SOCKET
@@ -667,7 +751,10 @@ NOEXPORT char *parse_global_option(CMD c
     case CMD_END:
         engine_init();
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
+        /* FIXME: investigate if we can free it */
         break;
     case CMD_DEFAULT:
         break;
@@ -692,6 +779,8 @@ NOEXPORT char *parse_global_option(CMD c
         }
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -712,6 +801,8 @@ NOEXPORT char *parse_global_option(CMD c
         return engine_default(arg);
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -748,6 +839,8 @@ NOEXPORT char *parse_global_option(CMD c
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -784,6 +877,8 @@ NOEXPORT char *parse_global_option(CMD c
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -810,7 +905,10 @@ NOEXPORT char *parse_global_option(CMD c
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
+        /* FIXME: investigate if we can free it */
         break;
     case CMD_DEFAULT:
         break;
@@ -832,7 +930,10 @@ NOEXPORT char *parse_global_option(CMD c
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
+        /* FIXME: investigate if we can free it */
         break;
     case CMD_DEFAULT:
         break;
@@ -854,7 +955,10 @@ NOEXPORT char *parse_global_option(CMD c
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
+        /* FIXME: investigate if we can free it */
         break;
     case CMD_DEFAULT:
         break;
@@ -882,6 +986,8 @@ NOEXPORT char *parse_global_option(CMD c
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -904,7 +1010,12 @@ NOEXPORT char *parse_global_option(CMD c
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
+        tmp=global_options.output_file;
+        global_options.output_file=NULL;
+        str_free(tmp);
         break;
     case CMD_DEFAULT:
         break;
@@ -929,7 +1040,12 @@ NOEXPORT char *parse_global_option(CMD c
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
+        tmp=global_options.pidfile;
+        global_options.pidfile=NULL;
+        str_free(tmp);
         break;
     case CMD_DEFAULT:
         break;
@@ -956,6 +1072,8 @@ NOEXPORT char *parse_global_option(CMD c
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -969,7 +1087,11 @@ NOEXPORT char *parse_global_option(CMD c
     /* RNDfile */
     switch(cmd) {
     case CMD_BEGIN:
+#ifdef RANDOM_FILE
+        new_global_options.rand_file=str_dup(RANDOM_FILE);
+#else
         new_global_options.rand_file=NULL;
+#endif
         break;
     case CMD_EXEC:
         if(strcasecmp(opt, "RNDfile"))
@@ -978,7 +1100,12 @@ NOEXPORT char *parse_global_option(CMD c
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
+        tmp=global_options.rand_file;
+        global_options.rand_file=NULL;
+        str_free(tmp);
         break;
     case CMD_DEFAULT:
 #ifdef RANDOM_FILE
@@ -1007,6 +1134,8 @@ NOEXPORT char *parse_global_option(CMD c
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -1018,52 +1147,6 @@ NOEXPORT char *parse_global_option(CMD c
         break;
     }
 
-#ifndef USE_WIN32
-    /* service */
-    switch(cmd) {
-    case CMD_BEGIN:
-        new_service_options.servname=str_dup("stunnel");
-        break;
-    case CMD_EXEC:
-        if(strcasecmp(opt, "service"))
-            break;
-        new_service_options.servname=str_dup(arg);
-        return NULL; /* OK */
-    case CMD_END:
-        break;
-    case CMD_FREE:
-        break;
-    case CMD_DEFAULT:
-        break;
-    case CMD_HELP:
-        s_log(LOG_NOTICE, "%-22s = service name", "service");
-        break;
-    }
-#endif
-
-    /* socket */
-    switch(cmd) {
-    case CMD_BEGIN:
-        init_socket_options();
-        break;
-    case CMD_EXEC:
-        if(strcasecmp(opt, "socket"))
-            break;
-        if(parse_socket_option(arg))
-            return "Illegal socket option";
-        return NULL; /* OK */
-    case CMD_END:
-        break;
-    case CMD_FREE:
-        break;
-    case CMD_DEFAULT:
-        break;
-    case CMD_HELP:
-        s_log(LOG_NOTICE, "%-22s = a|l|r:option=value[:value]", "socket");
-        s_log(LOG_NOTICE, "%25sset an option on accept/local/remote socket", "");
-        break;
-    }
-
     /* syslog */
 #ifndef USE_WIN32
     switch(cmd) {
@@ -1082,6 +1165,8 @@ NOEXPORT char *parse_global_option(CMD c
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -1111,6 +1196,8 @@ NOEXPORT char *parse_global_option(CMD c
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP: /* not used for global options */
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -1122,13 +1209,24 @@ NOEXPORT char *parse_global_option(CMD c
     }
 #endif
 
-    if(cmd==CMD_EXEC)
+    /* final checks */
+    switch(cmd) {
+    case CMD_BEGIN:
+        break;
+    case CMD_EXEC:
         return option_not_found;
-
-    if(cmd==CMD_END) {
+    case CMD_END:
         /* FIPS needs to be initialized as early as possible */
         if(ssl_configure(&new_global_options)) /* configure global TLS settings */
             return "Failed to initialize TLS";
+    case CMD_DUP:
+        break;
+    case CMD_FREE:
+        break;
+    case CMD_DEFAULT:
+        break;
+    case CMD_HELP:
+        break;
     }
     return NULL; /* OK */
 }
@@ -1146,12 +1244,18 @@ NOEXPORT char *parse_service_option(CMD
     if(cmd==CMD_DEFAULT || cmd==CMD_HELP) {
         s_log(LOG_NOTICE, " ");
         s_log(LOG_NOTICE, "Service-level options:");
+    } else if(cmd==CMD_FREE) {
+        if(section==&service_options)
+            s_log(LOG_DEBUG, "Deallocating section defaults");
+        else
+            s_log(LOG_DEBUG, "Deallocating section [%s]", section->servname);
     }
 
     /* accept */
     switch(cmd) {
     case CMD_BEGIN:
         addrlist_clear(&section->local_addr, 1);
+        section->local_fd=NULL;
         break;
     case CMD_EXEC:
         if(strcasecmp(opt, "accept"))
@@ -1161,12 +1265,25 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         if(section->local_addr.names) {
+            unsigned i;
             if(!addrlist_resolve(&section->local_addr))
                 return "Cannot resolve accept target";
+            section->local_fd=str_alloc_detached(section->local_addr.num*sizeof(SOCKET));
+            for(i=0; i<section->local_addr.num; ++i)
+                section->local_fd[i]=INVALID_SOCKET;
             ++endpoints;
         }
         break;
+    case CMD_DUP:
+        addrlist_clear(&section->local_addr, 1);
+        section->local_fd=NULL;
+        name_list_dup(&section->local_addr.names,
+            new_service_options.local_addr.names);
+        break;
     case CMD_FREE:
+        name_list_free(section->local_addr.names);
+        str_free(section->local_addr.addr);
+        str_free(section->local_fd);
         break;
     case CMD_DEFAULT:
         break;
@@ -1187,14 +1304,19 @@ NOEXPORT char *parse_service_option(CMD
     case CMD_EXEC:
         if(strcasecmp(opt, "CApath"))
             break;
+        str_free(section->ca_dir);
         if(arg[0]) /* not empty */
-            section->ca_dir=str_dup(arg);
+            section->ca_dir=str_dup_detached(arg);
         else
             section->ca_dir=NULL;
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->ca_dir=str_dup_detached(new_service_options.ca_dir);
+        break;
     case CMD_FREE:
+        str_free(section->ca_dir);
         break;
     case CMD_DEFAULT:
 #if 0
@@ -1219,14 +1341,19 @@ NOEXPORT char *parse_service_option(CMD
     case CMD_EXEC:
         if(strcasecmp(opt, "CAfile"))
             break;
+        str_free(section->ca_file);
         if(arg[0]) /* not empty */
-            section->ca_file=str_dup(arg);
+            section->ca_file=str_dup_detached(arg);
         else
             section->ca_file=NULL;
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->ca_file=str_dup_detached(new_service_options.ca_file);
+        break;
     case CMD_FREE:
+        str_free(section->ca_file);
         break;
     case CMD_DEFAULT:
 #if 0
@@ -1248,7 +1375,8 @@ NOEXPORT char *parse_service_option(CMD
     case CMD_EXEC:
         if(strcasecmp(opt, "cert"))
             break;
-        section->cert=str_dup(arg);
+        str_free(section->cert);
+        section->cert=str_dup_detached(arg);
         return NULL; /* OK */
     case CMD_END:
 #ifndef OPENSSL_NO_PSK
@@ -1262,7 +1390,11 @@ NOEXPORT char *parse_service_option(CMD
         if(!section->option.client && !section->cert)
             return "TLS server needs a certificate";
         break;
+    case CMD_DUP:
+        section->cert=str_dup_detached(new_service_options.cert);
+        break;
     case CMD_FREE:
+        str_free(section->cert);
         break;
     case CMD_DEFAULT:
         break; /* no default certificate */
@@ -1284,10 +1416,15 @@ NOEXPORT char *parse_service_option(CMD
         name_list_append(&section->check_email, arg);
         return NULL; /* OK */
     case CMD_END:
-	if(section->check_email && !section->option.verify_chain && !section->option.verify_peer)
+        if(section->check_email && !section->option.verify_chain && !section->option.verify_peer)
             return "Either \"verifyChain\" or \"verifyPeer\" has to be enabled";
         break;
+    case CMD_DUP:
+        name_list_dup(&section->check_email,
+            new_service_options.check_email);
+        break;
     case CMD_FREE:
+        name_list_free(section->check_email);
         break;
     case CMD_DEFAULT:
         break;
@@ -1308,10 +1445,15 @@ NOEXPORT char *parse_service_option(CMD
         name_list_append(&section->check_host, arg);
         return NULL; /* OK */
     case CMD_END:
-        if(section->check_host  && !section->option.verify_chain && !section->option.verify_peer)
+        if(section->check_host && !section->option.verify_chain && !section->option.verify_peer)
             return "Either \"verifyChain\" or \"verifyPeer\" has to be enabled";
         break;
+    case CMD_DUP:
+        name_list_dup(&section->check_host,
+            new_service_options.check_host);
+        break;
     case CMD_FREE:
+        name_list_free(section->check_host);
         break;
     case CMD_DEFAULT:
         break;
@@ -1332,8 +1474,15 @@ NOEXPORT char *parse_service_option(CMD
         name_list_append(&section->check_ip, arg);
         return NULL; /* OK */
     case CMD_END:
+        if(section->check_ip && !section->option.verify_chain && !section->option.verify_peer)
+            return "Either \"verifyChain\" or \"verifyPeer\" has to be enabled";
+        break;
+    case CMD_DUP:
+        name_list_dup(&section->check_ip,
+            new_service_options.check_ip);
         break;
     case CMD_FREE:
+        name_list_free(section->check_ip);
         break;
     case CMD_DEFAULT:
         break;
@@ -1353,7 +1502,8 @@ NOEXPORT char *parse_service_option(CMD
     case CMD_EXEC:
         if(strcasecmp(opt, "ciphers"))
             break;
-        section->cipher_list=str_dup(arg);
+        str_free(section->cipher_list);
+        section->cipher_list=str_dup_detached(arg);
         return NULL; /* OK */
     case CMD_END:
         if(!section->cipher_list) {
@@ -1361,13 +1511,17 @@ NOEXPORT char *parse_service_option(CMD
              * because section->cipher_list is no longer NULL */
 #ifdef USE_FIPS
             if(new_global_options.option.fips)
-                section->cipher_list="FIPS";
+                section->cipher_list=str_dup_detached("FIPS");
             else
 #endif /* USE_FIPS */
-                section->cipher_list=stunnel_cipher_list;
+                section->cipher_list=str_dup_detached(stunnel_cipher_list);
         }
         break;
+    case CMD_DUP:
+        section->cipher_list=str_dup_detached(new_service_options.cipher_list);
+        break;
     case CMD_FREE:
+        str_free(section->cipher_list);
         break;
     case CMD_DEFAULT:
 #ifdef USE_FIPS
@@ -1401,6 +1555,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->option.client=new_service_options.option.client;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -1425,7 +1582,11 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        name_list_dup(&section->config, new_service_options.config);
+        break;
     case CMD_FREE:
+        name_list_free(section->config);
         break;
     case CMD_DEFAULT:
         break;
@@ -1441,6 +1602,7 @@ NOEXPORT char *parse_service_option(CMD
     switch(cmd) {
     case CMD_BEGIN:
         addrlist_clear(&section->connect_addr, 0);
+        section->connect_session=NULL;
         break;
     case CMD_EXEC:
         if(strcasecmp(opt, "connect"))
@@ -1453,15 +1615,26 @@ NOEXPORT char *parse_service_option(CMD
                     !addrlist_resolve(&section->connect_addr)) {
                 s_log(LOG_INFO,
                     "Cannot resolve connect target - delaying DNS lookup");
+                section->connect_addr.num=0;
                 section->redirect_addr.num=0;
-                str_free(section->redirect_addr.names);
-                section->redirect_addr.names=NULL;
                 section->option.delayed_lookup=1;
             }
+            if(section->option.client)
+                section->connect_session=
+                    str_alloc_detached(section->connect_addr.num*sizeof(SSL_SESSION *));
             ++endpoints;
         }
         break;
+    case CMD_DUP:
+        addrlist_clear(&section->connect_addr, 0);
+        section->connect_session=NULL;
+        name_list_dup(&section->connect_addr.names,
+            new_service_options.connect_addr.names);
+        break;
     case CMD_FREE:
+        name_list_free(section->connect_addr.names);
+        str_free(section->connect_addr.addr);
+        str_free(section->connect_session);
         break;
     case CMD_DEFAULT:
         break;
@@ -1479,14 +1652,19 @@ NOEXPORT char *parse_service_option(CMD
     case CMD_EXEC:
         if(strcasecmp(opt, "CRLpath"))
             break;
+        str_free(section->crl_dir);
         if(arg[0]) /* not empty */
-            section->crl_dir=str_dup(arg);
+            section->crl_dir=str_dup_detached(arg);
         else
             section->crl_dir=NULL;
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->crl_dir=str_dup_detached(new_service_options.crl_dir);
+        break;
     case CMD_FREE:
+        str_free(section->crl_dir);
         break;
     case CMD_DEFAULT:
         break;
@@ -1503,14 +1681,19 @@ NOEXPORT char *parse_service_option(CMD
     case CMD_EXEC:
         if(strcasecmp(opt, "CRLfile"))
             break;
+        str_free(section->crl_file);
         if(arg[0]) /* not empty */
-            section->crl_file=str_dup(arg);
+            section->crl_file=str_dup_detached(arg);
         else
             section->crl_file=NULL;
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->crl_file=str_dup_detached(new_service_options.crl_file);
+        break;
     case CMD_FREE:
+        str_free(section->crl_file);
         break;
     case CMD_DEFAULT:
         break;
@@ -1536,6 +1719,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->curve=new_service_options.curve;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -1562,6 +1748,9 @@ NOEXPORT char *parse_service_option(CMD
         return parse_debug_level(arg, section);
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->log_level=new_service_options.log_level;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -1597,6 +1786,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->option.delayed_lookup=new_service_options.option.delayed_lookup;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -1623,6 +1815,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->engine=new_service_options.engine;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -1652,6 +1847,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->engine=new_service_options.engine;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -1672,14 +1870,15 @@ NOEXPORT char *parse_service_option(CMD
     case CMD_EXEC:
         if(strcasecmp(opt, "exec"))
             break;
-        section->exec_name=str_dup(arg);
+        str_free(section->exec_name);
+        section->exec_name=str_dup_detached(arg);
 #ifdef USE_WIN32
-        section->exec_args=str_dup(arg);
+        section->exec_args=str_dup_detached(arg);
 #else
         if(!section->exec_args) {
-            section->exec_args=str_alloc(2*sizeof(char *));
-            section->exec_args[0]=section->exec_name;
-            section->exec_args[1]=NULL; /* to show that it's null-terminated */
+            section->exec_args=str_alloc_detached(2*sizeof(char *));
+            section->exec_args[0]=str_dup_detached(section->exec_name);
+            section->exec_args[1]=NULL; /* null-terminate */
         }
 #endif
         return NULL; /* OK */
@@ -1687,7 +1886,11 @@ NOEXPORT char *parse_service_option(CMD
         if(section->exec_name)
             ++endpoints;
         break;
+    case CMD_DUP:
+        section->exec_name=str_dup_detached(new_service_options.exec_name);
+        break;
     case CMD_FREE:
+        str_free(section->exec_name);
         break;
     case CMD_DEFAULT:
         break;
@@ -1706,14 +1909,28 @@ NOEXPORT char *parse_service_option(CMD
         if(strcasecmp(opt, "execArgs"))
             break;
 #ifdef USE_WIN32
-        section->exec_args=str_dup(arg);
+        str_free(section->exec_args);
+        section->exec_args=str_dup_detached(arg);
 #else
-        section->exec_args=argalloc(arg);
+        arg_free(section->exec_args);
+        section->exec_args=arg_alloc(arg);
 #endif
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+#ifdef USE_WIN32
+        section->exec_args=str_dup_detached(new_service_options.exec_args);
+#else
+        section->exec_args=arg_dup(new_service_options.exec_args);
+#endif
+        break;
     case CMD_FREE:
+#ifdef USE_WIN32
+        str_free(section->exec_args);
+#else
+        arg_free(section->exec_args);
+#endif
         break;
     case CMD_DEFAULT:
         break;
@@ -1726,8 +1943,8 @@ NOEXPORT char *parse_service_option(CMD
     /* failover */
     switch(cmd) {
     case CMD_BEGIN:
-        section->failover=FAILOVER_RR;
-        section->seq=0;
+        section->failover=FAILOVER_PRIO;
+        section->rr=0;
         break;
     case CMD_EXEC:
         if(strcasecmp(opt, "failover"))
@@ -1743,6 +1960,10 @@ NOEXPORT char *parse_service_option(CMD
         if(section->option.delayed_lookup)
             section->failover=FAILOVER_PRIO;
         break;
+    case CMD_DUP:
+        section->failover=new_service_options.failover;
+        section->rr=new_service_options.rr;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -1761,11 +1982,16 @@ NOEXPORT char *parse_service_option(CMD
     case CMD_EXEC:
         if(strcasecmp(opt, "ident"))
             break;
-        section->username=str_dup(arg);
+        str_free(section->username);
+        section->username=str_dup_detached(arg);
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->username=str_dup_detached(new_service_options.username);
+        break;
     case CMD_FREE:
+        str_free(section->username);
         break;
     case CMD_DEFAULT:
         break;
@@ -1782,13 +2008,18 @@ NOEXPORT char *parse_service_option(CMD
     case CMD_EXEC:
         if(strcasecmp(opt, "key"))
             break;
-        section->key=str_dup(arg);
+        str_free(section->key);
+        section->key=str_dup_detached(arg);
         return NULL; /* OK */
     case CMD_END:
         if(section->cert && !section->key)
-            section->key=str_dup(section->cert);
+            section->key=str_dup_detached(section->cert);
+        break;
+    case CMD_DUP:
+        section->key=str_dup_detached(new_service_options.key);
         break;
     case CMD_FREE:
+        str_free(section->key);
         break;
     case CMD_DEFAULT:
         break;
@@ -1797,6 +2028,7 @@ NOEXPORT char *parse_service_option(CMD
         break;
     }
 
+    /* libwrap */
 #ifdef USE_LIBWRAP
     switch(cmd) {
     case CMD_BEGIN:
@@ -1814,6 +2046,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->option.libwrap=new_service_options.option.libwrap;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -1839,6 +2074,11 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->option.local=new_service_options.option.local;
+        memcpy(&section->source_addr, &new_service_options.source_addr,
+            sizeof(SOCKADDR_UNION));
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -1870,6 +2110,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->log_id=new_service_options.log_id;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -1891,16 +2134,21 @@ NOEXPORT char *parse_service_option(CMD
     case CMD_EXEC:
         if(strcasecmp(opt, "ocsp"))
             break;
-        section->ocsp_url=str_dup(arg);
+        str_free(section->ocsp_url);
+        section->ocsp_url=str_dup_detached(arg);
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->ocsp_url=str_dup_detached(new_service_options.ocsp_url);
+        break;
     case CMD_FREE:
+        str_free(section->ocsp_url);
         break;
     case CMD_DEFAULT:
         break;
     case CMD_HELP:
-        s_log(LOG_NOTICE, "%-22s = OCSP responder URL", "ocsp");
+        s_log(LOG_NOTICE, "%-22s = OCSP responder URL", "OCSP");
         break;
     }
 
@@ -1921,6 +2169,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->option.aia=new_service_options.option.aia;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -1949,6 +2200,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL;
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->ocsp_flags=new_service_options.ocsp_flags;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -1975,6 +2229,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->option.nonce=new_service_options.option.nonce;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -1991,7 +2248,7 @@ NOEXPORT char *parse_service_option(CMD
     /* options */
     switch(cmd) {
     case CMD_BEGIN:
-        section->ssl_options_set|=SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
+        section->ssl_options_set=0;
 #if OPENSSL_VERSION_NUMBER>=0x009080dfL
         section->ssl_options_clear=0;
 #endif /* OpenSSL 0.9.8m or later */
@@ -2017,6 +2274,12 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->ssl_options_set=new_service_options.ssl_options_set;
+#if OPENSSL_VERSION_NUMBER>=0x009080dfL
+        section->ssl_options_clear=new_service_options.ssl_options_clear;
+#endif /* OpenSSL 0.9.8m or later */
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2036,7 +2299,8 @@ NOEXPORT char *parse_service_option(CMD
     case CMD_EXEC:
         if(strcasecmp(opt, "protocol"))
             break;
-        section->protocol=str_dup(arg);
+        str_free(section->protocol);
+        section->protocol=str_dup_detached(arg);
         return NULL; /* OK */
     case CMD_END:
         /* PROTOCOL_CHECK also initializes:
@@ -2055,7 +2319,11 @@ NOEXPORT char *parse_service_option(CMD
             section->ssl_options_set|=SSL_OP_NO_TICKET;
 #endif
         break;
+    case CMD_DUP:
+        section->protocol=str_dup_detached(new_service_options.protocol);
+        break;
     case CMD_FREE:
+        str_free(section->protocol);
         break;
     case CMD_DEFAULT:
         break;
@@ -2070,16 +2338,22 @@ NOEXPORT char *parse_service_option(CMD
     /* protocolAuthentication */
     switch(cmd) {
     case CMD_BEGIN:
-        section->protocol_authentication="basic";
+        section->protocol_authentication=str_dup_detached("basic");
         break;
     case CMD_EXEC:
         if(strcasecmp(opt, "protocolAuthentication"))
             break;
-        section->protocol_authentication=str_dup(arg);
+        str_free(section->protocol_authentication);
+        section->protocol_authentication=str_dup_detached(arg);
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->protocol_authentication=
+            str_dup_detached(new_service_options.protocol_authentication);
+        break;
     case CMD_FREE:
+        str_free(section->protocol_authentication);
         break;
     case CMD_DEFAULT:
         break;
@@ -2097,11 +2371,17 @@ NOEXPORT char *parse_service_option(CMD
     case CMD_EXEC:
         if(strcasecmp(opt, "protocolDomain"))
             break;
-        section->protocol_domain=str_dup(arg);
+        str_free(section->protocol_domain);
+        section->protocol_domain=str_dup_detached(arg);
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->protocol_domain=
+            str_dup_detached(new_service_options.protocol_domain);
+        break;
     case CMD_FREE:
+        str_free(section->protocol_domain);
         break;
     case CMD_DEFAULT:
         break;
@@ -2119,11 +2399,17 @@ NOEXPORT char *parse_service_option(CMD
     case CMD_EXEC:
         if(strcasecmp(opt, "protocolHost"))
             break;
-        section->protocol_host=str_dup(arg);
+        str_free(section->protocol_host);
+        section->protocol_host=str_dup_detached(arg);
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->protocol_host=
+            str_dup_detached(new_service_options.protocol_host);
+        break;
     case CMD_FREE:
+        str_free(section->protocol_host);
         break;
     case CMD_DEFAULT:
         break;
@@ -2141,11 +2427,17 @@ NOEXPORT char *parse_service_option(CMD
     case CMD_EXEC:
         if(strcasecmp(opt, "protocolPassword"))
             break;
-        section->protocol_password=str_dup(arg);
+        str_free(section->protocol_password);
+        section->protocol_password=str_dup_detached(arg);
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->protocol_password=
+            str_dup_detached(new_service_options.protocol_password);
+        break;
     case CMD_FREE:
+        str_free(section->protocol_password);
         break;
     case CMD_DEFAULT:
         break;
@@ -2163,11 +2455,17 @@ NOEXPORT char *parse_service_option(CMD
     case CMD_EXEC:
         if(strcasecmp(opt, "protocolUsername"))
             break;
-        section->protocol_username=str_dup(arg);
+        str_free(section->protocol_username);
+        section->protocol_username=str_dup_detached(arg);
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->protocol_username=
+            str_dup_detached(new_service_options.protocol_username);
+        break;
     case CMD_FREE:
+        str_free(section->protocol_username);
         break;
     case CMD_DEFAULT:
         break;
@@ -2190,7 +2488,8 @@ NOEXPORT char *parse_service_option(CMD
     case CMD_EXEC:
         if(strcasecmp(opt, "PSKidentity"))
             break;
-        section->psk_identity=str_dup(arg);
+        str_free(section->psk_identity);
+        section->psk_identity=str_dup_detached(arg);
         return NULL; /* OK */
     case CMD_END:
         if(!section->psk_keys) /* PSK not configured */
@@ -2211,7 +2510,13 @@ NOEXPORT char *parse_service_option(CMD
                     "PSK identity is ignored in the server mode");
         }
         break;
+    case CMD_DUP:
+        section->psk_identity=
+            str_dup_detached(new_service_options.psk_identity);
+        break;
     case CMD_FREE:
+        str_free(section->psk_identity);
+        str_free(section->psk_sorted.val);
         break;
     case CMD_DEFAULT:
         break;
@@ -2235,6 +2540,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->psk_keys=psk_dup(new_service_options.psk_keys);
+        break;
     case CMD_FREE:
         psk_free(section->psk_keys);
         break;
@@ -2266,6 +2574,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->option.pty=new_service_options.option.pty;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2299,15 +2610,21 @@ NOEXPORT char *parse_service_option(CMD
                 s_log(LOG_INFO,
                     "Cannot resolve redirect target - delaying DNS lookup");
                 section->connect_addr.num=0;
-                str_free(section->connect_addr.names);
-                section->connect_addr.names=NULL;
+                section->redirect_addr.num=0;
                 section->option.delayed_lookup=1;
             }
             if(!section->option.verify_chain && !section->option.verify_peer)
                 return "Either \"verifyChain\" or \"verifyPeer\" has to be enabled for \"redirect\" to work";
         }
         break;
+    case CMD_DUP:
+        addrlist_clear(&section->redirect_addr, 0);
+        name_list_dup(&section->redirect_addr.names,
+            new_service_options.redirect_addr.names);
+        break;
     case CMD_FREE:
+        name_list_free(section->redirect_addr.names);
+        str_free(section->redirect_addr.addr);
         break;
     case CMD_DEFAULT:
         break;
@@ -2335,6 +2652,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->option.renegotiation=new_service_options.option.renegotiation;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2364,6 +2684,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->option.require_cert=new_service_options.option.require_cert;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2391,13 +2714,16 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->option.reset=new_service_options.option.reset;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
         break;
     case CMD_HELP:
         s_log(LOG_NOTICE, "%-22s = yes|no send TCP RST on error",
-            "retry");
+            "reset");
         break;
     }
 
@@ -2418,6 +2744,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->option.retry=new_service_options.option.retry;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2429,6 +2758,34 @@ NOEXPORT char *parse_service_option(CMD
     }
 
 #ifndef USE_WIN32
+    /* service */
+    switch(cmd) {
+    case CMD_BEGIN:
+        section->servname=str_dup_detached("stunnel");
+        break;
+    case CMD_EXEC:
+        if(strcasecmp(opt, "service"))
+            break;
+        str_free(section->servname);
+        section->servname=str_dup_detached(arg);
+        return NULL; /* OK */
+    case CMD_END:
+        break;
+    case CMD_DUP:
+        /* servname is *not* copied from the global section */
+        break;
+    case CMD_FREE:
+        /* deallocation is performed at the end CMD_FREE */
+        break;
+    case CMD_DEFAULT:
+        break;
+    case CMD_HELP:
+        s_log(LOG_NOTICE, "%-22s = service name", "service");
+        break;
+    }
+#endif
+
+#ifndef USE_WIN32
     /* setgid */
     switch(cmd) {
     case CMD_BEGIN:
@@ -2451,6 +2808,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->gid=new_service_options.gid;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2484,6 +2844,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->uid=new_service_options.uid;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2511,6 +2874,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->session_size=new_service_options.session_size;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2538,6 +2904,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->session_timeout=new_service_options.session_timeout;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2570,6 +2939,11 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->option.sessiond=new_service_options.option.sessiond;
+        memcpy(&section->sessiond_addr, &new_service_options.sessiond_addr,
+            sizeof(SOCKADDR_UNION));
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2586,12 +2960,12 @@ NOEXPORT char *parse_service_option(CMD
     case CMD_BEGIN:
         section->servername_list_head=NULL;
         section->servername_list_tail=NULL;
-        section->option.sni=0;
         break;
     case CMD_EXEC:
         if(strcasecmp(opt, "sni"))
             break;
-        section->sni=str_dup(arg);
+        str_free(section->sni);
+        section->sni=str_dup_detached(arg);
         return NULL; /* OK */
     case CMD_END:
         {
@@ -2599,10 +2973,16 @@ NOEXPORT char *parse_service_option(CMD
             if(tmp_str)
                 return tmp_str;
         }
-        if(section->option.sni)
+        if(!section->option.client && section->sni)
             ++endpoints;
         break;
+    case CMD_DUP:
+        section->sni=
+            str_dup_detached(new_service_options.sni);
+        break;
     case CMD_FREE:
+        str_free(section->sni);
+        sni_free(section);
         break;
     case CMD_DEFAULT:
         break;
@@ -2613,85 +2993,52 @@ NOEXPORT char *parse_service_option(CMD
     }
 #endif /* !defined(OPENSSL_NO_TLSEXT) */
 
+    /* socket */
+    switch(cmd) {
+    case CMD_BEGIN:
+        section->sock_opts=socket_options_init();
+        break;
+    case CMD_EXEC:
+        if(strcasecmp(opt, "socket"))
+            break;
+        if(socket_option_parse(section->sock_opts, arg))
+            return "Illegal socket option";
+        return NULL; /* OK */
+    case CMD_END:
+        break;
+    case CMD_DUP:
+        section->sock_opts=socket_options_dup(new_service_options.sock_opts);
+        break;
+    case CMD_FREE:
+        socket_options_free(section->sock_opts);
+        break;
+    case CMD_DEFAULT:
+        break;
+    case CMD_HELP:
+        s_log(LOG_NOTICE, "%-22s = a|l|r:option=value[:value]", "socket");
+        s_log(LOG_NOTICE, "%25sset an option on accept/local/remote socket", "");
+        break;
+    }
+
     /* sslVersion */
     switch(cmd) {
     case CMD_BEGIN:
-#if OPENSSL_VERSION_NUMBER>=0x10100000L
-        section->client_method=(SSL_METHOD *)TLS_client_method();
-        section->server_method=(SSL_METHOD *)TLS_server_method();
-#else
-        section->client_method=(SSL_METHOD *)SSLv23_client_method();
-        section->server_method=(SSL_METHOD *)SSLv23_server_method();
-#endif
+        tls_methods_set(section, NULL);
         break;
     case CMD_EXEC:
         if(strcasecmp(opt, "sslVersion"))
             break;
-        if(!strcasecmp(arg, "all")) {
-#if OPENSSL_VERSION_NUMBER>=0x10100000L
-            section->client_method=(SSL_METHOD *)TLS_client_method();
-            section->server_method=(SSL_METHOD *)TLS_server_method();
-#else
-            section->client_method=(SSL_METHOD *)SSLv23_client_method();
-            section->server_method=(SSL_METHOD *)SSLv23_server_method();
-#endif
-#if OPENSSL_API_COMPAT<0x10100000L
-        } else if(!strcasecmp(arg, "SSLv2")) {
-#ifndef OPENSSL_NO_SSL2
-            section->client_method=(SSL_METHOD *)SSLv2_client_method();
-            section->server_method=(SSL_METHOD *)SSLv2_server_method();
-#else /* defined(OPENSSL_NO_SSL2) */
-            return "SSLv2 not supported";
-#endif /* !defined(OPENSSL_NO_SSL2) */
-        } else if(!strcasecmp(arg, "SSLv3")) {
-#ifndef OPENSSL_NO_SSL3
-            section->client_method=(SSL_METHOD *)SSLv3_client_method();
-            section->server_method=(SSL_METHOD *)SSLv3_server_method();
-#else /* defined(OPENSSL_NO_SSL3) */
-            return "SSLv3 not supported";
-#endif /* !defined(OPENSSL_NO_SSL3) */
-        } else if(!strcasecmp(arg, "TLSv1")) {
-#ifndef OPENSSL_NO_TLS1
-            section->client_method=(SSL_METHOD *)TLSv1_client_method();
-            section->server_method=(SSL_METHOD *)TLSv1_server_method();
-#else /* defined(OPENSSL_NO_TLS1) */
-            return "TLSv1 not supported";
-#endif /* !defined(OPENSSL_NO_TLS1) */
-        } else if(!strcasecmp(arg, "TLSv1.1")) {
-#ifndef OPENSSL_NO_TLS1_1
-            section->client_method=(SSL_METHOD *)TLSv1_1_client_method();
-            section->server_method=(SSL_METHOD *)TLSv1_1_server_method();
-#else /* defined(OPENSSL_NO_TLS1_1) */
-            return "TLSv1.1 not supported";
-#endif /* !defined(OPENSSL_NO_TLS1_1) */
-        } else if(!strcasecmp(arg, "TLSv1.2")) {
-#ifndef OPENSSL_NO_TLS1_2
-            section->client_method=(SSL_METHOD *)TLSv1_2_client_method();
-            section->server_method=(SSL_METHOD *)TLSv1_2_server_method();
-#else /* defined(OPENSSL_NO_TLS1_2) */
-            return "TLSv1.2 not supported";
-#endif /* !defined(OPENSSL_NO_TLS1_2) */
-#endif /* OPENSSL_API_COMPAT<0x10100000L */
-        } else
-            return "Incorrect version of TLS protocol";
-        return NULL; /* OK */
+        return tls_methods_set(section, arg);
     case CMD_END:
-#ifdef USE_FIPS
-        if(new_global_options.option.fips) {
-#ifndef OPENSSL_NO_SSL2
-            if(section->option.client ?
-                    section->client_method==(SSL_METHOD *)SSLv2_client_method() :
-                    section->server_method==(SSL_METHOD *)SSLv2_server_method())
-                return "\"sslVersion = SSLv2\" not supported in FIPS mode";
-#endif /* !defined(OPENSSL_NO_SSL2) */
-#ifndef OPENSSL_NO_SSL3
-            if(section->option.client ?
-                    section->client_method==(SSL_METHOD *)SSLv3_client_method() :
-                    section->server_method==(SSL_METHOD *)SSLv3_server_method())
-                return "\"sslVersion = SSLv3\" not supported in FIPS mode";
-#endif /* !defined(OPENSSL_NO_SSL3) */
+        {
+            char *tmp_str=tls_methods_check(section);
+            if(tmp_str)
+                return tmp_str;
         }
-#endif /* USE_FIPS */
+        break;
+    case CMD_DUP:
+        section->client_method=new_service_options.client_method;
+        section->server_method=new_service_options.server_method;
         break;
     case CMD_FREE:
         break;
@@ -2727,6 +3074,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->stack_size=new_service_options.stack_size;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2755,6 +3105,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->timeout_busy=new_service_options.timeout_busy;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2782,6 +3135,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->timeout_close=new_service_options.timeout_close;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2810,6 +3166,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->timeout_connect=new_service_options.timeout_connect;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2837,6 +3196,9 @@ NOEXPORT char *parse_service_option(CMD
         }
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->timeout_idle=new_service_options.timeout_idle;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2876,6 +3238,10 @@ NOEXPORT char *parse_service_option(CMD
         if(section->option.transparent_dst)
             ++endpoints;
         break;
+    case CMD_DUP:
+        section->option.transparent_src=new_service_options.option.transparent_src;
+        section->option.transparent_dst=new_service_options.option.transparent_dst;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2912,6 +3278,9 @@ NOEXPORT char *parse_service_option(CMD
                 !section->ca_file && !section->ca_dir)
             return "Either \"CAfile\" or \"CApath\" has to be configured";
         break;
+    case CMD_DUP:
+        section->option.request_cert=new_service_options.option.request_cert;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2953,6 +3322,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->option.verify_chain=new_service_options.option.verify_chain;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2983,6 +3355,9 @@ NOEXPORT char *parse_service_option(CMD
         return NULL; /* OK */
     case CMD_END:
         break;
+    case CMD_DUP:
+        section->option.verify_peer=new_service_options.option.verify_peer;
+        break;
     case CMD_FREE:
         break;
     case CMD_DEFAULT:
@@ -2996,6 +3371,7 @@ NOEXPORT char *parse_service_option(CMD
     /* final checks */
     switch(cmd) {
     case CMD_BEGIN:
+        section->ref=1;
         break;
     case CMD_EXEC:
         return option_not_found;
@@ -3006,15 +3382,31 @@ NOEXPORT char *parse_service_option(CMD
         } else { /* inetd mode checks */
             if(section->option.accept)
                 return "'accept' option is only allowed in a [section]";
-            /* no need to check for section->option.sni in inetd mode,
+            /* no need to check for section->sni in inetd mode,
                as it requires valid sections to be set */
             if(endpoints!=1)
                 return "Inetd mode must define one endpoint";
         }
         if(context_init(section)) /* initialize TLS context */
             return "Failed to initialize TLS context";
+        break;
+    case CMD_DUP:
+        section->ref=1;
+        break;
     case CMD_FREE:
+        str_free(section->chain);
+        if(section->session)
+            SSL_SESSION_free(section->session);
+        if(section->ctx)
+            SSL_CTX_free(section->ctx);
+        str_free(section->servname);
+        if(section==&service_options)
+            memset(section, 0, sizeof(SERVICE_OPTIONS));
+        else
+            str_free(section);
+        break;
     case CMD_DEFAULT:
+        break;
     case CMD_HELP:
         break;
     }
@@ -3025,6 +3417,7 @@ NOEXPORT char *parse_service_option(CMD
 /**************************************** validate and initialize configuration */
 
 #ifndef OPENSSL_NO_TLSEXT
+
 NOEXPORT char *sni_init(SERVICE_OPTIONS *section) {
     char *tmp_str;
     SERVICE_OPTIONS *tmpsrv;
@@ -3043,19 +3436,21 @@ NOEXPORT char *sni_init(SERVICE_OPTIONS
         if(tmpsrv->option.client)
             return "SNI master service is a TLS client";
         if(tmpsrv->servername_list_tail) {
-            tmpsrv->servername_list_tail->next=str_alloc(sizeof(SERVERNAME_LIST));
+            tmpsrv->servername_list_tail->next=str_alloc_detached(sizeof(SERVERNAME_LIST));
             tmpsrv->servername_list_tail=tmpsrv->servername_list_tail->next;
         } else { /* first virtual service */
             tmpsrv->servername_list_head=
                 tmpsrv->servername_list_tail=
-                str_alloc(sizeof(SERVERNAME_LIST));
+                str_alloc_detached(sizeof(SERVERNAME_LIST));
             tmpsrv->ssl_options_set|=
                 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
         }
-        tmpsrv->servername_list_tail->servername=str_dup(tmp_str);
+        /* a slave section reference is needed to prevent a race condition
+           while switching to a section after configuration file reload */
+        service_up_ref(section);
+        tmpsrv->servername_list_tail->servername=str_dup_detached(tmp_str);
         tmpsrv->servername_list_tail->opt=section;
         tmpsrv->servername_list_tail->next=NULL;
-        section->option.sni=1;
         /* always negotiate a new session on renegotiation, as the TLS
          * context settings (including access control) may be different */
         section->ssl_options_set|=
@@ -3066,23 +3461,128 @@ NOEXPORT char *sni_init(SERVICE_OPTIONS
     if(section->option.client && !section->sni) {
         /* setup host_name for SNI, prefer SNI and protocolHost if specified */
         if(section->protocol_host) /* 'protocolHost' option */
-            section->sni=str_dup(section->protocol_host);
+            section->sni=str_dup_detached(section->protocol_host);
         else if(section->connect_addr.names) /* 'connect' option */
-            section->sni=str_dup(section->connect_addr.names->name); /* first hostname */
+            section->sni=str_dup_detached(section->connect_addr.names->name); /* first hostname */
         if(section->sni) { /* either 'protocolHost' or 'connect' specified */
             tmp_str=strrchr(section->sni, ':');
             if(tmp_str) { /* 'host:port' -> drop ':port' */
                 *tmp_str='\0';
             } else { /* 'port' -> default to 'localhost' */
                 str_free(section->sni);
-                section->sni=str_dup("localhost");
+                section->sni=str_dup_detached("localhost");
             }
         }
     }
     return NULL;
 }
+
+NOEXPORT void sni_free(SERVICE_OPTIONS *section) {
+    SERVERNAME_LIST *curr=section->servername_list_head;
+    while(curr) {
+        SERVERNAME_LIST *next=curr->next;
+        str_free(curr->servername);
+        service_free(curr->opt); /* free the slave section */
+        str_free(curr);
+        curr=next;
+    }
+    section->servername_list_head=NULL;
+    section->servername_list_tail=NULL;
+}
+
 #endif /* !defined(OPENSSL_NO_TLSEXT) */
 
+/**************************************** (deprecated) TLS methods */
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif /* __GNUC__ */
+
+NOEXPORT char *tls_methods_set(SERVICE_OPTIONS *section, const char *arg) {
+    if(!arg) { /* defaults */
+#if OPENSSL_VERSION_NUMBER>=0x10100000L
+        section->client_method=(SSL_METHOD *)TLS_client_method();
+        section->server_method=(SSL_METHOD *)TLS_server_method();
+#else
+        section->client_method=(SSL_METHOD *)SSLv23_client_method();
+        section->server_method=(SSL_METHOD *)SSLv23_server_method();
+#endif
+    } else if(!strcasecmp(arg, "all")) {
+#if OPENSSL_VERSION_NUMBER>=0x10100000L
+        section->client_method=(SSL_METHOD *)TLS_client_method();
+        section->server_method=(SSL_METHOD *)TLS_server_method();
+#else
+        section->client_method=(SSL_METHOD *)SSLv23_client_method();
+        section->server_method=(SSL_METHOD *)SSLv23_server_method();
+#endif
+#if OPENSSL_API_COMPAT<0x10100000L
+    } else if(!strcasecmp(arg, "SSLv2")) {
+#ifndef OPENSSL_NO_SSL2
+        section->client_method=(SSL_METHOD *)SSLv2_client_method();
+        section->server_method=(SSL_METHOD *)SSLv2_server_method();
+#else /* OPENSSL_NO_SSL2 */
+        return "SSLv2 not supported";
+#endif /* !OPENSSL_NO_SSL2 */
+    } else if(!strcasecmp(arg, "SSLv3")) {
+#ifndef OPENSSL_NO_SSL3
+        section->client_method=(SSL_METHOD *)SSLv3_client_method();
+        section->server_method=(SSL_METHOD *)SSLv3_server_method();
+#else /* OPENSSL_NO_SSL3 */
+        return "SSLv3 not supported";
+#endif /* !OPENSSL_NO_SSL3 */
+    } else if(!strcasecmp(arg, "TLSv1")) {
+#ifndef OPENSSL_NO_TLS1
+        section->client_method=(SSL_METHOD *)TLSv1_client_method();
+        section->server_method=(SSL_METHOD *)TLSv1_server_method();
+#else /* OPENSSL_NO_TLS1 */
+        return "TLSv1 not supported";
+#endif /* !OPENSSL_NO_TLS1 */
+    } else if(!strcasecmp(arg, "TLSv1.1")) {
+#ifndef OPENSSL_NO_TLS1_1
+        section->client_method=(SSL_METHOD *)TLSv1_1_client_method();
+        section->server_method=(SSL_METHOD *)TLSv1_1_server_method();
+#else /* OPENSSL_NO_TLS1_1 */
+        return "TLSv1.1 not supported";
+#endif /* !OPENSSL_NO_TLS1_1 */
+    } else if(!strcasecmp(arg, "TLSv1.2")) {
+#ifndef OPENSSL_NO_TLS1_2
+        section->client_method=(SSL_METHOD *)TLSv1_2_client_method();
+        section->server_method=(SSL_METHOD *)TLSv1_2_server_method();
+#else /* OPENSSL_NO_TLS1_2 */
+        return "TLSv1.2 not supported";
+#endif /* !OPENSSL_NO_TLS1_2 */
+#endif /* OPENSSL_API_COMPAT<0x10100000L */
+    } else
+        return "Incorrect version of TLS protocol";
+    return NULL; /* OK */
+}
+
+NOEXPORT char *tls_methods_check(SERVICE_OPTIONS *section) {
+    (void)section; /* squash the unused parameter warning */
+#ifdef USE_FIPS
+    if(new_global_options.option.fips) {
+#ifndef OPENSSL_NO_SSL2
+        if(section->option.client ?
+                section->client_method==(SSL_METHOD *)SSLv2_client_method() :
+                section->server_method==(SSL_METHOD *)SSLv2_server_method())
+            return "\"sslVersion = SSLv2\" not supported in FIPS mode";
+#endif /* !OPENSSL_NO_SSL2 */
+#ifndef OPENSSL_NO_SSL3
+        if(section->option.client ?
+                section->client_method==(SSL_METHOD *)SSLv3_client_method() :
+                section->server_method==(SSL_METHOD *)SSLv3_server_method())
+            return "\"sslVersion = SSLv3\" not supported in FIPS mode";
+#endif /* !OPENSSL_NO_SSL3 */
+    }
+#endif /* USE_FIPS */
+    return NULL;
+}
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif /* __GNUC__ */
+
 /**************************************** facility/debug level */
 
 typedef struct {
@@ -3091,8 +3591,6 @@ typedef struct {
 } facilitylevel;
 
 NOEXPORT char *parse_debug_level(char *arg, SERVICE_OPTIONS *section) {
-    char *arg_copy;
-    char *string;
     facilitylevel *fl;
 
 /* facilities only make sense on unix */
@@ -3127,36 +3625,33 @@ NOEXPORT char *parse_debug_level(char *a
         {NULL, -1}
     };
 
-    arg_copy=str_dup(arg);
-    string=arg_copy;
-
 /* facilities only make sense on Unix */
 #if !defined (USE_WIN32) && !defined (__vms)
-    if(section==&new_service_options && strchr(string, '.')) {
+    if(section==&new_service_options && strchr(arg, '.')) {
         /* a facility was specified in the global options */
         new_global_options.log_facility=-1;
-        string=strtok(arg_copy, "."); /* break it up */
+        arg=strtok(arg, "."); /* break it up */
 
         for(fl=facilities; fl->name; ++fl) {
-            if(!strcasecmp(fl->name, string)) {
+            if(!strcasecmp(fl->name, arg)) {
                 new_global_options.log_facility=fl->value;
                 break;
             }
         }
         if(new_global_options.log_facility==-1)
             return "Illegal syslog facility";
-        string=strtok(NULL, ".");    /* set to the remainder */
+        arg=strtok(NULL, ".");    /* set to the remainder */
     }
 #endif /* USE_WIN32, __vms */
 
     /* time to check the syslog level */
-    if(string && strlen(string)==1 && *string>='0' && *string<='7') {
-        section->log_level=*string-'0';
+    if(arg && strlen(arg)==1 && *arg>='0' && *arg<='7') {
+        section->log_level=*arg-'0';
         return NULL; /* OK */
     }
     section->log_level=8;    /* illegal level */
     for(fl=levels; fl->name; ++fl) {
-        if(!strcasecmp(fl->name, string)) {
+        if(!strcasecmp(fl->name, arg)) {
             section->log_level=fl->value;
             break;
         }
@@ -3244,9 +3739,9 @@ NOEXPORT PSK_KEYS *psk_read(char *key_fi
             psk_free(head);
             return NULL;
         }
-        curr=str_alloc(sizeof(PSK_KEYS));
-        curr->identity=str_dup(line);
-        curr->key_val=(unsigned char *)str_dup(key_val);
+        curr=str_alloc_detached(sizeof(PSK_KEYS));
+        curr->identity=str_dup_detached(line);
+        curr->key_val=(unsigned char *)str_dup_detached(key_val);
         curr->key_len=key_len;
         curr->next=NULL;
         if(head)
@@ -3259,11 +3754,27 @@ NOEXPORT PSK_KEYS *psk_read(char *key_fi
     return head;
 }
 
-NOEXPORT void psk_free(PSK_KEYS *head) {
-    PSK_KEYS *next;
+NOEXPORT PSK_KEYS *psk_dup(PSK_KEYS *src) {
+    PSK_KEYS *head=NULL, *tail=NULL, *curr;
 
+    while(src) {
+        curr=str_alloc_detached(sizeof(PSK_KEYS));
+        curr->identity=str_dup_detached(src->identity);
+        curr->key_val=(unsigned char *)str_dup_detached((char *)src->key_val);
+        curr->key_len=src->key_len;
+        curr->next=NULL;
+        if(head)
+            tail->next=curr;
+        else
+            head=curr;
+        tail=curr;
+    }
+    return head;
+}
+
+NOEXPORT void psk_free(PSK_KEYS *head) {
     while(head) {
-        next=head->next;
+        PSK_KEYS *next=head->next;
         str_free(head->identity);
         str_free(head->key_val);
         str_free(head);
@@ -3275,104 +3786,146 @@ NOEXPORT void psk_free(PSK_KEYS *head) {
 
 /**************************************** socket options */
 
-static int on=1;
-#define DEF_ON ((void *)&on)
+#define VAL_TAB {NULL, NULL, NULL}
 
-SOCK_OPT *sock_opts=NULL, sock_opts_def[]= {
-    {"SO_DEBUG",        SOL_SOCKET,     SO_DEBUG,        TYPE_FLAG,    {NULL, NULL, NULL}},
-    {"SO_DONTROUTE",    SOL_SOCKET,     SO_DONTROUTE,    TYPE_FLAG,    {NULL, NULL, NULL}},
-    {"SO_KEEPALIVE",    SOL_SOCKET,     SO_KEEPALIVE,    TYPE_FLAG,    {NULL, NULL, NULL}},
-    {"SO_LINGER",       SOL_SOCKET,     SO_LINGER,       TYPE_LINGER,  {NULL, NULL, NULL}},
-    {"SO_OOBINLINE",    SOL_SOCKET,     SO_OOBINLINE,    TYPE_FLAG,    {NULL, NULL, NULL}},
-    {"SO_RCVBUF",       SOL_SOCKET,     SO_RCVBUF,       TYPE_INT,     {NULL, NULL, NULL}},
-    {"SO_SNDBUF",       SOL_SOCKET,     SO_SNDBUF,       TYPE_INT,     {NULL, NULL, NULL}},
+SOCK_OPT sock_opts_def[]={
+    {"SO_DEBUG",        SOL_SOCKET,     SO_DEBUG,        TYPE_FLAG,     VAL_TAB},
+    {"SO_DONTROUTE",    SOL_SOCKET,     SO_DONTROUTE,    TYPE_FLAG,     VAL_TAB},
+    {"SO_KEEPALIVE",    SOL_SOCKET,     SO_KEEPALIVE,    TYPE_FLAG,     VAL_TAB},
+    {"SO_LINGER",       SOL_SOCKET,     SO_LINGER,       TYPE_LINGER,   VAL_TAB},
+    {"SO_OOBINLINE",    SOL_SOCKET,     SO_OOBINLINE,    TYPE_FLAG,     VAL_TAB},
+    {"SO_RCVBUF",       SOL_SOCKET,     SO_RCVBUF,       TYPE_INT,      VAL_TAB},
+    {"SO_SNDBUF",       SOL_SOCKET,     SO_SNDBUF,       TYPE_INT,      VAL_TAB},
 #ifdef SO_RCVLOWAT
-    {"SO_RCVLOWAT",     SOL_SOCKET,     SO_RCVLOWAT,     TYPE_INT,     {NULL, NULL, NULL}},
+    {"SO_RCVLOWAT",     SOL_SOCKET,     SO_RCVLOWAT,     TYPE_INT,      VAL_TAB},
 #endif
 #ifdef SO_SNDLOWAT
-    {"SO_SNDLOWAT",     SOL_SOCKET,     SO_SNDLOWAT,     TYPE_INT,     {NULL, NULL, NULL}},
+    {"SO_SNDLOWAT",     SOL_SOCKET,     SO_SNDLOWAT,     TYPE_INT,      VAL_TAB},
 #endif
 #ifdef SO_RCVTIMEO
-    {"SO_RCVTIMEO",     SOL_SOCKET,     SO_RCVTIMEO,     TYPE_TIMEVAL, {NULL, NULL, NULL}},
+    {"SO_RCVTIMEO",     SOL_SOCKET,     SO_RCVTIMEO,     TYPE_TIMEVAL,  VAL_TAB},
 #endif
 #ifdef SO_SNDTIMEO
-    {"SO_SNDTIMEO",     SOL_SOCKET,     SO_SNDTIMEO,     TYPE_TIMEVAL, {NULL, NULL, NULL}},
+    {"SO_SNDTIMEO",     SOL_SOCKET,     SO_SNDTIMEO,     TYPE_TIMEVAL,  VAL_TAB},
 #endif
 #ifdef USE_WIN32
-    {"SO_EXCLUSIVEADDRUSE", SOL_SOCKET, SO_EXCLUSIVEADDRUSE, TYPE_FLAG, {DEF_ON, NULL, NULL}},
-    {"SO_REUSEADDR",    SOL_SOCKET,     SO_REUSEADDR,    TYPE_FLAG,    {NULL, NULL, NULL}},
-#else
-    {"SO_REUSEADDR",    SOL_SOCKET,     SO_REUSEADDR,    TYPE_FLAG,    {DEF_ON, NULL, NULL}},
+    {"SO_EXCLUSIVEADDRUSE", SOL_SOCKET, SO_EXCLUSIVEADDRUSE, TYPE_FLAG, VAL_TAB},
 #endif
+    {"SO_REUSEADDR",    SOL_SOCKET,     SO_REUSEADDR,    TYPE_FLAG,     VAL_TAB},
 #ifdef SO_BINDTODEVICE
-    {"SO_BINDTODEVICE", SOL_SOCKET,     SO_BINDTODEVICE, TYPE_STRING,  {NULL, NULL, NULL}},
+    {"SO_BINDTODEVICE", SOL_SOCKET,     SO_BINDTODEVICE, TYPE_STRING,   VAL_TAB},
 #endif
 #ifdef SOL_TCP
 #ifdef TCP_KEEPCNT
-    {"TCP_KEEPCNT",     SOL_TCP,        TCP_KEEPCNT,     TYPE_INT,     {NULL, NULL, NULL}},
+    {"TCP_KEEPCNT",     SOL_TCP,        TCP_KEEPCNT,     TYPE_INT,      VAL_TAB},
 #endif
 #ifdef TCP_KEEPIDLE
-    {"TCP_KEEPIDLE",    SOL_TCP,        TCP_KEEPIDLE,    TYPE_INT,     {NULL, NULL, NULL}},
+    {"TCP_KEEPIDLE",    SOL_TCP,        TCP_KEEPIDLE,    TYPE_INT,      VAL_TAB},
 #endif
 #ifdef TCP_KEEPINTVL
-    {"TCP_KEEPINTVL",   SOL_TCP,        TCP_KEEPINTVL,   TYPE_INT,     {NULL, NULL, NULL}},
+    {"TCP_KEEPINTVL",   SOL_TCP,        TCP_KEEPINTVL,   TYPE_INT,      VAL_TAB},
 #endif
 #endif /* SOL_TCP */
 #ifdef IP_TOS
-    {"IP_TOS",          IPPROTO_IP,     IP_TOS,          TYPE_INT,     {NULL, NULL, NULL}},
+    {"IP_TOS",          IPPROTO_IP,     IP_TOS,          TYPE_INT,      VAL_TAB},
 #endif
 #ifdef IP_TTL
-    {"IP_TTL",          IPPROTO_IP,     IP_TTL,          TYPE_INT,     {NULL, NULL, NULL}},
+    {"IP_TTL",          IPPROTO_IP,     IP_TTL,          TYPE_INT,      VAL_TAB},
 #endif
 #ifdef IP_MAXSEG
-    {"TCP_MAXSEG",      IPPROTO_TCP,    TCP_MAXSEG,      TYPE_INT,     {NULL, NULL, NULL}},
+    {"TCP_MAXSEG",      IPPROTO_TCP,    TCP_MAXSEG,      TYPE_INT,      VAL_TAB},
 #endif
-    {"TCP_NODELAY",     IPPROTO_TCP,    TCP_NODELAY,     TYPE_FLAG,    {NULL, DEF_ON, DEF_ON}},
+    {"TCP_NODELAY",     IPPROTO_TCP,    TCP_NODELAY,     TYPE_FLAG,     VAL_TAB},
 #ifdef IP_FREEBIND
-    {"IP_FREEBIND",     IPPROTO_IP,     IP_FREEBIND,     TYPE_FLAG,    {NULL, NULL, NULL}},
+    {"IP_FREEBIND",     IPPROTO_IP,     IP_FREEBIND,     TYPE_FLAG,     VAL_TAB},
 #endif
 #ifdef IP_BINDANY
-    {"IP_BINDANY",      IPPROTO_IP,     IP_BINDANY,      TYPE_FLAG,    {NULL, NULL, NULL}},
+    {"IP_BINDANY",      IPPROTO_IP,     IP_BINDANY,      TYPE_FLAG,     VAL_TAB},
 #endif
 #ifdef IPV6_BINDANY
-    {"IPV6_BINDANY",    IPPROTO_IPV6,   IPV6_BINDANY,    TYPE_FLAG,    {NULL, NULL, NULL}},
+    {"IPV6_BINDANY",    IPPROTO_IPV6,   IPV6_BINDANY,    TYPE_FLAG,     VAL_TAB},
 #endif
 #ifdef IPV6_V6ONLY
-    {"IPV6_V6ONLY",     IPPROTO_IPV6,   IPV6_V6ONLY,     TYPE_FLAG,    {NULL, NULL, NULL}},
+    {"IPV6_V6ONLY",     IPPROTO_IPV6,   IPV6_V6ONLY,     TYPE_FLAG,     VAL_TAB},
 #endif
-    {NULL,              0,              0,               TYPE_NONE,    {NULL, NULL, NULL}}
+    {NULL,              0,              0,               TYPE_NONE,     VAL_TAB}
 };
 
-NOEXPORT void init_socket_options(void) {
+NOEXPORT SOCK_OPT *socket_options_init(void) {
 #ifdef USE_WIN32
     DWORD version;
     int major, minor;
-    SOCK_OPT *ptr;
+#endif
 
+    SOCK_OPT *opt=str_alloc_detached(sizeof sock_opts_def);
+    memcpy(opt, sock_opts_def, sizeof sock_opts_def);
+
+#ifdef USE_WIN32
     version=GetVersion();
     major=LOBYTE(LOWORD(version));
     minor=HIBYTE(LOWORD(version));
     s_log(LOG_DEBUG, "Running on Windows %d.%d", major, minor);
 
-    for(ptr=sock_opts_def; ptr->opt_str; ++ptr)
-        if(ptr->opt_level==SOL_SOCKET && ptr->opt_name==SO_EXCLUSIVEADDRUSE)
-            ptr->opt_val[0]=major>5 ? DEF_ON : NULL; /* Vista or later */
+    if(major>5) /* Vista or later */
+        socket_option_set_int(opt, "SO_EXCLUSIVEADDRUSE", 0, 1); /* accepting socket */
+#else
+    socket_option_set_int(opt, "SO_REUSEADDR", 0, 1); /* accepting socket */
 #endif
+    socket_option_set_int(opt, "TCP_NODELAY", 1, 1); /* local socket */
+    socket_option_set_int(opt, "TCP_NODELAY", 2, 1); /* remote socket */
+    return opt;
+}
 
-    if(!sock_opts)
-        sock_opts=str_alloc_detached(sizeof sock_opts_def);
-    memcpy(sock_opts, sock_opts_def, sizeof sock_opts_def);
+NOEXPORT void socket_option_set_int(SOCK_OPT *opt, char *name, int type, int value) {
+    for(; opt->opt_str; ++opt) {
+        if(!strcmp(name, opt->opt_str)) {
+            opt->opt_val[type]=str_alloc_detached(sizeof(OPT_UNION));
+            opt->opt_val[type]->i_val=value;
+        }
+    }
 }
 
-NOEXPORT int print_socket_options(void) {
+NOEXPORT SOCK_OPT *socket_options_dup(SOCK_OPT *src) {
+    SOCK_OPT *dst=str_alloc_detached(sizeof sock_opts_def);
+    SOCK_OPT *ptr;
+
+    memcpy(dst, sock_opts_def, sizeof sock_opts_def);
+    for(ptr=dst; src->opt_str; ++src, ++ptr) {
+        int type;
+        for(type=0; type<3; ++type) {
+            if(src->opt_val[type]) {
+                ptr->opt_val[type]=str_alloc_detached(sizeof(OPT_UNION));
+                memcpy(ptr->opt_val[type],
+                    src->opt_val[type], sizeof(OPT_UNION));
+            }
+        }
+    }
+    return dst;
+}
+
+NOEXPORT void socket_options_free(SOCK_OPT *opt) {
+    SOCK_OPT *ptr;
+    if(!opt) {
+        s_log(LOG_ERR, "INTERNAL ERROR: Socket options not initialized");
+        return;
+    }
+    for(ptr=opt; ptr->opt_str; ++ptr) {
+        int type;
+        for(type=0; type<3; ++type)
+            str_free(ptr->opt_val[type]);
+    }
+    str_free(opt);
+}
+
+NOEXPORT int socket_options_print(void) {
+    SOCK_OPT *opt, *ptr;
     SOCKET fd;
     socklen_t optlen;
-    SOCK_OPT *ptr;
     OPT_UNION val;
     char *ta, *tl, *tr, *td;
 
     fd=socket(AF_INET, SOCK_STREAM, 0);
-    init_socket_options();
+    opt=socket_options_init();
 
     s_log(LOG_NOTICE, " ");
     s_log(LOG_NOTICE, "Socket option defaults:");
@@ -3380,7 +3933,7 @@ NOEXPORT int print_socket_options(void)
         "    Option Name         |  Accept  |   Local  |  Remote  |OS default");
     s_log(LOG_NOTICE,
         "    --------------------+----------+----------+----------+----------");
-    for(ptr=sock_opts; ptr->opt_str; ++ptr) {
+    for(ptr=opt; ptr->opt_str; ++ptr) {
         /* get OS default value */
         optlen=sizeof val;
         if(getsockopt(fd, ptr->opt_level,
@@ -3397,21 +3950,22 @@ NOEXPORT int print_socket_options(void)
                 return 1; /* FAILED */
             }
         } else
-            td=print_option(ptr->opt_type, &val);
+            td=socket_option_text(ptr->opt_type, &val);
         /* get stunnel default values */
-        ta=print_option(ptr->opt_type, ptr->opt_val[0]);
-        tl=print_option(ptr->opt_type, ptr->opt_val[1]);
-        tr=print_option(ptr->opt_type, ptr->opt_val[2]);
+        ta=socket_option_text(ptr->opt_type, ptr->opt_val[0]);
+        tl=socket_option_text(ptr->opt_type, ptr->opt_val[1]);
+        tr=socket_option_text(ptr->opt_type, ptr->opt_val[2]);
         /* print collected data and fee the memory */
         s_log(LOG_NOTICE, "    %-20s|%10s|%10s|%10s|%10s",
             ptr->opt_str, ta, tl, tr, td);
         str_free(ta); str_free(tl); str_free(tr); str_free(td);
     }
+    socket_options_free(opt);
     closesocket(fd);
     return 0; /* OK */
 }
 
-NOEXPORT char *print_option(int type, OPT_UNION *val) {
+NOEXPORT char *socket_option_text(VAL_TYPE type, OPT_UNION *val) {
     if(!val)
         return str_dup("    --    ");
     switch(type) {
@@ -3427,14 +3981,16 @@ NOEXPORT char *print_option(int type, OP
             (int)val->timeval_val.tv_sec, (int)val->timeval_val.tv_usec);
     case TYPE_STRING:
         return str_printf("%s", val->c_val);
+    case TYPE_NONE:
+        return str_dup("   none   "); /* internal error? */
     }
     return str_dup("  Ooops?  "); /* internal error? */
 }
 
-NOEXPORT int parse_socket_option(char *arg) {
+NOEXPORT int socket_option_parse(SOCK_OPT *opt, char *arg) {
     int socket_type; /* 0-accept, 1-local, 2-remote */
     char *opt_val_str, *opt_val2_str, *tmp_str;
-    SOCK_OPT *ptr;
+    OPT_UNION opt_val;
 
     if(arg[1]!=':')
         return 1; /* FAILED */
@@ -3453,72 +4009,72 @@ NOEXPORT int parse_socket_option(char *a
     if(!opt_val_str) /* no '='? */
         return 1; /* FAILED */
     *opt_val_str++='\0';
-    ptr=sock_opts;
-    for(;;) {
-        if(!ptr->opt_str)
-            return 1; /* FAILED */
-        if(!strcmp(arg, ptr->opt_str))
-            break; /* option name found */
-        ++ptr;
-    }
-    ptr->opt_val[socket_type]=str_alloc(sizeof(OPT_UNION));
-    switch(ptr->opt_type) {
+
+    for(; opt->opt_str && strcmp(arg, opt->opt_str); ++opt)
+        ;
+    if(!opt->opt_str)
+        return 1; /* FAILED */
+
+    switch(opt->opt_type) {
     case TYPE_FLAG:
         if(!strcasecmp(opt_val_str, "yes") || !strcmp(opt_val_str, "1")) {
-            ptr->opt_val[socket_type]->i_val=1;
-            return 0; /* OK */
+            opt_val.i_val=1;
+            break; /* OK */
         }
         if(!strcasecmp(opt_val_str, "no") || !strcmp(opt_val_str, "0")) {
-            ptr->opt_val[socket_type]->i_val=0;
-            return 0; /* OK */
+            opt_val.i_val=0;
+            break; /* OK */
         }
         return 1; /* FAILED */
     case TYPE_INT:
-        ptr->opt_val[socket_type]->i_val=(int)strtol(opt_val_str, &tmp_str, 10);
+        opt_val.i_val=(int)strtol(opt_val_str, &tmp_str, 10);
         if(tmp_str==arg || *tmp_str) /* not a number */
             return 1; /* FAILED */
-        return 0; /* OK */
+        break; /* OK */
     case TYPE_LINGER:
         opt_val2_str=strchr(opt_val_str, ':');
         if(opt_val2_str) {
             *opt_val2_str++='\0';
-            ptr->opt_val[socket_type]->linger_val.l_linger=
+            opt_val.linger_val.l_linger=
                 (u_short)strtol(opt_val2_str, &tmp_str, 10);
             if(tmp_str==arg || *tmp_str) /* not a number */
                 return 1; /* FAILED */
         } else {
-            ptr->opt_val[socket_type]->linger_val.l_linger=0;
+            opt_val.linger_val.l_linger=0;
         }
-        ptr->opt_val[socket_type]->linger_val.l_onoff=
+        opt_val.linger_val.l_onoff=
             (u_short)strtol(opt_val_str, &tmp_str, 10);
         if(tmp_str==arg || *tmp_str) /* not a number */
             return 1; /* FAILED */
-        return 0; /* OK */
+        break; /* OK */
     case TYPE_TIMEVAL:
         opt_val2_str=strchr(opt_val_str, ':');
         if(opt_val2_str) {
             *opt_val2_str++='\0';
-            ptr->opt_val[socket_type]->timeval_val.tv_usec=
+            opt_val.timeval_val.tv_usec=
                 (int)strtol(opt_val2_str, &tmp_str, 10);
             if(tmp_str==arg || *tmp_str) /* not a number */
                 return 1; /* FAILED */
         } else {
-            ptr->opt_val[socket_type]->timeval_val.tv_usec=0;
+            opt_val.timeval_val.tv_usec=0;
         }
-        ptr->opt_val[socket_type]->timeval_val.tv_sec=
+        opt_val.timeval_val.tv_sec=
             (int)strtol(opt_val_str, &tmp_str, 10);
         if(tmp_str==arg || *tmp_str) /* not a number */
             return 1; /* FAILED */
-        return 0; /* OK */
+        break; /* OK */
     case TYPE_STRING:
         if(strlen(opt_val_str)+1>sizeof(OPT_UNION))
             return 1; /* FAILED */
-        strcpy(ptr->opt_val[socket_type]->c_val, opt_val_str);
-        return 0; /* OK */
+        strcpy(opt_val.c_val, opt_val_str);
+        break; /* OK */
     default:
-        ; /* ANSI C compiler needs it */
+        return 1; /* FAILED */
     }
-    return 1; /* FAILED */
+    str_free(opt->opt_val[socket_type]);
+    opt->opt_val[socket_type]=str_alloc_detached(sizeof(OPT_UNION));
+    memcpy(opt->opt_val[socket_type], &opt_val, sizeof(OPT_UNION));
+    return 0;
 }
 
 /**************************************** OCSP */
@@ -3731,31 +4287,76 @@ NOEXPORT void print_syntax(void) {
 NOEXPORT void name_list_append(NAME_LIST **ptr, char *name) {
     while(*ptr) /* find the null pointer */
         ptr=&(*ptr)->next;
-    *ptr=str_alloc(sizeof(NAME_LIST));
-    (*ptr)->name=str_dup(name);
+    *ptr=str_alloc_detached(sizeof(NAME_LIST));
+    (*ptr)->name=str_dup_detached(name);
     (*ptr)->next=NULL;
 }
 
+NOEXPORT void name_list_dup(NAME_LIST **dst, NAME_LIST *src) {
+    for(; src; src=src->next)
+        name_list_append(dst, src->name);
+}
+
+NOEXPORT void name_list_free(NAME_LIST *ptr) {
+    while(ptr) {
+        NAME_LIST *next=ptr->next;
+        str_free(ptr->name);
+        str_free(ptr);
+        ptr=next;
+    }
+}
+
 #ifndef USE_WIN32
 
-NOEXPORT char **argalloc(char *str) { /* allocate 'exec' argumets */
+/* allocate 'exec' arguments */
+/* TODO: support quotes */
+NOEXPORT char **arg_alloc(char *str) {
     size_t max_arg, i;
-    char *ptr, **retval;
+    char **tmp, **retval;
 
     max_arg=strlen(str)/2+1;
-    ptr=str_dup(str);
-    retval=str_alloc((max_arg+1)*sizeof(char *));
+    tmp=str_alloc((max_arg+1)*sizeof(char *));
+
     i=0;
-    while(*ptr && i<max_arg) {
-        retval[i++]=ptr;
-        while(*ptr && !isspace((unsigned char)*ptr))
-            ++ptr;
-        while(*ptr && isspace((unsigned char)*ptr))
-            *ptr++='\0';
+    while(*str && i<max_arg) {
+        tmp[i++]=str;
+        while(*str && !isspace((unsigned char)*str))
+            ++str;
+        while(*str && isspace((unsigned char)*str))
+            *str++='\0';
     }
-    retval[i]=NULL; /* to show that it's null-terminated */
+    tmp[i]=NULL; /* null-terminate the table */
+
+    retval=arg_dup(tmp);
+    str_free(tmp);
     return retval;
 }
+
+NOEXPORT char **arg_dup(char **src) {
+    size_t i, n;
+    char **dst;
+
+    if(!src)
+        return NULL;
+    for(n=0; src[n]; ++n)
+        ;
+    dst=str_alloc_detached((n+1)*sizeof(char *));
+    for(i=0; i<n; ++i)
+        dst[i]=str_dup_detached(src[i]);
+    dst[n]=NULL;
+    return dst;
+}
+
+NOEXPORT void arg_free(char **arg) {
+    size_t i;
+
+    if(arg) {
+        for(i=0; arg[i]; ++i)
+            str_free(arg[i]);
+        str_free(arg);
+    }
+}
+
 #endif
 
 /* end of options.c */
diff -pruN 3:5.44-1/src/os2.mak 3:5.49-1/src/os2.mak
--- 3:5.44-1/src/os2.mak	2017-11-14 14:01:47.000000000 +0000
+++ 3:5.49-1/src/os2.mak	2018-08-09 05:43:52.000000000 +0000
@@ -1,11 +1,11 @@
 prefix=.
 DEFS = -DPACKAGE_NAME=\"stunnel\" \
 	-DPACKAGE_TARNAME=\"stunnel\" \
-	-DPACKAGE_VERSION=\"5.44\" \
-	-DPACKAGE_STRING=\"stunnel\ 5.44\" \
+	-DPACKAGE_VERSION=\"5.49\" \
+	-DPACKAGE_STRING=\"stunnel\ 5.49\" \
 	-DPACKAGE_BUGREPORT=\"\" \
 	-DPACKAGE=\"stunnel\" \
-	-DVERSION=\"5.44\" \
+	-DVERSION=\"5.49\" \
 	-DSTDC_HEADERS=1 \
 	-DHAVE_SYS_TYPES_H=1 \
 	-DHAVE_SYS_STAT_H=1 \
diff -pruN 3:5.44-1/src/protocol.c 3:5.49-1/src/protocol.c
--- 3:5.44-1/src/protocol.c	2017-01-19 08:51:32.000000000 +0000
+++ 3:5.49-1/src/protocol.c	2018-07-02 21:30:10.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -161,12 +161,12 @@ NOEXPORT void socks5_client_method(CLI *
     s_ssl_read(c, &resp, sizeof resp);
     if(resp.ver!=5) {
         s_log(LOG_ERR, "Invalid SOCKS5 message version 0x%02x", resp.ver);
-        longjmp(c->err, 2); /* don't reset */
+        throw_exception(c, 2); /* don't reset */
     }
     /* TODO: add USERNAME/PASSWORD authentication */
     if(resp.method!=0x00) {
         s_log(LOG_ERR, "No supported SOCKS5 authentication method received");
-        longjmp(c->err, 2); /* don't reset */
+        throw_exception(c, 2); /* don't reset */
     }
 }
 
@@ -175,7 +175,7 @@ NOEXPORT void socks5_client_address(CLI
     SOCKS5_UNION socks;
 
     if(original_dst(c->local_rfd.fd, &addr))
-        longjmp(c->err, 2); /* don't reset */
+        throw_exception(c, 2); /* don't reset */
     memset(&socks, 0, sizeof socks);
     socks.req.ver=5; /* SOCKS5 */
     socks.req.cmd=0x01; /* CONNECT */
@@ -198,7 +198,7 @@ NOEXPORT void socks5_client_address(CLI
 #endif
     default:
         s_log(LOG_ERR, "Unsupported address type 0x%02x", addr.sa.sa_family);
-        longjmp(c->err, 2); /* don't reset */
+        throw_exception(c, 2); /* don't reset */
     }
 
     s_ssl_read(c, &socks, sizeof socks.resp);
@@ -208,7 +208,7 @@ NOEXPORT void socks5_client_address(CLI
         s_ssl_read(c, &socks.v4.addr, 4+2);
     if(socks.resp.ver!=5) {
         s_log(LOG_ERR, "Invalid SOCKS5 message version 0x%02x", socks.req.ver);
-        longjmp(c->err, 2); /* don't reset */
+        throw_exception(c, 2); /* don't reset */
     }
     switch(socks.resp.rep) {
         case 0x00:
@@ -251,7 +251,7 @@ NOEXPORT void socks5_client_address(CLI
             s_log(LOG_ERR,
                 "SOCKS5 request failed: Unknown error 0x%02x", socks.resp.rep);
     }
-    longjmp(c->err, 2); /* don't reset */
+    throw_exception(c, 2); /* don't reset */
 }
 
 NOEXPORT char *socks_server(CLI *c, SERVICE_OPTIONS *opt, const PHASE phase) {
@@ -274,7 +274,7 @@ NOEXPORT char *socks_server(CLI *c, SERV
             break;
         default:
             s_log(LOG_ERR, "Unsupported SOCKS version 0x%02x", version);
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
         }
         break;
     case PROTOCOL_LATE:
@@ -359,7 +359,7 @@ NOEXPORT void socks4_server(CLI *c) {
     }
     s_ssl_write(c, &socks, sizeof socks);
     if(close_connection)
-        longjmp(c->err, 2); /* don't reset */
+        throw_exception(c, 2); /* don't reset */
 }
 
 NOEXPORT void socks5_server_method(CLI *c) {
@@ -383,7 +383,7 @@ NOEXPORT void socks5_server_method(CLI *
     s_ssl_write(c, &response, sizeof response);
     if(response.method) { /* request failed */
         s_log(LOG_ERR, "No supported SOCKS5 authentication method received");
-        longjmp(c->err, 2); /* don't reset */
+        throw_exception(c, 2); /* don't reset */
     }
 }
 
@@ -509,7 +509,7 @@ NOEXPORT void socks5_server(CLI *c) {
         s_ssl_write(c, &socks, sizeof socks.v4);
     }
     if(close_connection) /* request failed */
-        longjmp(c->err, 2); /* don't reset */
+        throw_exception(c, 2); /* don't reset */
 }
 
 /* validate the allocated address */
@@ -574,25 +574,25 @@ NOEXPORT char *proxy_server(CLI *c, SERV
     addrlen=sizeof addr;
     if(getpeername(c->local_rfd.fd, &addr.sa, &addrlen)) {
         sockerror("getpeername");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     err=getnameinfo(&addr.sa, addr_len(&addr), src_host, IP_LEN,
         src_port, PORT_LEN, NI_NUMERICHOST|NI_NUMERICSERV);
     if(err) {
         s_log(LOG_ERR, "getnameinfo: %s", s_gai_strerror(err));
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
 
     addrlen=sizeof addr;
     if(getsockname(c->local_rfd.fd, &addr.sa, &addrlen)) {
         sockerror("getsockname");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     err=getnameinfo(&addr.sa, addr_len(&addr), dst_host, IP_LEN,
         dst_port, PORT_LEN, NI_NUMERICHOST|NI_NUMERICSERV);
     if(err) {
         s_log(LOG_ERR, "getnameinfo: %s", s_gai_strerror(err));
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
 
     switch(addr.sa.sa_family) {
@@ -625,15 +625,15 @@ NOEXPORT char *cifs_client(CLI *c, SERVI
     s_read(c, c->remote_fd.fd, buffer, 5);
     if(buffer[0]!=0x83) { /* NB_SSN_NEGRESP */
         s_log(LOG_ERR, "Negative response expected");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     if(buffer[2]!=0 || buffer[3]!=1) { /* length != 1 */
         s_log(LOG_ERR, "Unexpected NetBIOS response size");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     if(buffer[4]!=0x8e) { /* use TLS */
         s_log(LOG_ERR, "Remote server does not require TLS");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     return NULL;
 }
@@ -651,13 +651,13 @@ NOEXPORT char *cifs_server(CLI *c, SERVI
     len=(uint16_t)(((uint16_t)(buffer[2])<<8)|buffer[3]);
     if(len>sizeof buffer-4) {
         s_log(LOG_ERR, "Received block too long");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     s_read(c, c->local_rfd.fd, buffer+4, len);
     if(buffer[0]!=0x81) { /* NB_SSN_REQUEST */
         s_log(LOG_ERR, "Client did not send session setup");
         s_write(c, c->local_wfd.fd, response_access_denied, 5);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     s_write(c, c->local_wfd.fd, response_use_ssl, 5);
     return NULL;
@@ -679,7 +679,7 @@ NOEXPORT char *pgsql_client(CLI *c, SERV
     /* S - accepted, N - rejected, non-TLS preferred */
     if(buffer[0]!='S') {
         s_log(LOG_ERR, "PostgreSQL server rejected TLS");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     return NULL;
 }
@@ -695,7 +695,7 @@ NOEXPORT char *pgsql_server(CLI *c, SERV
     if(safe_memcmp(buffer, ssl_request, sizeof ssl_request)) {
         s_log(LOG_ERR, "PostgreSQL client did not request TLS, rejecting");
         /* no way to send error on startup, so just drop the client */
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     s_write(c, c->local_wfd.fd, ssl_ok, sizeof ssl_ok);
     return NULL;
@@ -743,7 +743,7 @@ NOEXPORT void smtp_client_negotiate(CLI
     if(!is_prefix(line, "250 ")) { /* error */
         s_log(LOG_ERR, "Remote server is not RFC 1425 compliant");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
 
     fd_putline(c, c->remote_fd.fd, "STARTTLS");
@@ -754,7 +754,7 @@ NOEXPORT void smtp_client_negotiate(CLI
     if(!is_prefix(line, "220 ")) { /* error */
         s_log(LOG_ERR, "Remote server is not RFC 2487 compliant");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     str_free(line);
 }
@@ -769,7 +769,7 @@ NOEXPORT void smtp_client_plain(CLI *c,
     if(!encoded) {
         s_log(LOG_ERR, "Base64 encoder failed");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     str_free(line);
     line=str_printf("AUTH PLAIN %s", encoded);
@@ -781,7 +781,7 @@ NOEXPORT void smtp_client_plain(CLI *c,
     if(!is_prefix(line, "235 ")) { /* not 'Authentication successful' */
         s_log(LOG_ERR, "PLAIN Authentication Failed");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     str_free(line);
 }
@@ -794,14 +794,14 @@ NOEXPORT void smtp_client_login(CLI *c,
     if(!is_prefix(line, "334 ")) { /* not the username challenge */
         s_log(LOG_ERR, "Remote server does not support LOGIN authentication");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     str_free(line);
 
     encoded=base64(1, user, (int)strlen(user));
     if(!encoded) {
         s_log(LOG_ERR, "Base64 encoder failed");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     ssl_putline(c, encoded);
     str_free(encoded);
@@ -809,14 +809,14 @@ NOEXPORT void smtp_client_login(CLI *c,
     if(!is_prefix(line, "334 ")) { /* not the password challenge */
         s_log(LOG_ERR, "LOGIN authentication failed");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     str_free(line);
 
     encoded=base64(1, pass, (int)strlen(pass));
     if(!encoded) {
         s_log(LOG_ERR, "Base64 encoder failed");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     ssl_putline(c, encoded);
     str_free(encoded);
@@ -824,7 +824,7 @@ NOEXPORT void smtp_client_login(CLI *c,
     if(!is_prefix(line, "235 ")) { /* not 'Authentication successful' */
         s_log(LOG_ERR, "LOGIN authentication failed");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     str_free(line);
 }
@@ -849,7 +849,7 @@ NOEXPORT char *smtp_server(CLI *c, SERVI
         return NULL; /* return if RFC 2487 is not used */
     default: /* -1 */
         sockerror("RFC2487 (s_poll_wait)");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
 
     /* process server's greeting */
@@ -857,7 +857,7 @@ NOEXPORT char *smtp_server(CLI *c, SERVI
     if(!(is_prefix(line, "220 ") || is_prefix(line, "220-"))) {
         s_log(LOG_ERR, "Unknown server welcome");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     domain=str_dup(line+4); /* skip "220" and the separator */
     line[4]='\0';     /* only leave "220" and the separator */
@@ -882,7 +882,7 @@ NOEXPORT char *smtp_server(CLI *c, SERVI
         s_log(LOG_ERR, "Unknown client EHLO");
         str_free(line);
         str_free(domain);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     str_free(line);
     fd_printf(c, c->local_wfd.fd, "250-%s", domain);
@@ -894,7 +894,7 @@ NOEXPORT char *smtp_server(CLI *c, SERVI
     if(!is_prefix(line, "STARTTLS")) {
         s_log(LOG_ERR, "STARTTLS expected");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     fd_putline(c, c->local_wfd.fd, "220 Go ahead");
     str_free(line);
@@ -914,7 +914,7 @@ NOEXPORT char *pop3_client(CLI *c, SERVI
     if(!is_prefix(line, "+OK ")) {
         s_log(LOG_ERR, "Unknown server welcome");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     fd_putline(c, c->local_wfd.fd, line);
     fd_putline(c, c->remote_fd.fd, "STLS");
@@ -923,7 +923,7 @@ NOEXPORT char *pop3_client(CLI *c, SERVI
     if(!is_prefix(line, "+OK ")) {
         s_log(LOG_ERR, "Server does not support TLS");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     str_free(line);
     return NULL;
@@ -950,7 +950,7 @@ NOEXPORT char *pop3_server(CLI *c, SERVI
     if(!is_prefix(line, "STLS")) {
         s_log(LOG_ERR, "Client does not want TLS");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     str_free(line);
     fd_putline(c, c->local_wfd.fd, "+OK Stunnel starts TLS negotiation");
@@ -969,7 +969,7 @@ NOEXPORT char *imap_client(CLI *c, SERVI
     if(!is_prefix(line, "* OK")) {
         s_log(LOG_ERR, "Unknown server welcome");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     fd_putline(c, c->local_wfd.fd, line);
     fd_putline(c, c->remote_fd.fd, "stunnel STARTTLS");
@@ -980,7 +980,7 @@ NOEXPORT char *imap_client(CLI *c, SERVI
             "* BYE stunnel: Server does not support TLS");
         s_log(LOG_ERR, "Server does not support TLS");
         str_free(line);
-        longjmp(c->err, 2); /* don't reset */
+        throw_exception(c, 2); /* don't reset */
     }
     str_free(line);
     return NULL;
@@ -1004,7 +1004,7 @@ NOEXPORT char *imap_server(CLI *c, SERVI
         return NULL; /* return if RFC 2595 is not used */
     default: /* -1 */
         sockerror("RFC2595 (s_poll_wait)");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
 
     /* process server welcome and send it to client */
@@ -1012,7 +1012,7 @@ NOEXPORT char *imap_server(CLI *c, SERVI
     if(!is_prefix(line, "* OK")) {
         s_log(LOG_ERR, "Unknown server welcome");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     capa=strstr(line, "CAPABILITY");
     if(!capa)
@@ -1083,7 +1083,7 @@ NOEXPORT char *imap_server(CLI *c, SERVI
         line=fd_getline(c, c->remote_fd.fd);
     }
     str_free(line);
-    longjmp(c->err, 2); /* don't reset */
+    throw_exception(c, 2); /* don't reset */
     return NULL; /* some C compilers require a return value */
 }
 
@@ -1099,7 +1099,7 @@ NOEXPORT char *nntp_client(CLI *c, SERVI
     if(!is_prefix(line, "200 ") && !is_prefix(line, "201 ")) {
         s_log(LOG_ERR, "Unknown server welcome");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     fd_putline(c, c->local_wfd.fd, line);
     fd_putline(c, c->remote_fd.fd, "STARTTLS");
@@ -1108,7 +1108,7 @@ NOEXPORT char *nntp_client(CLI *c, SERVI
     if(!is_prefix(line, "382 ")) {
         s_log(LOG_ERR, "Server does not support TLS");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     str_free(line);
     return NULL;
@@ -1128,7 +1128,7 @@ NOEXPORT char *connect_server(CLI *c, SE
         fd_putline(c, c->local_wfd.fd, "Server: stunnel/" STUNNEL_VERSION);
         fd_putline(c, c->local_wfd.fd, "");
         str_free(request);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     proto=strchr(request+8, ' ');
     if(!proto || !is_prefix(proto, " HTTP/")) {
@@ -1136,7 +1136,7 @@ NOEXPORT char *connect_server(CLI *c, SE
         fd_putline(c, c->local_wfd.fd, "Server: stunnel/" STUNNEL_VERSION);
         fd_putline(c, c->local_wfd.fd, "");
         str_free(request);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     *proto='\0';
 
@@ -1152,7 +1152,7 @@ NOEXPORT char *connect_server(CLI *c, SE
         fd_putline(c, c->local_wfd.fd, "Server: stunnel/" STUNNEL_VERSION);
         fd_putline(c, c->local_wfd.fd, "");
         str_free(request);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     str_free(request);
     fd_putline(c, c->local_wfd.fd, "HTTP/1.0 200 OK");
@@ -1168,7 +1168,7 @@ NOEXPORT char *connect_client(CLI *c, SE
         return NULL;
     if(!opt->protocol_host) {
         s_log(LOG_ERR, "protocolHost not specified");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     fd_printf(c, c->remote_fd.fd, "CONNECT %s HTTP/1.1",
         opt->protocol_host);
@@ -1179,7 +1179,7 @@ NOEXPORT char *connect_client(CLI *c, SE
             ntlm(c, opt);
 #else
             s_log(LOG_ERR, "NTLM authentication is not available");
-            longjmp(c->err, 1);
+            throw_exception(c, 1);
 #endif
         } else { /* basic authentication */
             line=str_printf("%s:%s",
@@ -1188,7 +1188,7 @@ NOEXPORT char *connect_client(CLI *c, SE
             str_free(line);
             if(!encoded) {
                 s_log(LOG_ERR, "Base64 encoder failed");
-                longjmp(c->err, 1);
+                throw_exception(c, 1);
             }
             fd_printf(c, c->remote_fd.fd, "Proxy-Authorization: basic %s",
                 encoded);
@@ -1205,7 +1205,7 @@ NOEXPORT char *connect_client(CLI *c, SE
             line=fd_getline(c, c->remote_fd.fd);
         } while(*line);
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     s_log(LOG_INFO, "CONNECT request accepted");
     do {
@@ -1235,7 +1235,7 @@ NOEXPORT void ntlm(CLI *c, SERVICE_OPTIO
     ntlm1_txt=ntlm1();
     if(!ntlm1_txt) {
         s_log(LOG_ERR, "Proxy-Authenticate: Failed to build NTLM request");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     fd_printf(c, c->remote_fd.fd, "Proxy-Authorization: NTLM %s", ntlm1_txt);
     str_free(ntlm1_txt);
@@ -1250,7 +1250,7 @@ NOEXPORT void ntlm(CLI *c, SERVICE_OPTIO
             line=fd_getline(c, c->remote_fd.fd);
         } while(*line);
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     ntlm2_txt=NULL;
     do { /* read all headers */
@@ -1266,14 +1266,14 @@ NOEXPORT void ntlm(CLI *c, SERVICE_OPTIO
             if(tmpstr==line+16 || *tmpstr || content_length<0) {
                 s_log(LOG_ERR, "Proxy-Authenticate: Invalid Content-Length");
                 str_free(line);
-                longjmp(c->err, 1);
+                throw_exception(c, 1);
             }
         }
     } while(*line);
     if(!ntlm2_txt) { /* no Proxy-Authenticate: NTLM header */
         s_log(LOG_ERR, "Proxy-Authenticate: NTLM header not found");
         str_free(line);
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
 
     /* read and ignore HTTP content (if any) */
@@ -1291,7 +1291,7 @@ NOEXPORT void ntlm(CLI *c, SERVICE_OPTIO
     str_free(ntlm2_txt);
     if(!ntlm3_txt) {
         s_log(LOG_ERR, "Proxy-Authenticate: Failed to build NTLM response");
-        longjmp(c->err, 1);
+        throw_exception(c, 1);
     }
     fd_printf(c, c->remote_fd.fd, "Proxy-Authorization: NTLM %s", ntlm3_txt);
     str_free(ntlm3_txt);
@@ -1372,8 +1372,8 @@ NOEXPORT char *ntlm3(char *domain,
     crypt_DES(phase3+ntlm_off+16, decoded+24, md4_hash+14);
     str_free(decoded);
 
-    strncpy((char *)phase3+domain_off, domain, domain_len);
-    strncpy((char *)phase3+user_off, user, user_len);
+    memcpy((char *)phase3+domain_off, domain, domain_len);
+    memcpy((char *)phase3+user_off, user, user_len);
 
     return base64(1, (char *)phase3, (int)end_off); /* encode */
 }
diff -pruN 3:5.44-1/src/prototypes.h 3:5.49-1/src/prototypes.h
--- 3:5.44-1/src/prototypes.h	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/src/prototypes.h	2018-08-19 07:10:47.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -43,6 +43,7 @@
 /**************************************** forward declarations */
 
 typedef struct tls_data_struct TLS_DATA;
+typedef struct sock_opt_struct SOCK_OPT;
 
 /**************************************** data structures */
 
@@ -98,8 +99,6 @@ typedef struct name_list_struct {
 typedef struct sockaddr_list {                          /* list of addresses */
     struct sockaddr_list *parent;   /* used by copies to locate their parent */
     SOCKADDR_UNION *addr;                     /* array of resolved addresses */
-    SOCKET *fd;                       /* array of accepting file descriptors */
-    SSL_SESSION **session;                /* array of cached client sessions */
     unsigned start;              /* initial address for round-robin failover */
     unsigned num;                             /* how many addresses are used */
     int passive;                                         /* listening socket */
@@ -180,12 +179,14 @@ typedef struct service_options_struct {
     struct service_options_struct *next;   /* next node in the services list */
     SSL_CTX *ctx;                                            /*  TLS context */
     char *servname;        /* service name for logging & permission checking */
+    int ref;                   /* reference counter for delayed deallocation */
 
         /* service-specific data for stunnel.c */
 #ifndef USE_WIN32
     uid_t uid;
     gid_t gid;
 #endif
+    int bound_ports;                /* number of ports bound to this service */
 
         /* service-specific data for log.c */
     int log_level;                                /* debug level for logging */
@@ -196,6 +197,9 @@ typedef struct service_options_struct {
     size_t stack_size;                         /* stack size for this thread */
 #endif
 
+        /* some global data for network.c */
+    SOCK_OPT *sock_opts;
+
         /* service-specific data for verify.c */
     char *ca_dir;                              /* directory for hashed certs */
     char *ca_file;                       /* file containing bunches of certs */
@@ -238,7 +242,6 @@ typedef struct service_options_struct {
 #endif /* !defined(OPENSSL_NO_ENGINE) */
 
         /* service-specific data for client.c */
-    SSL_SESSION *session;                           /* recently used session */
     char *exec_name;                          /* program name for local mode */
 #ifdef USE_WIN32
     char *exec_args;                     /* program arguments for local mode */
@@ -247,12 +250,15 @@ typedef struct service_options_struct {
 #endif
     SOCKADDR_UNION source_addr;
     SOCKADDR_LIST local_addr, connect_addr, redirect_addr;
+    SOCKET *local_fd;                 /* array of accepting file descriptors */
+    SSL_SESSION **connect_session;   /* per-destination client session cache */
+    SSL_SESSION *session;    /* previous client session for delayed resolver */
     int timeout_busy;                       /* maximum waiting for data time */
     int timeout_close;                          /* maximum close_notify time */
     int timeout_connect;                           /* maximum connect() time */
     int timeout_idle;                        /* maximum idle connection time */
     enum {FAILOVER_RR, FAILOVER_PRIO} failover;         /* failover strategy */
-    unsigned seq;              /* sequential number for round-robin failover */
+    unsigned rr;   /* per-service sequential number for round-robin failover */
     char *username;
 
         /* service-specific data for protocol.c */
@@ -285,9 +291,6 @@ typedef struct service_options_struct {
         unsigned local:1;               /* outgoing interface specified */
         unsigned retry:1;               /* loop remote+program */
         unsigned sessiond:1;
-#ifndef OPENSSL_NO_TLSEXT
-        unsigned sni:1;                 /* endpoint: sni */
-#endif /* !defined(OPENSSL_NO_TLSEXT) */
 #ifndef USE_WIN32
         unsigned pty:1;
         unsigned transparent_src:1;
@@ -329,13 +332,13 @@ typedef union {
     struct timeval timeval_val;
 } OPT_UNION;
 
-typedef struct {
+struct sock_opt_struct {
     char *opt_str;
     int  opt_level;
     int  opt_name;
     VAL_TYPE opt_type;
     OPT_UNION *opt_val[3];
-} SOCK_OPT;
+};
 
 typedef enum {
     CONF_RELOAD, CONF_FILE, CONF_FD
@@ -380,39 +383,41 @@ typedef enum {
 } RENEG_STATE;
 
 typedef struct {
-    jmp_buf err; /* 64-bit platforms require jmp_buf to be 16-byte aligned */
-    SSL *ssl; /* TLS connection */
+    jmp_buf *exception_pointer;
+
+    SSL *ssl;                                              /* TLS connection */
     SERVICE_OPTIONS *opt;
     TLS_DATA *tls;
 
-    SOCKADDR_UNION peer_addr; /* peer address */
+    SOCKADDR_UNION peer_addr;                                /* peer address */
     socklen_t peer_addr_len;
-    SOCKADDR_UNION *bind_addr; /* address to bind() the socket */
-    SOCKADDR_LIST connect_addr; /* either copied or resolved dynamically */
-    unsigned idx; /* actually connected address in connect_addr */
-    FD local_rfd, local_wfd; /* read and write local descriptors */
-    FD remote_fd; /* remote file descriptor */
-        /* IP for explicit local bind or transparent proxy */
-    unsigned long pid; /* PID of the local process */
-    SOCKET fd; /* temporary file descriptor */
-    RENEG_STATE reneg_state; /* used to track renegotiation attempts */
-    unsigned long long seq; /* sequential thread number for logging */
+    char *accepted_address;    /* textual representation of the peer address */
+    SOCKADDR_UNION *bind_addr;               /* address to bind() the socket */
+    SOCKADDR_LIST connect_addr;     /* either copied or resolved dynamically */
+    unsigned idx;              /* actually connected address in connect_addr */
+    FD local_rfd, local_wfd;             /* read and write local descriptors */
+    FD remote_fd;                                  /* remote file descriptor */
+    unsigned long pid;                           /* PID of the local process */
+    SOCKET fd;                                  /* temporary file descriptor */
+    RENEG_STATE reneg_state;         /* used to track renegotiation attempts */
+    unsigned long long seq;          /* sequential thread number for logging */
+    unsigned rr;    /* per-client sequential number for round-robin failover */
 
     /* data for transfer() function */
-    char sock_buff[BUFFSIZE]; /* socket read buffer */
-    char ssl_buff[BUFFSIZE]; /* TLS read buffer */
-    size_t sock_ptr, ssl_ptr; /* index of the first unused byte */
-    FD *sock_rfd, *sock_wfd; /* read and write socket descriptors */
-    FD *ssl_rfd, *ssl_wfd; /* read and write TLS descriptors */
-    uint64_t sock_bytes, ssl_bytes; /* bytes written to socket and TLS */
-    s_poll_set *fds; /* file descriptors */
+    char sock_buff[BUFFSIZE];                          /* socket read buffer */
+    char ssl_buff[BUFFSIZE];                              /* TLS read buffer */
+    size_t sock_ptr, ssl_ptr;              /* index of the first unused byte */
+    FD *sock_rfd, *sock_wfd;            /* read and write socket descriptors */
+    FD *ssl_rfd, *ssl_wfd;                 /* read and write TLS descriptors */
+    uint64_t sock_bytes, ssl_bytes;       /* bytes written to socket and TLS */
+    s_poll_set *fds;                                     /* file descriptors */
 } CLI;
 
 /**************************************** prototypes for stunnel.c */
 
 #ifndef USE_FORK
-extern long max_clients;
-extern volatile long num_clients;
+extern int max_clients;
+extern int num_clients;
 #endif
 
 void main_init(void);
@@ -422,9 +427,9 @@ int drop_privileges(int);
 void daemon_loop(void);
 void unbind_ports(void);
 int bind_ports(void);
-void signal_post(int);
+void signal_post(uint8_t);
 #if !defined(USE_WIN32) && !defined(USE_OS2)
-void child_status(void);  /* dead libwrap or 'exec' process detected */
+void pid_status_hang(const char *);
 #endif
 void stunnel_info(int);
 
@@ -437,6 +442,10 @@ int options_cmdline(char *, char *);
 int options_parse(CONF_TYPE);
 void options_defaults(void);
 void options_apply(void);
+void options_free(void);
+
+void service_up_ref(SERVICE_OPTIONS *);
+void service_free(SERVICE_OPTIONS *);
 
 /**************************************** prototypes for fd.c */
 
@@ -451,12 +460,11 @@ void set_nonblock(SOCKET, unsigned long)
 
 /**************************************** prototypes for log.c */
 
-#if !defined(USE_WIN32) && !defined(__vms)
-void syslog_open(void);
-void syslog_close(void);
-#endif
-int log_open(void);
-void log_close(void);
+#define SINK_SYSLOG 1
+#define SINK_OUTFILE 2
+
+int log_open(int);
+void log_close(int);
 void log_flush(LOG_MODE);
 void s_log(int, const char *, ...)
 #ifdef __GNUC__
@@ -465,12 +473,13 @@ void s_log(int, const char *, ...)
     ;
 #endif
 char *log_id(CLI *);
-void fatal_debug(char *, const char *, int);
+void fatal_debug(char *, const char *, int) NORETURN;
 #define fatal(a) fatal_debug((a), __FILE__, __LINE__)
 void ioerror(const char *);
 void sockerror(const char *);
 void log_error(int, int, const char *);
 char *s_strerror(int);
+void bin2hexstring(const unsigned char *, size_t, char *, size_t);
 
 /**************************************** prototypes for pty.c */
 
@@ -506,6 +515,7 @@ int context_init(SERVICE_OPTIONS *);
 void psk_sort(PSK_TABLE *, PSK_KEYS *);
 PSK_KEYS *psk_find(const PSK_TABLE *, const char *);
 #endif /* !defined(OPENSSL_NO_PSK) */
+void print_session_id(SSL_SESSION *);
 void sslerror(char *);
 
 /**************************************** prototypes for verify.c */
@@ -539,15 +549,21 @@ void s_poll_dump(s_poll_set *, int);
 #define SIGNAL_TERMINATE        SIGTERM
 #endif
 
-int set_socket_options(SOCKET, int);
+int socket_options_set(SERVICE_OPTIONS *, SOCKET, int);
 int make_sockets(SOCKET[2]);
 int original_dst(const SOCKET, SOCKADDR_UNION *);
 
 /**************************************** prototypes for client.c */
 
 CLI *alloc_client_session(SERVICE_OPTIONS *, SOCKET, SOCKET);
-void *client_thread(void *);
+#if defined(USE_WIN32) || defined(USE_OS2)
+unsigned __stdcall
+#else
+void *
+#endif
+client_thread(void *);
 void client_main(CLI *);
+void throw_exception(CLI *, int) NORETURN;
 
 /**************************************** prototypes for network.c */
 
@@ -616,7 +632,7 @@ const char *s_gai_strerror(int);
 #ifndef _WIN32_WCE
 typedef int (CALLBACK * GETADDRINFO) (const char *,
     const char *, const struct addrinfo *, struct addrinfo **);
-typedef void (CALLBACK * FREEADDRINFO) (struct addrinfo FAR *);
+typedef void (CALLBACK * FREEADDRINFO) (struct addrinfo *);
 typedef int (CALLBACK * GETNAMEINFO) (const struct sockaddr *, socklen_t,
     char *, size_t, char *, size_t, int);
 extern GETADDRINFO s_getaddrinfo;
@@ -634,6 +650,12 @@ int getnameinfo(const struct sockaddr *,
 /**************************************** prototypes for sthreads.c */
 
 #if defined(USE_PTHREAD) || defined(USE_WIN32)
+#define USE_OS_THREADS
+#endif
+
+#if OPENSSL_VERSION_NUMBER<0x10100004L
+
+#ifdef USE_OS_THREADS
 
 struct CRYPTO_dynlock_value {
 #ifdef USE_PTHREAD
@@ -643,14 +665,24 @@ struct CRYPTO_dynlock_value {
     CRITICAL_SECTION critical_section;
 #endif
     const char *init_file, *read_lock_file, *write_lock_file,
-        *read_unlock_file, *write_unlock_file, *destroy_file;
-    int init_line, read_lock_line, write_lock_line,
-        read_unlock_line, write_unlock_line, destroy_line;
+        *unlock_file, *destroy_file;
+    int init_line, read_lock_line, write_lock_line, unlock_line, destroy_line;
 };
 
+typedef struct CRYPTO_dynlock_value CRYPTO_RWLOCK;
+
+#else /* USE_OS_THREADS */
+
+typedef void CRYPTO_RWLOCK;
+
+#endif /* USE_OS_THREADS */
+
+#endif /* OPENSSL_VERSION_NUMBER<0x10100004L */
+
 typedef enum {
     LOCK_SESSION, LOCK_ADDR,
     LOCK_CLIENTS, LOCK_SSL,                 /* client.c */
+    LOCK_REF,                               /* options.c */
     LOCK_INET,                              /* resolver.c */
 #ifndef USE_WIN32
     LOCK_LIBWRAP,                           /* libwrap.c */
@@ -662,42 +694,23 @@ typedef enum {
 #endif /* OPENSSL_NO_DH */
     STUNNEL_LOCKS                           /* number of locks */
 } LOCK_TYPE;
-extern struct CRYPTO_dynlock_value stunnel_locks[STUNNEL_LOCKS];
 
-void stunnel_rwlock_init_debug(struct CRYPTO_dynlock_value *, const char *, int);
-void stunnel_read_lock_debug(struct CRYPTO_dynlock_value *, const char *, int);
-void stunnel_write_lock_debug(struct CRYPTO_dynlock_value *, const char *, int);
-void stunnel_read_unlock_debug(struct CRYPTO_dynlock_value *, const char *, int);
-void stunnel_write_unlock_debug(struct CRYPTO_dynlock_value *, const char *, int);
-void stunnel_rwlock_destroy_debug(struct CRYPTO_dynlock_value *, const char *, int);
-
-#define stunnel_rwlock_init(x) stunnel_rwlock_init_debug((x),__FILE__,__LINE__)
-#define stunnel_read_lock(x) stunnel_read_lock_debug((x),__FILE__,__LINE__)
-#define stunnel_write_lock(x) stunnel_write_lock_debug((x),__FILE__,__LINE__)
-#define stunnel_read_unlock(x) stunnel_read_unlock_debug((x),__FILE__,__LINE__)
-#define stunnel_write_unlock(x) stunnel_write_unlock_debug((x),__FILE__,__LINE__)
-#define stunnel_rwlock_destroy(x) stunnel_rwlock_destroy_debug((x),__FILE__,__LINE__)
+extern CRYPTO_RWLOCK *stunnel_locks[STUNNEL_LOCKS];
 
 #if OPENSSL_VERSION_NUMBER<0x10100004L
-#define CRYPTO_atomic_add(addr,amount,result,type) \
-    *result = type ? CRYPTO_add(addr,amount,type) : (*addr+=amount)
+/* Emulate the OpenSSL 1.1 locking API for older OpenSSL versions */
+CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void);
+int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *);
+int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *);
+int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *);
+void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *);
+int CRYPTO_atomic_add(int *, int, int *, CRYPTO_RWLOCK *);
 #endif
 
-#else /* defined(USE_PTHREAD) || defined(USE_WIN32) */
-
-#define stunnel_rwlock_init(x) {}
-#define stunnel_read_lock(x) {}
-#define stunnel_write_lock(x) {}
-#define stunnel_read_unlock(x) {}
-#define stunnel_write_unlock(x) {}
-#define stunnel_rwlock_destroy(x) {}
-
-#endif /* defined(USE_PTHREAD) || defined(USE_WIN32) */
-
 int sthreads_init(void);
 unsigned long stunnel_process_id(void);
 unsigned long stunnel_thread_id(void);
-int create_client(SOCKET, SOCKET, CLI *, void *(*)(void *));
+int create_client(SOCKET, SOCKET, CLI *);
 #ifdef USE_UCONTEXT
 typedef struct CONTEXT_STRUCTURE {
     char *stack; /* CPU stack for this thread */
@@ -739,7 +752,7 @@ LPSTR tstr2str(LPCTSTR);
 /**************************************** prototypes for libwrap.c */
 
 int libwrap_init();
-void libwrap_auth(CLI *, char *);
+void libwrap_auth(CLI *);
 
 /**************************************** prototypes for tls.c */
 
@@ -768,6 +781,8 @@ void str_init(TLS_DATA *);
 void str_cleanup(TLS_DATA *);
 char *str_dup_debug(const char *, const char *, int);
 #define str_dup(a) str_dup_debug((a), __FILE__, __LINE__)
+char *str_dup_detached_debug(const char *, const char *, int);
+#define str_dup_detached(a) str_dup_detached_debug((a), __FILE__, __LINE__)
 char *str_vprintf(const char *, va_list);
 char *str_printf(const char *, ...)
 #ifdef __GNUC__
@@ -785,15 +800,18 @@ void *str_alloc_debug(size_t, const char
 #define str_alloc(a) str_alloc_debug((a), __FILE__, __LINE__)
 void *str_alloc_detached_debug(size_t, const char *, int);
 #define str_alloc_detached(a) str_alloc_detached_debug((a), __FILE__, __LINE__)
-void *str_realloc_detached_debug(void *, size_t, const char *, int);
 void *str_realloc_debug(void *, size_t, const char *, int);
 #define str_realloc(a, b) str_realloc_debug((a), (b), __FILE__, __LINE__)
+void *str_realloc_detached_debug(void *, size_t, const char *, int);
+#define str_realloc_detached(a, b) str_realloc_detached_debug((a), (b), __FILE__, __LINE__)
 void str_detach_debug(void *, const char *, int);
 #define str_detach(a) str_detach_debug((a), __FILE__, __LINE__)
 void str_free_debug(void *, const char *, int);
 #define str_free(a) str_free_debug((a), __FILE__, __LINE__), (a)=NULL
 #define str_free_expression(a) str_free_debug((a), __FILE__, __LINE__)
 
+void leak_table_utilization(void);
+
 int safe_memcmp(const void *, const void *, size_t);
 
 /**************************************** prototypes for ui_*.c */
diff -pruN 3:5.44-1/src/pty.c 3:5.49-1/src/pty.c
--- 3:5.44-1/src/pty.c	2017-01-02 14:27:26.000000000 +0000
+++ 3:5.49-1/src/pty.c	2018-04-06 14:25:10.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
diff -pruN 3:5.44-1/src/resolver.c 3:5.49-1/src/resolver.c
--- 3:5.44-1/src/resolver.c	2017-10-16 18:38:47.000000000 +0000
+++ 3:5.49-1/src/resolver.c	2018-07-02 21:30:10.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -106,6 +106,11 @@ void resolver_init() {
 }
 
 #if defined(USE_WIN32) && !defined(_WIN32_WCE)
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas"
+#pragma GCC diagnostic ignored "-Wcast-function-type"
+#endif /* __GNUC__ */
 NOEXPORT int get_ipv6(LPTSTR file) {
     HINSTANCE handle;
 
@@ -124,6 +129,9 @@ NOEXPORT int get_ipv6(LPTSTR file) {
     }
     return 1; /* IPv6 detected -> OK */
 }
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif /* __GNUC__ */
 #endif
 
 /**************************************** stunnel resolver API */
@@ -138,8 +146,6 @@ unsigned name2addr(SOCKADDR_UNION *addr,
     if(retval)
         addrlist2addr(addr, addr_list);
     str_free(addr_list->addr);
-    str_free(addr_list->fd);
-    str_free(addr_list->session);
     str_free(addr_list);
     return retval;
 }
@@ -155,8 +161,6 @@ unsigned hostport2addr(SOCKADDR_UNION *a
     if(num)
         addrlist2addr(addr, addr_list);
     str_free(addr_list->addr);
-    str_free(addr_list->fd);
-    str_free(addr_list->session);
     str_free(addr_list);
     return num;
 }
@@ -194,16 +198,10 @@ unsigned name2addrlist(SOCKADDR_LIST *ad
             s_log(LOG_ERR, "Unix socket path is too long");
             return 0; /* no results */
         }
-        addr_list->addr=str_realloc(addr_list->addr,
+        addr_list->addr=str_realloc_detached(addr_list->addr,
             (addr_list->num+1)*sizeof(SOCKADDR_UNION));
         addr_list->addr[addr_list->num].un.sun_family=AF_UNIX;
         strcpy(addr_list->addr[addr_list->num].un.sun_path, name);
-        addr_list->fd=str_realloc(addr_list->fd,
-            (addr_list->num+1)*sizeof(SOCKET));
-        addr_list->fd[addr_list->num]=INVALID_SOCKET;
-        addr_list->session=str_realloc(addr_list->session,
-            (addr_list->num+1)*sizeof(SSL_SESSION *));
-        addr_list->session[addr_list->num]=NULL;
         ++(addr_list->num);
         return 1; /* ok - return the number of new addresses */
     }
@@ -228,9 +226,9 @@ unsigned name2addrlist(SOCKADDR_LIST *ad
 
 unsigned hostport2addrlist(SOCKADDR_LIST *addr_list,
         char *host_name, char *port_name) {
-    struct addrinfo hints, *res=NULL, *cur;
+    struct addrinfo hints, *res, *cur;
     int err, retry=0;
-    unsigned num=0;
+    unsigned num;
 
     memset(&hints, 0, sizeof hints);
 #if defined(USE_IPv6) || defined(USE_WIN32)
@@ -241,19 +239,20 @@ unsigned hostport2addrlist(SOCKADDR_LIST
     hints.ai_socktype=SOCK_STREAM;
     hints.ai_protocol=IPPROTO_TCP;
     hints.ai_flags=0;
-    if(addr_list->passive) {
-        hints.ai_family=AF_INET; /* first try IPv4 for passive requests */
+    if(addr_list->passive)
         hints.ai_flags|=AI_PASSIVE;
-    }
 #ifdef AI_ADDRCONFIG
     hints.ai_flags|=AI_ADDRCONFIG;
 #endif
     for(;;) {
+        res=NULL;
         err=getaddrinfo(host_name, port_name, &hints, &res);
-        if(!err)
+        if(!err) /* success */
             break;
-        if(res)
-            freeaddrinfo(res);
+        if(err==EAI_SERVICE) {
+            s_log(LOG_ERR, "Unknown TCP service \"%s\"", port_name);
+            return 0; /* error */
+        }
         if(err==EAI_AGAIN && ++retry<=3) {
             s_log(LOG_DEBUG, "getaddrinfo: EAI_AGAIN received: retrying");
             sleep(1);
@@ -265,19 +264,6 @@ unsigned hostport2addrlist(SOCKADDR_LIST
             continue; /* retry for unconfigured network interfaces */
         }
 #endif
-#if defined(USE_IPv6) || defined(USE_WIN32)
-        if(hints.ai_family==AF_INET) {
-            hints.ai_family=AF_UNSPEC;
-            continue; /* retry for non-IPv4 addresses */
-        }
-#endif
-        break;
-    }
-    if(err==EAI_SERVICE) {
-        s_log(LOG_ERR, "Unknown TCP service \"%s\"", port_name);
-        return 0; /* error */
-    }
-    if(err) {
         s_log(LOG_ERR, "Error resolving \"%s\": %s",
             host_name ? host_name :
                 (addr_list->passive ? DEFAULT_ANY : DEFAULT_LOOPBACK),
@@ -285,26 +271,24 @@ unsigned hostport2addrlist(SOCKADDR_LIST
         return 0; /* error */
     }
 
-    /* copy the list of addresses */
+    /* find the number of newly resolved addresses */
+    num=0;
     for(cur=res; cur; cur=cur->ai_next) {
         if(cur->ai_addrlen>(int)sizeof(SOCKADDR_UNION)) {
             s_log(LOG_ERR, "INTERNAL ERROR: ai_addrlen value too big");
             freeaddrinfo(res);
             return 0; /* no results */
         }
-        addr_list->addr=str_realloc(addr_list->addr,
-            (addr_list->num+1)*sizeof(SOCKADDR_UNION));
-        memcpy(&addr_list->addr[addr_list->num], cur->ai_addr,
-            (size_t)cur->ai_addrlen);
-        addr_list->fd=str_realloc(addr_list->fd,
-            (addr_list->num+1)*sizeof(SOCKET));
-        addr_list->fd[addr_list->num]=INVALID_SOCKET;
-        addr_list->session=str_realloc(addr_list->session,
-            (addr_list->num+1)*sizeof(SSL_SESSION *));
-        addr_list->session[addr_list->num]=NULL;
-        ++(addr_list->num);
         ++num;
     }
+
+    /* append the newly resolved addresses to addr_list->addr */
+    addr_list->addr=str_realloc_detached(addr_list->addr,
+        (addr_list->num+num)*sizeof(SOCKADDR_UNION));
+    for(cur=res; cur; cur=cur->ai_next)
+        memcpy(&addr_list->addr[(addr_list->num)++], cur->ai_addr,
+            (size_t)cur->ai_addrlen);
+
     freeaddrinfo(res);
     return num; /* ok - return the number of new addresses */
 }
@@ -320,8 +304,6 @@ void addrlist_clear(SOCKADDR_LIST *addr_
 NOEXPORT void addrlist_reset(SOCKADDR_LIST *addr_list) {
     addr_list->num=0;
     addr_list->addr=NULL;
-    addr_list->fd=NULL;
-    addr_list->session=NULL;
     addr_list->start=0;
     addr_list->parent=addr_list; /* allow a copy to locate its parent */
 }
@@ -329,13 +311,11 @@ NOEXPORT void addrlist_reset(SOCKADDR_LI
 unsigned addrlist_dup(SOCKADDR_LIST *dst, const SOCKADDR_LIST *src) {
     memcpy(dst, src, sizeof(SOCKADDR_LIST));
     if(src->num) { /* already resolved */
-        dst->addr=str_alloc(src->num*sizeof(SOCKADDR_UNION));
+        dst->addr=str_alloc_detached(src->num*sizeof(SOCKADDR_UNION));
         memcpy(dst->addr, src->addr, src->num*sizeof(SOCKADDR_UNION));
     } else { /* delayed resolver */
         addrlist_resolve(dst);
     }
-    /* a client does not have its own local copy of
-       src->session and src->fd */
     return dst->num;
 }
 
@@ -459,7 +439,7 @@ NOEXPORT int getaddrinfo(const char *nod
     /* not numerical: need to call resolver library */
     *res=NULL;
     ai=NULL;
-    stunnel_write_lock(&stunnel_locks[LOCK_INET]);
+    CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_INET]);
 #ifdef HAVE_GETHOSTBYNAME2
     h=gethostbyname2(node, AF_INET6);
     if(h) /* some IPv6 addresses found */
@@ -477,7 +457,7 @@ NOEXPORT int getaddrinfo(const char *nod
 #ifdef HAVE_ENDHOSTENT
     endhostent();
 #endif
-    stunnel_write_unlock(&stunnel_locks[LOCK_INET]);
+    CRYPTO_THREAD_unlock(stunnel_locks[LOCK_INET]);
     if(retval) { /* error: free allocated memory */
         freeaddrinfo(*res);
         *res=NULL;
@@ -612,10 +592,11 @@ int getnameinfo(const struct sockaddr *s
                 (void *)&((struct sockaddr_in *)sa)->sin_addr,
             host, hostlen);
 #else /* USE_IPv6 */
-        stunnel_write_lock(&stunnel_locks[LOCK_INET]); /* inet_ntoa is not mt-safe */
+        /* inet_ntoa is not mt-safe */
+        CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_INET]);
         strncpy(host, inet_ntoa(((struct sockaddr_in *)sa)->sin_addr),
             hostlen);
-        stunnel_write_unlock(&stunnel_locks[LOCK_INET]);
+        CRYPTO_THREAD_unlock(stunnel_locks[LOCK_INET]);
         host[hostlen-1]='\0';
 #endif /* USE_IPv6 */
     }
diff -pruN 3:5.44-1/src/resources.rc 3:5.49-1/src/resources.rc
--- 3:5.44-1/src/resources.rc	2017-01-02 14:27:26.000000000 +0000
+++ 3:5.49-1/src/resources.rc	2018-04-06 14:25:10.000000000 +0000
@@ -19,7 +19,7 @@ BEGIN
             VALUE "FileDescription",    "stunnel - TLS offloading and load-balancing proxy"
             VALUE "FileVersion",        STUNNEL_VERSION
             VALUE "InternalName",       "stunnel"
-            VALUE "LegalCopyright",     " by Michal Trojnara, 1998-2017"
+            VALUE "LegalCopyright",     " by Michal Trojnara, 1998-2018"
             VALUE "OriginalFilename",   "stunnel.exe"
             VALUE "ProductName",        STUNNEL_PRODUCTNAME
             VALUE "ProductVersion",     STUNNEL_VERSION
@@ -104,7 +104,7 @@ BEGIN
     ICON            IDI_STUNNEL_MAIN, -1,                        6,  6,  20, 20
     LTEXT           "stunnel version", -1,                      30,  4,  49,  8
     LTEXT           STUNNEL_VERSION, -1,                        79,  4,  57,  8
-    LTEXT           " by Michal Trojnara, 1998-2017", -1,      30, 12, 106,  8
+    LTEXT           " by Michal Trojnara, 1998-2018", -1,      30, 12, 106,  8
     LTEXT           "All Rights Reserved", -1,                  30, 20, 106,  8
     LTEXT           "Licensed under the GNU GPL version 2", -1,  4, 28, 132,  8
     LTEXT           "with a special exception for OpenSSL", -1,  4, 36, 132,  8
diff -pruN 3:5.44-1/src/ssl.c 3:5.49-1/src/ssl.c
--- 3:5.44-1/src/ssl.c	2017-10-07 14:23:08.000000000 +0000
+++ 3:5.49-1/src/ssl.c	2018-08-26 18:26:52.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -39,13 +39,21 @@
 #include "prototypes.h"
 
     /* global OpenSSL initialization: compression, engine, entropy */
-NOEXPORT void cb_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+#if OPENSSL_VERSION_NUMBER>=0x10100000L
+NOEXPORT int cb_dup_addr(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
+    void *from_d, int idx, long argl, void *argp);
+#else
+NOEXPORT int cb_dup_addr(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from,
+    void *from_d, int idx, long argl, void *argp);
+#endif
+NOEXPORT void cb_free_addr(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
     int idx, long argl, void *argp);
 #ifndef OPENSSL_NO_COMP
 NOEXPORT int compression_init(GLOBAL_OPTIONS *);
 #endif
 NOEXPORT int prng_init(GLOBAL_OPTIONS *);
 NOEXPORT int add_rand_file(GLOBAL_OPTIONS *, const char *);
+NOEXPORT void update_rand_file(const char *);
 
 int index_ssl_cli, index_ssl_ctx_opt;
 int index_session_authenticated, index_session_connect_address;
@@ -66,7 +74,7 @@ int ssl_init(void) { /* init TLS before
     index_session_authenticated=SSL_SESSION_get_ex_new_index(0,
         "session authenticated", NULL, NULL, NULL);
     index_session_connect_address=SSL_SESSION_get_ex_new_index(0,
-        "session connect address", NULL, NULL, cb_free);
+        "session connect address", NULL, cb_dup_addr, cb_free_addr);
     if(index_ssl_cli<0 || index_ssl_ctx_opt<0 ||
             index_session_authenticated<0 ||
             index_session_connect_address<0) {
@@ -106,7 +114,31 @@ int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNU
 #endif
 #endif
 
-NOEXPORT void cb_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+#if OPENSSL_VERSION_NUMBER>=0x10100000L
+NOEXPORT int cb_dup_addr(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
+        void *from_d, int idx, long argl, void *argp) {
+#else
+NOEXPORT int cb_dup_addr(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from,
+        void *from_d, int idx, long argl, void *argp) {
+#endif
+    SOCKADDR_UNION *src, *dst;
+    socklen_t len;
+
+    (void)to; /* squash the unused parameter warning */
+    (void)from; /* squash the unused parameter warning */
+    (void)idx; /* squash the unused parameter warning */
+    (void)argl; /* squash the unused parameter warning */
+    s_log(LOG_DEBUG, "Duplicating application specific data for %s",
+        (char *)argp);
+    src=*(void **)from_d;
+    len=addr_len(src);
+    dst=str_alloc_detached((size_t)len);
+    memcpy(dst, src, (size_t)len);
+    *(void **)from_d=dst;
+    return 1;
+}
+
+NOEXPORT void cb_free_addr(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
         int idx, long argl, void *argp) {
     (void)parent; /* squash the unused parameter warning */
     (void)ad; /* squash the unused parameter warning */
@@ -140,13 +172,30 @@ int ssl_configure(GLOBAL_OPTIONS *global
 #endif /* OPENSSL_NO_COMP */
     if(prng_init(global))
         return 1;
-    s_log(LOG_DEBUG, "PRNG seeded successfully");
     return 0; /* SUCCESS */
 }
 
 #ifndef OPENSSL_NO_COMP
+
+#if OPENSSL_VERSION_NUMBER<0x10100000L
+
+NOEXPORT int COMP_get_type(const COMP_METHOD *meth) {
+    return meth->type;
+}
+
+NOEXPORT const char *SSL_COMP_get0_name(const SSL_COMP *comp) {
+    return comp->name;
+}
+
+NOEXPORT int SSL_COMP_get_id(const SSL_COMP *comp) {
+    return comp->id;
+}
+
+#endif /* OPENSSL_VERSION_NUMBER<0x10100000L */
+
 NOEXPORT int compression_init(GLOBAL_OPTIONS *global) {
     STACK_OF(SSL_COMP) *methods;
+    int num_methods, i;
 
     methods=SSL_COMP_get_compression_methods();
     if(!methods) {
@@ -159,40 +208,51 @@ NOEXPORT int compression_init(GLOBAL_OPT
         }
     }
 
-    if(global->compression==COMP_NONE ||
-            OpenSSL_version_num()<0x00908051L /* 0.9.8e-beta1 */) {
+    if(global->compression==COMP_NONE) {
         /* delete OpenSSL defaults (empty the SSL_COMP stack) */
         /* cannot use sk_SSL_COMP_pop_free,
          * as it also destroys the stack itself */
         /* only leave the standard RFC 1951 (DEFLATE) algorithm,
          * if any of the private algorithms is enabled */
-        /* only allow DEFLATE with OpenSSL 0.9.8 or later
-         * with OpenSSL #1468 zlib memory leak fixed */
         while(sk_SSL_COMP_num(methods))
             OPENSSL_free(sk_SSL_COMP_pop(methods));
-    }
-
-    if(global->compression==COMP_NONE) {
         s_log(LOG_DEBUG, "Compression disabled");
         return 0; /* success */
     }
 
+    if(!sk_SSL_COMP_num(methods)) {
+        s_log(LOG_ERR, "No compression method is available");
+        return 1;
+    }
+
     /* also insert the obsolete ZLIB algorithm */
     if(global->compression==COMP_ZLIB) {
         /* 224 - within the private range (193 to 255) */
         COMP_METHOD *meth=COMP_zlib();
-#if OPENSSL_VERSION_NUMBER>=0x10100000L
         if(!meth || COMP_get_type(meth)==NID_undef) {
-#else
-        if(!meth || meth->type==NID_undef) {
-#endif
             s_log(LOG_ERR, "ZLIB compression is not supported");
             return 1;
         }
-        SSL_COMP_add_compression_method(0xe0, meth);
+        if(SSL_COMP_add_compression_method(0xe0, meth)) {
+            sslerror("SSL_COMP_add_compression_method");
+            return 1;
+        }
+    }
+
+    num_methods=sk_SSL_COMP_num(methods);
+    s_log(LOG_INFO, "Compression enabled: %d method%s",
+        num_methods, num_methods==1 ? "" : "s");
+    for(i=0; i<num_methods; ++i) {
+        SSL_COMP *comp=sk_SSL_COMP_value(methods, i);
+        if(comp) {
+            const char *name=SSL_COMP_get0_name(comp);
+            /* see OpenSSL commit 847406923534dd791f73d0cda15d3f17f513f2a5 */
+            if(!name)
+                name="unknown";
+            s_log(LOG_INFO, "Compression id 0x%02x: %s",
+                SSL_COMP_get_id(comp), name);
+        }
     }
-    s_log(LOG_INFO, "Compression enabled: %d method(s)",
-        sk_SSL_COMP_num(methods));
     return 0; /* success */
 }
 #endif /* OPENSSL_NO_COMP */
@@ -201,7 +261,10 @@ NOEXPORT int prng_init(GLOBAL_OPTIONS *g
     int totbytes=0;
     char filename[256];
 
-    filename[0]='\0';
+    if(RAND_status()) {
+        s_log(LOG_DEBUG, "No PRNG seeding was required");
+        return 0; /* success */
+    }
 
     /* if they specify a rand file on the command line we
        assume that they really do want it, so try it first */
@@ -212,46 +275,47 @@ NOEXPORT int prng_init(GLOBAL_OPTIONS *g
     }
 
     /* try the $RANDFILE or $HOME/.rnd files */
-    RAND_file_name(filename, 256);
+    filename[0]='\0';
+    RAND_file_name(filename, sizeof filename);
     if(filename[0]) {
         totbytes+=add_rand_file(global, filename);
         if(RAND_status())
             return 0; /* success */
     }
 
-#ifdef RANDOM_FILE
-    totbytes+=add_rand_file(global, RANDOM_FILE);
-    if(RAND_status())
-        return 0; /* success */
-#endif
-
 #ifdef USE_WIN32
+
+#if OPENSSL_VERSION_NUMBER<0x10100000L
     RAND_screen();
     if(RAND_status()) {
         s_log(LOG_DEBUG, "Seeded PRNG with RAND_screen");
         return 0; /* success */
     }
     s_log(LOG_DEBUG, "RAND_screen failed to sufficiently seed PRNG");
-#else
+#endif
+
+#else /* USE_WIN32 */
+
 #ifndef OPENSSL_NO_EGD
     if(global->egd_sock) {
         int bytes=RAND_egd(global->egd_sock);
-        if(bytes==-1) {
-            s_log(LOG_WARNING, "EGD Socket %s failed", global->egd_sock);
-            bytes=0;
-        } else {
-            totbytes+=bytes;
+        if(bytes>=0) {
             s_log(LOG_DEBUG, "Snagged %d random bytes from EGD Socket %s",
                 bytes, global->egd_sock);
             return 0; /* OpenSSL always gets what it needs or fails,
                          so no need to check if seeded sufficiently */
         }
+        s_log(LOG_WARNING, "EGD Socket %s failed", global->egd_sock);
     }
 #endif
-    /* try the good-old default /dev/urandom, if available  */
+
+#ifndef RANDOM_FILE
+    /* try the good-old default /dev/urandom, if no RANDOM_FILE is defined */
     totbytes+=add_rand_file(global, "/dev/urandom");
     if(RAND_status())
         return 0; /* success */
+#endif
+
 #endif /* USE_WIN32 */
 
     /* random file specified during configure */
@@ -262,28 +326,39 @@ NOEXPORT int prng_init(GLOBAL_OPTIONS *g
 
 NOEXPORT int add_rand_file(GLOBAL_OPTIONS *global, const char *filename) {
     int readbytes;
-    int writebytes;
     struct stat sb;
 
     if(stat(filename, &sb))
         return 0; /* could not stat() file --> return 0 bytes */
-    if((readbytes=RAND_load_file(filename, global->random_bytes)))
-        s_log(LOG_DEBUG, "Snagged %d random bytes from %s",
-            readbytes, filename);
-    else
+
+    readbytes=RAND_load_file(filename, global->random_bytes);
+    if(readbytes<0) {
+        sslerror("RAND_load_file");
         s_log(LOG_INFO, "Cannot retrieve any random data from %s",
             filename);
-    /* write new random data for future seeding if it's a regular file */
-    if(global->option.rand_write && S_ISREG(sb.st_mode)) {
-        writebytes=RAND_write_file(filename);
-        if(writebytes==-1)
-            s_log(LOG_WARNING, "Failed to write strong random data to %s - "
-                "may be a permissions or seeding problem", filename);
-        else
-            s_log(LOG_DEBUG, "Wrote %d new random bytes to %s",
-                writebytes, filename);
+        return 0;
     }
+    s_log(LOG_DEBUG, "Snagged %d random bytes from %s", readbytes, filename);
+
+    /* write new random data for future seeding if it's a regular file */
+    if(global->option.rand_write && S_ISREG(sb.st_mode))
+        update_rand_file(filename);
+
     return readbytes;
 }
 
+NOEXPORT void update_rand_file(const char *filename) {
+    int writebytes;
+
+    writebytes=RAND_write_file(filename);
+    if(writebytes<0) {
+        sslerror("RAND_write_file");
+        s_log(LOG_WARNING, "Failed to write strong random data to %s - "
+            "may be a permissions or seeding problem", filename);
+        return;
+    }
+    s_log(LOG_DEBUG, "Wrote %d new random bytes to %s",
+        writebytes, filename);
+}
+
 /* end of ssl.c */
diff -pruN 3:5.44-1/src/sthreads.c 3:5.49-1/src/sthreads.c
--- 3:5.44-1/src/sthreads.c	2017-08-17 09:18:53.000000000 +0000
+++ 3:5.49-1/src/sthreads.c	2018-07-02 21:30:10.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -114,44 +114,40 @@ void thread_id_init(void) {
 
 /**************************************** locking */
 
+/* we only need to initialize locking with OpenSSL older than 1.1.0 */
+#if OPENSSL_VERSION_NUMBER<0x10100004L
+
 #ifdef USE_PTHREAD
 
-void stunnel_rwlock_init_debug(struct CRYPTO_dynlock_value *lock,
+NOEXPORT void s_lock_init_debug(struct CRYPTO_dynlock_value *lock,
         const char *file, int line) {
     pthread_rwlock_init(&lock->rwlock, NULL);
     lock->init_file=file;
     lock->init_line=line;
 }
 
-void stunnel_read_lock_debug(struct CRYPTO_dynlock_value *lock,
+NOEXPORT void s_read_lock_debug(struct CRYPTO_dynlock_value *lock,
         const char *file, int line) {
     pthread_rwlock_rdlock(&lock->rwlock);
     lock->read_lock_file=file;
     lock->read_lock_line=line;
 }
 
-void stunnel_write_lock_debug(struct CRYPTO_dynlock_value *lock,
+NOEXPORT void s_write_lock_debug(struct CRYPTO_dynlock_value *lock,
         const char *file, int line) {
     pthread_rwlock_wrlock(&lock->rwlock);
     lock->write_lock_file=file;
     lock->write_lock_line=line;
 }
 
-void stunnel_read_unlock_debug(struct CRYPTO_dynlock_value *lock,
+NOEXPORT void s_unlock_debug(struct CRYPTO_dynlock_value *lock,
         const char *file, int line) {
     pthread_rwlock_unlock(&lock->rwlock);
-    lock->read_unlock_file=file;
-    lock->read_unlock_line=line;
+    lock->unlock_file=file;
+    lock->unlock_line=line;
 }
 
-void stunnel_write_unlock_debug(struct CRYPTO_dynlock_value *lock,
-        const char *file, int line) {
-    pthread_rwlock_unlock(&lock->rwlock);
-    lock->write_unlock_file=file;
-    lock->write_unlock_line=line;
-}
-
-void stunnel_rwlock_destroy_debug(struct CRYPTO_dynlock_value *lock,
+NOEXPORT void s_lock_destroy_debug(struct CRYPTO_dynlock_value *lock,
         const char *file, int line) {
     pthread_rwlock_destroy(&lock->rwlock);
     lock->destroy_file=file;
@@ -167,42 +163,35 @@ void stunnel_rwlock_destroy_debug(struct
  * but it is unsupported on Windows XP (and earlier versions of Windows):
  * https://msdn.microsoft.com/en-us/library/windows/desktop/aa904937%28v=vs.85%29.aspx */
 
-void stunnel_rwlock_init_debug(struct CRYPTO_dynlock_value *lock,
+NOEXPORT void s_lock_init_debug(struct CRYPTO_dynlock_value *lock,
         const char *file, int line) {
     InitializeCriticalSection(&lock->critical_section);
     lock->init_file=file;
     lock->init_line=line;
 }
 
-void stunnel_read_lock_debug(struct CRYPTO_dynlock_value *lock,
+NOEXPORT void s_read_lock_debug(struct CRYPTO_dynlock_value *lock,
         const char *file, int line) {
     EnterCriticalSection(&lock->critical_section);
     lock->read_lock_file=file;
     lock->read_lock_line=line;
 }
 
-void stunnel_write_lock_debug(struct CRYPTO_dynlock_value *lock,
+NOEXPORT void s_write_lock_debug(struct CRYPTO_dynlock_value *lock,
         const char *file, int line) {
     EnterCriticalSection(&lock->critical_section);
     lock->write_lock_file=file;
     lock->write_lock_line=line;
 }
 
-void stunnel_read_unlock_debug(struct CRYPTO_dynlock_value *lock,
+NOEXPORT void s_unlock_debug(struct CRYPTO_dynlock_value *lock,
         const char *file, int line) {
     LeaveCriticalSection(&lock->critical_section);
-    lock->read_unlock_file=file;
-    lock->read_unlock_line=line;
+    lock->unlock_file=file;
+    lock->unlock_line=line;
 }
 
-void stunnel_write_unlock_debug(struct CRYPTO_dynlock_value *lock,
-        const char *file, int line) {
-    LeaveCriticalSection(&lock->critical_section);
-    lock->write_unlock_file=file;
-    lock->write_unlock_line=line;
-}
-
-void stunnel_rwlock_destroy_debug(struct CRYPTO_dynlock_value *lock,
+NOEXPORT void s_lock_destroy_debug(struct CRYPTO_dynlock_value *lock,
         const char *file, int line) {
     DeleteCriticalSection(&lock->critical_section);
     lock->destroy_file=file;
@@ -212,81 +201,162 @@ void stunnel_rwlock_destroy_debug(struct
 
 #endif /* USE_WIN32 */
 
-#if defined(USE_PTHREAD) || defined(USE_WIN32)
-
-struct CRYPTO_dynlock_value stunnel_locks[STUNNEL_LOCKS];
+NOEXPORT int s_atomic_add(int *val, int amount, CRYPTO_RWLOCK *lock) {
+    int ret;
 
-#if OPENSSL_VERSION_NUMBER<0x10100004L
-#define CRYPTO_THREAD_lock_new() CRYPTO_get_new_dynlockid()
+    (void)lock; /* squash the unused parameter warning */
+#if !defined(USE_OS_THREADS)
+    /* no synchronization is needed */
+    return *val+=amount;
+#elif defined(__GNUC__) && defined(__ATOMIC_ACQ_REL)
+    if(__atomic_is_lock_free(sizeof *val, val))
+        return __atomic_add_fetch(val, amount, __ATOMIC_ACQ_REL);
+#elif defined(_MSC_VER)
+    return InterlockedExchangeAdd(val, amount)+amount;
 #endif
+    CRYPTO_THREAD_write_lock(lock);
+    ret=(*val+=amount);
+    CRYPTO_THREAD_unlock(lock);
+    return ret;
+}
+
+#endif /* OPENSSL_VERSION_NUMBER<0x10100004L */
+
+CRYPTO_RWLOCK *stunnel_locks[STUNNEL_LOCKS];
 
 #if OPENSSL_VERSION_NUMBER<0x10100004L
 
+#ifdef USE_OS_THREADS
+
 static struct CRYPTO_dynlock_value *lock_cs;
 
-NOEXPORT struct CRYPTO_dynlock_value *dyn_create_function(const char *file,
+NOEXPORT struct CRYPTO_dynlock_value *s_dynlock_create_cb(const char *file,
         int line) {
     struct CRYPTO_dynlock_value *lock;
 
     lock=str_alloc_detached(sizeof(struct CRYPTO_dynlock_value));
-    stunnel_rwlock_init_debug(lock, file, line);
+    s_lock_init_debug(lock, file, line);
     return lock;
 }
 
-NOEXPORT void dyn_lock_function(int mode, struct CRYPTO_dynlock_value *lock,
+NOEXPORT void s_dynlock_lock_cb(int mode, struct CRYPTO_dynlock_value *lock,
         const char *file, int line) {
     if(mode&CRYPTO_LOCK) {
         /* either CRYPTO_READ or CRYPTO_WRITE (but not both) are needed */
         if(!(mode&CRYPTO_READ)==!(mode&CRYPTO_WRITE))
             fatal("Invalid locking mode");
         if(mode&CRYPTO_WRITE)
-            stunnel_write_lock_debug(lock, file, line);
+            s_write_lock_debug(lock, file, line);
         else
-            stunnel_read_lock_debug(lock, file, line);
+            s_read_lock_debug(lock, file, line);
     } else
-        stunnel_write_unlock_debug(lock, file, line);
+        s_unlock_debug(lock, file, line);
 }
 
-NOEXPORT void dyn_destroy_function(struct CRYPTO_dynlock_value *lock,
+NOEXPORT void s_dynlock_destroy_cb(struct CRYPTO_dynlock_value *lock,
         const char *file, int line) {
-    stunnel_rwlock_destroy_debug(lock, file, line);
+    s_lock_destroy_debug(lock, file, line);
     str_free(lock);
 }
 
-NOEXPORT void locking_callback(int mode, int type, const char *file, int line) {
-    dyn_lock_function(mode, lock_cs+type, file, line);
+NOEXPORT void s_locking_cb(int mode, int type, const char *file, int line) {
+    s_dynlock_lock_cb(mode, lock_cs+type, file, line);
+}
+
+NOEXPORT int s_add_lock_cb(int *num, int amount, int type,
+        const char *file, int line) {
+    (void)file; /* squash the unused parameter warning */
+    (void)line; /* squash the unused parameter warning */
+    return s_atomic_add(num, amount, lock_cs+type);
+}
+
+CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) {
+    struct CRYPTO_dynlock_value *lock;
+
+    lock=str_alloc_detached(sizeof(CRYPTO_RWLOCK));
+    s_lock_init_debug(lock, __FILE__, __LINE__);
+    return lock;
+}
+
+int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock) {
+    s_read_lock_debug(lock, __FILE__, __LINE__);
+    return 1;
+}
+
+int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock) {
+    s_write_lock_debug(lock, __FILE__, __LINE__);
+    return 1;
+}
+
+int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock) {
+    s_unlock_debug(lock, __FILE__, __LINE__);
+    return 1;
+}
+
+void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock) {
+    s_lock_destroy_debug(lock, __FILE__, __LINE__);
+    str_free(lock);
+}
+
+#else /* USE_OS_THREADS */
+
+CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) {
+    return NULL;
+}
+
+int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock) {
+    (void)lock; /* squash the unused parameter warning */
+    return 1;
+}
+
+int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock) {
+    (void)lock; /* squash the unused parameter warning */
+    return 1;
+}
+
+int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock) {
+    (void)lock; /* squash the unused parameter warning */
+    return 1;
+}
+
+void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock) {
+    (void)lock; /* squash the unused parameter warning */
+}
+
+#endif /* USE_OS_THREADS */
+
+int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock) {
+    *ret=s_atomic_add(val, amount, lock);
+    return 1;
 }
 
 #endif /* OPENSSL_VERSION_NUMBER<0x10100004L */
 
 void locking_init(void) {
     size_t i;
-#if OPENSSL_VERSION_NUMBER<0x10100004L
+#if defined(USE_OS_THREADS) && OPENSSL_VERSION_NUMBER<0x10100004L
     size_t num;
-#endif
 
-    /* initialize stunnel critical sections */
-    for(i=0; i<STUNNEL_LOCKS; i++) /* all the mutexes */
-        stunnel_rwlock_init(&stunnel_locks[i]);
-
-#if OPENSSL_VERSION_NUMBER<0x10100004L
     /* initialize the OpenSSL static locking */
     num=(size_t)CRYPTO_num_locks();
     lock_cs=str_alloc_detached(num*sizeof(struct CRYPTO_dynlock_value));
     for(i=0; i<num; i++)
-        stunnel_rwlock_init(&lock_cs[i]);
+        s_lock_init_debug(lock_cs+i, __FILE__, __LINE__);
 
     /* initialize the OpenSSL static locking callbacks */
-    CRYPTO_set_locking_callback(locking_callback);
+    CRYPTO_set_locking_callback(s_locking_cb);
+    CRYPTO_set_add_lock_callback(s_add_lock_cb);
 
     /* initialize the OpenSSL dynamic locking callbacks */
-    CRYPTO_set_dynlock_create_callback(dyn_create_function);
-    CRYPTO_set_dynlock_lock_callback(dyn_lock_function);
-    CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function);
-#endif
-}
+    CRYPTO_set_dynlock_create_callback(s_dynlock_create_cb);
+    CRYPTO_set_dynlock_lock_callback(s_dynlock_lock_cb);
+    CRYPTO_set_dynlock_destroy_callback(s_dynlock_destroy_cb);
+#endif /* defined(USE_OS_THREADS) && OPENSSL_VERSION_NUMBER<0x10100004L */
 
-#endif /* defined(USE_PTHREAD) || defined(USE_WIN32) */
+    /* initialize stunnel critical sections */
+    for(i=0; i<STUNNEL_LOCKS; i++) /* all the mutexes */
+        stunnel_locks[i]=CRYPTO_THREAD_lock_new();
+}
 
 /**************************************** creating a client */
 
@@ -339,6 +409,7 @@ NOEXPORT CONTEXT *new_context(void) {
 
 int sthreads_init(void) {
     thread_id_init();
+    locking_init();
     /* create the first (listening) context and put it in the running queue */
     if(!new_context()) {
         s_log(LOG_ERR, "Cannot create the listening context");
@@ -351,7 +422,7 @@ int sthreads_init(void) {
     return 0;
 }
 
-int create_client(SOCKET ls, SOCKET s, CLI *arg, void *(*cli)(void *)) {
+int create_client(SOCKET ls, SOCKET s, CLI *arg) {
     CONTEXT *context;
 
     (void)ls; /* this parameter is only used with USE_FORK */
@@ -386,7 +457,7 @@ int create_client(SOCKET ls, SOCKET s, C
     context->context.uc_stack.ss_size=arg->opt->stack_size;
     context->context.uc_stack.ss_flags=0;
 
-    makecontext(&context->context, (void(*)(void))cli, ARGC, arg);
+    makecontext(&context->context, (void(*)(void))client_thread, ARGC, arg);
     s_log(LOG_DEBUG, "New context created");
     return 0;
 }
@@ -397,6 +468,7 @@ int create_client(SOCKET ls, SOCKET s, C
 
 int sthreads_init(void) {
     thread_id_init();
+    locking_init();
     return 0;
 }
 
@@ -405,7 +477,7 @@ NOEXPORT void null_handler(int sig) {
     signal(SIGCHLD, null_handler);
 }
 
-int create_client(SOCKET ls, SOCKET s, CLI *arg, void *(*cli)(void *)) {
+int create_client(SOCKET ls, SOCKET s, CLI *arg) {
     switch(fork()) {
     case -1:    /* error */
         str_free(arg);
@@ -416,7 +488,7 @@ int create_client(SOCKET ls, SOCKET s, C
         if(ls>=0)
             closesocket(ls);
         signal(SIGCHLD, null_handler);
-        cli(arg);
+        client_thread(arg);
         _exit(0);
     default:    /* parent */
         str_free(arg);
@@ -436,7 +508,7 @@ int sthreads_init(void) {
     return 0;
 }
 
-int create_client(SOCKET ls, SOCKET s, CLI *arg, void *(*cli)(void *)) {
+int create_client(SOCKET ls, SOCKET s, CLI *arg) {
     pthread_t thread;
     pthread_attr_t pth_attr;
     int error;
@@ -458,7 +530,7 @@ int create_client(SOCKET ls, SOCKET s, C
     pthread_attr_init(&pth_attr);
     pthread_attr_setdetachstate(&pth_attr, PTHREAD_CREATE_DETACHED);
     pthread_attr_setstacksize(&pth_attr, arg->opt->stack_size);
-    error=pthread_create(&thread, &pth_attr, cli, arg);
+    error=pthread_create(&thread, &pth_attr, client_thread, arg);
     pthread_attr_destroy(&pth_attr);
 #if defined(HAVE_PTHREAD_SIGMASK) && !defined(__APPLE__)
     pthread_sigmask(SIG_SETMASK, &old_set, NULL); /* unblock signals */
@@ -479,23 +551,31 @@ int create_client(SOCKET ls, SOCKET s, C
 
 #ifdef USE_WIN32
 
+#if !defined(_MT)
+#error _beginthreadex requires a multithreaded C run-time library
+#endif
+
 int sthreads_init(void) {
     thread_id_init();
     locking_init();
     return 0;
 }
 
-int create_client(SOCKET ls, SOCKET s, CLI *arg, void *(*cli)(void *)) {
+int create_client(SOCKET ls, SOCKET s, CLI *arg) {
+    HANDLE thread;
+
     (void)ls; /* this parameter is only used with USE_FORK */
     s_log(LOG_DEBUG, "Creating a new thread");
-    if((long)_beginthread((void(*)(void *))cli,
-            (unsigned)arg->opt->stack_size, arg)==-1) {
-        ioerror("_beginthread");
+    thread=(HANDLE)_beginthreadex(NULL, (unsigned)arg->opt->stack_size,
+        client_thread, arg, 0, NULL);
+    if(!thread) {
+        ioerror("_beginthreadex");
         str_free(arg);
         if(s!=INVALID_SOCKET)
             closesocket(s);
         return -1;
     }
+    CloseHandle(thread);
     s_log(LOG_DEBUG, "New thread created");
     return 0;
 }
@@ -520,10 +600,10 @@ unsigned long stunnel_thread_id(void) {
     return (unsigned long)ppib->pib_ulpid;
 }
 
-int create_client(SOCKET ls, SOCKET s, CLI *arg, void *(*cli)(void *)) {
+int create_client(SOCKET ls, SOCKET s, CLI *arg) {
     (void)ls; /* this parameter is only used with USE_FORK */
     s_log(LOG_DEBUG, "Creating a new thread");
-    if((long)_beginthread((void(*)(void *))cli, NULL, arg->opt->stack_size, arg)==-1L) {
+    if((long)_beginthread(client_thread, NULL, arg->opt->stack_size, arg)==-1L) {
         ioerror("_beginthread");
         str_free(arg);
         if(s>=0)
@@ -538,22 +618,16 @@ int create_client(SOCKET ls, SOCKET s, C
 
 #ifdef _WIN32_WCE
 
-long _beginthread(void (*start_address)(void *),
-        int stack_size, void *arglist) {
-    DWORD thread_id;
-    HANDLE handle;
-
-    handle=CreateThread(NULL, stack_size,
+uintptr_t _beginthreadex(void *security, unsigned stack_size,
+        unsigned ( __stdcall *start_address)(void *),
+        void *arglist, unsigned initflag, unsigned *thrdaddr) {
+    return CreateThread(NULL, stack_size,
         (LPTHREAD_START_ROUTINE)start_address, arglist,
-        STACK_SIZE_PARAM_IS_A_RESERVATION, &thread_id);
-    if(!handle)
-        return -1L;
-    CloseHandle(handle);
-    return 0;
+        STACK_SIZE_PARAM_IS_A_RESERVATION, NULL);
 }
 
-void _endthread(void) {
-    ExitThread(0);
+void _endthreadex(unsigned retval) {
+    ExitThread(retval);
 }
 
 #endif /* _WIN32_WCE */
diff -pruN 3:5.44-1/src/str.c 3:5.49-1/src/str.c
--- 3:5.44-1/src/str.c	2017-08-17 09:18:53.000000000 +0000
+++ 3:5.49-1/src/str.c	2018-08-09 05:43:52.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -38,6 +38,9 @@
 #include "common.h"
 #include "prototypes.h"
 
+/* Uncomment to see allocation sources in core dumps */
+/* #define DEBUG_PADDING 64 */
+
 /* reportedly, malloc does not always return 16-byte aligned addresses
  * for 64-bit targets as specified by
  * https://msdn.microsoft.com/en-us/library/6ewkz86d.aspx */
@@ -66,6 +69,9 @@ struct alloc_list_struct {
     size_t size;
     const char *alloc_file, *free_file;
     int alloc_line, free_line;
+#ifdef DEBUG_PADDING
+    char debug[DEBUG_PADDING];
+#endif
     uint64_t valid_canary, magic;
 #ifdef __GNUC__
 } __attribute__((aligned(16)));
@@ -116,11 +122,23 @@ NOEXPORT volatile uint64_t canary_initia
 char *str_dup_debug(const char *str, const char *file, int line) {
     char *retval;
 
+    if(!str)
+        return NULL;
     retval=str_alloc_debug(strlen(str)+1, file, line);
     strcpy(retval, str);
     return retval;
 }
 
+char *str_dup_detached_debug(const char *str, const char *file, int line) {
+    char *retval;
+
+    if(!str)
+        return NULL;
+    retval=str_alloc_detached_debug(strlen(str)+1, file, line);
+    strcpy(retval, str);
+    return retval;
+}
+
 char *str_printf(const char *format, ...) {
     char *txt;
     va_list arglist;
@@ -132,7 +150,9 @@ char *str_printf(const char *format, ...
 }
 
 #ifdef __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 #pragma GCC diagnostic push
+#endif /* __GNUC__>=4.6 */
 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
 #endif /* __GNUC__ */
 char *str_vprintf(const char *format, va_list start_ap) {
@@ -155,7 +175,9 @@ char *str_vprintf(const char *format, va
     }
 }
 #ifdef __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 #pragma GCC diagnostic pop
+#endif /* __GNUC__>=4.6 */
 #endif /* __GNUC__ */
 
 #ifdef USE_WIN32
@@ -246,7 +268,7 @@ void *str_alloc_debug(size_t size, const
     tls_data=tls_get();
     if(!tls_data) {
         tls_data=tls_alloc(NULL, NULL, "alloc");
-        s_log(LOG_ERR, "INTERNAL ERROR: Uninitialized TLS at %s, line %d",
+        s_log(LOG_CRIT, "INTERNAL ERROR: Uninitialized TLS at %s, line %d",
             file, line);
     }
 
@@ -281,6 +303,10 @@ void *str_alloc_detached_debug(size_t si
     alloc_list->alloc_line=line;
     alloc_list->free_file="none";
     alloc_list->free_line=0;
+#ifdef DEBUG_PADDING
+    snprintf(alloc_list->debug+1, DEBUG_PADDING-1, "ALLOC_%lu@%s:%d",
+        (unsigned long)size, file, line);
+#endif
     alloc_list->valid_canary=canary_initialized; /* before memcpy */
     memcpy((uint8_t *)(alloc_list+1)+size, canary, sizeof canary);
     alloc_list->magic=MAGIC_ALLOCATED;
@@ -332,6 +358,10 @@ NOEXPORT void *str_realloc_internal_debu
     alloc_list->alloc_line=line;
     alloc_list->free_file="none";
     alloc_list->free_line=0;
+#ifdef DEBUG_PADDING
+    snprintf(alloc_list->debug+1, DEBUG_PADDING-1, "ALLOC_%lu@%s:%d",
+        (unsigned long)size, file, line);
+#endif
     alloc_list->valid_canary=canary_initialized; /* before memcpy */
     memcpy((uint8_t *)ptr+size, canary, sizeof canary);
     str_leak_debug(alloc_list, 1);
@@ -372,8 +402,8 @@ void str_free_debug(void *ptr, const cha
     alloc_list=(ALLOC_LIST *)ptr-1;
     if(alloc_list->magic==MAGIC_DEALLOCATED) { /* double free */
         /* this may (unlikely) log garbage instead of file names */
-        s_log(LOG_CRIT,
-            "Double free attempt: ptr=%p alloc=%s:%d free#1=%s:%d free#2=%s:%d",
+        s_log(LOG_CRIT, "INTERNAL ERROR: Double free attempt: "
+                "ptr=%p alloc=%s:%d free#1=%s:%d free#2=%s:%d",
             ptr,
             alloc_list->alloc_file, alloc_list->alloc_line,
             alloc_list->free_file, alloc_list->free_line,
@@ -410,12 +440,15 @@ NOEXPORT ALLOC_LIST *get_alloc_list_ptr(
 NOEXPORT void str_leak_debug(const ALLOC_LIST *alloc_list, int change) {
     static size_t entries=0;
     LEAK_ENTRY *entry;
-    int new_entry, allocations;
+    int new_entry;
+    int allocations;
 
-#if defined(USE_PTHREAD) || defined(USE_WIN32)
-    if(!&stunnel_locks[STUNNEL_LOCKS-1]) /* threads not initialized */
+    if(service_options.log_level<LOG_DEBUG) /* performance optimization */
+        return;
+#ifdef USE_OS_THREADS
+    if(!stunnel_locks[STUNNEL_LOCKS-1]) /* threads not initialized */
         return;
-#endif /* defined(USE_PTHREAD) || defined(USE_WIN32) */
+#endif /* USE_OS_THREADS */
     if(!number_of_sections) /* configuration file not initialized */
         return;
 
@@ -425,27 +458,37 @@ NOEXPORT void str_leak_debug(const ALLOC
         entry->alloc_file!=alloc_list->alloc_file;
 
     if(new_entry) { /* the file:line pair was encountered for the first time */
-        stunnel_write_lock(&stunnel_locks[LOCK_LEAK_HASH]);
+        CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_LEAK_HASH]);
         entry=leak_search(alloc_list); /* the list may have changed */
         if(entry->alloc_line==0) {
             if(entries>LEAK_TABLE_SIZE-100) { /* this should never happen */
-                stunnel_write_unlock(&stunnel_locks[LOCK_LEAK_HASH]);
+                CRYPTO_THREAD_unlock(stunnel_locks[LOCK_LEAK_HASH]);
                 return;
             }
             entries++;
             entry->alloc_line=alloc_list->alloc_line;
             entry->alloc_file=alloc_list->alloc_file;
         }
-        stunnel_write_unlock(&stunnel_locks[LOCK_LEAK_HASH]);
+        CRYPTO_THREAD_unlock(stunnel_locks[LOCK_LEAK_HASH]);
     }
 
-#ifdef PRECISE_LEAK_ALLOCATON_COUNTERS
-    /* this is *really* slow in OpenSSL < 1.1.0 */
+    /* for performance we try to avoid calling CRYPTO_atomic_add() here */
+#ifdef USE_OS_THREADS
+#if defined(__GNUC__) && defined(__ATOMIC_ACQ_REL)
+    if(__atomic_is_lock_free(sizeof entry->num, &entry->num))
+        allocations=__atomic_add_fetch(&entry->num, change, __ATOMIC_ACQ_REL);
+    else
+        CRYPTO_atomic_add(&entry->num, change, &allocations,
+            stunnel_locks[LOCK_LEAK_HASH]);
+#elif defined(_MSC_VER)
+    allocations=InterlockedExchangeAdd(&entry->num, change)+change;
+#else /* atomic add not directly supported by the compiler */
     CRYPTO_atomic_add(&entry->num, change, &allocations,
-        &stunnel_locks[LOCK_LEAK_HASH]);
-#else
-    allocations=(entry->num+=change); /* we just need an estimate... */
+        stunnel_locks[LOCK_LEAK_HASH]);
 #endif
+#else /* USE_OS_THREADS */
+    allocations=(entry->num+=change);
+#endif /* USE_OS_THREADS */
 
     if(allocations<=leak_threshold()) /* leak not detected */
         return;
@@ -457,7 +500,7 @@ NOEXPORT void str_leak_debug(const ALLOC
     }
     /* we *may* need to allocate a new leak_results entry */
     /* locking is slow, so we try to avoid it if possible */
-    stunnel_write_lock(&stunnel_locks[LOCK_LEAK_RESULTS]);
+    CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_LEAK_RESULTS]);
     if(entry->max==0) { /* the table may have changed */
         leak_results[leak_result_num]=entry;
         entry->max=allocations;
@@ -465,12 +508,14 @@ NOEXPORT void str_leak_debug(const ALLOC
     } else { /* gracefully handle the race condition */
         entry->max=allocations;
     }
-    stunnel_write_unlock(&stunnel_locks[LOCK_LEAK_RESULTS]);
+    CRYPTO_THREAD_unlock(stunnel_locks[LOCK_LEAK_RESULTS]);
 }
 
 /* O(1) hash table lookup */
 NOEXPORT LEAK_ENTRY *leak_search(const ALLOC_LIST *alloc_list) {
-    int i=alloc_list->alloc_line%LEAK_TABLE_SIZE;
+    /* a trivial hash based on source file name *address* and line number */
+    unsigned i=((unsigned)(uintptr_t)alloc_list->alloc_file+
+        (unsigned)alloc_list->alloc_line)%LEAK_TABLE_SIZE;
 
     while(!(leak_hash_table[i].alloc_line==0 ||
             (leak_hash_table[i].alloc_line==alloc_list->alloc_line &&
@@ -479,6 +524,22 @@ NOEXPORT LEAK_ENTRY *leak_search(const A
     return leak_hash_table+i;
 }
 
+void leak_table_utilization() {
+    int i, utilization=0;
+
+    for(i=0; i<LEAK_TABLE_SIZE; ++i) {
+        if(leak_hash_table[i].alloc_line) {
+            ++utilization;
+#if 0
+            s_log(LOG_DEBUG, "Leak hash entry %d: %s:%d", i,
+                leak_hash_table[i].alloc_file, leak_hash_table[i].alloc_line);
+#endif
+        }
+    }
+    s_log(LOG_DEBUG, "Leak detection table utilization: %d/%d, %02.2f%%",
+        utilization, LEAK_TABLE_SIZE, 100.0*utilization/LEAK_TABLE_SIZE);
+}
+
 /* report identified leaks */
 NOEXPORT void leak_report() {
     int i;
@@ -508,11 +569,33 @@ NOEXPORT long leak_threshold() {
 /* a version of memcmp() with execution time not dependent on data values */
 /* it does *not* allow testing whether s1 is greater or lesser than s2  */
 int safe_memcmp(const void *s1, const void *s2, size_t n) {
-    uint8_t *p1=(uint8_t *)s1, *p2=(uint8_t *)s2;
-    int r=0;
+#ifdef _WIN64
+    typedef unsigned long long TL;
+#else
+    typedef unsigned long TL;
+#endif
+    typedef unsigned char TS;
+    TL r=0, *pl1, *pl2;
+    TS *ps1, *ps2;
+    int n1=(int)((uintptr_t)s1&(sizeof(TL)-1)); /* unaligned bytes in s1 */
+    int n2=(int)((uintptr_t)s2&(sizeof(TL)-1)); /* unaligned bytes in s2 */
+
+    if(n1 || n2) { /* either pointer unaligned */
+        ps1=(TS *)s1;
+        ps2=(TS *)s2;
+    } else { /* both pointers aligned -> compare full words */
+        pl1=(TL *)s1;
+        pl2=(TL *)s2;
+        while(n>=sizeof(TL)) {
+            n-=sizeof(TL);
+            r|=(*pl1++)^(*pl2++);
+        }
+        ps1=(TS *)pl1;
+        ps2=(TS *)pl2;
+    }
     while(n--)
-        r|=(*p1++)^(*p2++);
-    return r;
+        r|=(*ps1++)^(*ps2++);
+    return r!=0;
 }
 
 /* end of str.c */
diff -pruN 3:5.44-1/src/stunnel3.in 3:5.49-1/src/stunnel3.in
--- 3:5.44-1/src/stunnel3.in	2016-05-03 18:35:03.000000000 +0000
+++ 3:5.49-1/src/stunnel3.in	2018-04-06 14:25:10.000000000 +0000
@@ -1,7 +1,7 @@
 #!/usr/bin/perl
 #
 # stunnel3      Perl wrapper to use stunnel 3.x syntax in stunnel >=4.05
-# Copyright (C) 2004-2012 Michal Trojnara <Michal.Trojnara@stunnel.org>
+# Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
 # Version:      2.03
 # Date:         2011.10.22
 #
diff -pruN 3:5.44-1/src/stunnel.c 3:5.49-1/src/stunnel.c
--- 3:5.44-1/src/stunnel.c	2017-10-07 14:23:08.000000000 +0000
+++ 3:5.49-1/src/stunnel.c	2018-08-25 07:15:03.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -42,14 +42,18 @@
 #ifdef USE_WIN32
 
 #ifdef __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 #pragma GCC diagnostic push
+#endif /* __GNUC__>=4.6 */
 #pragma GCC diagnostic ignored "-Wpedantic"
 #endif /* __GNUC__ */
 
 #include <openssl/applink.c>
 
 #ifdef __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 #pragma GCC diagnostic pop
+#endif /* __GNUC__>=4.6 */
 #endif /* __GNUC__ */
 
 #endif /* USE_WIN32 */
@@ -64,7 +68,12 @@ struct sockaddr_un {
 };
 #endif
 
+#if !defined(USE_WIN32) && !defined(USE_OS2)
+NOEXPORT void pid_status_nohang(const char *);
+NOEXPORT void status_info(int, int, const char *);
+#endif
 NOEXPORT int accept_connection(SERVICE_OPTIONS *, unsigned);
+NOEXPORT int exec_connect_start(void);
 NOEXPORT void unbind_port(SERVICE_OPTIONS *, unsigned);
 NOEXPORT SOCKET bind_port(SERVICE_OPTIONS *, int, unsigned);
 #ifdef HAVE_CHROOT
@@ -72,9 +81,6 @@ NOEXPORT int change_root(void);
 #endif
 NOEXPORT int signal_pipe_init(void);
 NOEXPORT int signal_pipe_dispatch(void);
-#ifdef USE_FORK
-NOEXPORT void client_status(void); /* dead children detected */
-#endif
 NOEXPORT char *signal_name(int);
 
 /**************************************** global variables */
@@ -82,9 +88,9 @@ NOEXPORT char *signal_name(int);
 static SOCKET signal_pipe[2]={INVALID_SOCKET, INVALID_SOCKET};
 
 #ifndef USE_FORK
-long max_clients=0;
+int max_clients=0;
 /* -1 before a valid config is loaded, then the current number of clients */
-volatile long num_clients=-1;
+int num_clients=-1;
 #endif
 s_poll_set *fds; /* file descriptors of listening sockets */
 int systemd_fds; /* number of file descriptors passed by systemd */
@@ -143,11 +149,9 @@ int main_configure(char *arg1, char *arg
         return cmdline_status;
     options_apply();
     str_canary_init(); /* needs prng initialization from options_cmdline */
-#if !defined(USE_WIN32) && !defined(__vms)
-    /* syslog_open() must be called before change_root()
+    /* log_open(SINK_SYSLOG) must be called before change_root()
      * to be able to access /dev/log socket */
-    syslog_open();
-#endif /* !defined(USE_WIN32) && !defined(__vms) */
+    log_open(SINK_SYSLOG);
     if(bind_ports())
         return 1;
 
@@ -161,15 +165,16 @@ int main_configure(char *arg1, char *arg
     if(drop_privileges(1))
         return 1;
 
-    /* log_open() must be called after drop_privileges()
+    /* log_open(SINK_OUTFILE) must be called after drop_privileges()
      * or logfile rotation won't be possible */
-    /* log_open() must be called before daemonize()
-     * since daemonize() invalidates stderr */
-    if(log_open())
+    if(log_open(SINK_OUTFILE))
         return 1;
 #ifndef USE_FORK
     num_clients=0; /* the first valid config */
 #endif
+    /* log_flush(LOG_MODE_CONFIGURED) must be called before daemonize()
+     * since daemonize() invalidates stderr */
+    log_flush(LOG_MODE_CONFIGURED);
     return 0;
 }
 
@@ -213,79 +218,65 @@ void main_cleanup() {
     str_stats(); /* main thread allocation tracking */
 #endif
     log_flush(LOG_MODE_ERROR);
-#if !defined(USE_WIN32) && !defined(__vms)
-    syslog_close();
-#endif /* !defined(USE_WIN32) && !defined(__vms) */
+    log_close(SINK_SYSLOG|SINK_OUTFILE);
 }
 
 /**************************************** Unix-specific initialization */
 
-#ifndef USE_WIN32
+#if !defined(USE_WIN32) && !defined(USE_OS2)
 
-#ifdef USE_FORK
-NOEXPORT void client_status(void) { /* dead children detected */
+NOEXPORT void pid_status_nohang(const char *info) {
     int pid, status;
 
-#ifdef HAVE_WAIT_FOR_PID
-    while((pid=wait_for_pid(-1, &status, WNOHANG))>0) {
-#else
-    if((pid=wait(&status))>0) {
-#endif
-#ifdef WIFSIGNALED
-        if(WIFSIGNALED(status)) {
-            char *sig_name=signal_name(WTERMSIG(status));
-            s_log(LOG_DEBUG, "Process %d terminated on %s",
-                pid, sig_name);
-            str_free(sig_name);
-        } else {
-            s_log(LOG_DEBUG, "Process %d finished with code %d",
-                pid, WEXITSTATUS(status));
-        }
-    }
-#else
-        s_log(LOG_DEBUG, "Process %d finished with code %d",
-            pid, status);
-    }
+#ifdef HAVE_WAITPID /* POSIX.1 */
+    s_log(LOG_DEBUG, "Retrieving pid statuses with waitpid()");
+    while((pid=waitpid(-1, &status, WNOHANG))>0)
+        status_info(pid, status, info);
+#elif defined(HAVE_WAIT4) /* 4.3BSD */
+    s_log(LOG_DEBUG, "Retrieving pid statuses with wait4()");
+    while((pid=wait4(-1, &status, WNOHANG, NULL))>0)
+        status_info(pid, status, info);
+#else /* no support for WNOHANG */
+    pid_status_hang(info);
 #endif
 }
-#endif /* defined USE_FORK */
-
-#ifndef USE_OS2
 
-void child_status(void) { /* dead libwrap or 'exec' process detected */
+void pid_status_hang(const char *info) {
     int pid, status;
 
-#ifdef HAVE_WAIT_FOR_PID
-    while((pid=wait_for_pid(-1, &status, WNOHANG))>0) {
-#else
-    if((pid=wait(&status))>0) {
-#endif
+    s_log(LOG_DEBUG, "Retrieving a pid status with wait()");
+    if((pid=wait(&status))>0)
+        status_info(pid, status, info);
+}
+
+NOEXPORT void status_info(int pid, int status, const char *info) {
 #ifdef WIFSIGNALED
-        if(WIFSIGNALED(status)) {
-            char *sig_name=signal_name(WTERMSIG(status));
-            s_log(LOG_INFO, "Child process %d terminated on %s",
-                pid, sig_name);
-            str_free(sig_name);
-        } else {
-            s_log(LOG_INFO, "Child process %d finished with code %d",
-                pid, WEXITSTATUS(status));
-        }
+    if(WIFSIGNALED(status)) {
+        char *sig_name=signal_name(WTERMSIG(status));
+        s_log(LOG_INFO, "%s %d terminated on %s", info, pid, sig_name);
+        str_free(sig_name);
+    } else {
+        s_log(LOG_INFO, "%s %d finished with code %d",
+            info, pid, WEXITSTATUS(status));
+    }
 #else
-        s_log(LOG_INFO, "Child process %d finished with status %d",
-            pid, status);
+    s_log(LOG_INFO, "%s %d finished with status %d", info, pid, status);
 #endif
-    }
 }
 
-#endif /* !defined(USE_OS2) */
-
-#endif /* !defined(USE_WIN32) */
+#endif /* !defined(USE_WIN32) && !defined(USE_OS2) */
 
 /**************************************** main loop accepting connections */
 
 void daemon_loop(void) {
-    if(cron_init()) /* initialize periodic events */
-        fatal("Cron initialization failed");
+    if(cron_init()) { /* initialize periodic events */
+        s_log(LOG_CRIT, "Cron initialization failed");
+        exit(1);
+    }
+    if(exec_connect_start()) {
+        s_log(LOG_CRIT, "Failed to start exec+connect services");
+        exit(1);
+    }
     while(1) {
         int temporary_lack_of_resources=0;
         int num=s_poll_wait(fds, -1, -1);
@@ -299,10 +290,13 @@ void daemon_loop(void) {
                     break; /* terminate daemon_loop */
             for(opt=service_options.next; opt; opt=opt->next) {
                 unsigned i;
-                for(i=0; i<opt->local_addr.num; ++i)
-                    if(s_poll_canread(fds, opt->local_addr.fd[i]))
-                        if(accept_connection(opt, i))
-                            temporary_lack_of_resources=1;
+                for(i=0; i<opt->local_addr.num; ++i) {
+                    SOCKET fd=opt->local_fd[i];
+                    if(fd!=INVALID_SOCKET &&
+                            s_poll_canread(fds, fd) &&
+                            accept_connection(opt, i))
+                        temporary_lack_of_resources=1;
+                }
             }
         } else {
             log_error(LOG_NOTICE, get_last_socket_error(),
@@ -315,13 +309,14 @@ void daemon_loop(void) {
             sleep(1); /* to avoid log trashing */
         }
     }
+    leak_table_utilization();
 }
 
     /* return 1 when a short delay is needed before another try */
 NOEXPORT int accept_connection(SERVICE_OPTIONS *opt, unsigned i) {
     SOCKADDR_UNION addr;
     char *from_address;
-    SOCKET s, fd=opt->local_addr.fd[i];
+    SOCKET s, fd=opt->local_fd[i];
     socklen_t addrlen;
 
     addrlen=sizeof addr;
@@ -355,15 +350,21 @@ NOEXPORT int accept_connection(SERVICE_O
     RAND_add("", 1, 0.0); /* each child needs a unique entropy pool */
 #else
     if(max_clients && num_clients>=max_clients) {
-        s_log(LOG_WARNING, "Connection rejected: too many clients (>=%ld)",
+        s_log(LOG_WARNING, "Connection rejected: too many clients (>=%d)",
             max_clients);
         closesocket(s);
         return 0;
     }
 #endif
-    if(create_client(fd, s, alloc_client_session(opt, s, s), client_thread)) {
+#ifndef USE_FORK
+    service_up_ref(opt);
+#endif
+    if(create_client(fd, s, alloc_client_session(opt, s, s))) {
         s_log(LOG_ERR, "Connection rejected: create_client failed");
         closesocket(s);
+#ifndef USE_FORK
+        service_free(opt);
+#endif
         return 0;
     }
     return 0;
@@ -371,6 +372,30 @@ NOEXPORT int accept_connection(SERVICE_O
 
 /**************************************** initialization helpers */
 
+NOEXPORT int exec_connect_start(void) {
+    SERVICE_OPTIONS *opt;
+
+    for(opt=service_options.next; opt; opt=opt->next) {
+        if(opt->exec_name && opt->connect_addr.names) {
+            s_log(LOG_DEBUG, "Starting exec+connect service [%s]",
+                opt->servname);
+#ifndef USE_FORK
+            service_up_ref(opt);
+#endif
+            if(create_client(INVALID_SOCKET, INVALID_SOCKET,
+                    alloc_client_session(opt, INVALID_SOCKET, INVALID_SOCKET))) {
+                s_log(LOG_ERR, "Failed to start exec+connect service [%s]",
+                    opt->servname);
+#ifndef USE_FORK
+                service_free(opt);
+#endif
+                return 1; /* fatal error */
+            }
+        }
+    }
+    return 0; /* OK */
+}
+
 /* clear fds, close old ports */
 void unbind_ports(void) {
     SERVICE_OPTIONS *opt;
@@ -378,7 +403,11 @@ void unbind_ports(void) {
     s_poll_init(fds);
     s_poll_add(fds, signal_pipe[0], 1, 0);
 
-    for(opt=service_options.next; opt; opt=opt->next) {
+    opt=service_options.next;
+    service_options.next=NULL;
+    service_free(&service_options);
+
+    while(opt) {
         unsigned i;
         s_log(LOG_DEBUG, "Unbinding service [%s]", opt->servname);
         for(i=0; i<opt->local_addr.num; ++i)
@@ -388,6 +417,7 @@ void unbind_ports(void) {
             /* create exec+connect services             */
             /* FIXME: this is just a crude workaround   */
             /*        is it better to kill the service? */
+            /* FIXME: this won't work with FORK threads */
             opt->option.retry=0;
         }
         /* purge session cache of the old SSL_CTX object */
@@ -397,19 +427,26 @@ void unbind_ports(void) {
             SSL_CTX_flush_sessions(opt->ctx,
                 (long)time(NULL)+opt->session_timeout+1);
         s_log(LOG_DEBUG, "Service [%s] closed", opt->servname);
+
+        {
+            SERVICE_OPTIONS *garbage=opt;
+            opt=opt->next;
+            garbage->next=NULL;
+            service_free(garbage);
+        }
     }
 }
 
 NOEXPORT void unbind_port(SERVICE_OPTIONS *opt, unsigned i) {
-    SOCKET fd=opt->local_addr.fd[i];
-    SOCKADDR_UNION *addr=opt->local_addr.addr+i;
+    SOCKET fd=opt->local_fd[i];
 #ifdef HAVE_STRUCT_SOCKADDR_UN
+    SOCKADDR_UNION *addr=opt->local_addr.addr+i;
     struct stat sb; /* buffer for lstat() */
 #endif
 
     if(fd==INVALID_SOCKET)
         return;
-    opt->local_addr.fd[i]=INVALID_SOCKET;
+    opt->local_fd[i]=INVALID_SOCKET;
 
     if(fd<(SOCKET)listen_fds_start ||
             fd>=(SOCKET)(listen_fds_start+systemd_fds))
@@ -454,29 +491,38 @@ int bind_ports(void) {
     for(opt=service_options.next; opt; opt=opt->next) {
         unsigned i;
         for(i=0; i<opt->local_addr.num; ++i)
-            opt->local_addr.fd[i]=INVALID_SOCKET;
+            opt->local_fd[i]=INVALID_SOCKET;
     }
 
     listening_section=0;
     for(opt=service_options.next; opt; opt=opt->next) {
-        unsigned i;
-        s_log(LOG_DEBUG, "Binding service [%s]", opt->servname);
-        for(i=0; i<opt->local_addr.num; ++i) {
-            SOCKET fd;
-            fd=bind_port(opt, listening_section, i);
-            if(fd==INVALID_SOCKET)
+        opt->bound_ports=0;
+        if(opt->local_addr.num) { /* ports to bind for this service */
+            unsigned i;
+            s_log(LOG_DEBUG, "Binding service [%s]", opt->servname);
+            for(i=0; i<opt->local_addr.num; ++i) {
+                SOCKET fd;
+                fd=bind_port(opt, listening_section, i);
+                opt->local_fd[i]=fd;
+                if(fd!=INVALID_SOCKET) {
+                    s_poll_add(fds, fd, 1, 0);
+                    ++opt->bound_ports;
+                }
+            }
+            if(!opt->bound_ports) {
+                s_log(LOG_ERR, "Binding service [%s] failed", opt->servname);
                 return 1;
-            s_poll_add(fds, fd, 1, 0);
-            opt->local_addr.fd[i]=fd;
-        }
-        if(opt->local_addr.num)
+            }
             ++listening_section;
-        /* create exec+connect services */
-        if(opt->exec_name && opt->connect_addr.names) {
-            /* FIXME: needs to be delayed on reload with opt->option.retry set */
-            create_client(INVALID_SOCKET, INVALID_SOCKET,
-                alloc_client_session(opt, INVALID_SOCKET, INVALID_SOCKET),
-                client_thread);
+        } else if(opt->exec_name && opt->connect_addr.names) {
+            s_log(LOG_DEBUG, "Skipped exec+connect service [%s]", opt->servname);
+#ifndef OPENSSL_NO_TLSEXT
+        } else if(!opt->option.client && opt->sni) {
+            s_log(LOG_DEBUG, "Skipped SNI slave service [%s]", opt->servname);
+#endif
+        } else { /* each service must define two endpoints */
+            s_log(LOG_ERR, "Invalid service [%s]", opt->servname);
+            return 1;
         }
     }
     if(listening_section<systemd_fds) {
@@ -509,7 +555,7 @@ NOEXPORT SOCKET bind_port(SERVICE_OPTION
             (long)fd);
     }
 
-    if(set_socket_options(fd, 0)<0) {
+    if(socket_options_set(opt, fd, 0)<0) {
         closesocket(fd);
         return INVALID_SOCKET;
     }
@@ -519,9 +565,9 @@ NOEXPORT SOCKET bind_port(SERVICE_OPTION
     /* we don't bind or listen on a socket inherited from systemd */
     if(listening_section>=systemd_fds) {
         if(bind(fd, &addr->sa, addr_len(addr))) {
-            sockerror("bind");
-            s_log(LOG_ERR, "Error binding service [%s] to %s",
-                opt->servname, local_address);
+            int err=get_last_socket_error();
+            s_log(LOG_NOTICE, "Binding service [%s] to %s: %s (%d)",
+                opt->servname, local_address, s_strerror(err), err);
             str_free(local_address);
             closesocket(fd);
             return INVALID_SOCKET;
@@ -558,7 +604,7 @@ NOEXPORT SOCKET bind_port(SERVICE_OPTION
     }
 #endif
 
-    s_log(LOG_DEBUG, "Service [%s] (FD=%ld) bound to %s",
+    s_log(LOG_INFO, "Service [%s] (FD=%ld) bound to %s",
         opt->servname, (long)fd, local_address);
     str_free(local_address);
     return fd;
@@ -576,6 +622,7 @@ NOEXPORT int change_root(void) {
         sockerror("chdir");
         return 1;
     }
+    s_log(LOG_NOTICE, "Switched to chroot directory: %s", global_options.chroot_dir);
     return 0;
 }
 #endif /* HAVE_CHROOT */
@@ -623,96 +670,115 @@ NOEXPORT int signal_pipe_init(void) {
 }
 
 #ifdef __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || defined(__clang__)
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wunused-result"
+#endif /* __GNUC__>=4.6 */
 #endif /* __GNUC__ */
-void signal_post(int sig) {
+void signal_post(uint8_t sig) {
     /* no meaningful way here to handle the result */
-    writesocket(signal_pipe[1], (char *)&sig, sizeof sig);
+    writesocket(signal_pipe[1], (char *)&sig, 1);
 }
 #ifdef __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 #pragma GCC diagnostic pop
+#endif /* __GNUC__>=4.6 */
 #endif /* __GNUC__ */
 
+/* make a single attempt to dispatch a signal from the signal pipe */
+/* return 1 on SIGNAL_TERMINATE or a fatal error, 0 otherwise */
 NOEXPORT int signal_pipe_dispatch(void) {
-    static int sig;
-    static size_t ptr=0;
+    uint8_t sig=0xff;
     ssize_t num;
     char *sig_name;
 
-    s_log(LOG_DEBUG, "Dispatching signals from the signal pipe");
-    for(;;) {
-        num=readsocket(signal_pipe[0], (char *)&sig+ptr, sizeof sig-ptr);
-        if(num==-1 && get_last_socket_error()==S_EWOULDBLOCK) {
-            s_log(LOG_DEBUG, "Signal pipe is empty");
-            return 0;
-        }
-        if(num==-1 || num==0) {
-            if(num)
-                sockerror("signal pipe read");
-            else
-                s_log(LOG_ERR, "Signal pipe closed");
-            s_poll_remove(fds, signal_pipe[0]);
-            closesocket(signal_pipe[0]);
-            closesocket(signal_pipe[1]);
-            if(signal_pipe_init()) {
-                s_log(LOG_ERR,
-                    "Signal pipe reinitialization failed; terminating");
-                return 1;
+    s_log(LOG_DEBUG, "Dispatching a signal from the signal pipe");
+    num=readsocket(signal_pipe[0], (char *)&sig, 1);
+    if(num!=1) {
+        if(num) {
+            if(get_last_socket_error()==S_EWOULDBLOCK) {
+                s_log(LOG_DEBUG, "Signal pipe is empty");
+                return 0;
             }
-            s_poll_add(fds, signal_pipe[0], 1, 0);
-            s_log(LOG_ERR, "Signal pipe reinitialized");
-            return 0;
-        }
-        ptr+=(size_t)num;
-        if(ptr<sizeof sig) {
-            s_log(LOG_DEBUG, "Incomplete signal pipe read (ptr=%ld)",
-                (long)ptr);
-            return 0;
+            sockerror("signal pipe read");
+        } else {
+            s_log(LOG_ERR, "Signal pipe closed");
+        }
+        s_poll_remove(fds, signal_pipe[0]);
+        closesocket(signal_pipe[0]);
+        closesocket(signal_pipe[1]);
+        if(signal_pipe_init()) {
+            s_log(LOG_ERR,
+                "Signal pipe reinitialization failed; terminating");
+            return 1;
         }
-        ptr=0;
-        switch(sig) {
+        s_poll_add(fds, signal_pipe[0], 1, 0);
+        s_log(LOG_ERR, "Signal pipe reinitialized");
+        return 0;
+    }
+
+    switch(sig) {
 #ifndef USE_WIN32
-        case SIGCHLD:
-            s_log(LOG_DEBUG, "Processing SIGCHLD");
+    case SIGCHLD:
+        s_log(LOG_DEBUG, "Processing SIGCHLD");
 #ifdef USE_FORK
-            client_status(); /* report status of client process */
+        pid_status_nohang("Process"); /* client process */
 #else /* USE_UCONTEXT || USE_PTHREAD */
-            child_status();  /* report status of libwrap or 'exec' process */
+        pid_status_nohang("Child process"); /* 'exec' process */
 #endif /* defined USE_FORK */
-            break;
+        return 0;
 #endif /* !defind USE_WIN32 */
-        case SIGNAL_RELOAD_CONFIG:
-            s_log(LOG_DEBUG, "Processing SIGNAL_RELOAD_CONFIG");
-            if(options_parse(CONF_RELOAD)) {
-                s_log(LOG_ERR, "Failed to reload the configuration file");
-            } else {
-                unbind_ports();
-                log_close();
-                options_apply();
-                log_open();
-                ui_config_reloaded();
-                if(bind_ports()) {
-                    /* FIXME: handle the error */
-                }
+    case SIGNAL_RELOAD_CONFIG:
+        s_log(LOG_DEBUG, "Processing SIGNAL_RELOAD_CONFIG");
+        if(options_parse(CONF_RELOAD)) {
+            s_log(LOG_ERR, "Failed to reload the configuration file");
+        } else {
+#ifdef HAVE_CHROOT
+            struct stat sb;
+#endif /* HAVE_CHROOT */
+            unbind_ports();
+            log_flush(LOG_MODE_BUFFER);
+#ifdef HAVE_CHROOT
+            /* we don't close SINK_SYSLOG if chroot is enabled and
+             * there is no /dev/log inside it, which could allow
+             * openlog(3) to reopen the syslog socket later */
+            if(global_options.chroot_dir && stat("/dev/log", &sb))
+                log_close(SINK_OUTFILE);
+            else
+#endif /* HAVE_CHROOT */
+                log_close(SINK_SYSLOG|SINK_OUTFILE);
+            options_free(); /* FIXME: the pattern should be copy-apply-free */
+            options_apply();
+            /* we hope that a sane openlog(3) implementation won't
+             * attempt to reopen /dev/log if it's already open */
+            log_open(SINK_SYSLOG|SINK_OUTFILE);
+            log_flush(LOG_MODE_CONFIGURED);
+            ui_config_reloaded();
+            if(bind_ports()) {
+                /* FIXME: handle the error */
+            }
+            if(exec_connect_start()) {
+                /* FIXME: handle the error */
             }
-            break;
-        case SIGNAL_REOPEN_LOG:
-            s_log(LOG_DEBUG, "Processing SIGNAL_REOPEN_LOG");
-            log_close();
-            log_open();
-            s_log(LOG_NOTICE, "Log file reopened");
-            break;
-        case SIGNAL_TERMINATE:
-            s_log(LOG_DEBUG, "Processing SIGNAL_TERMINATE");
-            s_log(LOG_NOTICE, "Terminated");
-            return 1;
-        default:
-            sig_name=signal_name(sig);
-            s_log(LOG_ERR, "Received %s; terminating", sig_name);
-            str_free(sig_name);
-            return 1;
         }
+        return 0;
+    case SIGNAL_REOPEN_LOG:
+        s_log(LOG_DEBUG, "Processing SIGNAL_REOPEN_LOG");
+        log_flush(LOG_MODE_BUFFER);
+        log_close(SINK_OUTFILE);
+        log_open(SINK_OUTFILE);
+        log_flush(LOG_MODE_CONFIGURED);
+        s_log(LOG_NOTICE, "Log file reopened");
+        return 0;
+    case SIGNAL_TERMINATE:
+        s_log(LOG_DEBUG, "Processing SIGNAL_TERMINATE");
+        s_log(LOG_NOTICE, "Terminated");
+        return 1;
+    default:
+        sig_name=signal_name(sig);
+        s_log(LOG_ERR, "Received %s; terminating", sig_name);
+        str_free(sig_name);
+        return 1;
     }
 }
 
diff -pruN 3:5.44-1/src/tls.c 3:5.49-1/src/tls.c
--- 3:5.44-1/src/tls.c	2017-01-02 14:27:26.000000000 +0000
+++ 3:5.49-1/src/tls.c	2018-04-06 14:25:10.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
diff -pruN 3:5.44-1/src/ui_unix.c 3:5.49-1/src/ui_unix.c
--- 3:5.44-1/src/ui_unix.c	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/src/ui_unix.c	2018-06-08 17:30:06.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -38,8 +38,6 @@
 #include "common.h"
 #include "prototypes.h"
 
-NOEXPORT unsigned long dpid;
-
 NOEXPORT int main_unix(int, char*[]);
 #if !defined(__vms) && !defined(USE_OS2)
 NOEXPORT int daemonize(int);
@@ -110,6 +108,9 @@ NOEXPORT int main_unix(int argc, char* a
             signal(SIGINT, signal_handler); /* fatal */
 #endif
         daemon_loop();
+#if !defined(__vms) && !defined(USE_OS2)
+        delete_pid();
+#endif /* standard Unix */
     } else { /* inetd mode */
         CLI *c;
 #if !defined(__vms) && !defined(USE_OS2)
@@ -133,7 +134,7 @@ NOEXPORT void signal_handler(int sig) {
     int saved_errno;
 
     saved_errno=errno;
-    signal_post(sig);
+    signal_post((uint8_t)sig);
     signal(sig, signal_handler);
     errno=saved_errno;
 }
@@ -186,17 +187,18 @@ NOEXPORT int create_pid(void) {
         s_log(LOG_ERR, "Pid file (%s) must be full path name", global_options.pidfile);
         return 1;
     }
-    dpid=(unsigned long)getpid();
 
-    /* silently remove old pid file */
+    /* silently remove the old pid file */
     unlink(global_options.pidfile);
+
+    /* create a new pid file */
     pf=open(global_options.pidfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644);
     if(pf==-1) {
         s_log(LOG_ERR, "Cannot create pid file %s", global_options.pidfile);
         ioerror("create");
         return 1;
     }
-    pid=str_printf("%lu\n", dpid);
+    pid=str_printf("%lu\n", (unsigned long)getpid());
     if(write(pf, pid, strlen(pid))<(int)strlen(pid)) {
         s_log(LOG_ERR, "Cannot write pid file %s", global_options.pidfile);
         ioerror("write");
@@ -205,16 +207,18 @@ NOEXPORT int create_pid(void) {
     str_free(pid);
     close(pf);
     s_log(LOG_DEBUG, "Created pid file %s", global_options.pidfile);
-    atexit(delete_pid);
     return 0;
 }
 
 NOEXPORT void delete_pid(void) {
-    if((unsigned long)getpid()!=dpid)
-        return; /* current process is not main daemon process */
-    s_log(LOG_DEBUG, "removing pid file %s", global_options.pidfile);
-    if(unlink(global_options.pidfile)<0)
-        ioerror(global_options.pidfile); /* not critical */
+    if(global_options.pidfile) {
+        if(unlink(global_options.pidfile)<0)
+            ioerror(global_options.pidfile); /* not critical */
+        else
+            s_log(LOG_DEBUG, "Removed pid file %s", global_options.pidfile);
+    } else {
+        s_log(LOG_DEBUG, "No pid file to remove");
+    }
 }
 
 #endif /* standard Unix */
diff -pruN 3:5.44-1/src/ui_win_cli.c 3:5.49-1/src/ui_win_cli.c
--- 3:5.44-1/src/ui_win_cli.c	2017-02-19 22:16:00.000000000 +0000
+++ 3:5.49-1/src/ui_win_cli.c	2018-04-06 14:25:10.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
diff -pruN 3:5.44-1/src/ui_win_gui.c 3:5.49-1/src/ui_win_gui.c
--- 3:5.44-1/src/ui_win_gui.c	2017-02-23 13:52:40.000000000 +0000
+++ 3:5.49-1/src/ui_win_gui.c	2018-08-19 07:10:47.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -79,7 +79,7 @@ NOEXPORT int save_text_file(LPTSTR, char
 NOEXPORT void update_logs(void);
 NOEXPORT LPTSTR log_txt(void);
 
-NOEXPORT void daemon_thread(void *);
+NOEXPORT unsigned __stdcall daemon_thread(void *);
 
 NOEXPORT void valid_config(void);
 NOEXPORT void invalid_config(void);
@@ -331,6 +331,7 @@ NOEXPORT int initialize_winsock() {
 /**************************************** GUI thread */
 
 NOEXPORT int gui_loop() {
+    HANDLE handle;
 #ifdef _WIN32_WCE
     WNDCLASS wc;
 #else
@@ -381,8 +382,12 @@ NOEXPORT int gui_loop() {
     /* auto-reset, non-signaled events */
     main_initialized=CreateEvent(NULL, FALSE, FALSE, NULL);
     config_ready=CreateEvent(NULL, FALSE, FALSE, NULL);
-    /* hwnd needs to be initialized before _beginthread() */
-    _beginthread(daemon_thread, DEFAULT_STACK_SIZE, NULL);
+    /* hwnd needs to be initialized before _beginthreadex() */
+    handle=(HANDLE)_beginthreadex(NULL, DEFAULT_STACK_SIZE,
+        daemon_thread, NULL, 0, NULL);
+    if(!handle)
+        fatal("Failed to create the daemon thread");
+    CloseHandle(handle);
     WaitForSingleObject(main_initialized, INFINITE);
     /* logging subsystem is now available */
 
@@ -893,7 +898,7 @@ NOEXPORT LPTSTR log_txt(void) {
 
 /**************************************** worker thread */
 
-NOEXPORT void daemon_thread(void *arg) {
+NOEXPORT unsigned __stdcall daemon_thread(void *arg) {
     (void)arg; /* squash the unused parameter warning */
 
     tls_alloc(NULL, NULL, "main"); /* new thread-local storage */
@@ -907,14 +912,14 @@ NOEXPORT void daemon_thread(void *arg) {
         log_flush(LOG_MODE_ERROR); /* otherwise logs are buffered */
         PostMessage(hwnd, WM_INVALID_CONFIG, 0, 0); /* display error */
         WaitForSingleObject(config_ready, INFINITE);
-        log_close(); /* prevent main_configure() from logging in error mode */
     }
     PostMessage(hwnd, WM_VALID_CONFIG, 0, 0);
 
     /* start the main loop */
     daemon_loop();
     main_cleanup();
-    _endthread(); /* SIGNAL_TERMINATE received */
+    _endthreadex(0); /* SIGNAL_TERMINATE received */
+    return 0;
 }
 
 /**************************************** helper functions */
diff -pruN 3:5.44-1/src/vc.mak 3:5.49-1/src/vc.mak
--- 3:5.44-1/src/vc.mak	2017-11-14 14:01:47.000000000 +0000
+++ 3:5.49-1/src/vc.mak	2018-04-06 14:25:10.000000000 +0000
@@ -1,4 +1,4 @@
-# vc.mak by Michal Trojnara 1998-2017
+# vc.mak by Michal Trojnara 1998-2018
 # with help of David Gillingham <dgillingham@gmail.com>
 # with help of Pierre Delaage <delaage.pierre@free.fr>
 
diff -pruN 3:5.44-1/src/verify.c 3:5.49-1/src/verify.c
--- 3:5.44-1/src/verify.c	2017-05-13 09:01:07.000000000 +0000
+++ 3:5.49-1/src/verify.c	2018-07-02 21:30:10.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -302,42 +302,35 @@ NOEXPORT int cert_check_subject(CLI *c,
     NAME_LIST *ptr;
     char *peername=NULL;
 
-    if(c->opt->check_host) {
-        for(ptr=c->opt->check_host; ptr; ptr=ptr->next)
-            if(X509_check_host(cert, ptr->name, 0, 0, &peername)>0)
-                break;
-        if(!ptr) {
-            s_log(LOG_WARNING, "CERT: No matching host name found");
-            return 0; /* reject */
-        }
-        s_log(LOG_INFO, "CERT: Host name \"%s\" matched with \"%s\"",
-            ptr->name, peername);
-        OPENSSL_free(peername);
+    if(!c->opt->check_host && !c->opt->check_email && !c->opt->check_ip) {
+        s_log(LOG_INFO, "CERT: No subject checks configured");
+        return 1; /* accept */
     }
 
-    if(c->opt->check_email) {
-        for(ptr=c->opt->check_email; ptr; ptr=ptr->next)
-            if(X509_check_email(cert, ptr->name, 0, 0)>0)
-                break;
-        if(!ptr) {
-            s_log(LOG_WARNING, "CERT: No matching email address found");
-            return 0; /* reject */
+    for(ptr=c->opt->check_host; ptr; ptr=ptr->next)
+        if(X509_check_host(cert, ptr->name, 0, 0, &peername)>0) {
+            s_log(LOG_INFO, "CERT: Host name \"%s\" matched with \"%s\"",
+                ptr->name, peername);
+            OPENSSL_free(peername);
+            return 1; /* accept */
         }
-        s_log(LOG_INFO, "CERT: Email address \"%s\" matched", ptr->name);
-    }
 
-    if(c->opt->check_ip) {
-        for(ptr=c->opt->check_ip; ptr; ptr=ptr->next)
-            if(X509_check_ip_asc(cert, ptr->name, 0)>0)
-                break;
-        if(!ptr) {
-            s_log(LOG_WARNING, "CERT: No matching IP address found");
-            return 0; /* reject */
+    for(ptr=c->opt->check_email; ptr; ptr=ptr->next)
+        if(X509_check_email(cert, ptr->name, 0, 0)>0) {
+            s_log(LOG_INFO, "CERT: Email address \"%s\" matched",
+                ptr->name);
+            return 1; /* accept */
         }
-        s_log(LOG_INFO, "CERT: IP address \"%s\" matched", ptr->name);
-    }
 
-    return 1; /* accept */
+    for(ptr=c->opt->check_ip; ptr; ptr=ptr->next)
+        if(X509_check_ip_asc(cert, ptr->name, 0)>0) {
+            s_log(LOG_INFO, "CERT: IP address \"%s\" matched",
+                ptr->name);
+            return 1; /* accept */
+        }
+
+    s_log(LOG_WARNING, "CERT: Subject checks failed");
+    return 0; /* reject */
 }
 #endif /* OPENSSL_VERSION_NUMBER>=0x10002000L */
 
diff -pruN 3:5.44-1/src/version.h 3:5.49-1/src/version.h
--- 3:5.44-1/src/version.h	2017-11-14 14:01:47.000000000 +0000
+++ 3:5.49-1/src/version.h	2018-08-09 05:43:52.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *   stunnel       TLS offloading and load-balancing proxy
- *   Copyright (C) 1998-2017 Michal Trojnara <Michal.Trojnara@stunnel.org>
+ *   Copyright (C) 1998-2018 Michal Trojnara <Michal.Trojnara@stunnel.org>
  *
  *   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
@@ -65,7 +65,7 @@
 
 /* START CUSTOMIZE */
 #define VERSION_MAJOR 5
-#define VERSION_MINOR 44
+#define VERSION_MINOR 49
 /* END CUSTOMIZE */
 
 /* all the following macros are ABSOLUTELY NECESSARY to have proper string
diff -pruN 3:5.44-1/tests/certs/CACertCRL.pem 3:5.49-1/tests/certs/CACertCRL.pem
--- 3:5.44-1/tests/certs/CACertCRL.pem	2017-08-23 05:03:13.000000000 +0000
+++ 3:5.49-1/tests/certs/CACertCRL.pem	2018-08-31 14:52:52.000000000 +0000
@@ -1,13 +1,13 @@
 -----BEGIN X509 CRL-----
-MIIB/jCB5wIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJwbDEQMA4GA1UE
-CgwHQ0FfY2VydDEQMA4GA1UECwwHQ0FfY2VydDEQMA4GA1UEAwwHQ0FfY2VydDEi
-MCAGCSqGSIb3DQEJARYTQ0FfY2VydEBleGFtcGxlLmNvbRcNMTcwNTI5MTQxMTAw
-WhcNMjcwNjI4MTQxMTAwWjA8MDoCAQMXDTE3MDQyNjE5MDAxM1owJjAYBgNVHRgE
-ERgPMjAxNzA0MjYxOTAwMDBaMAoGA1UdFQQDCgEGoA4wDDAKBgNVHRQEAwIBAjAN
-BgkqhkiG9w0BAQUFAAOCAQEAKzIVMH126DHmfgLmm7jPBi4L6xs0N75zIiay8f2S
-2/XjD7xU3r8vA0Qd06wEUhSe63tqEb+qForNEZwNJpKxM2OW0Z8fTM40793/8WY4
-m6b5IE2SH8mrCUP4ASmB3Jo/uyFPJ+zXhI7Oj59noN+nu/T6DUloJcVMHh0rYeUR
-QpXwdsllJgVVDnqvD4jOVPSVr2NHuMBPk1cw07HZe+V2/xbI/jFNRIKf+KVWE2h8
-4hpiWRONQF9c0eLRskLCqcfyDulpk62hZJV61c4ckGeUyq7aG2N+Ypmm/stnRWGG
-NkSLu99WGPRPjVGderIjBD9I6SNe0LbvUn6t2+DfFoBn4w==
+MIIB7TCB1gIBATANBgkqhkiG9w0BAQsFADBoMQswCQYDVQQGEwJQTDEbMBkGA1UE
+CgwSU3R1bm5lbCBEZXZlbG9wZXJzMRAwDgYDVQQLDAdSb290IENBMQswCQYDVQQD
+DAJDQTEdMBsGCSqGSIb3DQEJARYOQ0FAZXhhbXBsZS5jb20XDTE4MDgzMTE0NTI1
+MVoXDTIyMDgzMTE0NTI1MVowFTATAgIQABcNMTgwODMxMTQ1MjUxWqAjMCEwHwYD
+VR0jBBgwFoAURxFszWdqm1f0uM4OjK2EU+2Y3JswDQYJKoZIhvcNAQELBQADggEB
+AF5ek7J4dLGcByBVk47iw4nbXxzUG8+rpiXPEqzXYZ/HaNZhrDJ/pU0866k82DsV
+Uk7+jwAK4thVMR4vSfAjc2QnLc0XU90WiEuU+eRncIkAzIvEk6NepiEBQ38Lasaf
+LCQ+vd43r2UBUic/1ffoIuLcCEg5SWLrgjStR6m9844ZumMnXKBM5NrGLx8irdBL
+sIwbRxfwYdwHhjX0hN4GsLgchK1puh30lEEONIXwC93/anjFkkUeZT3bIlz0vsO2
+4J4om2yDBKYUtU9X9Xz7ls3Bwyren7s6MwUN38jkZjswWrR16qmCMAIsWGpGeSvJ
+RXksMpYNlZwOUQD25me0EdY=
 -----END X509 CRL-----
diff -pruN 3:5.44-1/tests/certs/CACert.pem 3:5.49-1/tests/certs/CACert.pem
--- 3:5.44-1/tests/certs/CACert.pem	2017-08-23 05:03:13.000000000 +0000
+++ 3:5.49-1/tests/certs/CACert.pem	2018-08-31 14:52:52.000000000 +0000
@@ -1,20 +1,22 @@
 -----BEGIN CERTIFICATE-----
-MIIDWTCCAkGgAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJwbDEQ
-MA4GA1UECgwHQ0FfY2VydDEQMA4GA1UECwwHQ0FfY2VydDEQMA4GA1UEAwwHQ0Ff
-Y2VydDEiMCAGCSqGSIb3DQEJARYTQ0FfY2VydEBleGFtcGxlLmNvbTAeFw0xNzA0
-MjYxODQxMDBaFw0xODA0MTMxNTQ1MDBaMGcxCzAJBgNVBAYTAnBsMRAwDgYDVQQK
-DAdDQV9jZXJ0MRAwDgYDVQQLDAdDQV9jZXJ0MRAwDgYDVQQDDAdDQV9jZXJ0MSIw
-IAYJKoZIhvcNAQkBFhNDQV9jZXJ0QGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEAr8xh9XMrSTxiwLDWGw9eMtFJSAGyNTaoBKPgfuQd
-+cv+EQrDLrE+h0ywctdzBLooxyu0ZxMOXQV/Z726f8WJsEjWIUvoOnCs3OT1Q8PJ
-V39z8Tuw5aWQRJ9uwyr1q+YV897NRCNeT8LrRFls9XZGsHz8Wd8glwwPQ67fR/bS
-eP3GvhHPJqGNh3QvybUbK52klUQMVN4MEtSNFFcxp6hwEWhuID12ychFUNVOL/Fu
-eCUjBUVufREqs+iIbmgpLKLCPc9BULXhUY+O9DYP9ahjXikdtP5xQ9AqviossWLG
-ubxNlYBOYOzpeZIZMZyyAHQ7oYBXtCJFyNMap0/2ABI1twIDAQABoxAwDjAMBgNV
-HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCXA7LBokSKKpwdPMthpvm8f08h
-/GnY8zF7S+UrNEIZAxpAr/p+GJOZqHjLMhUjdW5Jbazuyl7W0mlatUoTzXx35PJt
-oC1jL2K1viTuEtciPt3SVgeBysTPTCw2ZDJSsXZ2X8dFhrk0Gsc3DDjOiyCLcKEz
-oOE97ZomwATnNcVBq735zBCNEj967rOjmDUJsuVfqiIWfhjfYaw9MEj3d0FcJb1v
-3FPQ89fMM/Z3NpkL5I8+g+TKOlhvc1WDbqcBsiG/CVQo4+ClT73XZqL4woFvDaq6
-b32pz28GqKKxWzv5e4m/9cTt8F7PZIc5hJBsyeBdtFSup2zntCop/qtiT5HQ
+MIIDtjCCAp6gAwIBAgIJAMwoDh67DqKyMA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNV
+BAYTAlBMMRswGQYDVQQKDBJTdHVubmVsIERldmVsb3BlcnMxEDAOBgNVBAsMB1Jv
+b3QgQ0ExCzAJBgNVBAMMAkNBMR0wGwYJKoZIhvcNAQkBFg5DQUBleGFtcGxlLmNv
+bTAeFw0xODA4MzExNDUyNTFaFw0xODA5MzAxNDUyNTFaMGgxCzAJBgNVBAYTAlBM
+MRswGQYDVQQKDBJTdHVubmVsIERldmVsb3BlcnMxEDAOBgNVBAsMB1Jvb3QgQ0Ex
+CzAJBgNVBAMMAkNBMR0wGwYJKoZIhvcNAQkBFg5DQUBleGFtcGxlLmNvbTCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKLiq1ZejziUKMasKUB/w9/KggdO
+eCFtxFNadyDyCwDKZ1ZruwTIGRUyTEa6Dm2IP61YXIDGgN1pMaQsxPeYIA6mrvI0
+k6fD+9uVmjLMsSPqHIJlCH2vVFyO7+sCpSzTBJ++MJDs9VTYKTFkLikTR29JHYyM
+2VUEAdcLDJMCw4luiUlvAC8bNWfhAqduyZKrDqDfdEB+1jLdCpazZHzTtePCM1jQ
+fyrns6AkD1CiAOfCEu23oIYNnTvPszVZdYokBaHkvWNfuXtRyogKp1xfq/SX8mBE
+lh1+oqKBsyKnRCiJvwWAR0tu5j1R45AhqmSM3s9RrUUxjIAD4PEadFnkZfUCAwEA
+AaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQURxFszWdqm1f0uM4OjK2E
+U+2Y3JswHwYDVR0jBBgwFoAURxFszWdqm1f0uM4OjK2EU+2Y3JswDgYDVR0PAQH/
+BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4IBAQAxy0BfXLCde9QU95NquYAXelBCtDMd
+Qdth4cniUPw4tITnqEgib4BTAn91KNBlCtaw1OByciMw8eMF2T3h1ZdMz3OFXgHY
+PYgHvNavSlEyHpgOkR8hjKNvm9Gg9vZXd4xkgh3ROUTKXh8mliBFUYpD7jxJLMf/
+JS5oPbo8p+RBWDAwoJQZ2utJE+FrMZlXogYLGkEfcULMVj0wglmBIv+GZ4oqbyY4
+ef/ebvutDO2tLevHOBqFFn9riLAyFQ2GHeay6WiJ8do9YQlrVu4GduSkv5NxMZ86
+WyGuISRlQSL80V2HCOUyX+IQjnnk5ktWIiAZD0yPpjJKIsXyf8XYA6i0
 -----END CERTIFICATE-----
diff -pruN 3:5.44-1/tests/certs/cafile.pem 3:5.49-1/tests/certs/cafile.pem
--- 3:5.44-1/tests/certs/cafile.pem	2017-08-23 05:03:13.000000000 +0000
+++ 3:5.49-1/tests/certs/cafile.pem	1970-01-01 00:00:00.000000000 +0000
@@ -1,23 +0,0 @@
------BEGIN CERTIFICATE-----
-MIID5TCCAs2gAwIBAgIJAJoOR3t6TXSbMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYD
-VQQGEwJVUzETMBEGA1UECAwKQ2Fsb2Zvcm5pYTESMBAGA1UEBwwJU2FjcmFtZXRv
-MRgwFgYDVQQKDA9FeGFtcGxlIENvbXBhbnkxHDAaBgNVBAsME1RlY2hub2xvZ3kg
-RGl2aXNpb24xGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNjA5MjkwODI5
-MjNaFw0xNzA5MjkwODI5MjNaMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2Fs
-b2Zvcm5pYTESMBAGA1UEBwwJU2FjcmFtZXRvMRgwFgYDVQQKDA9FeGFtcGxlIENv
-bXBhbnkxHDAaBgNVBAsME1RlY2hub2xvZ3kgRGl2aXNpb24xGDAWBgNVBAMMD3d3
-dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKi0
-nOJAoZIimJkLQ3A6osD2ZgX635Esqwb819plRyDOc9Lyt2CKiVrLyHNXrZQE7FRC
-6Uq5evb1EQYie0eTxzp8n0lOw/R4goapksLk+yLiVJXt76/ivLjATTC2B5uxUyiO
-euZDFiVO9jjfTGeG0ASdkrL69Ngw6EdkzjvvFc1XCDMLy5UZ59d9x6PNncIUJk7l
-FcxCGSh5qlggj3lHTc/9nHpz5gZpLbq4DFdsGMOfNSkjyes2dFbnHKAQrq6s49ns
-7X3iYCmJF2mfVDCtca3+NYgvujdBGGO2FaX1P9VTtBUTomO9NGcphJGGayRwtpf6
-14F4aY1KRjoq9Ln4fHkCAwEAAaNQME4wHQYDVR0OBBYEFA0sd/zjLicJm3nWXEqU
-IPMpNB2VMB8GA1UdIwQYMBaAFA0sd/zjLicJm3nWXEqUIPMpNB2VMAwGA1UdEwQF
-MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAH+NDRfE44vMKv8Wfx8PZ08QlSTsyUt5
-vvEnxum6j3Hj+LDiAEXzlZ5oxX/zNEVHPAkwcvhs7dgRFNJ8+SlebGzk+u//53rW
-iOqMD1YKiFxmzVa+KlQIHBE/yO24/XG/pe7PVtZV8pF2w8Wi1ppTrZt1pzCRPiCM
-ga7ijgizp+972wt33YRWnX486XuolYc3gMLIha9vADodRH+tYtkEY6TnCga+tz4u
-LGY5eMbTTUIOEK4rGxr78FruEYOBZPKq0CtSwlGT2MMVngYg+ah51rIU6V0DXA+W
-B9YmCA2mrCMtCVaUbiQ3Zc+dHTtmameVNtv7RQGnCDY7zWPyXjmZ1oU=
------END CERTIFICATE-----
diff -pruN 3:5.44-1/tests/certs/client_cert.pem 3:5.49-1/tests/certs/client_cert.pem
--- 3:5.44-1/tests/certs/client_cert.pem	2017-08-23 05:03:13.000000000 +0000
+++ 3:5.49-1/tests/certs/client_cert.pem	2018-08-31 14:52:52.000000000 +0000
@@ -1,48 +1,49 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEA2aO1hQpGK5z3OsLeyRbqb0B0cjt+cO3sTQ4+KU05BNWjGXso
-3KwN9Bx7Nx0Tu73Ub2CeeUKmbeCWYzuvbx/dUeH1NcOPIk07aHqx79aaTuOhnogG
-Kjmq2UcdAtmhLo8OSBm9MSq+UYEIC3S4dMaIDHFIVEIcjUVYgLYKv2k7JSH9oVVV
-rm0PxKkpnBZXx5OE3jpq5Zy+1yMQs+FJzVf98FrezAQQiqlKCDCpVqknbGiJk0X2
-lDWcIl8nqmmSvSevr2U6Ggnu1d47N6gEX5BnEBsRABbb1sdrf18cbFP+Dq285yl1
-wFDmq2c7KzCocQAETULJZ9QblG6qkrvMrlmq+QIDAQABAoIBACtVfloMDqa2bT+E
-94kAiBM4uTbZg7aGmQtKr7PXjWfaBcyYCi3OEEUvupThtEEobfjzOvqX+71a/3ao
-tqigppecLw/SbVh+GjsWWwGPMFBO4KpJGTklHFCA6VTc8kvr7gMLJPF6OkTONUTa
-q7OMqCAaGjW0qCy0xwdxt7gfAsjEmtLNH7rLocQFk56y0Nz68jWLIMjnRxAq3NaQ
-ZgGE0NRwxUPhgbYl0s3MmhDPulth8+FLryZ8pmIZkKphtIvSXSPQBivdLAUkkhFx
-elUu9xHHXbqHhnCGjPjwK4CUGGp2m6mlCev/OlcHkzKWcBOJZKaAoWAQMGqCg0bu
-OS0T79UCgYEA7279C7IW7EgI9co4exxZl41gMuZxEcQzXAaHwx2m//9sPm6CczZt
-5OIAsenFU7b8hWCO5hJro7hhbp2YBTqtfQNM6KaY33W8iH6k7JcO+HfpLGHcNz1P
-S4+31Kj4k5dnz1us90uv8A77Jji1OSTJTBCgyrgmfGhPzqQnbNWNV+8CgYEA6LKw
-cYmzBUL//H2Y5HYafqOYlsC5YVGZTm//mp7DpGXdi2twmATskcnQ8BR5WtZ5Ca+2
-VHEoEAUTRLbX+CoUKeE34mnIXTIEU0dzRmw3CMK4DZVRPnIYaqckJH6GLxwCEMZE
-zlI8Hks+OrCSVgKYsKqMiOdTDdNoX4/9WaQ9A5cCgYEA6r8IfXUHoHUnw8OWCK3M
-8Rd9H6prZR3VtP36EUR7PTYx7Cvw3gCZUfR69fPasa8Qebwnnk6lFglqDUeZilbz
-TUP1HYxpCX2ncLOqAwQ/e0AlbowrmkUT/2NSur9Hp3ykHNsnA/ZC8rvdZKXol7QH
-X/pViyttIEAtLs4mkT/2qiUCgYBJfbXQBecuMDzcp2YUMWCowk48vl1N6RF7/k9B
-rAap8yoHEEWdHWEBojWEvVKeZ8IOVxpEjQBUHuY4+242CEQZ/fFCZppLJLLNAnHb
-ue2frK+oSpJAIJSpimQVyofidPwKBDRS3RHzl1vt+ToeQ++pTBPaYQSQB0add8JR
-/1btvQKBgG2uNFimmJ29DKSt8nRXm7wUkdQNORTZa0wygZbDaQgHxyiHOY9TgfhF
-PQHI/7abb/9PrMhchTWjV7w/e0E6q9Sc4kG1tz5MV9pWreXY7Uolg532zUsYqZVW
-0tQbWQR2fk+3ZoN9qHYZqYE/coqNdbtpLUIVWh3Yrh3V6L9Xw0us
------END RSA PRIVATE KEY-----
 -----BEGIN CERTIFICATE-----
-MIIDZjCCAk6gAwIBAgIBBDANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJwbDEQ
-MA4GA1UECgwHQ0FfY2VydDEQMA4GA1UECwwHQ0FfY2VydDEQMA4GA1UEAwwHQ0Ff
-Y2VydDEiMCAGCSqGSIb3DQEJARYTQ0FfY2VydEBleGFtcGxlLmNvbTAeFw0xNzA0
-MjYxODQ1MDBaFw0xODA0MTMxNTQ1MDBaMIGFMQswCQYDVQQGEwJwbDEPMA0GA1UE
-CBMGY2xpZW50MQ8wDQYDVQQHEwZjbGllbnQxDzANBgNVBAoTBmNsaWVudDEPMA0G
-A1UECxMGY2xpZW50MQ8wDQYDVQQDEwZjbGllbnQxITAfBgkqhkiG9w0BCQEWEmNs
-aWVudEBleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-ANmjtYUKRiuc9zrC3skW6m9AdHI7fnDt7E0OPilNOQTVoxl7KNysDfQcezcdE7u9
-1G9gnnlCpm3glmM7r28f3VHh9TXDjyJNO2h6se/Wmk7joZ6IBio5qtlHHQLZoS6P
-DkgZvTEqvlGBCAt0uHTGiAxxSFRCHI1FWIC2Cr9pOyUh/aFVVa5tD8SpKZwWV8eT
-hN46auWcvtcjELPhSc1X/fBa3swEEIqpSggwqVapJ2xoiZNF9pQ1nCJfJ6ppkr0n
-r69lOhoJ7tXeOzeoBF+QZxAbEQAW29bHa39fHGxT/g6tvOcpdcBQ5qtnOyswqHEA
-BE1CyWfUG5RuqpK7zK5ZqvkCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAZO2G+h4X
-UUMB0uVIiz/+iX9b/EifbLwLs87zEAzfYlWCr0pq2DGMxhEUq+vSxr3j3YV1I6Rz
-y2Ao2CyWI/2NoS0Jvf2MpyX+lmGV1diFJWOl4BFf5MzTU1Smc0ryulVV2uOadbkt
-ekwHYaoohAg9aQe1DXFJV7ZSwoM3KfaJmaGV+BlOSqD6TGs75jmUwG11GyTEebg9
-DxXm39mEczVnxLIZNIv4zv0DYIof4sAzMhnGqSesqoUjJeSUUVysp7Mwmk4E48WA
-wCiubahEe0boWHlrT2is5tF88Fwkjjcwqw2jQX1+LeWiB/RA3kNxU4WTx0BFLvyH
-lfwzVP+lAnWMng==
+MIIDoDCCAoigAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwaDELMAkGA1UEBhMCUEwx
+GzAZBgNVBAoMElN0dW5uZWwgRGV2ZWxvcGVyczEQMA4GA1UECwwHUm9vdCBDQTEL
+MAkGA1UEAwwCQ0ExHTAbBgkqhkiG9w0BCQEWDkNBQGV4YW1wbGUuY29tMB4XDTE4
+MDgzMTE0NTI1MVoXDTIyMDgzMTE0NTI1MVowbzELMAkGA1UEBhMCUEwxGzAZBgNV
+BAoMElN0dW5uZWwgRGV2ZWxvcGVyczEPMA0GA1UECwwGY2xpZW50MQ8wDQYDVQQD
+DAZjbGllbnQxITAfBgkqhkiG9w0BCQEWEmNsaWVudEBleGFtcGxlLmNvbTCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOQPrlToMIdTnwvc5H1japRuWNkL
+G5gBQmxvheasgiHI3MU9Iaaqfg162Wj7UbF/7+u3fonCmOUk9qJGopIh0RukpvQY
+KGhBGAoHXvPOwP15016X5ayCnbl3406wpnWeDnerhuSeaPHdan2/eGjOxeHL3nEA
+6beUJ+LM5OJCAaIo36LB/7sym4OgtVakBBKtnGcp9/LdeSJPgNd6vOqM1O3BZzOB
+yR2eVJmbGc3GrZRNHb5RC/3MTp2gaBkIZZcaRyZVzme54NHnxRZyMLqXo1zTz9Gc
+w5K2uno7SBRvQtBVhgcI4CgKIG07zSvjqI7/echMkNFxN/AYK28OhX4P9a8CAwEA
+AaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUZgW1rnb1qNhMp7oanHEpsUiRhOIw
+HwYDVR0jBBgwFoAURxFszWdqm1f0uM4OjK2EU+2Y3JswDQYJKoZIhvcNAQELBQAD
+ggEBABpxDuFkaknN3i40/pd5GvX42C34iezOtXOVeo+c4y0/0Dsn8GtUE1EyjjMy
+Zd29Aw9OkfNbqxwf1OAWQG1ICUx5xVyjQKUoebkw128SIwdjhQJ/o/bDUA8vaupS
+tyATbKTSuXzN/jUO6G7eBibsHlPHcTM4BvjO5vkBQ85wvWmzBCXCS9YcdNs2RBJk
+IrQoVrmrBTcBY10k/ndccy95ZWhOvgkWZY0EouLLFmlxu6q+8Nl7aqrg4HsY9cZe
+TJffpIrT/0WepbX/2DR519Sazs2VLlDX4Fa4t/h3ZF1ITTU+h11A6fBTTNf7pZw/
+vKHLqotxaGbttLsuBq2InId1TAw=
 -----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEA5A+uVOgwh1OfC9zkfWNqlG5Y2QsbmAFCbG+F5qyCIcjcxT0h
+pqp+DXrZaPtRsX/v67d+icKY5ST2okaikiHRG6Sm9BgoaEEYCgde887A/XnTXpfl
+rIKduXfjTrCmdZ4Od6uG5J5o8d1qfb94aM7F4cvecQDpt5Qn4szk4kIBoijfosH/
+uzKbg6C1VqQEEq2cZyn38t15Ik+A13q86ozU7cFnM4HJHZ5UmZsZzcatlE0dvlEL
+/cxOnaBoGQhllxpHJlXOZ7ng0efFFnIwupejXNPP0ZzDkra6ejtIFG9C0FWGBwjg
+KAogbTvNK+Oojv95yEyQ0XE38Bgrbw6Ffg/1rwIDAQABAoIBAED0nmicgUXp8UDF
+t2ZnLHH+Q9v9p+xRX4PW98JNm/rXZNngoXcA1EoulUGrYwc1MzZl2uqNvFJ3hq+N
+grwwWYiQCuU3BDs9XwVsOAUk/B611hf5F3dc9GNg3CMLeT3CuMgo2JDA9Y79y1jp
+cfgX/JBlKoPxCKA62GlmhkJTHnf6toyw72zXvPkwMKbzqGsD1O/LUcHGN2f8WiOB
+FY9oVq+NRQd9N4zNzpYGcvMzL0wRYGI+GmSlkIG3M3EMKDL6GJoxvvXIu3U34nGZ
+l2VxbU21MtLb7Jhr/+FMVWpoKBCP0Z3Wr41mHXeO3uvzACCSiBdHodxTzixwxO4d
+ctE2V6ECgYEA+nfT/aiWPMyrzdCuQO4HL+ncO9ii1cQusd9KbWXBsXtRDN67tRX4
+MKjAI1N6YIYsN5GijVFQllbsLKU5cXcnbSsXbh5O9Vear/8BinDt+tmhXVpcp7uQ
+wwsSCPjcHc2tHzeJs+XRixYZROlAIPPfhZruL6lJyt0wvz3c46zwSAcCgYEA6Rkp
+lV9XvmdXE7JWNpW9G9MEegJ5tb4iiOqYJPD6H77btEMiFxMDfdRskqqZgiRBQoH0
+EyrE/urKp1tYxR9XVOqr4vCv8Wc4GnmOGGFnyicp/dWnFjZuLzVIJlspj8+q+j/D
+A7d1oTHFbgbC2mvv3FfxcO3s94HmAUJ4JAQSaxkCgYBxFDBtUPOjN3RJU3GYdt5f
+z2FS05eQkyXRwFHF2i78hgQtn1F3jBelQEqeqE2Tzn+gBuwwiQmtFklCTsYEaBsw
+uke1u5FCSu7XjnWPnzSSEDc+AlHamF/e7tyRmGkoO3dxpI1S3usftDZsWjJNrky3
+8R6f/foG0J31eWSElctVeQKBgCDRbRxdtxHUpNreEetPe7eOJyQycwZWhbA3L0KM
+Nvr/ORmRFhyfja9KmBqyMDi1eAawGzgTnnaxgeS8JKxkNDx9acPi1TKssKZxlMLz
++9PnXa8iRIsJEMxOuSDFVv2rZEwlbAR68PHH+x75jreH2NZx/0lCBkn2nPZycE3J
+0PoJAoGAAXjmmnCwqDaIXRJfyP1IBN2vg2iWQtnHzXe7Xat9Vtz2j/O2pzI2L5WP
+k0uZqw6OfZ9xO4wbVPKbSmpMKqM91TNr0xnIfHiJUKxAxT5PmymvGslU5HTUTSU/
+tmv5Pq6R5pdi5++fgtzdaBqva3V69J9Cp1kVyFlF9DARAaVS1iY=
+-----END RSA PRIVATE KEY-----
diff -pruN 3:5.44-1/tests/certs/Makefile.am 3:5.49-1/tests/certs/Makefile.am
--- 3:5.44-1/tests/certs/Makefile.am	1970-01-01 00:00:00.000000000 +0000
+++ 3:5.49-1/tests/certs/Makefile.am	2018-08-31 14:49:02.000000000 +0000
@@ -0,0 +1,14 @@
+## Process this file with automake to produce Makefile.in
+# by Michal Trojnara 1998-2018
+
+EXTRA_DIST = maketestcert.sh openssltest.cnf
+EXTRA_DIST += CACertCRL.pem CACert.pem
+EXTRA_DIST += server_cert.pem server_cert.p12 client_cert.pem
+EXTRA_DIST += revoked_cert.pem stunnel.pem PeerCerts.pem
+EXTRA_DIST += psk1.txt psk2.txt secrets.txt
+
+check-local:
+	$(srcdir)/maketestcert.sh
+
+dist-local:
+	$(srcdir)/maketestcert.sh
diff -pruN 3:5.44-1/tests/certs/Makefile.in 3:5.49-1/tests/certs/Makefile.in
--- 3:5.44-1/tests/certs/Makefile.in	1970-01-01 00:00:00.000000000 +0000
+++ 3:5.49-1/tests/certs/Makefile.in	2018-08-31 14:51:16.000000000 +0000
@@ -0,0 +1,457 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# by Michal Trojnara 1998-2018
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = tests/certs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/src/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFAULT_GROUP = @DEFAULT_GROUP@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANDOM_FILE = @RANDOM_FILE@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SSLDIR = @SSLDIR@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = maketestcert.sh openssltest.cnf CACertCRL.pem CACert.pem \
+	server_cert.pem server_cert.p12 client_cert.pem \
+	revoked_cert.pem stunnel.pem PeerCerts.pem psk1.txt psk2.txt \
+	secrets.txt
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/certs/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu tests/certs/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: all all-am check check-am check-local clean clean-generic \
+	clean-libtool cscopelist-am ctags-am distclean \
+	distclean-generic distclean-libtool distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
+	uninstall-am
+
+.PRECIOUS: Makefile
+
+
+check-local:
+	$(srcdir)/maketestcert.sh
+
+dist-local:
+	$(srcdir)/maketestcert.sh
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff -pruN 3:5.44-1/tests/certs/maketestcert.sh 3:5.49-1/tests/certs/maketestcert.sh
--- 3:5.44-1/tests/certs/maketestcert.sh	1970-01-01 00:00:00.000000000 +0000
+++ 3:5.49-1/tests/certs/maketestcert.sh	2018-08-31 14:49:02.000000000 +0000
@@ -0,0 +1,114 @@
+#!/bin/sh
+
+result_path=$(pwd)
+cd $(dirname "$0")
+script_path=$(pwd)
+cd "${result_path}"
+
+mkdir "tmp/"
+
+# create new psk secrets
+gen_psk () {
+  tr -c -d 'A-Za-z0-9' </dev/urandom 2>> "maketestcert.log" | head -c 50 > tmp/psk.txt
+  if [ -s tmp/psk.txt ]
+    then
+      printf "test$1:" > tmp/psk$1.txt
+      cat tmp/psk.txt >> tmp/psk$1.txt 2>> "maketestcert.log"
+      printf "\n" >> tmp/psk$1.txt
+    fi
+  rm -f tmp/psk.txt
+}
+
+export LC_ALL=C
+gen_psk 1
+cat tmp/psk1.txt > tmp/secrets.txt 2>> "maketestcert.log"
+gen_psk 2
+cat tmp/psk2.txt >> tmp/secrets.txt 2>> "maketestcert.log"
+gen_psk 2
+
+# OpenSSL settings
+CONF="${script_path}/openssltest.cnf"
+
+if test -n "$1"; then
+    OPENSSL="$2/bin/openssl"
+    LD_LIBRARY_PATH="$2/lib"
+else
+    OPENSSL=openssl
+fi
+
+mkdir "demoCA/"
+touch "demoCA/index.txt"
+touch "demoCA/index.txt.attr"
+echo 1000 > "demoCA/serial"
+
+# generate a self-signed certificate
+$OPENSSL req -config $CONF -new -x509 -keyout tmp/stunnel.pem -out tmp/stunnel.pem \
+    -subj "/C=PL/ST=Mazovia Province/L=Warsaw/O=Stunnel Developers/OU=Provisional CA/CN=localhost/emailAddress=stunnel@example.com" \
+    1>&2 2>> "maketestcert.log"
+
+# generate root CA certificate
+$OPENSSL genrsa -out demoCA/CA.key 1>&2 2>> "maketestcert.log"
+$OPENSSL req -config $CONF -new -x509 -key demoCA/CA.key -out tmp/CACert.pem \
+    -subj "/C=PL/O=Stunnel Developers/OU=Root CA/CN=CA/emailAddress=CA@example.com" \
+    1>&2 2>> "maketestcert.log"
+
+# generate a certificate to revoke
+$OPENSSL genrsa -out demoCA/revoked.key 1>&2 2>> "maketestcert.log"
+$OPENSSL req -config $CONF -new -key demoCA/revoked.key -out demoCA/revoked.csr \
+    -subj "/C=PL/O=Stunnel Developers/OU=revoked/CN=revoked/emailAddress=revoked@example.com" \
+    1>&2 2>> "maketestcert.log"
+
+$OPENSSL ca -config $CONF -batch -in demoCA/revoked.csr -out demoCA/revoked.cer 1>&2 2>> "maketestcert.log"
+
+$OPENSSL x509 -in demoCA/revoked.cer -out tmp/revoked_cert.pem 1>&2 2>> "maketestcert.log"
+cat demoCA/revoked.key >> tmp/revoked_cert.pem 2>> "maketestcert.log"
+
+# revoke above certificate and generate CRL file
+$OPENSSL ca -config $CONF -revoke demoCA/1000.pem 1>&2 2>> "maketestcert.log"
+$OPENSSL ca -config $CONF -gencrl -out tmp/CACertCRL.pem 1>&2 2>> "maketestcert.log"
+
+# generate a client certificate
+$OPENSSL genrsa -out demoCA/client.key 1>&2 2>> "maketestcert.log"
+$OPENSSL req -config $CONF -new -key demoCA/client.key -out demoCA/client.csr \
+    -subj "/C=PL/O=Stunnel Developers/OU=client/CN=client/emailAddress=client@example.com" \
+    1>&2 2>> "maketestcert.log"
+
+$OPENSSL ca -config $CONF -batch -in demoCA/client.csr -out demoCA/client.cer 1>&2 2>> "maketestcert.log"
+
+$OPENSSL x509 -in demoCA/client.cer -out tmp/client_cert.pem 1>&2 2>> "maketestcert.log"
+cat tmp/client_cert.pem > tmp/PeerCerts.pem 2>> "maketestcert.log"
+cat demoCA/client.key >> tmp/client_cert.pem 2>> "maketestcert.log"
+
+# generate a server certificate
+$OPENSSL genrsa -out demoCA/server.key 1>&2 2>> "maketestcert.log"
+$OPENSSL req -config $CONF -new -key demoCA/server.key -out demoCA/server.csr \
+    -subj "/C=PL/O=Stunnel Developers/OU=server/CN=server/emailAddress=server@example.com" \
+    1>&2 2>> "maketestcert.log"
+
+$OPENSSL ca -config $CONF -batch -in demoCA/server.csr -out demoCA/server.cer 1>&2 2>> "maketestcert.log"
+
+$OPENSSL x509 -in demoCA/server.cer -out tmp/server_cert.pem 1>&2 2>> "maketestcert.log"
+cat tmp/server_cert.pem >> tmp/PeerCerts.pem 2>> "maketestcert.log"
+cat demoCA/server.key >> tmp/server_cert.pem 2>> "maketestcert.log"
+
+# create a PKCS#12 file with a server certificate
+$OPENSSL pkcs12 -export -in tmp/server_cert.pem -out tmp/server_cert.p12 -passout pass: 1>&2 2>> "maketestcert.log"
+
+# copy new files
+if [ -s tmp/stunnel.pem ] && [ -s tmp/CACert.pem ] && [ -s tmp/CACertCRL.pem ] && \
+   [ -s tmp/revoked_cert.pem ] && [ -s tmp/client_cert.pem ] &&  [ -s tmp/server_cert.pem ] && \
+   [ -s tmp/PeerCerts.pem ] && [ -s tmp/server_cert.p12 ] && \
+   [ -s tmp/psk1.txt ] && [ -s tmp/psk2.txt ] && [ -s tmp/secrets.txt ]
+  then
+    cp tmp/* ./
+    printf "%s\n" "keys & certificates successfully generated"
+    printf "%s\n" "./maketestcert.sh finished"
+    rm -f "maketestcert.log"
+  else
+    printf "%s\n" "./maketestcert.sh failed"
+    printf "%s\n" "error logs ${result_path}/maketestcert.log"
+  fi
+
+# remove the working directory
+rm -rf "demoCA/"
+rm -rf "tmp/"
diff -pruN 3:5.44-1/tests/certs/openssltest.cnf 3:5.49-1/tests/certs/openssltest.cnf
--- 3:5.44-1/tests/certs/openssltest.cnf	1970-01-01 00:00:00.000000000 +0000
+++ 3:5.49-1/tests/certs/openssltest.cnf	2018-08-31 14:49:02.000000000 +0000
@@ -0,0 +1,60 @@
+# OpenSSL root CA configuration file
+
+[ ca ]
+default_ca = CA_default
+
+[ CA_default ]
+# Directory and file locations.
+dir                             = .
+certs                           = $dir/demoCA
+crl_dir                         = $dir/demoCA
+new_certs_dir                   = $dir/demoCA
+database                        = $dir/demoCA/index.txt
+serial                          = $dir/demoCA/serial
+crl_extensions                  = crl_ext
+default_crl_days                = 1461
+default_days                    = 1461
+default_md                      = sha256
+preserve                        = no
+policy                          = policy_match
+x509_extensions                 = usr_cert
+private_key                     = $dir/demoCA/CA.key
+certificate                     = $dir/tmp/CACert.pem
+
+[ req ]
+encrypt_key                     = no
+default_bits                    = 2048
+default_md                      = sha256
+string_mask                     = utf8only
+x509_extensions                 = ca_extensions
+distinguished_name              = req_distinguished_name
+
+[ crl_ext ]
+authorityKeyIdentifier          = keyid:always
+
+[ usr_cert ]
+basicConstraints                = CA:FALSE
+subjectKeyIdentifier            = hash
+authorityKeyIdentifier          = keyid, issuer
+
+[ ca_extensions ]
+basicConstraints                = critical, CA:true
+subjectKeyIdentifier            = hash
+authorityKeyIdentifier          = keyid:always,issuer
+keyUsage                        = critical, digitalSignature, cRLSign, keyCertSign
+
+[ policy_match ]
+countryName                     = match
+organizationName                = match
+organizationalUnitName          = optional
+commonName                      = supplied
+emailAddress                    = optional
+
+[ req_distinguished_name ]
+countryName                     = Country Name (2 letter code)
+stateOrProvinceName             = State or Province Name
+localityName                    = Locality Name
+0.organizationName              = Organization Name
+organizationalUnitName          = Organizational Unit Name
+commonName                      = Common Name
+emailAddress                    = Email Address
diff -pruN 3:5.44-1/tests/certs/PeerCerts.pem 3:5.49-1/tests/certs/PeerCerts.pem
--- 3:5.44-1/tests/certs/PeerCerts.pem	2017-08-23 05:03:13.000000000 +0000
+++ 3:5.49-1/tests/certs/PeerCerts.pem	2018-08-31 14:52:52.000000000 +0000
@@ -1,41 +1,44 @@
 -----BEGIN CERTIFICATE-----
-MIIDZjCCAk6gAwIBAgIBBDANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJwbDEQ
-MA4GA1UECgwHQ0FfY2VydDEQMA4GA1UECwwHQ0FfY2VydDEQMA4GA1UEAwwHQ0Ff
-Y2VydDEiMCAGCSqGSIb3DQEJARYTQ0FfY2VydEBleGFtcGxlLmNvbTAeFw0xNzA0
-MjYxODQ1MDBaFw0xODA0MTMxNTQ1MDBaMIGFMQswCQYDVQQGEwJwbDEPMA0GA1UE
-CBMGY2xpZW50MQ8wDQYDVQQHEwZjbGllbnQxDzANBgNVBAoTBmNsaWVudDEPMA0G
-A1UECxMGY2xpZW50MQ8wDQYDVQQDEwZjbGllbnQxITAfBgkqhkiG9w0BCQEWEmNs
-aWVudEBleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-ANmjtYUKRiuc9zrC3skW6m9AdHI7fnDt7E0OPilNOQTVoxl7KNysDfQcezcdE7u9
-1G9gnnlCpm3glmM7r28f3VHh9TXDjyJNO2h6se/Wmk7joZ6IBio5qtlHHQLZoS6P
-DkgZvTEqvlGBCAt0uHTGiAxxSFRCHI1FWIC2Cr9pOyUh/aFVVa5tD8SpKZwWV8eT
-hN46auWcvtcjELPhSc1X/fBa3swEEIqpSggwqVapJ2xoiZNF9pQ1nCJfJ6ppkr0n
-r69lOhoJ7tXeOzeoBF+QZxAbEQAW29bHa39fHGxT/g6tvOcpdcBQ5qtnOyswqHEA
-BE1CyWfUG5RuqpK7zK5ZqvkCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAZO2G+h4X
-UUMB0uVIiz/+iX9b/EifbLwLs87zEAzfYlWCr0pq2DGMxhEUq+vSxr3j3YV1I6Rz
-y2Ao2CyWI/2NoS0Jvf2MpyX+lmGV1diFJWOl4BFf5MzTU1Smc0ryulVV2uOadbkt
-ekwHYaoohAg9aQe1DXFJV7ZSwoM3KfaJmaGV+BlOSqD6TGs75jmUwG11GyTEebg9
-DxXm39mEczVnxLIZNIv4zv0DYIof4sAzMhnGqSesqoUjJeSUUVysp7Mwmk4E48WA
-wCiubahEe0boWHlrT2is5tF88Fwkjjcwqw2jQX1+LeWiB/RA3kNxU4WTx0BFLvyH
-lfwzVP+lAnWMng==
+MIIDoDCCAoigAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwaDELMAkGA1UEBhMCUEwx
+GzAZBgNVBAoMElN0dW5uZWwgRGV2ZWxvcGVyczEQMA4GA1UECwwHUm9vdCBDQTEL
+MAkGA1UEAwwCQ0ExHTAbBgkqhkiG9w0BCQEWDkNBQGV4YW1wbGUuY29tMB4XDTE4
+MDgzMTE0NTI1MVoXDTIyMDgzMTE0NTI1MVowbzELMAkGA1UEBhMCUEwxGzAZBgNV
+BAoMElN0dW5uZWwgRGV2ZWxvcGVyczEPMA0GA1UECwwGY2xpZW50MQ8wDQYDVQQD
+DAZjbGllbnQxITAfBgkqhkiG9w0BCQEWEmNsaWVudEBleGFtcGxlLmNvbTCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOQPrlToMIdTnwvc5H1japRuWNkL
+G5gBQmxvheasgiHI3MU9Iaaqfg162Wj7UbF/7+u3fonCmOUk9qJGopIh0RukpvQY
+KGhBGAoHXvPOwP15016X5ayCnbl3406wpnWeDnerhuSeaPHdan2/eGjOxeHL3nEA
+6beUJ+LM5OJCAaIo36LB/7sym4OgtVakBBKtnGcp9/LdeSJPgNd6vOqM1O3BZzOB
+yR2eVJmbGc3GrZRNHb5RC/3MTp2gaBkIZZcaRyZVzme54NHnxRZyMLqXo1zTz9Gc
+w5K2uno7SBRvQtBVhgcI4CgKIG07zSvjqI7/echMkNFxN/AYK28OhX4P9a8CAwEA
+AaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUZgW1rnb1qNhMp7oanHEpsUiRhOIw
+HwYDVR0jBBgwFoAURxFszWdqm1f0uM4OjK2EU+2Y3JswDQYJKoZIhvcNAQELBQAD
+ggEBABpxDuFkaknN3i40/pd5GvX42C34iezOtXOVeo+c4y0/0Dsn8GtUE1EyjjMy
+Zd29Aw9OkfNbqxwf1OAWQG1ICUx5xVyjQKUoebkw128SIwdjhQJ/o/bDUA8vaupS
+tyATbKTSuXzN/jUO6G7eBibsHlPHcTM4BvjO5vkBQ85wvWmzBCXCS9YcdNs2RBJk
+IrQoVrmrBTcBY10k/ndccy95ZWhOvgkWZY0EouLLFmlxu6q+8Nl7aqrg4HsY9cZe
+TJffpIrT/0WepbX/2DR519Sazs2VLlDX4Fa4t/h3ZF1ITTU+h11A6fBTTNf7pZw/
+vKHLqotxaGbttLsuBq2InId1TAw=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
-MIIDVDCCAjygAwIBAgIBAjANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJwbDEQ
-MA4GA1UECgwHQ0FfY2VydDEQMA4GA1UECwwHQ0FfY2VydDEQMA4GA1UEAwwHQ0Ff
-Y2VydDEiMCAGCSqGSIb3DQEJARYTQ0FfY2VydEBleGFtcGxlLmNvbTAeFw0xNzA0
-MjYxODQzMDBaFw0xODA0MTMxNTQ1MDBaMHQxCzAJBgNVBAYTAnBsMQ8wDQYDVQQI
-EwZzZXJ2ZXIxDzANBgNVBAoTBnNlcnZlcjEPMA0GA1UECxMGc2VydmVyMQ8wDQYD
-VQQDEwZzZXJ2ZXIxITAfBgkqhkiG9w0BCQEWEnNlcnZlckBleGFtcGxlLmNvbTCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3S0m42/yBrStPI8A8eV0ig
-fehupIp0sDft/zBAf0r7bg7A1rAuJLkupIfm6Dnc0/vK43/pO8rCTQu7Xf9hMXyQ
-TL3Hr7CamjAITJQ3CSwTBXrWfvwzzr+h2SG2U6DKBh9eBhb7f3ndVcwLIc4WCjJy
-45gv5caKF9RSYUYVSun1tRzRI7xEiSMmQPbLJN1WGsP9nICFd4P2jj/cKJpPzU1O
-wEf4V6wm0sdZ2ECJ8hG5PqfKlxCy1UtSpzMaFR+wqKk1Rujx9hR9CycaROe+0Csk
-97DnygirND6V651tzuTheIrcL5tWAIShVgwxdisi1ui8mxSVUv6Q6DHAPLcx7+0C
-AwEAATANBgkqhkiG9w0BAQUFAAOCAQEAiPQrjJbTZ6NB+FO0lJtt5vEBLdepkl6x
-mtopQRxHPZIuUqV8viP9EW2PlrrPkpdbYZtkD0AuCXiqGD9u31kIHKG05GiQYj8q
-XPy55QuOntWfwJc4GEZ9uebYckHGSNLsyubdkneLeXlEZz2RbtCoZS5337nlaUCm
-93Hp/bRCFZ7if9tiscxwTft92z2+Tc5bI4JGAJfex/VgyggpNRLSDDRibNvFrooO
-1kSnDxySyCtysodXfonWpJFA9EAcUHXY6vlGvzLVJRfrqsS7vC/fuKOz684XDYIL
-g/eJED4XR47T8gA85vM8LWl80lXvfFIYsirOnYmeQDSfTRDG9eZG6Q==
+MIIDoDCCAoigAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwaDELMAkGA1UEBhMCUEwx
+GzAZBgNVBAoMElN0dW5uZWwgRGV2ZWxvcGVyczEQMA4GA1UECwwHUm9vdCBDQTEL
+MAkGA1UEAwwCQ0ExHTAbBgkqhkiG9w0BCQEWDkNBQGV4YW1wbGUuY29tMB4XDTE4
+MDgzMTE0NTI1MloXDTIyMDgzMTE0NTI1MlowbzELMAkGA1UEBhMCUEwxGzAZBgNV
+BAoMElN0dW5uZWwgRGV2ZWxvcGVyczEPMA0GA1UECwwGc2VydmVyMQ8wDQYDVQQD
+DAZzZXJ2ZXIxITAfBgkqhkiG9w0BCQEWEnNlcnZlckBleGFtcGxlLmNvbTCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMg7Y842yNncXINmTFbn+An6fizD
+FZcg8Uy1azXPO/LytEW5DGWCt1SsoQ1lrtXgvo2gjcnl7dEHJniG1skD4VKbbFEz
+qI+dk8RBe4pS6PSIWfIiGqWG16cvcXdK2LeNQVJlwiNzB6H4JpoNgF3gAwRCGQNu
+E3tI6144PqEpzFN6NfExAim/GUkt95nrNeyc0oRzTRsy6nU1IOg/GvlCkFK4ItwG
+9i3hxiT/nxBP83mEUe+wAE8PUEHnu7E3kMolLBWDt0FKpll+bvy0jOWR5qhBwwdt
+4iJqTUtO8Ju6UvnaAZL0J3+iAsdQ1FQKrmEEuZA3yjsaxppfXm1I8B97WKECAwEA
+AaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUT37WyP68DIvymyi4O8LKnlNoMKgw
+HwYDVR0jBBgwFoAURxFszWdqm1f0uM4OjK2EU+2Y3JswDQYJKoZIhvcNAQELBQAD
+ggEBAKJxBm0QtjAHQI1tLiPbbVgixqkHok7fCmOevZ3Z/okjchyC4gZvdfSelrOE
+gBrn90XH407X9zyHgyVNoVUXfZTKOUDl/VkF/tQ9zdCloukQs/+v3sa+MBFF3G0T
+WQ/WLvY7wqJ7he1LhE9gUWI5DXO8XH5c9PvEkjxMPwOzeho+60l1Gtvn0Yj/Ho9L
+2oD71+CTEo24k3zdFQhVf46vI7Wk/C90McOO0/rwNQRnNNH9ELtJizrBoxMamHSw
+HXLT71ZTjeSB3DMJfWE59i1ty1V7/fLvz8T+FQfaVdpDUNAQlZaUVqz6o2w7IcnG
+QAlePz5YHNF7pw7jEgXr7HnkYRA=
 -----END CERTIFICATE-----
diff -pruN 3:5.44-1/tests/certs/psk1.txt 3:5.49-1/tests/certs/psk1.txt
--- 3:5.44-1/tests/certs/psk1.txt	2017-08-23 05:03:13.000000000 +0000
+++ 3:5.49-1/tests/certs/psk1.txt	2018-08-31 14:52:52.000000000 +0000
@@ -1 +1 @@
-test1:oaP4EishaeSaishei6rio6xeeph3az
+test1:kdQkBOkGfSarEJYFO0pyA6RGsuj3rH81dMfvCH1zU3zEMjCZtd
diff -pruN 3:5.44-1/tests/certs/psk2.txt 3:5.49-1/tests/certs/psk2.txt
--- 3:5.44-1/tests/certs/psk2.txt	2017-08-23 05:03:13.000000000 +0000
+++ 3:5.49-1/tests/certs/psk2.txt	2018-08-31 14:52:52.000000000 +0000
@@ -1 +1 @@
-test2:sah5uishaeSaishei6rio6r8iap3az
+test2:6K21l1viOWhLT2YBQBB5zQ7hwWa9NOJoy9biCZtohcsMyJUcg3
diff -pruN 3:5.44-1/tests/certs/revoked_cert.pem 3:5.49-1/tests/certs/revoked_cert.pem
--- 3:5.44-1/tests/certs/revoked_cert.pem	2017-08-23 05:03:13.000000000 +0000
+++ 3:5.49-1/tests/certs/revoked_cert.pem	2018-08-31 14:52:52.000000000 +0000
@@ -1,48 +1,49 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEA7VkojMNX9wmcnIJsRHist/phM9XN5Y5E3yfPzuOYj2ZaA7yE
-yMtl8qMngQJBjYEgkBGr3GD02Xz+j/CDAYD7XbicuyxnR0UH1eADsIQok9ATCAyp
-LJMN7yHix60B62GvdiWUFQC18K8ldhR3497uDf7FVUxcKEnG+pz+jRV+njDUYqGl
-CpoNAfON+9Kf87qdV+Mkxb+Rt+VvNKqzSjrktqtF9kjAs1sibOCuaQq55HdPNJDu
-RATtknx1jwwRnjVANirdYAlgD5J0psLM568B/eBgVlv6wnV+SJClNupNshX3FQox
-vuVENqGEA2d6fXHoyWBD/Dyz6sTwbHst14p9twIDAQABAoIBABL4S0tk2YT/GatQ
-qUKXuoZB1r8D2Z79TffgALXybuEXNx6RVLOPvig0bhXbjk23AllBcFD+1tMDMH1k
-pbPbETweYzh6hg6mL8giTWkwRuX5fWvpRyQu5LA2Lx/ybfLYLePtgPZkxiXkecQE
-QsjNqo0nzbHRlpQJwYOKRLYV/7a43PP6PVszOOz/gxHl4A5o2a6sDY8YDRbJz9BX
-w+PhuhtJMYaTIPnHYD+4zbi3szftkFH/AXyJmKWpusyBUuyAEh07fETAOA7FD7QQ
-TEg7vmLr50uNBt7+luVbfFTC156ehriU+/0DkEgnPORNLPfbv65iRoxAd+T6JxVj
-fbU76OECgYEA/ttZoE+5MyPO+drefjB5OC4sJI/rgf9v8xZdD9MoJNVl/ewst7Pk
-0gkW+t9mD9ZKyi5ecylU2U4vb/MGkrSzkimxEXMxGMMudmhjFcRvoDMBBj7klfsd
-EoQ0YVs5yyJkehGX3+8hSAyIbkrMLQtJrduPVy8qGV7qeupZfKIjCpkCgYEA7mm0
-D82FD2wl8ZqaTe44TNjkDQ6Nk6NmNPNprjwNeMSqNvHvF+irfLagSKAnQfkFs6vQ
-XjGB+3mnBkg+/8BndB5iEYJ41nMkPSNMPy0FYznmLwMFf11p7E6ncqrCLwOEQ3vi
-s3YONadV7ifv/MEBDlmJIgwq74QIAZo/QYu7zM8CgYBKPXWfWHn3pr+9Uv+rPM2j
-Cvg68l3FcbaX1nTnjjhMeomKbYkdPl8yvAkgrYEare79dIJ5A5o+7yKsdtv8Un1Y
-36JAFhFASGM5hPEQPzfRL+plel62Pf9bDH4BukRcozknwgY+6ncEePopPsq5eGdP
-KP1ZhVi7KUYe5jOJNeYFSQKBgGgJ2pi2z+T+BcTb+ZAeb5UhZMtJ2YBe4sAipLBy
-5lIYSEs34mVllEgVDfcDZH5GpDVWudQQ+K771GZKaquCk+K5S4RmkkLK9jpzx9cd
-12cIoilLwT9mTU3guPOyDpEjkLk+O5yi3OqO/lGyPejndIWFjvE7rBTfYfsJC6eX
-yblDAoGAWMZ3050vZXVOlaMJDVEBXT+TVm6lAS+GbAoW1A31Fv6fs+PSGgaRUz/l
-tc1Da39UEBBbX/pudD5XVShnXhR1KeBG9nPRaP70NSXOQjHh0W1OzL9viSMvUx3f
-EsK3y9WO1cr8C89e/9vNektU29irMzTwQQolb+tR9f9BIpae0XM=
------END RSA PRIVATE KEY-----
 -----BEGIN CERTIFICATE-----
-MIIDbDCCAlSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJwbDEQ
-MA4GA1UECgwHQ0FfY2VydDEQMA4GA1UECwwHQ0FfY2VydDEQMA4GA1UEAwwHQ0Ff
-Y2VydDEiMCAGCSqGSIb3DQEJARYTQ0FfY2VydEBleGFtcGxlLmNvbTAeFw0xNzA0
-MjYxODQ1MDBaFw0xODA0MTMxNTQ1MDBaMIGLMQswCQYDVQQGEwJwbDEQMA4GA1UE
-CBMHcmV2b2tlZDEQMA4GA1UEBxMHcmV2b2tlZDEQMA4GA1UEChMHcmV2b2tlZDEQ
-MA4GA1UECxMHcmV2b2tlZDEQMA4GA1UEAxMHcmV2b2tlZDEiMCAGCSqGSIb3DQEJ
-ARYTcmV2b2tlZEBleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
-AQoCggEBAO1ZKIzDV/cJnJyCbER4rLf6YTPVzeWORN8nz87jmI9mWgO8hMjLZfKj
-J4ECQY2BIJARq9xg9Nl8/o/wgwGA+124nLssZ0dFB9XgA7CEKJPQEwgMqSyTDe8h
-4setAethr3YllBUAtfCvJXYUd+Pe7g3+xVVMXChJxvqc/o0Vfp4w1GKhpQqaDQHz
-jfvSn/O6nVfjJMW/kbflbzSqs0o65LarRfZIwLNbImzgrmkKueR3TzSQ7kQE7ZJ8
-dY8MEZ41QDYq3WAJYA+SdKbCzOevAf3gYFZb+sJ1fkiQpTbqTbIV9xUKMb7lRDah
-hANnen1x6MlgQ/w8s+rE8Gx7LdeKfbcCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
-TFyPHPwb3CwDvPVlC6pgaowXbDEiQ5vU2Oecq/RwMxhC1FJ5ks+VIQ+KBrDRs9Ao
-k7dF5kuGc3ZAFHgWnzpyUobAyeZchaykLYy8yslwW6xFEbWXW599mjI3D5/N9xcy
-v8IHwqTTQRaxPPdcu3vjDtdpgJY89lFE2mzdPNz24Z/qsTPdLG1668L2CxoplGl2
-0THVrNHxpDF0QqINZpTc6TzsZgvROXmcAYzg2D4v5TmUzXQaLhnPTkcKWfwxpUu0
-XDlFJuNKr+YLS9GY+0lE1kNHpiTEusnfTPRXneDZipD3Hr6LsXX0ahRgbA3loyTJ
-B9Kk23ftqSr4oePTJytIAA==
+MIIDozCCAougAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwaDELMAkGA1UEBhMCUEwx
+GzAZBgNVBAoMElN0dW5uZWwgRGV2ZWxvcGVyczEQMA4GA1UECwwHUm9vdCBDQTEL
+MAkGA1UEAwwCQ0ExHTAbBgkqhkiG9w0BCQEWDkNBQGV4YW1wbGUuY29tMB4XDTE4
+MDgzMTE0NTI1MVoXDTIyMDgzMTE0NTI1MVowcjELMAkGA1UEBhMCUEwxGzAZBgNV
+BAoMElN0dW5uZWwgRGV2ZWxvcGVyczEQMA4GA1UECwwHcmV2b2tlZDEQMA4GA1UE
+AwwHcmV2b2tlZDEiMCAGCSqGSIb3DQEJARYTcmV2b2tlZEBleGFtcGxlLmNvbTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6vZCsJmdsIUhP9a5R0+tWn
+WXiZjK3F5A6LTHGOVsK2Gla9+WzTVJP6MlrG0CsoRWckHBpujfKwOWDzQdJVkRgp
+hF19uaMO6JTMJeScV5/Y9aTeMXkfNDaGr48NTrGkcogHjcQOSAGDMwmnN52R2bEa
+kx1lUqGPN8puWfhwO3CV5S1vRajuLq+Ti4HD7CdvTsWV2omyBMX6FYQEcr4nuVrP
+zrt9ZBQjDp5x7m9eBbHOYDjGyIpGFQmKMdZlUxefQRQew+lgPu2R+0MbZF4w402y
++F5L/izkAdM84eVL6EB3JJhkDlzhzVBbF8jMk7kwllse5NdQddMPWNMBUNS0rGUC
+AwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUo26K1Us+OAZSasqx0Kfj/pU7
+FJkwHwYDVR0jBBgwFoAURxFszWdqm1f0uM4OjK2EU+2Y3JswDQYJKoZIhvcNAQEL
+BQADggEBAEeQgKUhKt35LufM0y7ZeDJBmPd0z318wrKIOVm5Vh9Bot6hVZhPTfYJ
+iYUWGKTWNYlr/z/i+PJDucghdQ0mwOtAWOfMG8/1ZgMHjY+Ix1+NAKQBREfjA63+
+pd+40Xjr+0oX5r9U8y34Hdib0ZGMPwkbPHrq4MvrRFh/a9LZsv0lPTJ1nDAyrpw8
+P3/rbzhVBqqTLMCtCXKKDRKzf5E7MXfBgL9imsZQXgvVxtQTIFotK2DV8ti6kbfB
+b8Aj5PoZ3CU5Ynhd2rLG/3ncZmHXM9meq77j6iqb+dwWQIGzPPSdokrTKLYy3/pP
+MvZwgXm9s/UrK/0WDG1xETgRrdUMnQ4=
 -----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAzq9kKwmZ2whSE/1rlHT61adZeJmMrcXkDotMcY5WwrYaVr35
+bNNUk/oyWsbQKyhFZyQcGm6N8rA5YPNB0lWRGCmEXX25ow7olMwl5JxXn9j1pN4x
+eR80Noavjw1OsaRyiAeNxA5IAYMzCac3nZHZsRqTHWVSoY83ym5Z+HA7cJXlLW9F
+qO4ur5OLgcPsJ29OxZXaibIExfoVhARyvie5Ws/Ou31kFCMOnnHub14Fsc5gOMbI
+ikYVCYox1mVTF59BFB7D6WA+7ZH7QxtkXjDjTbL4Xkv+LOQB0zzh5UvoQHckmGQO
+XOHNUFsXyMyTuTCWWx7k11B10w9Y0wFQ1LSsZQIDAQABAoIBAQCNtYeSUoTgvnW4
+KvsF0KbislkP7QedZZ8VscB540PtQHoSmzJWwRauVs8LmmDEFlpvezyhisdcbCML
+K/4nPm+7B0wv5bHP8LraupYIhoE1ocXaglWdXB2qfPIFvPQFrGCyj6tNjxUjpFbr
++XCSYpvFaBkSAJSFHPL9omehhSHb8E1U/THB6K7lPDyWIXJrVZwqNGeRkGTQL0Dx
+Oi4YZcZuIOPyxutw+4IkZ2KxmpxdOYbLDNjFe69RRM1j3kWgBCgG68M0pynHyJmW
+EFbq4nh1p/Oa2NwFiGcnC4nIOhVt98VeCFXgRWiKY05dmFHimmP3nrSiR+rUo+6y
+RF/XHQUJAoGBAPz365LHQleQcQ04dnniAu8BfVoqU8ulC4AyT8sKcqXRmw0WXNxR
+IuB2lkfaT500WL2aYEttkrEqNLdtHwwIg+zMfodnSjE0qyP+Zr6W6YxrRCH7qD78
+VFe8B5fmiBLnV0TjF1++jVTki52kSjg12456SD/LvsQkpLw5+jey6rUzAoGBANEp
+epceRqn/+csPcOz5V5foX111wil9+p7u8XipiGTQO1eNhi3nw+t5w6i4AdQuKnc2
+vyliLoab1/m6vFPOzCj5fr9Krx0CHtwbdUEipKcRGjnmdbgz3+Oc+byaL8OSi7/Q
+7tCX6FUCGspX4hAQmXZ8Cfm2RzmI3gTVWv7En2gHAoGAZROCcxFe9rHmGgw3epfN
+6EXGGmLTPIljwQNZUp2IFa1csKwAyp84uktn3KnkKcIiuw+V7k2H0XY1vhzBzQMS
+A2nqHJwuzt5mi2k5EGooQ00Q2is9nH0iDjQ5LH6WXEdHXWUHj+AJhKQVDRX5+d+7
+LIC7oZH9VU327KaVze+VTHUCgYBk2Gjg35oWcPKQ8xrxRq7y8Pi56QL6WmExq+cE
+1EiMwtE5v2SIUYxmxkiN2loXYULcQ6sbWtkv0YfqQhx3E+ffgZuYw3t2swUJ/rsj
+8n4MhvRsIi9z5p718UN/qZ+J3eg/TY83R2afReqA0KqQMFCtjdSJb1cb6F+TWQMM
+fuSUlQKBgFPqd4zTmhcBb219EEpIB2iNMXQNKnqQfg20+yiyJv/lQzUWZNhuQxvK
+FGqaeHnWM9rkhdEUYY3kHBCYiD8qfU72I9icnKvyDQDBG1RGKeLwhJMDTp2OKeEQ
++iJqzFmz/TW+w7XEIuHneXcRx6pRhc4k1M1/tlsLsvzhkUZQTaOq
+-----END RSA PRIVATE KEY-----
diff -pruN 3:5.44-1/tests/certs/secrets.txt 3:5.49-1/tests/certs/secrets.txt
--- 3:5.44-1/tests/certs/secrets.txt	2017-08-23 05:03:13.000000000 +0000
+++ 3:5.49-1/tests/certs/secrets.txt	2018-08-31 14:52:52.000000000 +0000
@@ -1,2 +1,2 @@
-test1:oaP4EishaeSaishei6rio6xeeph3az
-test2:yah5uS4aijooxilier8iaphuwah1Lo
+test1:kdQkBOkGfSarEJYFO0pyA6RGsuj3rH81dMfvCH1zU3zEMjCZtd
+test2:ufCA3QI9rVV6RJNULutu6cqtqgtko2aTedkefMHzcVJMVnUsSy
Binary files 3:5.44-1/tests/certs/server_cert.p12 and 3:5.49-1/tests/certs/server_cert.p12 differ
diff -pruN 3:5.44-1/tests/certs/server_cert.pem 3:5.49-1/tests/certs/server_cert.pem
--- 3:5.44-1/tests/certs/server_cert.pem	2017-08-23 05:03:13.000000000 +0000
+++ 3:5.49-1/tests/certs/server_cert.pem	2018-08-31 14:52:52.000000000 +0000
@@ -1,47 +1,49 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEArdLSbjb/IGtK08jwDx5XSKB96G6kinSwN+3/MEB/SvtuDsDW
-sC4kuS6kh+boOdzT+8rjf+k7ysJNC7td/2ExfJBMvcevsJqaMAhMlDcJLBMFetZ+
-/DPOv6HZIbZToMoGH14GFvt/ed1VzAshzhYKMnLjmC/lxooX1FJhRhVK6fW1HNEj
-vESJIyZA9ssk3VYaw/2cgIV3g/aOP9womk/NTU7AR/hXrCbSx1nYQInyEbk+p8qX
-ELLVS1KnMxoVH7CoqTVG6PH2FH0LJxpE577QKyT3sOfKCKs0PpXrnW3O5OF4itwv
-m1YAhKFWDDF2KyLW6LybFJVS/pDoMcA8tzHv7QIDAQABAoIBAAbCvWaGAxRKuAVW
-umeMIY70lxEURJgSA8yZGCTTTWAoOVafj3oYwVrmgoW6qGufuCsB8ClIdAfl2MNN
-DVHigN88aY+0FZRD3x1hJUFahqPNNZhagWPjy/XOILjb85K8aNKNgKUiMQoXXr/p
-6u2uE8V0jH+d1U0Mj/K1JY1pRJmm4W7Tp366z3goibOK6tWwSbGGiPWXvfy8fZdz
-8Hs/pG3oGEciof5hg55wSfJ+XF24iu850GaIKSNAf6pLUoU6S4zKj01qpSOEY1vN
-Sv5r8/yd3VQzoxk6wVDQvo7qIS7zqvvUqw0iCf3JsWGnQmEGQqwWmLiT8yE1CxFy
-H8veha0CgYEA3lffU6HSXw5zHW3o3Bx6/pGGkPlNzUDi/NbOd2kr/wBOZvmJOR2d
-U0CKoqjJpBTs7CEnpvbSkz4Hit/Y00UgQS1Zvfqo5m1yhWl1jiiHqoe0Alc/P5fa
-YMkkV+++eUUQFNJCiQKMRElkEEEITw21EmflWW86/ln9GAO8YZ1Ne0cCgYEAyCK9
-J4plfXEyTJpltg/7z/0DMuJwc3qRLMicaXcHHWK+C6ZSFOn6rzx/1GWa25Z3sXT8
-XAe98ZCYDK2+twCLtM6z2uKj/xCkZWH8AmaKKbLsMYCHXkOi38EpuxT1uiXosjVf
-ArZoAL472X5d4Eg/szGsfeMmvPm52V7OM3tHbSsCgYBydtR/DqDp1NuIfAvUPUlI
-gwy+18mo8E2rEr7qFJfUyIiUVMTDRa63rFNy1+gu86LhEVSDjS/tI5LoeML8SOsJ
-Atrfhgqrzg6WBivByrXFIeWXCumByKBhEUwHhWIOtnJH9dLRDCHACfRctc4cPJdK
-aXhWKYA6b4NveITj0AKSgwKBgDYFen1j1AVKOsOGoZHFOrlnmCdyC9x/5xPpip7F
-LDx4XMgUOu++QJZwhCi2zFgdg215IG1PAaxk1UYG2AXZtdw2N0IMDyxYN6fODRIw
-z3Z1/19VTDTbmOlA4JzJCZMXjHoeAelfhy88KjeI7poNpnQeImtQlzJHTi0odAxd
-aGhFAoGAfxHh4GhsIpIwxQMKINUXvwQAI3rUph5gMv0MS3CAwoVAFNzKZeJQsRVW
-IsI830HC+sPEpekiGcYFsRIbZv+Eh/f4j9TJ7eqUrkxVluleFU6YFHuFepbmcH4L
-nZKr5bR+kg4g0g3iqNey5pJIfTj+GoLmnv6GakqQNUdFSBAJ98g=
------END RSA PRIVATE KEY-----
 -----BEGIN CERTIFICATE-----
-MIIDVDCCAjygAwIBAgIBAjANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJwbDEQ
-MA4GA1UECgwHQ0FfY2VydDEQMA4GA1UECwwHQ0FfY2VydDEQMA4GA1UEAwwHQ0Ff
-Y2VydDEiMCAGCSqGSIb3DQEJARYTQ0FfY2VydEBleGFtcGxlLmNvbTAeFw0xNzA0
-MjYxODQzMDBaFw0xODA0MTMxNTQ1MDBaMHQxCzAJBgNVBAYTAnBsMQ8wDQYDVQQI
-EwZzZXJ2ZXIxDzANBgNVBAoTBnNlcnZlcjEPMA0GA1UECxMGc2VydmVyMQ8wDQYD
-VQQDEwZzZXJ2ZXIxITAfBgkqhkiG9w0BCQEWEnNlcnZlckBleGFtcGxlLmNvbTCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3S0m42/yBrStPI8A8eV0ig
-fehupIp0sDft/zBAf0r7bg7A1rAuJLkupIfm6Dnc0/vK43/pO8rCTQu7Xf9hMXyQ
-TL3Hr7CamjAITJQ3CSwTBXrWfvwzzr+h2SG2U6DKBh9eBhb7f3ndVcwLIc4WCjJy
-45gv5caKF9RSYUYVSun1tRzRI7xEiSMmQPbLJN1WGsP9nICFd4P2jj/cKJpPzU1O
-wEf4V6wm0sdZ2ECJ8hG5PqfKlxCy1UtSpzMaFR+wqKk1Rujx9hR9CycaROe+0Csk
-97DnygirND6V651tzuTheIrcL5tWAIShVgwxdisi1ui8mxSVUv6Q6DHAPLcx7+0C
-AwEAATANBgkqhkiG9w0BAQUFAAOCAQEAiPQrjJbTZ6NB+FO0lJtt5vEBLdepkl6x
-mtopQRxHPZIuUqV8viP9EW2PlrrPkpdbYZtkD0AuCXiqGD9u31kIHKG05GiQYj8q
-XPy55QuOntWfwJc4GEZ9uebYckHGSNLsyubdkneLeXlEZz2RbtCoZS5337nlaUCm
-93Hp/bRCFZ7if9tiscxwTft92z2+Tc5bI4JGAJfex/VgyggpNRLSDDRibNvFrooO
-1kSnDxySyCtysodXfonWpJFA9EAcUHXY6vlGvzLVJRfrqsS7vC/fuKOz684XDYIL
-g/eJED4XR47T8gA85vM8LWl80lXvfFIYsirOnYmeQDSfTRDG9eZG6Q==
+MIIDoDCCAoigAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwaDELMAkGA1UEBhMCUEwx
+GzAZBgNVBAoMElN0dW5uZWwgRGV2ZWxvcGVyczEQMA4GA1UECwwHUm9vdCBDQTEL
+MAkGA1UEAwwCQ0ExHTAbBgkqhkiG9w0BCQEWDkNBQGV4YW1wbGUuY29tMB4XDTE4
+MDgzMTE0NTI1MloXDTIyMDgzMTE0NTI1MlowbzELMAkGA1UEBhMCUEwxGzAZBgNV
+BAoMElN0dW5uZWwgRGV2ZWxvcGVyczEPMA0GA1UECwwGc2VydmVyMQ8wDQYDVQQD
+DAZzZXJ2ZXIxITAfBgkqhkiG9w0BCQEWEnNlcnZlckBleGFtcGxlLmNvbTCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMg7Y842yNncXINmTFbn+An6fizD
+FZcg8Uy1azXPO/LytEW5DGWCt1SsoQ1lrtXgvo2gjcnl7dEHJniG1skD4VKbbFEz
+qI+dk8RBe4pS6PSIWfIiGqWG16cvcXdK2LeNQVJlwiNzB6H4JpoNgF3gAwRCGQNu
+E3tI6144PqEpzFN6NfExAim/GUkt95nrNeyc0oRzTRsy6nU1IOg/GvlCkFK4ItwG
+9i3hxiT/nxBP83mEUe+wAE8PUEHnu7E3kMolLBWDt0FKpll+bvy0jOWR5qhBwwdt
+4iJqTUtO8Ju6UvnaAZL0J3+iAsdQ1FQKrmEEuZA3yjsaxppfXm1I8B97WKECAwEA
+AaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUT37WyP68DIvymyi4O8LKnlNoMKgw
+HwYDVR0jBBgwFoAURxFszWdqm1f0uM4OjK2EU+2Y3JswDQYJKoZIhvcNAQELBQAD
+ggEBAKJxBm0QtjAHQI1tLiPbbVgixqkHok7fCmOevZ3Z/okjchyC4gZvdfSelrOE
+gBrn90XH407X9zyHgyVNoVUXfZTKOUDl/VkF/tQ9zdCloukQs/+v3sa+MBFF3G0T
+WQ/WLvY7wqJ7he1LhE9gUWI5DXO8XH5c9PvEkjxMPwOzeho+60l1Gtvn0Yj/Ho9L
+2oD71+CTEo24k3zdFQhVf46vI7Wk/C90McOO0/rwNQRnNNH9ELtJizrBoxMamHSw
+HXLT71ZTjeSB3DMJfWE59i1ty1V7/fLvz8T+FQfaVdpDUNAQlZaUVqz6o2w7IcnG
+QAlePz5YHNF7pw7jEgXr7HnkYRA=
 -----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAyDtjzjbI2dxcg2ZMVuf4Cfp+LMMVlyDxTLVrNc878vK0RbkM
+ZYK3VKyhDWWu1eC+jaCNyeXt0QcmeIbWyQPhUptsUTOoj52TxEF7ilLo9IhZ8iIa
+pYbXpy9xd0rYt41BUmXCI3MHofgmmg2AXeADBEIZA24Te0jrXjg+oSnMU3o18TEC
+Kb8ZSS33mes17JzShHNNGzLqdTUg6D8a+UKQUrgi3Ab2LeHGJP+fEE/zeYRR77AA
+Tw9QQee7sTeQyiUsFYO3QUqmWX5u/LSM5ZHmqEHDB23iImpNS07wm7pS+doBkvQn
+f6ICx1DUVAquYQS5kDfKOxrGml9ebUjwH3tYoQIDAQABAoIBAAC9R2cRiLhVOfo6
+PHntrVrME/8yUTgXpQx1dwnh1ATXpJbFUihlzSuA369e+sBLbiizuRJPyQsGjbvQ
+M6bWXtShQksid7LgEBWfcEdYewe8ISjlu1d1IgK6CB86pYY3/U/ClG7xE8wjUHEt
+L5YpJ5mybMk4dNX1tPjKGGEb+GcugKqsEoFNwLWBHZiLzYqeJvQdyzkXm76oljmK
+WrS8nz+YWMS0XLdrexynjrw1ccDDYJrVGqApfIiekwbpiiZuB/d82tOXXx2DdBq+
+qUXTtfWhfplGcSnEPKLL4NnQM3baBY6zLcfT0BIBz+XbN95SOLqUQuLlF70NFnTA
+PSEXoGECgYEA9/NoAUw9yY3eIbqaNLj6t3Dq6N0XXvvML6U/TukbO2VLhv9x18cr
+DrKJUd/X4IkQ1ow8PHu21JMNnv9AT7/la9IE6RHR7s5HyEG3anXhZihcCTJzDm8E
+TH8T71ZFwLgn/a/w3hXwhsuxNhuvspmXAv5YAE6uu+7x2Qv+5pzDtK0CgYEAzrtq
+qsgTSA4CgZoiXdj7azBcqR+bt58kTjfO4BDdTDwiLLumqCcIqpwRZLWRgLx6f2Xg
+PTJvBRd3DFALSYj/3EbbkFuxF+4MvcsavF25MMyj5XKOdmOi7sd0gIopK5beAx+W
+4K3TcZhPUmfV/EQo5mJIBg5LotkZagvtEq5Y/kUCgYBFDtD/04k98rpUcJF0b7S8
+lMGIe9N/i+fRuVeJldkU0OCZR9ogPAOdA1LFr++DRQmgh8xbGCXSzOY1S2hRDeRL
+BGKDu4fZ2DAb8VmxWAWgG0uO8DMlaPwshhQ6S6//vgq9WFxgroGgOWkw5cMonih2
+F/rQkxmNlD5dsj6bYjwLvQKBgQCvUF5nz94SF9dmQujr/ytPPicGQUjTkgC+2DL2
+7zZMBR7SIpx1Mwz1af6SEiv/KVcUnLdqDk/52GlbprG7vZOFIQ3nwOpQqc5iUVAt
+96kpyhEfbmOD4ID2z2xr6T56uakyquJPTPnn9ksmTeo40TCCF0yO3iakRkl4Ff8I
+/ZN4pQKBgQDWRHuMAo1/uaaW8S375IJ0YG3mbKU68FuR0ZDe1vWQqsyM8EGtwHh+
+hRwvh1Anj11J+yCG45lAGVsphO4EIaJnQScsBLP1v01zNpC3T+uOy5h33QM5/z8B
+FNbak5bvtbMOG+HRb524Z5LfacvyCvI/yQodmdHZfR1RAH06ROeZkA==
+-----END RSA PRIVATE KEY-----
diff -pruN 3:5.44-1/tests/certs/stunnel.pem 3:5.49-1/tests/certs/stunnel.pem
--- 3:5.44-1/tests/certs/stunnel.pem	2017-08-23 05:03:13.000000000 +0000
+++ 3:5.49-1/tests/certs/stunnel.pem	2018-08-31 14:52:52.000000000 +0000
@@ -1,52 +1,53 @@
 -----BEGIN PRIVATE KEY-----
-MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDOzXhuuDTB83n4
-5gy6buWIi4umz40Qdw11SuQQt3xV1MlZGFl+MuX+Py8/PmvvzzCdwYLG0oTGCrzK
-zdO08tbr0z9y50Q6i+YXP33myS75kMvoB/jVHGx7cVZq/xjwCE8gFJNPI52HUEOH
-Prtqg51a1shWy+208uYK96iROUaoTeIFhhJ8SScsiMWZIKgEqalWjdeSwBrSEEUa
-EM3ORd3huJ2FElDMeZ86ucAlAaOqIhw37M9OpunkOqE37GagnYxQdU8bxKLOuNGr
-ShT2eU8fDDqw9ypSfwCrordSz0oBV6sjUYAEAIOXOpWfTBDXlk0CO5hnSDjDaikp
-lTax3ze7AgMBAAECggEBALryujV1JpRSs2fTJ5x91dgbNlLE++Pvi+YFnqiSBr9c
-zexR+8z+3DV8Dw0gM9klNvDV15A/DTIu0L6RVRoWET48yPXppR88CvPnPLyeEG4h
-fIO0eTjGKjdpnNK662NKT6VTlFuNecGySGmBx1Ehy+Urlw4H6kqS7mzpt6QY4AwS
-Qr1CHx43tyc7XyAWjb+7d+VUhAhoJPKobkF4J83KxDFN1q+7/gLaX+2Twh78aM8A
-PBxEOG37FcJx2l81EK5UpxNXoJPo15uPzUD8mH+1p4z203eNYo4qB1ruo4wNJhLB
-cO6kA4z5M6xQkgB4UafQh5R2/CseNHvvGmhB61R6eOkCgYEA+Pa8UASeDcNrnF/l
-ObtSETEnJbijBabObbxRYlLdhwF6hp+ASdLt0agQGOTnhJUP7goQyJr6ww9ODoA8
-dJw5utmIGGv1vBae5SwxEamBgMRkn3tSZy6MW06LfhHjPc7Ky1DMbuzGlIoYJzXs
-W7ECAIGblgv2NFJHSRVJFB7aJccCgYEA1KWyXA2TGCLY4xY3QMjiprwbzQgcPRH/
-w6mmOzh44nrT3YhQrDC+55KjXPoml8NKc+smW6cR8Yv01fLFc6Ec0mBWZqpOQvwM
-P58JAFf/us/L5ZcdKuYwYxVYHW1s/t4SXZPD/A5TdspLrJvF6Ib8NrzFfu1ym7z8
-N8Kg2uqxzm0CgYEAy8TnDHc7BfjUswCqFT6ERR399JnSlGWav6ZK1jcMqdtD9bvG
-vKWvkNIFmtp/w7xddW83nXl7lPuJ38SFtsvHVG+HPLXgQzogg2JQJyydmk8kLIQ7
-RciLiJAZC+6IF6aRxSc0q/WP8zOz4SP5eHLAOLncJktUEC7nuaF6VsWJtzECgYAM
-Yo4t0FiV2km5iCy1qD2TKneQDH3gjLDRy4qz/kkEH9VBHNReAwTLZf3/x04CHsyy
-TarRQbzIzbb30wjvAB42nofJuPeP7TAlcHTMwVNSpRGiEJgRTJDa5H5aUGo9ud9l
-9do/TvJLg+K+beAr99ius3XpO5kmOu6RrNNDjNHITQKBgQDr0V+awa944XZLUCmD
-uxCiheqiUKJKe5uYX8/jBFQ4onQFHlzGRtd3wpTZ3JHPPLOGYkAVognXy0LqM9zG
-E1nozTRsSqfy2qfSgSGiSmxktoPWTen7YpA0+J+d+T6UcBfvWVbAFvBmk+2n1nXa
-040QCD05eHlIWVrTIMgGqfRrgQ==
+MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDtVGjHVrTx2Ypz
+MTV0tJ5Q9WC4mkq9kC36fr+KakcQmS9gaW5W8IUXH8otQ8w9VBmZMDSLHO1q7Ps7
+cIA3KbXMhb0c9uqc/3GcNY9AnLH5BU8FyKOh2z51hjwTSzvZvbuZw/AZjCGDBvtl
+6TWHNnqz71IkNuWsu/SAWbG54alMf8Beu3v6Qf+NxSa1/MPC361yi502fEaO50eB
+SDo1kfgrgfbJ1r+oQwXFf1FgRriZp8QTa155LbKQPIGI5PG0PXyVuAN6t3M+53ci
+aoflGTdDgqT0jfMDCS+/tpD9z1aD/Y1nIhs5eN7oZcDzpz4Zkc9R1pxEBtN+AJrm
+2yq+T5YFAgMBAAECggEBAKxgv83xg3GacT4jwtDmk4r3/u12W8z92Pd1ckfl04IR
+0WB0k4kgH3rhQybHdKQi3ojug2t7clJUmFHe77GhYQORK//KtDOeMfWkzUy/w2C8
+412vEnLwXJheDGpzHaCUd5tCvrS/nGOgAZ9O2OtBvbPNotrc6MsipX9IJpd9eUsu
+pQkNoYiAsdQf+2P3OC3op71xjSbfxKxiOgoKKOzabj1h1jyzvcnaG+e3AZs2+2Qy
+dWyw7zDFbeW6eA8dt6vqhlEdekEHRv5XOuh+G9YcZ3YtmmzF9rlsCC97oW45aHf6
+MQax8DhKcKCc75IP+qA9hMTiopRemCcx9khfMfums0ECgYEA9u/85nxkaRTxv2aN
+pZY8m3uEoUXpsaEq83hJs0F3/OXwr1vUHDbBrqhynds7I+uOurTFXuU6bg0jGof6
+raPN0d0PW+H0AbbCllFgPling0HfS7sf2nNhLnyonFWtEK15Fp7t6oNU6NIBPE9l
+TYkxWILDu2T/NfZH2CGv4zJp1xECgYEA9gonypab1CdWuiNCzVNcGRyhA2m1PCGM
+V9di2sqsLBg2zmvEjT658gjA3SI/XNbEb8yNVdZ+qawSkWlhGwP+6OCTYe6p+9Xj
+RSlXlCVtMXpwcTE12Cg2BP80x7wb2QLjWUSafITihZFf5bybO6KEIvaNP27oT/a+
+zZxLHDSoF7UCgYEAuBuJtNZ9jpMdApUVeqWenlXjNtKHP/ZnrYq7eDiRmy5c2oFe
+jYKNuQjCG8t+NnPDwJRSq0PA4phM2dUUIy4DoDpu3xSB9l0qiyQ024cBra0JLM9h
+Gl/3zs8Gbzi5hbuwkhsAS16LieI5JZwUbVCiR9mG0UqltLfgLNZA6uWFX+ECgYEA
+2ybqkJocTRmJN51G2GsC4t9MUCTtKJVdU7TnOalDOLeMwcreNU2FBSBk4dOqisBG
+EqspzSaUhf9ePqWVuCGUAcxfmuCiCk5W9HjBqJS5sVO1Ki3CHzqZ+1NyqOJWD7Nx
+3EauMHGQ75YwzAp2XuUAO8BOygy44tkO1Uf84y/H9e0CgYEA3FWPwAEdSsYx7s1n
+wm+OIX6EBlH/gCYVo7XCIZDnqdHvDf3ggiqckJs2072mGPskO6pIfaiifgBEdlKZ
+O56kHyAK2hU3VxhxT7L3hu+BwAaAe6COGdW73yMWfWbGvXrAwOIz1PfEwcpEOqZu
+Kw6SfxAgJ+sgBhivNoZbSIxzgMo=
 -----END PRIVATE KEY-----
 -----BEGIN CERTIFICATE-----
-MIIEAzCCAuugAwIBAgIJAIMM7qk8vX8HMA0GCSqGSIb3DQEBBQUAMIGDMQswCQYD
+MIIENjCCAx6gAwIBAgIJAKRmlerKkQXnMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYD
 VQQGEwJQTDEZMBcGA1UECAwQTWF6b3ZpYSBQcm92aW5jZTEPMA0GA1UEBwwGV2Fy
 c2F3MRswGQYDVQQKDBJTdHVubmVsIERldmVsb3BlcnMxFzAVBgNVBAsMDlByb3Zp
-c2lvbmFsIENBMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMTcwNDI3MTc1MzM5WhcN
-MjEwNDI3MTc1MzM5WjCBgzELMAkGA1UEBhMCUEwxGTAXBgNVBAgMEE1hem92aWEg
-UHJvdmluY2UxDzANBgNVBAcMBldhcnNhdzEbMBkGA1UECgwSU3R1bm5lbCBEZXZl
-bG9wZXJzMRcwFQYDVQQLDA5Qcm92aXNpb25hbCBDQTESMBAGA1UEAwwJbG9jYWxo
-b3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzs14brg0wfN5+OYM
-um7liIuLps+NEHcNdUrkELd8VdTJWRhZfjLl/j8vPz5r788wncGCxtKExgq8ys3T
-tPLW69M/cudEOovmFz995sku+ZDL6Af41Rxse3FWav8Y8AhPIBSTTyOdh1BDhz67
-aoOdWtbIVsvttPLmCveokTlGqE3iBYYSfEknLIjFmSCoBKmpVo3XksAa0hBFGhDN
-zkXd4bidhRJQzHmfOrnAJQGjqiIcN+zPTqbp5DqhN+xmoJ2MUHVPG8SizrjRq0oU
-9nlPHww6sPcqUn8Aq6K3Us9KAVerI1GABACDlzqVn0wQ15ZNAjuYZ0g4w2opKZU2
-sd83uwIDAQABo3gwdjARBglghkgBhvhCAQEEBAMCBkAwDwYDVR0TBAgwBgEB/wIB
-ADALBgNVHQ8EBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwLgYJYIZIAYb4QgEN
-BCEWH3N0dW5uZWwgc2VsZi1zaWduZWQgY2VydGlmaWNhdGUwDQYJKoZIhvcNAQEF
-BQADggEBAEVV6RJ4N+7Y4ImwrxalKnM+RX1c0tRXeX2NCLYeTypu1MNbyXJeWSrR
-N7r49JuxrJSnIFHpTcZzGxOFI8flVeDXDFdt6hpvWX/p+RIVPj2TARNh0VrTni7O
-imcTGlbakxiGk6whM9fh3I1Kxvz949DC6Y8prLuwnjBnQYsyHJC6WQsIKlT/+fnp
-hyX1lRUVAWa6UHPAFq39RsUQLOA5w95A6fDkfXevx/PfjHEpymK0C6/C+amu5dhz
-xNZQsGDEG749Ny+xI1azUG7pwOEZmXN+hZKMs8YPG6NpAf63xhNFBAYpjT4wlE1/
-96h/XIphwPJAiVbc7lxcHpTTlZfcQi8=
+c2lvbmFsIENBMRIwEAYDVQQDDAlsb2NhbGhvc3QxIjAgBgkqhkiG9w0BCQEWE3N0
+dW5uZWxAZXhhbXBsZS5jb20wHhcNMTgwODMxMTQ1MjUxWhcNMTgwOTMwMTQ1MjUx
+WjCBpzELMAkGA1UEBhMCUEwxGTAXBgNVBAgMEE1hem92aWEgUHJvdmluY2UxDzAN
+BgNVBAcMBldhcnNhdzEbMBkGA1UECgwSU3R1bm5lbCBEZXZlbG9wZXJzMRcwFQYD
+VQQLDA5Qcm92aXNpb25hbCBDQTESMBAGA1UEAwwJbG9jYWxob3N0MSIwIAYJKoZI
+hvcNAQkBFhNzdHVubmVsQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEA7VRox1a08dmKczE1dLSeUPVguJpKvZAt+n6/impHEJkvYGlu
+VvCFFx/KLUPMPVQZmTA0ixztauz7O3CANym1zIW9HPbqnP9xnDWPQJyx+QVPBcij
+ods+dYY8E0s72b27mcPwGYwhgwb7Zek1hzZ6s+9SJDblrLv0gFmxueGpTH/AXrt7
++kH/jcUmtfzDwt+tcoudNnxGjudHgUg6NZH4K4H2yda/qEMFxX9RYEa4mafEE2te
+eS2ykDyBiOTxtD18lbgDerdzPud3ImqH5Rk3Q4Kk9I3zAwkvv7aQ/c9Wg/2NZyIb
+OXje6GXA86c+GZHPUdacRAbTfgCa5tsqvk+WBQIDAQABo2MwYTAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBRU9MEjhCItr8+HwI8qT9BLCbnOYTAfBgNVHSMEGDAW
+gBRU9MEjhCItr8+HwI8qT9BLCbnOYTAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcN
+AQELBQADggEBAA4bo30VUKew8DQWRIGgxHadb96BqlOr1wnmbAhybpiW9j7Eudzy
+CFILW9YBQz2lb1J+pcOpNGIpfCf+VdPUDq2oDNeU8mtVEq3BLZ0i5yIdohMxLBSo
+VcLDkyb7awa0pFQYkxj3Q/e9J47aeMILBMdwdydh1sSnr0gZ14g8GP88j3zM4OZQ
+Kje47wGMwZl+H7sRIyL2ktnkJkDgO08ple6gxG8GBZ+qtlkZjNaJJUBjgoEUTVIt
++YriFV2e0EmJHQW1Oa4p4XDWUDyJGzXrzEGZng2lgu7SkMlbjIbTHH1BBHkmM875
+PaNtuJHQQZOHk2pPVtzL7crH0A84paMXOa4=
 -----END CERTIFICATE-----
diff -pruN 3:5.44-1/tests/execute_read 3:5.49-1/tests/execute_read
--- 3:5.44-1/tests/execute_read	1970-01-01 00:00:00.000000000 +0000
+++ 3:5.49-1/tests/execute_read	2018-04-06 14:29:30.000000000 +0000
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+cat >> "$1"
diff -pruN 3:5.44-1/tests/execute_write 3:5.49-1/tests/execute_write
--- 3:5.44-1/tests/execute_write	1970-01-01 00:00:00.000000000 +0000
+++ 3:5.49-1/tests/execute_write	2018-04-06 14:29:30.000000000 +0000
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+echo "$@" > "$1"
diff -pruN 3:5.44-1/tests/Makefile.am 3:5.49-1/tests/Makefile.am
--- 3:5.44-1/tests/Makefile.am	2017-08-23 05:03:13.000000000 +0000
+++ 3:5.49-1/tests/Makefile.am	2018-08-31 14:49:02.000000000 +0000
@@ -1,7 +1,9 @@
 ## Process this file with automake to produce Makefile.in
-# by Michal Trojnara 2017
+# by Michal Trojnara 1998-2018
 
-EXTRA_DIST = make_test test_library recipes certs execute
+SUBDIRS = certs
+
+EXTRA_DIST = make_test test_library recipes execute execute_read execute_write
 
 check-local:
 	$(srcdir)/make_test
diff -pruN 3:5.44-1/tests/Makefile.in 3:5.49-1/tests/Makefile.in
--- 3:5.44-1/tests/Makefile.in	2017-11-14 14:07:50.000000000 +0000
+++ 3:5.49-1/tests/Makefile.in	2018-08-31 14:51:16.000000000 +0000
@@ -14,7 +14,7 @@
 
 @SET_MAKE@
 
-# by Michal Trojnara 2017
+# by Michal Trojnara 1998-2018
 VPATH = @srcdir@
 am__is_gnu_make = { \
   if test -z '$(MAKELEVEL)'; then \
@@ -116,14 +116,74 @@ am__v_at_0 = @
 am__v_at_1 = 
 SOURCES =
 DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	distdir
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
 am__DIST_COMMON = $(srcdir)/Makefile.in
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -248,8 +308,9 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-EXTRA_DIST = make_test test_library recipes certs execute
-all: all-am
+SUBDIRS = certs
+EXTRA_DIST = make_test test_library recipes execute execute_read execute_write
+all: all-recursive
 
 .SUFFIXES:
 $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
@@ -287,12 +348,105 @@ mostlyclean-libtool:
 
 clean-libtool:
 	-rm -rf .libs _libs
-tags TAGS:
 
-ctags CTAGS:
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-recursive
 
-cscope cscopelist:
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
 
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
 distdir: $(DISTFILES)
 	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@@ -324,20 +478,46 @@ distdir: $(DISTFILES)
 	    || exit 1; \
 	  fi; \
 	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
 check-am: all-am
 	$(MAKE) $(AM_MAKEFLAGS) check-local
-check: check-am
+check: check-recursive
 all-am: Makefile
-installdirs:
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
 
 install-am: all-am
 	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
 
-installcheck: installcheck-am
+installcheck: installcheck-recursive
 install-strip:
 	if test -z '$(STRIP)'; then \
 	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
@@ -359,86 +539,88 @@ distclean-generic:
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
 	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
+clean: clean-recursive
 
 clean-am: clean-generic clean-libtool mostlyclean-am
 
-distclean: distclean-am
+distclean: distclean-recursive
 	-rm -f Makefile
-distclean-am: clean-am distclean-generic distclean-local
+distclean-am: clean-am distclean-generic distclean-local \
+	distclean-tags
 
-dvi: dvi-am
+dvi: dvi-recursive
 
 dvi-am:
 
-html: html-am
+html: html-recursive
 
 html-am:
 
-info: info-am
+info: info-recursive
 
 info-am:
 
 install-data-am:
 
-install-dvi: install-dvi-am
+install-dvi: install-dvi-recursive
 
 install-dvi-am:
 
 install-exec-am:
 
-install-html: install-html-am
+install-html: install-html-recursive
 
 install-html-am:
 
-install-info: install-info-am
+install-info: install-info-recursive
 
 install-info-am:
 
 install-man:
 
-install-pdf: install-pdf-am
+install-pdf: install-pdf-recursive
 
 install-pdf-am:
 
-install-ps: install-ps-am
+install-ps: install-ps-recursive
 
 install-ps-am:
 
 installcheck-am:
 
-maintainer-clean: maintainer-clean-am
+maintainer-clean: maintainer-clean-recursive
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
-mostlyclean: mostlyclean-am
+mostlyclean: mostlyclean-recursive
 
 mostlyclean-am: mostlyclean-generic mostlyclean-libtool
 
-pdf: pdf-am
+pdf: pdf-recursive
 
 pdf-am:
 
-ps: ps-am
+ps: ps-recursive
 
 ps-am:
 
 uninstall-am:
 
-.MAKE: check-am install-am install-strip
+.MAKE: $(am__recursive_targets) check-am install-am install-strip
 
-.PHONY: all all-am check check-am check-local clean clean-generic \
-	clean-libtool cscopelist-am ctags-am distclean \
-	distclean-generic distclean-libtool distclean-local distdir \
-	dvi dvi-am html html-am info info-am install install-am \
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-am check-local clean clean-generic clean-libtool \
+	cscopelist-am ctags ctags-am distclean distclean-generic \
+	distclean-libtool distclean-local distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
 	install-data install-data-am install-dvi install-dvi-am \
 	install-exec install-exec-am install-html install-html-am \
 	install-info install-info-am install-man install-pdf \
 	install-pdf-am install-ps install-ps-am install-strip \
-	installcheck installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
-	uninstall-am
+	installcheck installcheck-am installdirs installdirs-am \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am
 
 .PRECIOUS: Makefile
 
diff -pruN 3:5.44-1/tests/make_test 3:5.49-1/tests/make_test
--- 3:5.44-1/tests/make_test	2017-11-22 16:12:48.000000000 +0000
+++ 3:5.49-1/tests/make_test	2018-06-20 12:08:04.000000000 +0000
@@ -11,16 +11,48 @@ script_path=$(pwd)
 cd "${result_path}"
 result_path="${result_path}/logs"
 
-if [ -n "$(command -v ncat)" ]
-  then # ncat
-    mynetcat="ncat"
-  elif [ -n "$(command -v nc)" ]
-    then # nc
-      mynetcat="nc"
-  else # # netcat not found
-    mynetcat="null"
+autodetection() {
+
+  result=0
+  if [ -n "$(command -v ncat)" ]
+    then # ncat
+      mynetcat="ncat"
+    elif [ -n "$(command -v nc)" ]
+      then # nc
+        mynetcat="nc"
+    else # netcat is required
+      printf "%s\n" "ncat / nc not found in \$PATH"
+      result=1
   fi
-if [ "$mynetcat" != "null" ] # netcat is required
+
+  if [ -n "$(command -v netstat)" ] && ! netstat -a -n 2>&1 | grep -q -e "usage" -e "invalid" -e "illegal" -e "command not found"
+    then
+      mynetstat="netstat"
+    elif [ -n "$(command -v ss)" ] && ! ss -a -n -l 2>&1 | grep -q -e "usage" -e "invalid" -e "illegal" -e "command not found"
+      then
+        mynetstat="ss"
+    elif [ -n "$(command -v lsof)" ] && ! lsof -i -n -P 2>&1 | grep -q -e "usage" -e "invalid" -e "illegal" -e "command not found"
+      then
+        mynetstat="lsof"
+    else # netstat / ss / lsof is required
+      printf "%s\n" "netstat / ss / lsof not found in \$PATH or some option error"
+      result=1
+   fi
+
+  if [ -n "$(command -v stdbuf)" ]
+    then
+      mybuffer="stdbuf"
+    elif [ -n "$(command -v unbuffer)" ]
+      then
+        mybuffer="unbuffer"
+    else
+      mybuffer=""
+    fi
+
+  return $result
+}
+
+if autodetection
   then
     rm -rf "${result_path}"
     mkdir "${result_path}"
@@ -29,31 +61,38 @@ if [ "$mynetcat" != "null" ] # netcat is
     ../../src/stunnel -version 2>> "results.log"
     printf "\n%s\n" "Testing..." >> "results.log"
     head -n5 "results.log"
-    for plik in ${script_path}/recipes/*
-      do
-        /bin/sh $plik $mynetcat
-        state=$?
-        if [ "$state" -eq 0 ]
-          then # $state=0
-            count=$((count + 1))
-          elif [ "$state" -eq 125 ]
-            then # $state=125
-              skip=$((skip + 1))
-          else # $state=1
-            fail=$((fail + 1))
+    if ! grep -q "solaris" "results.log"
+      then
+        for plik in ${script_path}/recipes/*
+          do
+            /bin/sh $plik "$mynetcat" "$mynetstat" "$mybuffer"
+            state=$?
+            if [ "$state" -eq 0 ]
+              then # $state=0
+                count=$((count + 1))
+              elif [ "$state" -eq 125 ]
+                then # $state=125
+                  skip=$((skip + 1))
+              else # $state=1
+                fail=$((fail + 1))
+                result=1
+              fi
+          done
+        if [ $count -eq 0 ]
+          then # no test was done
             result=1
           fi
-      done
-    if [ $count -eq 0 ]
-      then # no test was done
-        result=1
+        printf "%s\n" "summary: success $count, skip $skip, fail $fail"
+        printf "%s\n" "summary: success $count, skip $skip, fail $fail" >> "results.log"
+        printf "%s\n" "./make_test finished"
+        cd ..
+      else # skip make test for solaris
+        printf "%s\n" "./make_test skipped"
+        printf "%s\n" "./make_test skipped" >> "results.log"
+        #result=125
       fi
-    printf "%s\n" "summary: success $count, skip $skip, fail $fail"
-    printf "%s\n" "summary: success $count, skip $skip, fail $fail" >> "results.log"
-    printf "%s\n" "./make_test finished"
-    cd ..
   else # netcat not found
-    printf "%s\n" "./make_test skipped: ncat (nc) not found in \$PATH"
+    printf "%s\n" "./make_test skipped"
     #result=125
   fi
 exit $result
diff -pruN 3:5.44-1/tests/recipes/010_require_cert 3:5.49-1/tests/recipes/010_require_cert
--- 3:5.44-1/tests/recipes/010_require_cert	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/010_require_cert	2018-07-02 21:30:10.000000000 +0000
@@ -8,21 +8,19 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
   cert = ${script_path}/certs/client_cert.pem
 
-  [https server]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
+  [server]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/server_cert.pem
   requireCert = yes
 EOT
 }
 
-check_ports "010_require_cert"
-start 2> "error.log"
-test_log_for "010_require_cert" "success" "$1" 2>> "stderr.log"
+test_log_for "010_require_cert" "success" "0" "$1" "$2" "$3" 2>> "stderr.log"
 exit $?
diff -pruN 3:5.44-1/tests/recipes/011_verify_peer 3:5.49-1/tests/recipes/011_verify_peer
--- 3:5.44-1/tests/recipes/011_verify_peer	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/011_verify_peer	2018-07-02 21:30:10.000000000 +0000
@@ -8,22 +8,20 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
   cert = ${script_path}/certs/client_cert.pem
 
-  [https server]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
+  [server]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/server_cert.pem
   verifyPeer = yes
   CAfile = ${script_path}/certs/PeerCerts.pem
 EOT
 }
 
-check_ports "011_verify_peer"
-start 2> "error.log"
-test_log_for "011_verify_peer" "success" "$1" 2>> "stderr.log"
+test_log_for "011_verify_peer" "success" "0" "$1" "$2" "$3" 2>> "stderr.log"
 exit $?
diff -pruN 3:5.44-1/tests/recipes/012_verify_chain 3:5.49-1/tests/recipes/012_verify_chain
--- 3:5.44-1/tests/recipes/012_verify_chain	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/012_verify_chain	2018-08-31 14:49:02.000000000 +0000
@@ -8,21 +8,26 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
   verifyChain = yes
   CAfile = ${script_path}/certs/CACert.pem
 
-  [https server]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
+  [server]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/server_cert.pem
 EOT
 }
 
-check_ports "012_verify_chain"
-start 2> "error.log"
-test_log_for "012_verify_chain" "success" "$1" 2>> "stderr.log"
-exit $?
+if grep -q -e "OpenSSL 0.9.8" -e "OpenSSL 1" "results.log"
+  then
+    test_log_for "012_verify_chain" "success" "0" "$1" "$2" "$3" 2>> "stderr.log"
+    exit $?
+  else # older OpenSSL doesn't support sha256
+    exit_logs "012_verify_chain" "skipped"
+    clean_logs
+    exit 125
+  fi
diff -pruN 3:5.44-1/tests/recipes/013_CRL_file 3:5.49-1/tests/recipes/013_CRL_file
--- 3:5.44-1/tests/recipes/013_CRL_file	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/013_CRL_file	2018-08-31 14:49:02.000000000 +0000
@@ -8,22 +8,27 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
   verifyChain = yes
   CAfile = ${script_path}/certs/CACert.pem
   CRLfile = ${script_path}/certs/CACertCRL.pem
 
-  [https server]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
+  [server]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/server_cert.pem
 EOT
 }
 
-check_ports "013_CRL_file"
-start 2> "error.log"
-test_log_for "013_CRL_file" "success" "$1" 2>> "stderr.log"
-exit $?
+if grep -q -e "OpenSSL 0.9.8" -e "OpenSSL 1" "results.log"
+  then
+    test_log_for "013_CRL_file" "success" "0" "$1" "$2" "$3" 2>> "stderr.log"
+    exit $?
+  else # older OpenSSL doesn't support sha256
+    exit_logs "013_CRL_file" "skipped"
+    clean_logs
+    exit 125
+  fi
diff -pruN 3:5.44-1/tests/recipes/014_PSK_secrets 3:5.49-1/tests/recipes/014_PSK_secrets
--- 3:5.44-1/tests/recipes/014_PSK_secrets	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/014_PSK_secrets	2018-07-02 21:30:10.000000000 +0000
@@ -7,29 +7,27 @@ start() {
   syslog = no
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
-  sslVersion = TLSv1
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
   PSKsecrets = ${script_path}/certs/psk1.txt
 
-  [https server]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
+  [server]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
   ciphers = PSK
   PSKsecrets = ${script_path}/certs/secrets.txt
 EOT
 }
 
-check_ports "014_PSK_secrets"
 if grep -q "OpenSSL 1" "results.log"
   then
-    start 2> "error.log"
-    test_log_for "014_PSK_secrets" "success" "$1" 2>> "stderr.log"
+    test_log_for "014_PSK_secrets" "success" "0" "$1" "$2" "$3" 2>> "stderr.log"
     exit $?
   else
     exit_logs "014_PSK_secrets" "skipped"
+    clean_logs
     exit 125
   fi
diff -pruN 3:5.44-1/tests/recipes/015_p12_cert 3:5.49-1/tests/recipes/015_p12_cert
--- 3:5.44-1/tests/recipes/015_p12_cert	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/015_p12_cert	2018-07-02 21:30:10.000000000 +0000
@@ -8,25 +8,24 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
 
-  [https server]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
+  [server]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/server_cert.p12
 EOT
 }
 
-check_ports "015_p12_cert"
 if grep -q "OpenSSL 1" "results.log"
   then
-    start 2> "error.log"
-    test_log_for "015_p12_cert" "success" "$1" 2>> "stderr.log"
+    test_log_for "015_p12_cert" "success" "0" "$1" "$2" "$3" 2>> "stderr.log"
     exit $?
   else
     exit_logs "015_p12_cert" "skipped"
+    clean_logs
     exit 125
   fi
diff -pruN 3:5.44-1/tests/recipes/020_IPv6 3:5.49-1/tests/recipes/020_IPv6
--- 3:5.44-1/tests/recipes/020_IPv6	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/020_IPv6	2018-07-02 21:30:10.000000000 +0000
@@ -8,25 +8,27 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = :::${https}
+  connect = ::1:${https1}
 
-  [https server]
-  accept = :::${https}
-  connect = 127.0.0.1:${http2}
-  cert = ${script_path}/certs/stunnel.pem
+  [server]
+  accept = ::1:${https1}
+  connect = 127.0.0.1:${http_nc}
+  cert = ${script_path}/certs/server_cert.pem
 EOT
 }
 
-check_ports "020_IPv6"
-if grep -q "IPv6" "results.log" && PATH="${PATH}:/sbin:/usr/sbin" ifconfig | grep -q "inet6" && [ -n "$(command -v ncat)" ] # nc does not support IPv6
+# nc does not support IPv6
+if grep -q "IPv6" "results.log" && [ -n "$(command -v ncat)" ] && \
+   (([ -n "$(command -v ip)" ] && PATH="${PATH}:/sbin:/usr/sbin" ip address | grep -q "inet6") || \
+   ([ -n "$(command -v ifconfig)" ] && PATH="${PATH}:/sbin:/usr/sbin" ifconfig | grep -q "inet6"))
   then
-    start 2> "error.log"
-    test_log_for "020_IPv6" "success" "$1" 2>> "stderr.log"
+    test_log_for "020_IPv6" "success" "0" "$1" "$2" "$3" 2>> "stderr.log"
     exit $?
   else
     exit_logs "020_IPv6" "skipped"
+    clean_logs
     exit 125
   fi
diff -pruN 3:5.44-1/tests/recipes/021_FIPS 3:5.49-1/tests/recipes/021_FIPS
--- 3:5.44-1/tests/recipes/021_FIPS	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/021_FIPS	2018-07-02 21:30:10.000000000 +0000
@@ -9,25 +9,24 @@ start() {
   output = ${result_path}/stunnel.log
   fips = yes
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
 
-  [https server]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
-  cert = ${script_path}/certs/stunnel.pem
+  [server]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
+  cert = ${script_path}/certs/server_cert.pem
 EOT
 }
 
-check_ports "021_FIPS"
 if grep -q "FIPS" results.log && grep -q "\-fips" results.log
   then
-    start 2> "error.log"
-    test_log_for "021_FIPS" "success" "$1" 2>> "stderr.log"
+    test_log_for "021_FIPS" "success" "0" "$1" "$2" "$3" 2>> "stderr.log"
     exit $?
   else
     exit_logs "021_FIPS" "skipped"
+    clean_logs
     exit 125
   fi
diff -pruN 3:5.44-1/tests/recipes/022_bind 3:5.49-1/tests/recipes/022_bind
--- 3:5.44-1/tests/recipes/022_bind	1970-01-01 00:00:00.000000000 +0000
+++ 3:5.49-1/tests/recipes/022_bind	2018-07-02 21:30:10.000000000 +0000
@@ -0,0 +1,25 @@
+#!/bin/sh
+. $(dirname $0)/../test_library
+
+start() {
+  ../../src/stunnel -fd 0 <<EOT
+  debug = debug
+  syslog = no
+  pid = ${result_path}/stunnel.pid
+  output = ${result_path}/stunnel.log
+
+  [client]
+  client = yes
+  accept = 127.0.0.1:${http1}
+  connect = ${https1}
+
+  [server]
+  accept = 127.0.0.1:${https1}
+  accept = 127.0.0.1:${https1}
+  connect = ${http_nc}
+  cert = ${script_path}/certs/server_cert.pem
+EOT
+}
+
+test_log_for "022_bind" "success" "0" "$1" "$2" "$3" 2>> "stderr.log"
+exit $?
diff -pruN 3:5.44-1/tests/recipes/030_simple_execute 3:5.49-1/tests/recipes/030_simple_execute
--- 3:5.44-1/tests/recipes/030_simple_execute	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/030_simple_execute	2018-07-02 21:30:10.000000000 +0000
@@ -8,20 +8,18 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
 
-  [https server]
-  accept = 127.0.0.1:${https}
+  [server]
+  accept = 127.0.0.1:${https1}
   exec = ${script_path}/execute
   execArgs = execute 030_simple_execute
   cert = ${script_path}/certs/server_cert.pem
 EOT
 }
 
-check_ports "030_simple_execute"
-start 2> "error.log"
-test_log_for "030_simple_execute" "execute" "$1" 2>> "stderr.log"
+test_log_for "030_simple_execute" "execute" "0" "$1" "$2" "$3" 2>> "stderr.log"
 exit $?
diff -pruN 3:5.44-1/tests/recipes/031_redirect 3:5.49-1/tests/recipes/031_redirect
--- 3:5.44-1/tests/recipes/031_redirect	2017-11-17 18:13:10.000000000 +0000
+++ 3:5.49-1/tests/recipes/031_redirect	2018-07-02 21:30:10.000000000 +0000
@@ -8,10 +8,10 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client_1]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
   ;cert = ${script_path}/certs/client_cert.pem
 ;wrong certificate
   cert = ${script_path}/certs/stunnel.pem
@@ -26,8 +26,8 @@ start() {
   accept = 127.0.0.1:${http3}
   connect = 127.0.0.1:${https3}
 
-  [https server]
-  accept = 127.0.0.1:${https}
+  [server_1]
+  accept = 127.0.0.1:${https1}
   connect = 127.0.0.1:${http2}
   redirect = ${http3}
   cert = ${script_path}/certs/server_cert.pem
@@ -48,7 +48,5 @@ start() {
 EOT
 }
 
-check_ports "031_redirect"
-start 2> "error.log"
-test_log_for "031_redirect" "execute" "$1" 2>> "stderr.log"
+test_log_for "031_redirect" "execute" "0" "$1" "$2" "$3" 2>> "stderr.log"
 exit $?
diff -pruN 3:5.44-1/tests/recipes/032_no_redirect 3:5.49-1/tests/recipes/032_no_redirect
--- 3:5.44-1/tests/recipes/032_no_redirect	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/032_no_redirect	2018-07-02 21:30:10.000000000 +0000
@@ -8,10 +8,10 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client_1]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
 ;correct certificate
   cert = ${script_path}/certs/client_cert.pem
 
@@ -25,8 +25,8 @@ start() {
   accept = 127.0.0.1:${http3}
   connect = 127.0.0.1:${https3}
 
-  [https server]
-  accept = 127.0.0.1:${https}
+  [server_1]
+  accept = 127.0.0.1:${https1}
   connect = 127.0.0.1:${http2}
   redirect = ${http3}
   cert = ${script_path}/certs/server_cert.pem
@@ -47,7 +47,5 @@ start() {
 EOT
 }
 
-check_ports "032_no_redirect"
-start 2> "error.log"
-test_log_for "032_no_redirect" "execute" "$1" 2>> "stderr.log"
+test_log_for "032_no_redirect" "execute" "0" "$1" "$2" "$3" 2>> "stderr.log"
 exit $?
diff -pruN 3:5.44-1/tests/recipes/033_redirect_exec 3:5.49-1/tests/recipes/033_redirect_exec
--- 3:5.44-1/tests/recipes/033_redirect_exec	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/033_redirect_exec	2018-07-02 21:30:10.000000000 +0000
@@ -8,10 +8,10 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client_1]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
   ;cert = ${script_path}/certs/client_cert.pem
 ;wrong certificate
   cert = ${script_path}/certs/stunnel.pem
@@ -21,8 +21,8 @@ start() {
   accept = 127.0.0.1:${http2}
   connect = 127.0.0.1:${https2}
 
-  [https server]
-  accept = 127.0.0.1:${https}
+  [server_1]
+  accept = 127.0.0.1:${https1}
   exec = ${script_path}/execute
   execArgs = execute 033_redirect_exec_error
   redirect = ${http2}
@@ -38,7 +38,5 @@ start() {
 EOT
 }
 
-check_ports "033_redirect_exec"
-start 2> "error.log"
-test_log_for "033_redirect_exec" "execute" "$1" 2>> "stderr.log"
+test_log_for "033_redirect_exec" "execute" "0" "$1" "$2" "$3" 2>> "stderr.log"
 exit $?
diff -pruN 3:5.44-1/tests/recipes/034_no_redirect_exec 3:5.49-1/tests/recipes/034_no_redirect_exec
--- 3:5.44-1/tests/recipes/034_no_redirect_exec	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/034_no_redirect_exec	2018-07-02 21:30:10.000000000 +0000
@@ -8,10 +8,10 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client_1]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
 ;correct certificate
   cert = ${script_path}/certs/client_cert.pem
 
@@ -20,8 +20,8 @@ start() {
   accept = 127.0.0.1:${http2}
   connect = 127.0.0.1:${https2}
 
-  [https server]
-  accept = 127.0.0.1:${https}
+  [server_1]
+  accept = 127.0.0.1:${https1}
   exec = ${script_path}/execute
   execArgs = execute 034_no_redirect_exec
   redirect = ${http2}
@@ -37,7 +37,5 @@ start() {
 EOT
 }
 
-check_ports "034_no_redirect_exec"
-start 2> "error.log"
-test_log_for "034_no_redirect_exec" "execute" "$1" 2>> "stderr.log"
+test_log_for "034_no_redirect_exec" "execute" "0" "$1" "$2" "$3" 2>> "stderr.log"
 exit $?
diff -pruN 3:5.44-1/tests/recipes/035_SNI 3:5.49-1/tests/recipes/035_SNI
--- 3:5.44-1/tests/recipes/035_SNI	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/035_SNI	2018-07-02 21:30:10.000000000 +0000
@@ -8,21 +8,21 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
   sni = sni.mydomain.com
   cert = ${script_path}/certs/client_cert.pem
 
-  [virtual]
-  accept = 127.0.0.1:${https}
+  [server_virtual]
+  accept = 127.0.0.1:${https1}
   cert =  ${script_path}/certs/server_cert.pem
   exec = ${script_path}/execute
   execArgs = execute 035_SNI_error
 
   [sni]
-  sni = virtual:sni.mydomain.com
+  sni = server_virtual:*.mydomain.com
   cert = ${script_path}/certs/server_cert.pem
   exec = ${script_path}/execute
   execArgs = execute 035_SNI
@@ -31,13 +31,12 @@ start() {
 EOT
 }
 
-check_ports "035_SNI"
 if grep -q "OpenSSL 1" "results.log"
   then
-    start 2> "error.log"
-    test_log_for "035_SNI" "execute" "$1" 2>> "stderr.log"
+    test_log_for "035_SNI" "execute" "0" "$1" "$2" "$3" 2>> "stderr.log"
     exit $?
   else
     exit_logs "035_SNI" "skipped"
+    clean_logs
     exit 125
   fi
diff -pruN 3:5.44-1/tests/recipes/036_no_SNI 3:5.49-1/tests/recipes/036_no_SNI
--- 3:5.44-1/tests/recipes/036_no_SNI	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/036_no_SNI	2018-07-02 21:30:10.000000000 +0000
@@ -8,33 +8,32 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
   ;sni = sni.mydomain.com
 
-  [virtual]
-  accept = 127.0.0.1:${https}
+  [server_virtual]
+  accept = 127.0.0.1:${https1}
   cert =  ${script_path}/certs/server_cert.pem
   exec = ${script_path}/execute
   execArgs = execute 036_no_SNI
 
   [sni]
-  sni = virtual:sni.mydomain.com
+  sni = server_virtual:sni.mydomain.com
   cert = ${script_path}/certs/server_cert.pem
   exec = ${script_path}/execute
   execArgs = execute 036_no_SNI_error
 EOT
 }
 
-check_ports "036_no_SNI"
 if grep -q "OpenSSL 1" "results.log"
   then
-    start 2> "error.log"
-    test_log_for "036_no_SNI" "execute" "$1" 2>> "stderr.log"
+    test_log_for "036_no_SNI" "execute" "0" "$1" "$2" "$3" 2>> "stderr.log"
     exit $?
   else
     exit_logs "036_no_SNI" "skipped"
+    clean_logs
     exit 125
   fi
diff -pruN 3:5.44-1/tests/recipes/037_failover_prio1 3:5.49-1/tests/recipes/037_failover_prio1
--- 3:5.44-1/tests/recipes/037_failover_prio1	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/037_failover_prio1	2018-07-02 21:30:10.000000000 +0000
@@ -8,25 +8,24 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   failover = prio
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
   connect = 127.0.0.1:${https2}
 
-  [https server_1]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
+  [server_1]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/server_cert.pem
 
-  [https server_2]
+  [server_2]
   accept = 127.0.0.1:${https2}
-  connect = 127.0.0.1:${http2}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/server_cert.pem
 EOT
 }
 
-check_ports "037_failover_prio1"
-test_log_for "037_failover_prio1" "prio" "$1" 2>> "stderr.log"
+test_log_for "037_failover_prio1" "prio" "0" "$1" "$2" "$3" 2>> "stderr.log"
 exit $?
diff -pruN 3:5.44-1/tests/recipes/038_failover_prio2 3:5.49-1/tests/recipes/038_failover_prio2
--- 3:5.44-1/tests/recipes/038_failover_prio2	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/038_failover_prio2	2018-07-02 21:30:10.000000000 +0000
@@ -8,25 +8,24 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   failover = prio
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https_free}
   connect = 127.0.0.1:${https2}
 
-  ;[https server_1]
-  ;accept = 127.0.0.1:${https}
-  ;connect = 127.0.0.1:${http2}
+  ;[server_1]
+  ;accept = 127.0.0.1:${https_free}
+  ;connect = 127.0.0.1:${http_nc}
   ;cert = ${script_path}/certs/server_cert.pem
 
-  [https server_2]
+  [server_2]
   accept = 127.0.0.1:${https2}
-  connect = 127.0.0.1:${http2}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/server_cert.pem
 EOT
 }
 
-check_ports "038_failover_prio2"
-test_log_for "038_failover_prio2" "prio" "$1" 2>> "stderr.log"
+test_log_for "038_failover_prio2" "prio" "0" "$1" "$2" "$3" 2>> "stderr.log"
 exit $?
diff -pruN 3:5.44-1/tests/recipes/039_failover_rr 3:5.49-1/tests/recipes/039_failover_rr
--- 3:5.44-1/tests/recipes/039_failover_rr	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/039_failover_rr	2018-07-02 21:30:10.000000000 +0000
@@ -8,31 +8,30 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   failover = rr
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
   connect = 127.0.0.1:${https2}
   connect = 127.0.0.1:${https3}
 
-  [https server_1]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
+  [server_1]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/server_cert.pem
 
-  [https server_2]
+  [server_2]
   accept = 127.0.0.1:${https2}
-  connect = 127.0.0.1:${http2}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/server_cert.pem
 
-  [https server_3]
+  [server_3]
   accept = 127.0.0.1:${https3}
-  connect = 127.0.0.1:${http2}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/server_cert.pem
 EOT
 }
 
-check_ports "039_failover_rr"
-test_log_for "039_failover_rr" "rr" "$1" 2>> "stderr.log"
+test_log_for "039_failover_rr" "rr" "0" "$1" "$2" "$3" 2>> "stderr.log"
 exit $?
diff -pruN 3:5.44-1/tests/recipes/040_reload 3:5.49-1/tests/recipes/040_reload
--- 3:5.44-1/tests/recipes/040_reload	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/040_reload	2018-07-02 21:30:10.000000000 +0000
@@ -1,43 +1,51 @@
 #!/bin/sh
 . $(dirname $0)/../test_library
 
-check_ports "040_reload"
-
-echo "
+set_config() {
+  echo "
   debug = debug
   syslog = no
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client_1]
   client = yes
-  accept = 127.0.0.1:${http3}
-  connect = 127.0.0.1:${https}
+  accept = 127.0.0.1:${http2}
+  connect = 127.0.0.1:${https1}
 
-  [https server]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
+  [server_1]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/server_cert.pem" > "stunnel.conf"
+}
 
-../../src/stunnel stunnel.conf 2> "error.log"
-
-#  accept = 127.0.0.1:${http3} -> accept = 127.0.0.1:${http1}
-echo "
+change_config() {
+#  accept = 127.0.0.1:${http2} -> accept = 127.0.0.1:${http1}
+  echo "
   debug = debug
   syslog = no
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client_2]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
 
-  [https server]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
+  [server_2]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/server_cert.pem" > "stunnel.conf"
+}
 
-reload_stunnel
-test_log_for "040_reload" "success" "$1" 2>> "stderr.log"
+start() {
+  set_config
+  ../../src/stunnel stunnel.conf
+}
+
+myglobal "$1" "$2" "$3"
+check_ports "040_reload"
+start_stunnel "040_reload" 2> "error.log"
+reload_stunnel "040_reload" 2>> "error.log"
+test_log_for "040_reload" "success" "0" "$1" "$2" "$3" 2>> "stderr.log"
 exit $?
diff -pruN 3:5.44-1/tests/recipes/041_exec_connect 3:5.49-1/tests/recipes/041_exec_connect
--- 3:5.44-1/tests/recipes/041_exec_connect	1970-01-01 00:00:00.000000000 +0000
+++ 3:5.49-1/tests/recipes/041_exec_connect	2018-07-02 21:30:10.000000000 +0000
@@ -0,0 +1,26 @@
+#!/bin/sh
+. $(dirname $0)/../test_library
+
+start() {
+  ../../src/stunnel -fd 0 <<EOT
+  debug = debug
+  syslog = no
+  pid = ${result_path}/stunnel.pid
+  output = ${result_path}/stunnel.log
+
+  [client]
+  client = yes
+  exec = ${script_path}/execute
+  execArgs = execute 041_exec_connect
+  connect = 127.0.0.1:${https1}
+
+  [server]
+  accept = 127.0.0.1:${https1}
+  exec = ${script_path}/execute_read
+  execArgs = execute_read ${result_path}/temp.log
+  cert = ${script_path}/certs/server_cert.pem
+EOT
+}
+
+test_log_for "041_exec_connect" "exe_con" "0" "$1" "$2" "$3" 2>> "stderr.log"
+exit $?
diff -pruN 3:5.44-1/tests/recipes/042_inetd 3:5.49-1/tests/recipes/042_inetd
--- 3:5.44-1/tests/recipes/042_inetd	1970-01-01 00:00:00.000000000 +0000
+++ 3:5.49-1/tests/recipes/042_inetd	2018-07-02 21:30:10.000000000 +0000
@@ -0,0 +1,31 @@
+#!/bin/sh
+. $(dirname $0)/../test_library
+
+start() {
+  ../../src/stunnel -fd 0 <<EOT
+  debug = debug
+  syslog = no
+  pid = ${result_path}/stunnel.pid
+  output = ${result_path}/stunnel.log
+
+  [server]
+  accept = 127.0.0.1:${https1}
+  exec = ${script_path}/execute
+  execArgs = execute 042_inetd
+  cert = ${script_path}/certs/server_cert.pem
+EOT
+}
+
+start_inetd() {
+  ../../src/stunnel -fd 9 9<<EOT
+  debug = debug
+  syslog = no
+  output = ${result_path}/stunnel_0.log
+  service = inetd client
+  client = yes
+  connect = 127.0.0.1:${https1}
+EOT
+}
+
+test_log_for "042_inetd" "exe_con" "0" "$1" "$2" "$3" 2>> "stderr.log"
+exit $?
diff -pruN 3:5.44-1/tests/recipes/043_session_delay 3:5.49-1/tests/recipes/043_session_delay
--- 3:5.44-1/tests/recipes/043_session_delay	1970-01-01 00:00:00.000000000 +0000
+++ 3:5.49-1/tests/recipes/043_session_delay	2018-07-02 21:30:10.000000000 +0000
@@ -0,0 +1,35 @@
+#!/bin/sh
+. $(dirname $0)/../test_library
+
+start() {
+  ../../src/stunnel -fd 0 <<EOT
+  debug = debug
+  syslog = no
+  pid = ${result_path}/stunnel.pid
+  output = ${result_path}/stunnel.log
+
+  [client]
+  client = yes
+  exec = ${script_path}/execute_read
+  execArgs = execute_read ${result_path}/temp.log
+  connect = 127.0.0.1:${https1}
+  delay = yes
+  retry = yes
+
+  [server_1]
+  accept = 127.0.0.1:${https1}
+  exec = ${script_path}/execute
+  execArgs = execute 043_session_delay
+  cert = ${script_path}/certs/server_cert.pem
+EOT
+}
+
+if ! grep -q "FORK" results.log
+  then
+    test_log_for "043_session_delay" "session" "1" "$1" "$2" "$3" 2>> "stderr.log"
+    exit $?
+  else
+    exit_logs "043_session_delay" "skipped"
+    exit 125
+  fi
+exit $?
diff -pruN 3:5.44-1/tests/recipes/044_session_nodelay 3:5.49-1/tests/recipes/044_session_nodelay
--- 3:5.44-1/tests/recipes/044_session_nodelay	1970-01-01 00:00:00.000000000 +0000
+++ 3:5.49-1/tests/recipes/044_session_nodelay	2018-07-02 21:30:10.000000000 +0000
@@ -0,0 +1,42 @@
+#!/bin/sh
+. $(dirname $0)/../test_library
+
+start() {
+  ../../src/stunnel -fd 0 <<EOT
+  debug = debug
+  syslog = no
+  pid = ${result_path}/stunnel.pid
+  output = ${result_path}/stunnel.log
+
+  [client]
+  client = yes
+  failover = rr
+  exec = ${script_path}/execute_read
+  execArgs = execute_read ${result_path}/temp.log
+  connect = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${https2}
+  retry = yes
+
+  [server_1]
+  accept = 127.0.0.1:${https1}
+  exec = ${script_path}/execute
+  execArgs = execute 044_session_nodelay
+  cert = ${script_path}/certs/server_cert.pem
+
+  [server_2]
+  accept = 127.0.0.1:${https2}
+  exec = ${script_path}/execute
+  execArgs = execute 044_session_nodelay
+  cert = ${script_path}/certs/server_cert.pem
+EOT
+}
+
+if ! grep -q "FORK" results.log
+  then
+    test_log_for "044_session_nodelay" "session" "2" "$1" "$2" "$3" 2>> "stderr.log"
+    exit $?
+  else
+    exit_logs "044_session_nodelay" "skipped"
+    exit 125
+  fi
+exit $?
diff -pruN 3:5.44-1/tests/recipes/045_include 3:5.49-1/tests/recipes/045_include
--- 3:5.44-1/tests/recipes/045_include	1970-01-01 00:00:00.000000000 +0000
+++ 3:5.49-1/tests/recipes/045_include	2018-08-25 07:24:46.000000000 +0000
@@ -0,0 +1,36 @@
+#!/bin/sh
+. $(dirname $0)/../test_library
+
+set_config() {
+  mkdir -p "${result_path}/conf.d"
+  echo "
+  debug = debug
+  syslog = no
+  pid = ${result_path}/stunnel.pid
+  output = ${result_path}/stunnel.log" > "${result_path}/conf.d/00-global.conf"
+  echo "
+  [client]
+  client = yes
+  accept = 127.0.0.1:${http1}
+  connect = 127.0.0.1:${https1}" > "${result_path}/conf.d/01-service.conf"
+  echo "
+  [server]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
+  cert = ${script_path}/certs/server_cert.pem" > "${result_path}/conf.d/02-service.conf"
+}
+
+start() {
+  set_config
+  ../../src/stunnel -fd 0 <<EOT
+  include = ${result_path}/conf.d
+EOT
+}
+
+test_log_for "045_include" "success" "0" "$1" "$2" "$3" 2>> "stderr.log"
+result=$?
+if [ $result -eq 0 ]
+  then
+    rm -f -r "${result_path}/conf.d"
+  fi
+exit $result
diff -pruN 3:5.44-1/tests/recipes/110_failure_require_cert 3:5.49-1/tests/recipes/110_failure_require_cert
--- 3:5.44-1/tests/recipes/110_failure_require_cert	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/110_failure_require_cert	2018-07-02 21:30:10.000000000 +0000
@@ -8,21 +8,19 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
   ;cert = ${script_path}/certs/client_cert.pem
 
-  [https server]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
+  [server]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/server_cert.pem
   requireCert = yes
 EOT
 }
 
-check_ports "110_failure_require_cert"
-start 2> "error.log"
-test_log_for "110_failure_require_cert" "failure" "$1" 2>> "stderr.log"
+test_log_for "110_failure_require_cert" "failure" "0" "$1" "$2" "$3" 2>> "stderr.log"
 exit $?
diff -pruN 3:5.44-1/tests/recipes/111_failure_verify_peer 3:5.49-1/tests/recipes/111_failure_verify_peer
--- 3:5.44-1/tests/recipes/111_failure_verify_peer	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/111_failure_verify_peer	2018-07-02 21:30:10.000000000 +0000
@@ -8,22 +8,20 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
   cert = ${script_path}/certs/stunnel.pem
 
-  [https server]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
+  [server]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/server_cert.pem
   verifyPeer = yes
   CAfile = ${script_path}/certs/CACert.pem
 EOT
 }
 
-check_ports "111_failure_verify_peer"
-start 2> "error.log"
-test_log_for "111_failure_verify_peer" "failure" "$1" 2>> "stderr.log"
+test_log_for "111_failure_verify_peer" "failure" "0" "$1" "$2" "$3" 2>> "stderr.log"
 exit $?
diff -pruN 3:5.44-1/tests/recipes/112_failure_verify_chain 3:5.49-1/tests/recipes/112_failure_verify_chain
--- 3:5.44-1/tests/recipes/112_failure_verify_chain	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/112_failure_verify_chain	2018-07-02 21:30:10.000000000 +0000
@@ -8,21 +8,19 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
   verifyChain = yes
   CAfile = ${script_path}/certs/CACert.pem
 
-  [https server]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
+  [server]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/stunnel.pem
 EOT
 }
 
-check_ports "112_failure_verify_chain"
-start 2> "error.log"
-test_log_for "112_failure_verify_chain" "failure" "$1" 2>> "stderr.log"
+test_log_for "112_failure_verify_chain" "failure" "0" "$1" "$2" "$3" 2>> "stderr.log"
 exit $?
diff -pruN 3:5.44-1/tests/recipes/113_failure_CRL_file 3:5.49-1/tests/recipes/113_failure_CRL_file
--- 3:5.44-1/tests/recipes/113_failure_CRL_file	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/113_failure_CRL_file	2018-07-02 21:30:10.000000000 +0000
@@ -8,22 +8,20 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
   verifyChain = yes
   CAfile = ${script_path}/certs/CACert.pem
   CRLfile = ${script_path}/certs/CACertCRL.pem
 
-  [https server]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
+  [server]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/revoked_cert.pem
 EOT
 }
 
-check_ports "113_failure_CRL_file"
-start 2> "error.log"
-test_log_for "113_failure_CRL_file" "failure" "$1" 2>> "stderr.log"
+test_log_for "113_failure_CRL_file" "failure" "0" "$1" "$2" "$3" 2>> "stderr.log"
 exit $?
diff -pruN 3:5.44-1/tests/recipes/114_failure_PSK_secrets 3:5.49-1/tests/recipes/114_failure_PSK_secrets
--- 3:5.44-1/tests/recipes/114_failure_PSK_secrets	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/114_failure_PSK_secrets	2018-08-31 14:49:02.000000000 +0000
@@ -7,27 +7,24 @@ start() {
   syslog = no
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
-  sslVersion = TLSv1
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
   PSKsecrets = ${script_path}/certs/psk2.txt
 
-  [https server]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
+  [server]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
   ciphers = PSK
   PSKsecrets = ${script_path}/certs/secrets.txt
 EOT
 }
 
-check_ports "114_failure_PSK_secrets"
 if grep -q "OpenSSL 1" "results.log"
   then
-    start 2> "error.log"
-    test_log_for "114_failure_PSK_secrets" "failure" "$1" 2>> "stderr.log"
+    test_log_for "114_failure_PSK_secrets" "failure" "0" "$1" "$2" "$3" 2>> "stderr.log"
     exit $?
   else
     exit_logs "114_failure_PSK_secrets" "skipped" "error"
diff -pruN 3:5.44-1/tests/recipes/120_failure_no_cert 3:5.49-1/tests/recipes/120_failure_no_cert
--- 3:5.44-1/tests/recipes/120_failure_no_cert	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/120_failure_no_cert	2018-07-02 21:30:10.000000000 +0000
@@ -8,21 +8,19 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
-  connect = 127.0.0.1:${https}
+  connect = 127.0.0.1:${https1}
 
-  [https server]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
+  [server]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/server_cert.pem
   ;*** error***
   requireCert = yes
 EOT
 }
 
-check_ports "120_failure_no_cert"
-start 2> "error.log"
-test_log_for "120_failure_no_cert" "failure" "$1" 2>> "stderr.log"
+test_log_for "120_failure_no_cert" "failure" "0" "$1" "$2" "$3" 2>> "stderr.log"
 exit $?
diff -pruN 3:5.44-1/tests/recipes/121_failure_wrong_config 3:5.49-1/tests/recipes/121_failure_wrong_config
--- 3:5.44-1/tests/recipes/121_failure_wrong_config	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/recipes/121_failure_wrong_config	2018-07-02 21:30:10.000000000 +0000
@@ -8,23 +8,21 @@ start() {
   pid = ${result_path}/stunnel.pid
   output = ${result_path}/stunnel.log
 
-  [https client]
+  [client]
   client = yes
   accept = 127.0.0.1:${http1}
   ;*** error***
-  ;connect = 127.0.0.1:${https}
+  ;connect = 127.0.0.1:${https1}
   cert = ${script_path}/certs/client_cert.pem
 
-  [https server]
-  accept = 127.0.0.1:${https}
-  connect = 127.0.0.1:${http2}
+  [server]
+  accept = 127.0.0.1:${https1}
+  connect = 127.0.0.1:${http_nc}
   cert = ${script_path}/certs/server_cert.pem
 EOT
 }
 
-check_ports "121_failure_wrong_config"
-start 2> "error.log"
-test_log_for "121_failure_wrong_config" "failure" "$1" 2>> "stderr.log"
+test_log_for "121_failure_wrong_config" "failure" "0" "$1" "$2" "$3" 2>> "stderr.log"
 exit $?
 
 
diff -pruN 3:5.44-1/tests/test_library 3:5.49-1/tests/test_library
--- 3:5.44-1/tests/test_library	2017-11-26 21:50:09.000000000 +0000
+++ 3:5.49-1/tests/test_library	2018-08-09 05:43:52.000000000 +0000
@@ -8,7 +8,7 @@ cd "${result_path}"
 result_logs() {
   # $1 = test name
   # $2 = status: "ok" / "failed" / "configuration failed" / "expected error"
-  #              "skipped" / "ncat (nc) failed" / "shouldn't work"
+  #              "skipped" / "netcat failed" / "shouldn't work"
   # $3 = file name: "stunnel" / "error"
 
   if [ "$2" = "expected error" ]
@@ -17,7 +17,7 @@ result_logs() {
      else
       printf "%-35s\t%s\n" "test $1" "$2"
      fi
-  if [ "$2" != "ok" ] && [ "$2" != "ncat (nc) failed" ]
+  if [ "$2" != "ok" ]
     then
       printf "%-35s\t%s\n" "test $1" "$2" >> "results.log"
     fi
@@ -26,7 +26,11 @@ result_logs() {
       printf "%-35s\t%s\n" "error logs" "logs/$1.log"
       cat "$3.log" > "$1.log"
     else
-      cat "temp.log" >> "results.log" 2>> "stderr_nc.log"
+      cat "temp.log" 2>> "stderr_nc.log" | head -n1 >> "results.log"
+    fi
+  if [ "$2" = "netcat failed" ]
+    then
+      printf "\n%s\n" "Netcat failed" >> "stderr_nc.log"
     fi
   return 0
 }
@@ -41,112 +45,345 @@ exit_logs() {
     "configuration failed") result_logs "$1" "configuration failed" "error";;
     "expected error") result_logs "$1" "expected error" "UNUSED PATTERN";;
     "skipped") result_logs "$1" "skipped" "error";;
-    "ncat (nc) failed") result_logs "$1" "failed" "stunnel";;
+    "netcat failed") result_logs "$1" "netcat failed" "stunnel";;
     "shouldn't work") result_logs "$1" "shouldn't work" "stunnel";;
+    *) echo "$1 exit_logs error"
   esac
   return 0
 }
 
 clean_logs() {
+  cat "stderr_nc.log" >> "stderr.log"
+  rm -f "stderr_nc.log"
   rm -f "stunnel.log"
   rm -f "temp.log"
   rm -f "error.log"
-  rm -f "stderr_nc.log"
   rm -f "stunnel.conf"
+  rm -f "nodata"
   return 0
 }
 
+finding_text() {
+  # $1 = to find (yes) or not to find (no)
+  # $2 = pattern
+  # $3 = file 1
+  # $4 = file 2
+
+  local result=0
+  if grep -q "$2" "$3" "$4"
+    then
+      if [ $1 = "yes" ]
+        then # to find
+          exit_code="ok"
+        else # not to find
+          exit_code="failed"
+          result=1
+        fi
+    else # no matching
+      if [ $1 = "yes" ]
+        then # to find
+          exit_code="failed"
+          result=1
+        fi
+    fi
+  return $result
+}
+
+no_file() {
+  # $1 = file
+
+  local result=0
+  if [ -s "$1" ]
+    then
+      exit_code="configuration failed"
+      result=1
+    fi
+  return $result
+}
+
 waiting_for() {
-  # waiting for strings ($2 or $3 or $4) to appear in the file $1.log
+  # waiting for string $2 to appear in the file $1.log
 
-  mkfifo "fifo"
+  mkfifo "fifo" 2>> "stderr_nc.log"
   (cat "$1.log"; tail -f "$1.log") > "fifo" 2>> "stderr_nc.log" &
   pid_tail=$!
   (sleep 3; echo "TIMEOUT") > "fifo" &
   pid_timeout=$!
-  grep -q -e "$2" -e "$3" -e "$4" -e "TIMEOUT" "fifo"
+  grep -q -e "$2" -e "TIMEOUT" "fifo"
   pid_children=$(ps -o pid,ppid | \
     awk -v ppid1="${pid_tail}" -v ppid2="${pid_timeout}" \
       '{if ($2==ppid1 || $2==ppid2) print $1}')
-  kill ${pid_tail} ${pid_timeout} ${pid_children} 2>> "stderr_nc.log"
+  kill -TERM ${pid_tail} ${pid_timeout} ${pid_children} 2>> "stderr_nc.log"
   wait ${pid_tail} ${pid_timeout} 2>> "stderr_nc.log"
   rm -f "fifo"
   return 0
 }
 
-connecting_ncat() {
+find_free() {
+  # finding a free port
+  # $1 = mynetstat name: "netstat -a -n" / "ss -a -n -l" / "lsof -i -n -P"
+
+  while $mynetstat $opt_net | grep "$http_find" | grep "LISTEN" >> "stderr_nc.log"
+    do
+      http_find=$((http_find+1))
+    done
+  return 0
+}
+
+check_ports() {
+  # seting the initial ports
   # $1 = test name
-  # $2 = string to send
-  # $3 = netcat name: "ncat" / "nc"
 
   result=0
-  mkfifo "nodata"
-  printf "\n%s\n" "test $1" > "stderr_nc.log"
-  cat "nodata" | "$3" -l -p "$http2" -vvv >"temp.log" 2>> "stderr_nc.log" &
-  pid_nc=$!
-  waiting_for "stderr_nc" "Listening" "listening" "QUITTING"
-  if grep -q "istening" "stderr_nc.log"
-    then # Listening or listening
-      if [ "$3" = "ncat" ]
+  printf "\n%s\n" "test $1" >> "stderr_nc.log"
+  http_find=8080
+  find_free
+  http_nc=$http_find
+  http_find=4567
+  find_free
+  https_free=$http_find
+
+  http1=$((http_nc+1))
+  http2=$((http_nc+2))
+  http3=$((http_nc+3))
+  https1=4433
+  https2=4434
+  https3=4435
+  return 0
+}
+
+bind_http_ports(){
+  grep "Binding service \[client.*to" "error.log" >> "stderr_nc.log"
+  grep "Binding service \[client.*failed" "error.log" >> "stderr_nc.log"
+  while [ -s "error.log" ] && grep -q "Binding service \[client.*failed" "error.log"
+    do
+      if [ $http_bind -eq $http1 ]
         then
-          printf "%-35s\t%s\n" "test $1" "$2" | "$3" 127.0.0.1 "$http1" -vv 2>> "stderr_nc.log"
+          http1=$((http1+1))
+          http2=$((http2+1))
+          http3=$((http3+1))
+        elif [ $http_bind -eq $http2 ]
+          then
+            http2=$((http2+1))
+            http3=$((http3+1))
         else
-          printf "%-35s\t%s\n" "test $1" "$2" | "$3" 127.0.0.1 "$http1" -vv 2>> "stderr_nc.log" &
+          http3=$((http3+1))
         fi
-    else # ncat (nc) failed
+      http_bind=$((http_bind+1))
+      start 2> "error.log"
+    grep "Binding service \[client.*to" "error.log" >> "stderr_nc.log"
+    grep "Binding service \[client.*failed" "error.log" >> "stderr_nc.log"
+    done
+  return 0
+}
+
+bind_https_ports(){
+  grep "Binding service \[server.*to" "error.log" >> "stderr_nc.log"
+  grep "Binding service \[server.*failed" "error.log" >> "stderr_nc.log"
+  while [ -s "error.log" ] && grep -q "Binding service \[server.*failed" "error.log"
+    do
+      if [ $https_bind -eq $https1 ]
+        then
+          https1=$((https1+1))
+          https2=$((https2+1))
+          https3=$((https3+1))
+        elif [ $https_bind -eq $https2 ]
+          then
+            https2=$((https2+1))
+            https3=$((https3+1))
+        else
+          https3=$((https3+1))
+        fi
+      https_bind=$((https_bind+1))
+      start 2> "error.log"
+      grep "Binding service \[server.*to" "error.log" >> "stderr_nc.log"
+      grep "Binding service \[server.*failed" "error.log" >> "stderr_nc.log"
+    done
+  return 0
+}
+
+start_stunnel() {
+  # running stunnel until to bind free ports
+  # $1 = test name
+
+  start 2> "error.log"
+  http_bind=$http1
+  bind_http_ports
+  http_bind=$http2
+  bind_http_ports
+  http_bind=$http3
+  bind_http_ports
+
+  https_bind=$https1
+  bind_https_ports
+  https_bind=$https2
+  bind_https_ports
+  https_bind=$https3
+  bind_https_ports
+
+  printf "\n%s %s %s %s %s %s %s\n" "test $1 ports: $http_nc $http1 $http2 $http3 $https1 $https2 $https3 $https_free" >> "stderr_nc.log"
+  return 0
+}
+
+killing_stunnel() {
+
+  local result=0
+  if kill -TERM $(tail "stunnel.pid") 2>> "stderr_nc.log"
+    then
+      waiting_for "stunnel" "Removed pid file"
+    else
+      exit_code="failed"
       result=1
     fi
-  if [  "$3" = ncat ]
+  return $result
+}
+
+reload_stunnel() {
+  # $1 = test name
+
+  local result=0
+  printf "\n%s\n" "test $1 - reload stunnel" >> "stderr_nc.log"
+  if [ ! -s "error.log" ]
     then
-      waiting_for "stderr_nc" "Closing" "Connection reset by peer" "UNUSED PATTERN"
+      change_config
+      waiting_for "stunnel" "stunnel.pid"
+      kill -HUP $(tail "stunnel.pid") 2>> "stderr_nc.log"
+      waiting_for "stunnel" "127.0.0.1:$http1"
+      grep "Binding service \[client.*$http1" "stunnel.log" >> "stderr_nc.log"
+      grep "Binding service \[client.*failed" "stunnel.log" >> "stderr_nc.log"
+      while ! grep -q "Service \[client.*bound to.*$http1" "stunnel.log"
+        do
+          http1=$((http1+1))
+          change_config
+          kill -HUP $(tail "stunnel.pid") 2>> "stderr_nc.log"
+          waiting_for "stunnel" "127.0.0.1:$http1"
+          grep "Binding service \[client.*$http1" "stunnel.log" >> "stderr_nc.log"
+        done
+      printf "\n%s\n" "test $1 - accept port: $http1" >> "stderr_nc.log"
     else
-      waiting_for "stderr_nc" "accepted" "from localhost" "Connection reset by peer"
-  fi
-  kill -TERM ${pid_nc} 2>> "stderr_nc.log"
-  cat "stderr_nc.log" >> "stderr.log"
-  echo "somedata" > "nodata"
-  rm -f "nodata"
+      printf "\n%s" "$1 error: failed to reload the configuration file" >> "error.log"
+      result=1
+    fi
   return $result
 }
 
-killing_stunnel() {
-  waiting_for "$1" "Service .* finished" "Sent socket write shutdown" "UNUSED PATTERN"
-  kill -TERM $(tail "stunnel.pid") 2>> "stderr.log"
-  waiting_for "stunnel" "removing pid file" "UNUSED PATTERN" "UNUSED PATTERN"
-  return 0
+check_listening() {
+  # waiting for netcat listening on port
+  # $1 = port number
+
+  result=0
+  while [ $result -eq 0 ] && ! $mynetstat $opt_net | grep "$1" | grep "LISTEN" >> "stderr_nc.log"
+    do
+      printf "\n%s\n" "waiting for netcat listening on $1" >> "stderr_nc.log"
+      if grep -q -e "failed:" -e "usage" -e "QUITTING" -e "invalid" -e "command not found" "stderr_nc.log"
+        then
+          result=1
+        fi
+    done
+  return $result
 }
 
-reload_stunnel() {
-  waiting_for "stunnel" "stunnel.pid" "UNUSED PATTERN" "UNUSED PATTERN"
-  kill -HUP $(tail "stunnel.pid") 2>> "stderr.log"
-  waiting_for "stunnel" "127.0.0.1:${http1}" "UNUSED PATTERN" "UNUSED PATTERN"
+connecting_ncat() {
+  # $1 = test name
+  # $2 = string to send
+
+  local result=0
+  mkfifo "nodata" 2>> "stderr_nc.log"
+  printf "\n%s\n" "test $1 - netcat connection" >> "stderr_nc.log"
+  if [ "$mynetcat" = "nc" ]
+    then # nc
+      if man "$mynetcat" | grep -q  "error to use this option in conjunction"
+        then # BSD nc
+              cat "nodata" | $mybuffer $opt_buf $mynetcat -l "$http_nc" -vvv > "temp.log" 2>> "stderr_nc.log" &
+        else # traditional nc
+              cat "nodata" | $mybuffer $opt_buf $mynetcat -l -p "$http_nc" -vvv > "temp.log" 2>> "stderr_nc.log" &
+        fi
+      pid_nc=$!
+      if check_listening "$http_nc"
+        then
+          printf "%-35s\t%s\n" "test $1" "$2" | $mynetcat 127.0.0.1 "$http1" -vv 1>&2 2>> "stderr_nc.log" &
+          pid_nce=$!
+          if [ "$2" = "shouldn't work" ]
+            then
+              waiting_for "stunnel" "Service .* finished"
+            else
+              waiting_for "temp" "test $1"
+            fi
+        else # nc failed
+          exit_code="netcat failed"
+          result=1
+        fi
+    else # ncat
+      cat "nodata" | $mybuffer $opt_buf $mynetcat -l -p $http_nc -vvv > temp.log 2>> stderr_nc.log &
+      pid_nc=$!
+      if check_listening "$http_nc"
+        then
+          if ncat --version 2>&1 | grep -q -e 'Version [0-5]\.' -e 'Version [6]\.[0-1]' -e 'Version [6]\.[2][0-4]'
+            then # ncat version < 6.25
+              printf "%-35s\t%s\n" "test $1" "$2" | "$mynetcat" 127.0.0.1 "$http1" -vv  1>&2 2>> "stderr_nc.log" &
+            else # ncat version >= 6.25
+              printf "%-35s\t%s\n" "test $1" "$2" | "$mynetcat" 127.0.0.1 "$http1" -vv  1>&2 2>> "stderr_nc.log"
+            fi
+          pid_nce=$!
+          if [ "$2" = "shouldn't work" ]
+            then
+              waiting_for "stunnel" "Service .* finished"
+            else
+              waiting_for "temp" "test $1"
+            fi
+        else # ncat failed
+          exit_code="netcat failed"
+          result=1
+        fi
+    fi
+  kill -TERM ${pid_nc} ${pid_nce} 2>> "stderr_nc.log"
+  echo "somedata" > "nodata" 2>> "stderr_nc.log"
+  rm -f "nodata"
+  return $result
+}
+
+sending_ncat() {
+  # starting netcat for execute tests
+  # $1 = test name
+
+  mkfifo "nodata" 2>> "stderr_nc.log"
+  cat "nodata" | $mybuffer $opt_buf $mynetcat 127.0.0.1 "$http1" -vv >"temp.log" 2>> "stderr_nc.log" &
+  pid_nce=$(pgrep -P $!)
+  waiting_for "temp" "test $1"
+  kill -TERM ${pid_nce} 2>> "stderr_nc.log"
+  echo "somedata" > "nodata" 2>> "stderr_nc.log"
+  rm -f "nodata"
   return 0
 }
 
 expected_success() {
-  # expects to send the s using stunnel
+  # expects to send the message using stunnel
   # $1 = test name
-  # $2 = netcat name: "ncat" / "nc"
 
-  result=0
-  if [ ! -s "error.log" ]
+  local result=0
+  if [ "$1" != "040_reload" ]
     then
-      if connecting_ncat "$1" "success" "$2"
+      check_ports "$1"
+      start_stunnel "$1"
+    fi
+  if no_file "error.log"
+    then
+      if connecting_ncat "$1" "success"
         then
-          if grep -q "test $1.*success" "temp.log"
-            then
-              exit_code="ok"
-            else # test failed
-              exit_code="failed"
-              result=1
-            fi
+          finding_text "yes" "test $1.*success" "temp.log" "UNUSED PATTERN"
+          result=$?
         else # ncat (nc) failed
-          exit_code="ncat (nc) failed"
           result=1
         fi
-      killing_stunnel stunnel
+      if ! killing_stunnel
+        then
+          result=1
+        fi
     else # configuration failed
-      exit_code="configuration failed"
+      result=1
+    fi
+  if ! finding_text "no" "INTERNAL ERROR" "stunnel.log" "error.log"
+    then
       result=1
     fi
   exit_logs "$1" "$exit_code"
@@ -155,14 +392,15 @@ expected_success() {
 
 expected_failure() {
   # $1 = test name
-  # $2 = netcat name: "ncat" / "nc"
 
-  result=0
-  if [ ! -s "error.log" ]
+  local result=0
+  check_ports "$1"
+  start_stunnel "$1"
+  if no_file "error.log"
     then
-      if connecting_ncat "$1" "shouldn't work" "$2"
+      if connecting_ncat "$1" "shouldn't work"
         then
-          if grep -q "test $1.*shouldn't work" "temp.log"
+          if ! finding_text "no" "test $1.*shouldn't work" "temp.log" "UNUSED PATTERN"
             then # ops...stunnel works
               exit_code="shouldn't work"
               result=1
@@ -170,117 +408,158 @@ expected_failure() {
               exit_code="expected error"
             fi
         else # ncat (nc) failed
-          exit_code="ncat (nc) failed"
           result=1
         fi
-      killing_stunnel stunnel
+      if ! killing_stunnel
+        then
+          result=1
+        fi
     else # configuration failed, but it is ok
       exit_code="expected error"
     fi
+  if ! finding_text "no" "INTERNAL ERROR" "stunnel.log" "error.log"
+    then
+      result=1
+    fi
   exit_logs "$1" "$exit_code"
   return $result
 }
 
 execute_program() {
   # $1 = test name
-  # $2 = netcat name: "ncat" / "nc"
 
-  result=0
-  mkfifo "nodata"
-  if [ ! -s "error.log" ]
+  local result=0
+  check_ports "$1"
+  start_stunnel "$1"
+  if no_file "error.log"
     then
-      cat "nodata" | "$2" 127.0.0.1 "$http1" -vv > "temp.log" 2>>"stderr.log" &
-      pid_nce=$!
-      killing_stunnel stunnel
-      kill -TERM ${pid_nce} 2>> "stderr.log"
-      echo "somedata" > "nodata" 2>> "stderr.log"
-      rm -f "nodata"
-      if grep -q "test $1.*success" "temp.log"
+      sending_ncat "$1"
+      if ! killing_stunnel
         then
-          if grep -q "$1_error" "temp.log"
-            then # only for redirect tests
-              exit_code="failed"
-              result=1
+          result=1
+        fi
+      if [ $result -eq 0 ]
+        then
+          if finding_text "yes" "test $1.*success" "temp.log" "UNUSED PATTERN"
+            then
+              finding_text "no" "$1_error" "temp.log" "UNUSED PATTERN"
+              result=$?
             else
-              exit_code="ok"
-          fi
-        else # test failed
-          exit_code="failed"
+              result=1
+            fi
+        fi
+    else # configuration failed
+      result=1
+    fi
+  if ! finding_text "no" "INTERNAL ERROR" "stunnel.log" "error.log"
+    then
+      result=1
+    fi
+  exit_logs "$1" "$exit_code"
+  return $result
+}
+
+execute_connect() {
+  # $1 = test name
+
+  local result=0
+  check_ports "$1"
+  start_stunnel "$1"
+  if [ "$1" = "042_inetd" ]
+    then # inetd test
+      mkfifo "nodata" 2>> "stderr_nc.log"
+      cat "nodata" | start_inetd > "temp.log" 2>> "error.log" &
+    fi
+  if no_file "error.log"
+    then
+      waiting_for "stunnel" "Service .* finished"
+      if [ $1 = "042_inetd" ]
+        then # inetd test
+          waiting_for "stunnel_0" "Service .* finished"
+          echo "somedata" > "nodata" 2>> "stderr_nc.log"
+          rm -f "nodata"
+        fi
+      finding_text "yes" "test $1.*success" "temp.log" "UNUSED PATTERN"
+      result=$?
+      if [ "$1" = "042_inetd" ]
+        then # inetd test
+          printf "%s\n" "*** inetd mode ***" >> "stunnel.log"
+          cat "stunnel_0.log" >> "stunnel.log"
+        fi
+      if ! killing_stunnel
+        then
           result=1
         fi
     else # configuration failed
-      exit_code="configuration failed"
       result=1
     fi
+  if ! finding_text "no" "INTERNAL ERROR" "stunnel.log" "error.log"
+    then
+      result=1
+    fi
+  rm -f "stunnel_0.log"
   exit_logs "$1" "$exit_code"
   return $result
 }
 
 loop_prio() {
   # $1 = test name
-  # $2 = netcat name: "ncat" / "nc"
 
-  result=0
-  i=1
-  max=12
-  start $i 2> "error.log"
-  if [ ! -s "error.log" ]
+  local result=0
+  local i=1
+  local max=12
+  if [ $1 = "037_failover_prio1" ]
     then
-      waiting_for "stunnel" "Created pid file" "UNUSED PATTERN" "UNUSED PATTERN"
+      local serv="server_2\] accepted connection"
+    else
+      local serv="server_1\] accepted connection"
+  fi
+  check_ports "$1"
+  start_stunnel "$1"
+  if no_file "error.log"
+    then
+      waiting_for "stunnel" "Created pid file"
       mv "stunnel.log" "stunnel_0.log"
-      kill -USR1 $(tail "stunnel.pid") 2>> "stderr.log"
+      kill -USR1 $(tail "stunnel.pid") 2>> "stderr_nc.log"
       while [ $i -le $max ] && [ $result -eq 0 ]
         do
-          if connecting_ncat "$1" "success" "$2"
+          if connecting_ncat "$1" "success"
             then
-              waiting_for "stunnel" "Service .* finished" "Sent socket write shutdown" "UNUSED PATTERN"
-              if grep -q "test $1.*success" "temp.log"
-                then
-                  if [ $1 = "037_failover_prio1" ]
-                    then
-                      serv="server_2\] accepted connection"
-                    else
-                      serv="server_1\] accepted connection"
-                    fi
-		  if ! grep -q "$serv" "stunnel.log"
-		    then # second server doesn't accept any client
-		      if [ $i -eq $max ]
-			then # last successed turn of the loop
-			  exit_code="ok"
-			fi
-		    else # error - second server accepts a client
-                      exit_code="failed"
-		      result=1
-		    fi
-                else # stunnel doesn't work
-                  exit_code="failed"
-                  result=1
+              finding_text "yes" "test $1.*success" "temp.log" "UNUSED PATTERN"
+              result=$?
+              if [ $result -eq 0 ] && ! finding_text "no" "$serv" "stunnel.log" "UNUSED PATTERN"
+                then # error - second server accepts a client
+		  result=1
                 fi
             else # ncat (nc) failed
-              exit_code="ncat (nc) failed"
               result=1
             fi
-          waiting_for "stunnel" "Service .* finished" "Sent socket write shutdown" "UNUSED PATTERN"
           mv "stunnel.log" "stunnel_$i.log"
-          kill -USR1 $(tail "stunnel.pid") 2>> "stderr.log"
+          kill -USR1 $(tail "stunnel.pid") 2>> "stderr_nc.log"
           i=$((i + 1))
         done
       cat "stunnel_0.log" > "stunnel_all.log"
       rm -f "stunnel_0.log"
-      j=1
+      local j=1
       while [ $j -lt $i ]
         do
-          printf "%s\n" "connection $j" >> "stunnel_all.log"
+          printf "%s\n" "*** connection $j ***" >> "stunnel_all.log"
           cat "stunnel_$j.log" >> "stunnel_all.log"
           rm -f "stunnel_$j.log"
           j=$((j + 1))
         done
-      killing_stunnel stunnel_all
+      if ! killing_stunnel
+        then
+          result=1
+        fi
       cat "stunnel.log" >> "stunnel_all.log"
       cat "stunnel_all.log" > "stunnel.log"
       rm -f "stunnel_all.log"
     else # configuration failed
-      exit_code="configuration failed"
+      result=1
+    fi
+  if ! finding_text "no" "INTERNAL ERROR" "stunnel.log" "error.log"
+    then
       result=1
     fi
   exit_logs "$1" "$exit_code"
@@ -289,37 +568,31 @@ loop_prio() {
 
 loop_rr() {
   # $1 = test name
-  # $2 = netcat name: "ncat" / "nc"
 
-  result=0
-  i=1
-  max=3
-  first=0
-  second=0
-  third=0
-  start $i 2> "error.log"
-  if [ ! -s "error.log" ]
+  local result=0
+  local i=1
+  local max=3
+  local first=0
+  local second=0
+  local third=0
+  check_ports "$1"
+  start_stunnel "$1"
+  if no_file "error.log"
     then
-      waiting_for "stunnel" "Created pid file" "UNUSED PATTERN" "UNUSED PATTERN"
+      waiting_for "stunnel" "Created pid file"
       mv "stunnel.log" "stunnel_0.log"
-      kill -USR1 $(tail "stunnel.pid") 2>> "stderr.log"
+      kill -USR1 $(tail "stunnel.pid") 2>> "stderr_nc.log"
       while [ $i -le $max ] && [ $result -eq 0 ]
         do
-          if connecting_ncat "$1" "success" "$2"
+          if connecting_ncat "$1" "success"
             then
-              waiting_for "stunnel" "Service .* finished" "Sent socket write shutdown" "UNUSED PATTERN"
-              if ! grep -q "test $1.*success" "temp.log"
-                then # stunnel doesn't work
-                  exit_code="failed"
-                  result=1
-                fi
+              finding_text "yes" "test $1.*success" "temp.log" "UNUSED PATTERN"
+              result=$?
             else # ncat (nc) failed
-              exit_code="ncat (nc) failed"
               result=1
             fi
-          waiting_for "stunnel" "Service .* finished" "Sent socket write shutdown" "UNUSED PATTERN"
           mv "stunnel.log" "stunnel_$i.log"
-          kill -USR1 $(tail "stunnel.pid") 2>> "stderr.log"
+          kill -USR1 $(tail "stunnel.pid") 2>> "stderr_nc.log"
           i=$((i + 1))
         done
       cat "stunnel_0.log" > "stunnel_all.log"
@@ -327,83 +600,124 @@ loop_rr() {
       j=1
       while [ $j -lt $i ]
         do
-          printf "%s\n" "connection $j" >> "stunnel_all.log"
+          printf "%s\n" "*** connection $j ***" >> "stunnel_all.log"
           cat "stunnel_$j.log" >> "stunnel_all.log"
           rm -f "stunnel_$j.log"
           j=$((j + 1))
         done
-      killing_stunnel stunnel_all
+      if ! killing_stunnel
+        then
+          result=1
+        fi
       cat "stunnel.log" >> "stunnel_all.log"
       cat "stunnel_all.log" > "stunnel.log"
       rm -f "stunnel_all.log"
-      first=$(grep -c "server_1\] accepted connection" "stunnel.log")
-      second=$(grep -c "server_2\] accepted connection" "stunnel.log")
-      third=$(grep -c "server_3\] accepted connection" "stunnel.log")
+      if [ $result -eq 0 ]
+        then
+          first=$(grep -c "server_1\] accepted connection" "stunnel.log")
+          second=$(grep -c "server_2\] accepted connection" "stunnel.log")
+          third=$(grep -c "server_3\] accepted connection" "stunnel.log")
+          product=$((first * second * third))
+          if [ $product -ne 0 ]
+            then # round robin
+              printf "%-35s\t%s\n" "test $1: $first x $second x $third" "success" > "temp.log"
+            else
+              printf "%-35s\t%s\n" "test $1: $first x $second x $third" "failed" > "temp.log"
+              exit_code="failed"
+              result=1
+            fi
+        fi
     else # configuration failed
-      exit_code="configuration failed"
       result=1
     fi
-    if [ $result -eq 0 ]
-      then
-        product=$((first * second * third))
-        if [ $product -ne 0 ]
-          then # round robin
-            printf "%-35s\t%s\n" "test $1: $first x $second x $third" "success" > "temp.log"
-            exit_code="ok"
-          else
-            printf "%-35s\t%s\n" "test $1: $first x $second x $third" "failed" > "temp.log"
-            exit_code="failed"
-            result=1
-          fi
-      fi
+  if ! finding_text "no" "INTERNAL ERROR" "stunnel.log" "error.log"
+    then
+      result=1
+    fi
   exit_logs "$1" "$exit_code"
   return $result
 }
 
-test_log_for() {
+loop_session() {
   # $1 = test name
-  # $2 = function name
-  # $3 = netcat name: "ncat" / "nc"
+  # $2 = number of connections
 
-  case "$2" in
-    "success") expected_success "$1" "$3";;
-    "failure") expected_failure "$1" "$3";;
-    "execute") execute_program "$1" "$3";;
-    "prio") loop_prio "$1" "$3";;
-    "rr") loop_rr "$1" "$3";;
-  esac
-  result=$?
-  clean_logs
+  local result=0
+  local i=0
+  local j=0
+  local max=$((2*$2))
+  check_ports "$1"
+  start_stunnel "$1"
+  if no_file "error.log"
+    then
+      waiting_for "stunnel" "Created pid file"
+      while [ $i -lt $max ]
+        do
+          i=$(grep -c "Retrying an exec+connect section" "stunnel.log")
+        done
+      if ! killing_stunnel stunnel
+        then
+          result=1
+        fi
+      finding_text "yes" "test $1.*success" "temp.log" "UNUSED PATTERN"
+      result=$?
+      j=$(grep -c "accepted: new session negotiated" "stunnel.log")
+      if [ $result -eq 0 ] && [ $j -ne $2 ]
+        then
+          exit_code="failed"
+          result=1
+        fi
+    else # configuration failed
+      result=1
+    fi
+  if ! finding_text "no" "INTERNAL ERROR" "stunnel.log" "error.log"
+    then
+      result=1
+    fi
+  exit_logs "$1" "$exit_code"
   return $result
 }
 
-set_port() {
-  port=$((port+1))
-  while netstat -an 2>> "stderr.log" | grep $port | grep -q LISTEN
-    do
-      port=$((port+1))
-    done
+myglobal() {
+  # $1 = mynetcat name: "ncat" / "nc"
+  # $2 = mynetstat name: "netstat" / "ss" / "lsof"
+  # $3 = mybuffer name: "stdbuf" / "unbuffer" / ""
+
+  mynetcat="$1"
+  mynetstat="$2"
+  mybuffer="$3"
+
+  case "$mynetstat" in
+    "netstat") opt_net="-a -n";;
+    "ss" ) opt_net="-a -n -l";;
+    "lsof" ) opt_net="-i -n -P";;
+  esac
+
+  case "$mybuffer" in
+    "stdbuf") opt_buf="-o0";;
+  esac
   return 0
 }
 
-check_ports() {
-  port=8079
-  set_port $port
-  http1=$port
-  set_port $port
-  http2=$port
-  set_port $port
-  http3=$port
-
-  port=4432
-  set_port $port
-  https=$port
-  set_port $port
-  https2=$port
-  set_port $port
-  https3=$port
+test_log_for() {
+  # $1 = test name
+  # $2 = function name
+  # $3 = number of connections for loop_session
+  # $4 = mynetcat name: "ncat" / "nc"
+  # $5 = mynetstat name: "netstat" / "ss" / "lsof"
+  # $6 = mybuffer name: "stdbuf" / "unbuffer" / ""
 
-  printf "\n%s\n" "test $1" >> "stderr.log"
-  printf "%s\n" "ports: $http1 $http2 $http3 $https $https2 $https3" >> "stderr.log"
-  return 0
+  myglobal "$4" "$5" "$6"
+  case "$2" in
+    "success") expected_success "$1";;
+    "failure") expected_failure "$1";;
+    "execute") execute_program "$1";;
+    "exe_con") execute_connect "$1";;
+    "prio") loop_prio "$1";;
+    "rr") loop_rr "$1";;
+    "session") loop_session "$1" "$3";;
+  esac
+  result=$?
+  clean_logs
+  return $result
 }
diff -pruN 3:5.44-1/TODO 3:5.49-1/TODO
--- 3:5.44-1/TODO	2017-01-16 20:10:16.000000000 +0000
+++ 3:5.49-1/TODO	2018-06-08 17:30:06.000000000 +0000
@@ -3,25 +3,18 @@ stunnel TODO
 
 High priority features.  They will likely be supported some day.
 A sponsor could allocate my time to get them faster.
+* Extend session tickets and/or sessiond to also serialize application
+  data ("redirect" state and session persistence).
 * Add client certificate autoselection based on the list of accepted issuers:
   SSL_CTX_set_client_cert_cb(), SSL_get_client_CA_list().
 * Add an Apparmor profile.
 * Optional line-buffering of the log file.
 * Log rotation on Windows.
 * Configuration file option to limit the number of concurrent connections.
-* Implement reference counting of the SERVICE_OPTIONS structure
-  - Add 'leastconn' failover strategy to order defined 'connect' targets
-    by the number of active connections.
-  - Add '-status' command line option reporting the number of clients
-    connected to each service.
-  - Deallocate SERVICE_OPTIONS structure when the configuration file
-    is reloaded *and* old connections are closed.
 * Command-line server control interface on both Unix and Windows.
 * Separate GUI process running as the current user on Windows.
 * An Android GUI.
 * OCSP stapling (tlsext_status).
-* Extend session tickets and/or sessiond to also serialize application
-  data ("redirect" state and session persistence).
 * Indirect CRL support (RFC 3280, section 5).
 * Provide 64-bit Windows builds (besides 32-bit builds).
   This requires either Microsoft Visual Studio Standard Edition or Microsoft
@@ -38,6 +31,10 @@ Low priority features.  They will unlike
 * Logging to NT EventLog on Windows.
 * Internationalization of logged messages (i18n).
 * Generic scripting engine instead or static protocol.c.
+* Add 'leastconn' failover strategy to order defined 'connect' targets
+  by the number of active connections.
+* Add '-status' command line option reporting the number of clients
+  connected to each service.
 
 Features I won't support, unless convinced otherwise by a wealthy sponsor.
 * Support for adding X-Forwarded-For to HTTP request headers.
diff -pruN 3:5.44-1/tools/makecert.sh 3:5.49-1/tools/makecert.sh
--- 3:5.44-1/tools/makecert.sh	2015-10-24 16:53:23.000000000 +0000
+++ 3:5.49-1/tools/makecert.sh	2018-08-25 07:14:58.000000000 +0000
@@ -8,6 +8,7 @@ fi
 
 if test -n "$2"; then
     OPENSSL="$2/bin/openssl"
+    LD_LIBRARY_PATH="$2/lib"
 else
     OPENSSL=openssl
 fi
diff -pruN 3:5.44-1/tools/Makefile.am 3:5.49-1/tools/Makefile.am
--- 3:5.44-1/tools/Makefile.am	2017-01-02 14:27:26.000000000 +0000
+++ 3:5.49-1/tools/Makefile.am	2018-04-06 14:25:10.000000000 +0000
@@ -1,5 +1,5 @@
 ## Process this file with automake to produce Makefile.in
-# by Michal Trojnara 2015-2017
+# by Michal Trojnara 1998-2018
 
 EXTRA_DIST = ca.html ca.pl importCA.html importCA.sh script.sh makecert.sh
 EXTRA_DIST += openssl.cnf stunnel.nsi stunnel.license stunnel.conf
diff -pruN 3:5.44-1/tools/Makefile.in 3:5.49-1/tools/Makefile.in
--- 3:5.44-1/tools/Makefile.in	2017-11-14 14:07:50.000000000 +0000
+++ 3:5.49-1/tools/Makefile.in	2018-08-31 14:51:16.000000000 +0000
@@ -14,7 +14,7 @@
 
 @SET_MAKE@
 
-# by Michal Trojnara 2015-2017
+# by Michal Trojnara 1998-2018
 
 VPATH = @srcdir@
 am__is_gnu_make = { \
diff -pruN 3:5.44-1/tools/openssl.cnf 3:5.49-1/tools/openssl.cnf
--- 3:5.44-1/tools/openssl.cnf	2017-01-02 14:27:26.000000000 +0000
+++ 3:5.49-1/tools/openssl.cnf	2018-08-25 07:19:41.000000000 +0000
@@ -1,12 +1,12 @@
 # OpenSSL configuration file to create a server certificate
-# by Michal Trojnara 1998-2017
+# by Michal Trojnara 1998-2018
 
 [ req ]
 # comment out the next line to protect the private key with a passphrase
 encrypt_key                     = no
 # the default key length is secure and quite fast - do not change it
 default_bits                    = 2048
-default_md                      = sha1
+default_md                      = sha256
 x509_extensions                 = stunnel_extensions
 distinguished_name              = stunnel_dn
 
diff -pruN 3:5.44-1/tools/stunnel.conf 3:5.49-1/tools/stunnel.conf
--- 3:5.44-1/tools/stunnel.conf	2017-01-19 08:51:32.000000000 +0000
+++ 3:5.49-1/tools/stunnel.conf	2018-04-06 14:25:10.000000000 +0000
@@ -1,4 +1,4 @@
-﻿; Sample stunnel configuration file for Win32 by Michal Trojnara 2002-2017
+﻿; Sample stunnel configuration file for Win32 by Michal Trojnara 2002-2018
 ; Some options used here may be inadequate for your particular configuration
 ; This sample file does *not* represent stunnel.conf defaults
 ; Please consult the manual for detailed description of available options
diff -pruN 3:5.44-1/tools/stunnel.conf-sample.in 3:5.49-1/tools/stunnel.conf-sample.in
--- 3:5.44-1/tools/stunnel.conf-sample.in	2017-01-19 08:51:32.000000000 +0000
+++ 3:5.49-1/tools/stunnel.conf-sample.in	2018-04-06 14:25:10.000000000 +0000
@@ -1,4 +1,4 @@
-﻿; Sample stunnel configuration file for Unix by Michal Trojnara 2002-2017
+﻿; Sample stunnel configuration file for Unix by Michal Trojnara 1998-2018
 ; Some options used here may be inadequate for your particular configuration
 ; This sample file does *not* represent stunnel.conf defaults
 ; Please consult the manual for detailed description of available options
diff -pruN 3:5.44-1/tools/stunnel.init.in 3:5.49-1/tools/stunnel.init.in
--- 3:5.44-1/tools/stunnel.init.in	2016-12-13 11:28:35.000000000 +0000
+++ 3:5.49-1/tools/stunnel.init.in	2018-08-31 14:49:02.000000000 +0000
@@ -26,7 +26,6 @@ DAEMON=@bindir@/stunnel
 NAME=stunnel
 DESC="TLS tunnels"
 OPTIONS=""
-ENABLED=0
 
 get_opt() {
   sed -e "s;^[[:space:]]*;;" -e "s;[[:space:]]*$;;" \
@@ -86,7 +85,7 @@ killdaemons()
 {
   local sig file pidfile status
 
-  sig=${1:-TERM}
+  sig=$1
   res=0
   for file in $FILES; do
     echo -n " $file: "
@@ -95,7 +94,7 @@ killdaemons()
       echo -n "no pid file"
     else
       status=0
-      killproc -p "$pidfile" "$DAEMON" "$sig" || status=$?
+      killproc -p "$pidfile" "$DAEMON" ${sig:+"$sig"} || status=$?
       if [ "$status" -eq 0 ]; then
         echo -n 'stopped'
       else
@@ -137,15 +136,52 @@ querydaemons()
   exit "$res"
 }
 
+restartrunningdaemons()
+{
+  local res file pidfile status args
+
+  res=0
+  for file in $FILES; do
+    echo -n " $file: "
+    pidfile=`get_pidfile "$file"`
+    if [ ! -e "$pidfile" ]; then
+      echo -n 'no pid file'
+    else
+      status=0
+      pidofproc -p "$pidfile" "$DAEMON" >/dev/null || status="$?"
+      if [ "$status" = 0 ]; then
+        echo -n 'stopping'
+        killproc -p "$pidfile" "$DAEMON" "$sig" || status="$?"
+        if [ "$status" -eq 0 ]; then
+          echo -n ' starting'
+          args="$file $OPTIONS"
+          start_daemon -p "$pidfile" "$DAEMON" $args || status="$?"
+          if [ "$status" -eq 0 ]; then
+            echo -n ' started'
+          else
+            echo ' failed'
+            res=1
+          fi
+        else
+          echo -n ' failed'
+          res=1
+        fi
+      elif [ "$status" = 4 ]; then
+        echo "cannot access the pid file $pidfile"
+      else
+        echo -n 'stopped'
+      fi
+    fi
+  done
+  echo ''
+  exit "$res"
+}
+
 if [ "x$OPTIONS" != "x" ]; then
   OPTIONS="-- $OPTIONS"
 fi
 
 [ -f @sysconfdir@/default/stunnel ] && . @sysconfdir@/default/stunnel
-if [ "$ENABLED" = "0" ] ; then
-  echo "$DESC disabled, see @sysconfdir@/default/stunnel"
-  exit 0
-fi
 
 # If the user want to manage a single tunnel, the conf file's name
 # is in $2. Otherwise, respect @sysconfdir@/default/stunnel4 setting.
@@ -194,6 +230,11 @@ case "$1" in
     killdaemons && startdaemons
     res=$?
     ;;
+  try-restart)
+    echo -n "Restarting $DESC if running:"
+    restartrunningdaemons
+    res=$?
+    ;;
   status)
     echo -n "$DESC status:"
     querydaemons
@@ -201,7 +242,7 @@ case "$1" in
     ;;
   *)
     N=@sysconfdir@/init.d/$NAME
-    echo "Usage: $N {start|stop|status|reload|reopen-logs|restart} [<stunnel instance>]" >&2
+    echo "Usage: $N {start|stop|status|reload|reopen-logs|restart|try-restart} [<stunnel instance>]" >&2
     res=1
     ;;
 esac
diff -pruN 3:5.44-1/tools/stunnel.license 3:5.49-1/tools/stunnel.license
--- 3:5.44-1/tools/stunnel.license	2017-01-02 14:27:26.000000000 +0000
+++ 3:5.49-1/tools/stunnel.license	2018-04-06 14:25:10.000000000 +0000
@@ -1,4 +1,4 @@
-Copyright (C) 1998-2017 Michal Trojnara
+Copyright (C) 1998-2018 Michal Trojnara
 
 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 of the License, or (at your option) any later version.
 
diff -pruN 3:5.44-1/tools/stunnel.nsi 3:5.49-1/tools/stunnel.nsi
--- 3:5.44-1/tools/stunnel.nsi	2017-11-26 21:50:16.000000000 +0000
+++ 3:5.49-1/tools/stunnel.nsi	2018-08-09 05:43:52.000000000 +0000
@@ -1,4 +1,4 @@
-# NSIS stunnel installer by Michal Trojnara 1998-2017
+# NSIS stunnel installer by Michal Trojnara 1998-2018
 
 !define /ifndef VERSION testing
 !define /ifndef ARCH win32
@@ -173,6 +173,11 @@ no_service_restart:
   Delete "$INSTDIR\bin\zlib1.pdb"
   Delete "$INSTDIR\bin\msvcr90.dll"
   Delete "$INSTDIR\bin\Microsoft.VC90.CRT.Manifest"
+  Delete "$INSTDIR\bin\libcrypto-1_1-x64.dll"
+  Delete "$INSTDIR\bin\libcrypto-1_1-x64.pdb"
+  Delete "$INSTDIR\bin\libssl-1_1-x64.dll"
+  Delete "$INSTDIR\bin\libssl-1_1-x64.pdb"
+  Delete "$INSTDIR\bin\vcruntime140.dll"
   RMDir "$INSTDIR\bin"
 
   Delete "$INSTDIR\engines\4758cca.dll"
@@ -327,7 +332,16 @@ Section "Core Files" sectionCORE
   !else
   File "${OPENSSL_BIN_DIR}\libcrypto-1_1-x64.dll"
   File "${OPENSSL_BIN_DIR}\libssl-1_1-x64.dll"
-  File "${REDIST_DIR}\vcruntime140.dll"
+  SetOutPath "$INSTDIR"
+  ReadRegStr $0 HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64" "Installed"
+  ${If} $0 == 1
+    DetailPrint "VC 2017 Redistributable already installed"
+  ${Else}
+    DetailPrint "Installing VC 2017 Redistributable"
+    File "${REDIST_DIR}\VC_redist.x64.exe"
+    ExecWait '"$INSTDIR\VC_redist.x64.exe" /quiet'
+    Delete "$INSTDIR\VC_redist.x64.exe"
+  ${EndIf}
   !endif
 
   # write new engine libraries
@@ -483,8 +497,8 @@ Section /o "Debugging Symbols" sectionDE
   File "${OPENSSL_BIN_DIR}\ssleay32.pdb"
   File "${ZLIB_DIR}\zlib1.pdb"
   !else
-  File "${OPENSSL_BIN_DIR}\libcrypto-1_1-x64.dll"
-  File "${OPENSSL_BIN_DIR}\libssl-1_1-x64.dll"
+  File "${OPENSSL_BIN_DIR}\libcrypto-1_1-x64.pdb"
+  File "${OPENSSL_BIN_DIR}\libssl-1_1-x64.pdb"
   !endif
 
   # optional tstunnel.exe
@@ -505,7 +519,7 @@ no_openssl_pdb:
   SetOutPath "$INSTDIR\engines"
   File "${OPENSSL_ENGINES_DIR}\capi.pdb"
   File "${OPENSSL_ENGINES_DIR}\padlock.pdb"
-  # File "${OPENSSL_ENGINES_DIR}\pkcs11.pdb"
+  File "${OPENSSL_ENGINES_DIR}\pkcs11.pdb"
   SetOutPath "$INSTDIR"
 SectionEnd
 
diff -pruN 3:5.44-1/tools/stunnel.spec 3:5.49-1/tools/stunnel.spec
--- 3:5.44-1/tools/stunnel.spec	2017-11-14 14:01:47.000000000 +0000
+++ 3:5.49-1/tools/stunnel.spec	2018-08-09 05:43:52.000000000 +0000
@@ -1,5 +1,5 @@
 Name:           stunnel
-Version:        5.44
+Version:        5.49
 Release:        1%{?dist}
 Summary:        An TLS-encrypting socket wrapper
 Group:          Applications/Internet
diff -pruN 3:5.44-1/.travis.yml 3:5.49-1/.travis.yml
--- 3:5.44-1/.travis.yml	2017-10-16 18:44:02.000000000 +0000
+++ 3:5.49-1/.travis.yml	2018-06-20 12:08:04.000000000 +0000
@@ -25,7 +25,7 @@ addons:
     - nmap
 
 before_script:
-  - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update; brew install autoconf-archive nmap; fi; true
+  - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update; brew install openssl autoconf-archive nmap expect; fi; true
   - autoreconf -fvi && touch src/dhparam.c
 
 script:
