PKG_NAME:=haproxy
PKG_VERSION:=1.8.19
-PKG_RELEASE:=2
+PKG_RELEASE:=3
PKG_SOURCE:=haproxy-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.haproxy.org/download/1.8/src/
--- /dev/null
+commit 7c3fd37724c58cf09359e0d381a9be305dd7869b
+Author: Olivier Houchard <cognet@ci0.org>
+Date: Mon Feb 25 16:18:16 2019 +0100
+
+ BUG/MAJOR: listener: Make sure the listener exist before using it.
+
+ In listener_accept(), make sure we have a listener before attempting to
+ use it.
+ An another thread may have closed the FD meanwhile, and set fdtab[fd].owner
+ to NULL.
+ As the listener is not free'd, it is ok to attempt to accept() a new
+ connection even if the listener was closed. At worst the fd has been
+ reassigned to another connection, and accept() will fail anyway.
+
+ Many thanks to Richard Russo for reporting the problem, and suggesting the
+ fix.
+
+ This should be backported to 1.9 and 1.8.
+
+ (cherry picked from commit d16a9dfed80e75d730754b717370515265698cdd)
+ Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
+ (cherry picked from commit a2511ed1fcdfa8047dbe2268fc0259f9b06cf891)
+ Signed-off-by: William Lallemand <wlallemand@haproxy.org>
+
+diff --git a/src/listener.c b/src/listener.c
+index a30efe03..5f6fafbc 100644
+--- a/src/listener.c
++++ b/src/listener.c
+@@ -441,8 +441,8 @@ void delete_listener(struct listener *listener)
+ void listener_accept(int fd)
+ {
+ struct listener *l = fdtab[fd].owner;
+- struct proxy *p = l->bind_conf->frontend;
+- int max_accept = l->maxaccept ? l->maxaccept : 1;
++ struct proxy *p;
++ int max_accept;
+ int expire;
+ int cfd;
+ int ret;
+@@ -450,6 +450,10 @@ void listener_accept(int fd)
+ static int accept4_broken;
+ #endif
+
++ if (!l)
++ return;
++ p = l->bind_conf->frontend;
++ max_accept = l->maxaccept ? l->maxaccept : 1;
+ if (HA_SPIN_TRYLOCK(LISTENER_LOCK, &l->lock))
+ return;
+
+++ /dev/null
---- a/src/ssl_sock.c
-+++ b/src/ssl_sock.c
-@@ -39,6 +39,7 @@
- #include <netdb.h>
- #include <netinet/tcp.h>
-
-+#include <openssl/bn.h>
- #include <openssl/crypto.h>
- #include <openssl/ssl.h>
- #include <openssl/x509.h>
-@@ -60,6 +61,17 @@
- #include <openssl/async.h>
- #endif
-
-+#ifndef OPENSSL_VERSION
-+#define OPENSSL_VERSION SSLEAY_VERSION
-+#define OpenSSL_version(x) SSLeay_version(x)
-+#define OpenSSL_version_num SSLeay
-+#endif
-+
-+#if OPENSSL_VERSION_NUMBER < 0x10100000L
-+#define X509_getm_notBefore X509_get_notBefore
-+#define X509_getm_notAfter X509_get_notAfter
-+#endif
-+
- #include <import/lru.h>
- #include <import/xxhash.h>
-
-@@ -217,7 +229,7 @@ static struct {
- .capture_cipherlist = 0,
- };
-
--#ifdef USE_THREAD
-+#if defined(USE_THREAD) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
-
- static HA_RWLOCK_T *ssl_rwlocks;
-
-@@ -1716,8 +1728,8 @@ ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL
- ASN1_INTEGER_set(X509_get_serialNumber(newcrt), HA_ATOMIC_ADD(&ssl_ctx_serial, 1));
-
- /* Set duration for the certificate */
-- if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
-- !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
-+ if (!X509_gmtime_adj(X509_getm_notBefore(newcrt), (long)-60*60*24) ||
-+ !X509_gmtime_adj(X509_getm_notAfter(newcrt),(long)60*60*24*365))
- goto mkcert_error;
-
- /* set public key in the certificate */
-@@ -6299,7 +6311,7 @@ smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char
- goto out;
-
- smp_trash = get_trash_chunk();
-- if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
-+ if (ssl_sock_get_time(X509_getm_notAfter(crt), smp_trash) <= 0)
- goto out;
-
- smp->data.u.str = *smp_trash;
-@@ -6399,7 +6411,7 @@ smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char
- goto out;
-
- smp_trash = get_trash_chunk();
-- if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
-+ if (ssl_sock_get_time(X509_getm_notBefore(crt), smp_trash) <= 0)
- goto out;
-
- smp->data.u.str = *smp_trash;
-@@ -8976,10 +8988,12 @@ static void __ssl_sock_init(void)
- #endif
-
- xprt_register(XPRT_SSL, &ssl_sock);
-+#if OPENSSL_VERSION_NUMBER < 0x10100000L
- SSL_library_init();
-+#endif
- cm = SSL_COMP_get_compression_methods();
- sk_SSL_COMP_zero(cm);
--#ifdef USE_THREAD
-+#if defined(USE_THREAD) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
- ssl_locking_init();
- #endif
- #if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
-@@ -9008,8 +9022,8 @@ static void __ssl_sock_init(void)
- #else /* OPENSSL_IS_BORINGSSL */
- OPENSSL_VERSION_TEXT
- "\nRunning on OpenSSL version : %s%s",
-- SSLeay_version(SSLEAY_VERSION),
-- ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
-+ OpenSSL_version(OPENSSL_VERSION),
-+ ((OPENSSL_VERSION_NUMBER ^ OpenSSL_version_num()) >> 8) ? " (VERSIONS DIFFER!)" : "");
- #endif
- memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
- #if OPENSSL_VERSION_NUMBER < 0x00907000L
-@@ -9100,12 +9114,14 @@ static void __ssl_sock_deinit(void)
- }
- #endif
-
-+#if OPENSSL_VERSION_NUMBER < 0x10100000L
- ERR_remove_state(0);
- ERR_free_strings();
-
- EVP_cleanup();
-+#endif
-
--#if OPENSSL_VERSION_NUMBER >= 0x00907000L
-+#if OPENSSL_VERSION_NUMBER >= 0x00907000L && OPENSSL_VERSION_NUMBER < 0x10100000L
- CRYPTO_cleanup_all_ex_data();
- #endif
- }
--- /dev/null
+commit 78714ea673cefa83d3dff5aa9aa5e97726cfb5cd
+Author: Willy Tarreau <w@1wt.eu>
+Date: Mon Feb 25 15:02:04 2019 +0100
+
+ BUG/MINOR: listener: keep accept rate counters accurate under saturation
+
+ The test on l->nbconn forces to exit the loop before updating the freq
+ counters, so the last session which reaches a listener's limit will not
+ be accounted for in the session rate measurement.
+
+ Let's move the test at the beginning of the loop and mark the listener
+ as saturated on exit.
+
+ This may be backported to 1.9 and 1.8.
+
+ (cherry picked from commit 741b4d6b7aad1e4a66dd8584b5eff729b08fade7)
+ Signed-off-by: William Lallemand <wlallemand@haproxy.org>
+ (cherry picked from commit 5c7c7e447df84a04bda88c40382b652cdb77a079)
+ Signed-off-by: William Lallemand <wlallemand@haproxy.org>
+
+diff --git a/src/listener.c b/src/listener.c
+index 5f6fafbc..b94d823c 100644
+--- a/src/listener.c
++++ b/src/listener.c
+@@ -457,11 +457,6 @@ void listener_accept(int fd)
+ if (HA_SPIN_TRYLOCK(LISTENER_LOCK, &l->lock))
+ return;
+
+- if (unlikely(l->nbconn >= l->maxconn)) {
+- listener_full(l);
+- goto end;
+- }
+-
+ if (!(l->options & LI_O_UNLIMITED) && global.sps_lim) {
+ int max = freq_ctr_remain(&global.sess_per_sec, global.sps_lim, 0);
+
+@@ -520,7 +515,7 @@ void listener_accept(int fd)
+ * worst case. If we fail due to system limits or temporary resource
+ * shortage, we try again 100ms later in the worst case.
+ */
+- while (max_accept--) {
++ while (l->nbconn < l->maxconn && max_accept--) {
+ struct sockaddr_storage addr;
+ socklen_t laddr = sizeof(addr);
+ unsigned int count;
+@@ -627,11 +622,6 @@ void listener_accept(int fd)
+ goto transient_error;
+ }
+
+- if (l->nbconn >= l->maxconn) {
+- listener_full(l);
+- goto end;
+- }
+-
+ /* increase the per-process number of cumulated connections */
+ if (!(l->options & LI_O_UNLIMITED)) {
+ count = update_freq_ctr(&global.sess_per_sec, 1);
+@@ -659,6 +649,9 @@ void listener_accept(int fd)
+ limit_listener(l, &global_listener_queue);
+ task_schedule(global_listener_queue_task, tick_first(expire, global_listener_queue_task->expire));
+ end:
++ if (l->nbconn >= l->maxconn)
++ listener_full(l);
++
+ HA_SPIN_UNLOCK(LISTENER_LOCK, &l->lock);
+ }
+
--- /dev/null
+commit 4c82743abd299f0aa8105e98ec92b76375a7f344
+Author: Olivier Houchard <ohouchard@haproxy.com>
+Date: Thu Mar 7 14:19:24 2019 +0100
+
+ BUG/MEDIUM: logs: Only attempt to free startup_logs once.
+
+ deinit_log_buffers() can be called once per thread, however startup_logs
+ is common to all threads. So only attempt to free it once.
+
+ This should be backported to 1.9 and 1.8.
+
+ (cherry picked from commit 7c49711d6041d1afc42d5b310ddfd7d6f6817c3c)
+ Signed-off-by: William Lallemand <wlallemand@haproxy.org>
+ (cherry picked from commit bc3e21b27849275306a0580488613b7dfd4d8eb5)
+ Signed-off-by: William Lallemand <wlallemand@haproxy.org>
+
+diff --git a/src/log.c b/src/log.c
+index b3f33662..9c112255 100644
+--- a/src/log.c
++++ b/src/log.c
+@@ -1380,11 +1380,15 @@ int init_log_buffers()
+ /* Deinitialize log buffers used for syslog messages */
+ void deinit_log_buffers()
+ {
++ void *tmp_startup_logs;
++
+ free(logheader);
+ free(logheader_rfc5424);
+ free(logline);
+ free(logline_rfc5424);
+- free(startup_logs);
++ tmp_startup_logs = HA_ATOMIC_XCHG(&startup_logs, NULL);
++ free(tmp_startup_logs);
++
+ logheader = NULL;
+ logheader_rfc5424 = NULL;
+ logline = NULL;
--- /dev/null
+commit 63f5dbf1b9fcdc5b10537d733b0e0798905ff1dc
+Author: Dragan Dosen <ddosen@haproxy.com>
+Date: Thu Mar 7 15:24:23 2019 +0100
+
+ BUG/MEDIUM: 51d: fix possible segfault on deinit_51degrees()
+
+ When haproxy is built with 51Degrees support, but not configured to use
+ 51Degrees database, a segfault can occur when deinit_51degrees()
+ function is called, eg. during soft-stop on SIGUSR1 signal.
+
+ Only builds that use Pattern algorithm are affected.
+
+ This fix must be backported to all stable branches where 51Degrees
+ support is available. Additional adjustments are required for some
+ branches due to API and naming changes.
+
+ (cherry picked from commit bc6218e1b02860c6cdad0d2bb4dc8874557087f8)
+ Signed-off-by: William Lallemand <wlallemand@haproxy.org>
+ (cherry picked from commit 4e0363e84cb3f6ca341e1f83c6fd490c76c9ae6b)
+ Signed-off-by: William Lallemand <wlallemand@haproxy.org>
+
+diff --git a/src/51d.c b/src/51d.c
+index a36333ef..03101136 100644
+--- a/src/51d.c
++++ b/src/51d.c
+@@ -639,7 +639,8 @@ static void deinit_51degrees(void)
+
+ free(global_51degrees.header_names);
+ #ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED
+- fiftyoneDegreesWorksetPoolFree(global_51degrees.pool);
++ if (global_51degrees.pool)
++ fiftyoneDegreesWorksetPoolFree(global_51degrees.pool);
+ #endif
+ #ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED
+ free(global_51degrees.device_offsets.firstOffset);
--- /dev/null
+commit 57e2606f70fa8d26fe4b5563ba72a6c7f2a25655
+Author: Lukas Tribus <lukas@ltri.eu>
+Date: Tue Mar 5 23:14:32 2019 +0100
+
+ BUG/MINOR: ssl: fix warning about ssl-min/max-ver support
+
+ In 84e417d8 ("MINOR: ssl: support Openssl 1.1.1 early callback for
+ switchctx") the code was extended to also support OpenSSL 1.1.1
+ (code already supported BoringSSL). A configuration check warning
+ was updated but with the wrong logic, the #ifdef needs a && instead
+ of an ||.
+
+ Reported in #54.
+
+ Should be backported to 1.8.
+
+ (cherry picked from commit 1aabc939780d5eab1f88089d01fb077ad9315c65)
+ Signed-off-by: William Lallemand <wlallemand@haproxy.org>
+ (cherry picked from commit f407d16b8f4cf2afb148668a23a1ba1cc4dd942a)
+ Signed-off-by: William Lallemand <wlallemand@haproxy.org>
+
+diff --git a/src/ssl_sock.c b/src/ssl_sock.c
+index 7736c324..afdb1fce 100644
+--- a/src/ssl_sock.c
++++ b/src/ssl_sock.c
+@@ -7418,7 +7418,7 @@ static int parse_tls_method_minmax(char **args, int cur_arg, struct tls_version_
+
+ static int ssl_bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
+ {
+-#if (OPENSSL_VERSION_NUMBER < 0x10101000L) || !defined(OPENSSL_IS_BORINGSSL)
++#if (OPENSSL_VERSION_NUMBER < 0x10101000L) && !defined(OPENSSL_IS_BORINGSSL)
+ ha_warning("crt-list: ssl-min-ver and ssl-max-ver are not supported with this Openssl version (skipped).\n");
+ #endif
+ return parse_tls_method_minmax(args, cur_arg, &conf->ssl_methods, err);
--- /dev/null
+commit 62aec002ccd6a7129b4f5e2e88be1957a6b2308b
+Author: Olivier Houchard <ohouchard@haproxy.com>
+Date: Thu Mar 7 18:48:22 2019 +0100
+
+ MEDIUM: threads: Use __ATOMIC_SEQ_CST when using the newer atomic API.
+
+ When using the new __atomic* API, ask the compiler to generate barriers.
+ A variant of those functions that don't generate barriers will be added later.
+ Before that, using HA_ATOMIC* would not generate any barrier, and some parts
+ of the code should be reviewed and missing barriers should be added.
+
+ This should probably be backported to 1.8 and 1.9.
+
+ (cherry picked from commit 113537967c8680f94977473e18c9e14dc09c3356)
+ [wt: this is in fact a real bug fix : all these atomics do not provide
+ the slightest sequential consistency by default as the value 0 is
+ __ATOMIC_RELAXED, which will definitely cause random issues with
+ threads on non-x86 platforms].
+ Signed-off-by: Willy Tarreau <w@1wt.eu>
+ (cherry picked from commit e5d1670f5fa95972fed6391201c0da8982bb9f94)
+ Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
+
+diff --git a/include/common/hathreads.h b/include/common/hathreads.h
+index 24fb1d1a..8a738aaf 100644
+--- a/include/common/hathreads.h
++++ b/include/common/hathreads.h
+@@ -213,14 +213,14 @@ static inline unsigned long thread_isolated()
+ })
+ #else
+ /* gcc >= 4.7 */
+-#define HA_ATOMIC_CAS(val, old, new) __atomic_compare_exchange_n(val, old, new, 0, 0, 0)
+-#define HA_ATOMIC_ADD(val, i) __atomic_add_fetch(val, i, 0)
+-#define HA_ATOMIC_XADD(val, i) __atomic_fetch_add(val, i, 0)
+-#define HA_ATOMIC_SUB(val, i) __atomic_sub_fetch(val, i, 0)
+-#define HA_ATOMIC_AND(val, flags) __atomic_and_fetch(val, flags, 0)
+-#define HA_ATOMIC_OR(val, flags) __atomic_or_fetch(val, flags, 0)
+-#define HA_ATOMIC_XCHG(val, new) __atomic_exchange_n(val, new, 0)
+-#define HA_ATOMIC_STORE(val, new) __atomic_store_n(val, new, 0)
++#define HA_ATOMIC_CAS(val, old, new) __atomic_compare_exchange_n(val, old, new, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
++#define HA_ATOMIC_ADD(val, i) __atomic_add_fetch(val, i, __ATOMIC_SEQ_CST)
++#define HA_ATOMIC_XADD(val, i) __atomic_fetch_add(val, i, __ATOMIC_SEQ_CST)
++#define HA_ATOMIC_SUB(val, i) __atomic_sub_fetch(val, i, __ATOMIC_SEQ_CST)
++#define HA_ATOMIC_AND(val, flags) __atomic_and_fetch(val, flags, __ATOMIC_SEQ_CST)
++#define HA_ATOMIC_OR(val, flags) __atomic_or_fetch(val, flags, __ATOMIC_SEQ_CST)
++#define HA_ATOMIC_XCHG(val, new) __atomic_exchange_n(val, new, __ATOMIC_SEQ_CST)
++#define HA_ATOMIC_STORE(val, new) __atomic_store_n(val, new, __ATOMIC_SEQ_CST)
+ #endif
+
+ #define HA_ATOMIC_UPDATE_MAX(val, new) \
--- /dev/null
+commit 1dfa4fd4be313a87f2a4861e81d0ad8ea8214223
+Author: Willy Tarreau <w@1wt.eu>
+Date: Thu Mar 14 19:10:55 2019 +0100
+
+ BUG/MEDIUM: threads/fd: do not forget to take into account epoll_fd/pipes
+
+ Each thread uses one epoll_fd or kqueue_fd, and a pipe (thus two FDs).
+ These ones have to be accounted for in the maxsock calculation, otherwise
+ we can reach maxsock before maxconn. This is difficult to observe but it
+ in fact happens when a server connects back to the frontend and has checks
+ enabled : the check uses its FD and serves to fill the loop. In this case
+ all FDs planed for the datapath are used for this.
+
+ This needs to be backported to 1.9 and 1.8.
+
+ (cherry picked from commit 2c58b41c96e70f567d0f9ae876a80770630c06ee)
+ Signed-off-by: Willy Tarreau <w@1wt.eu>
+ (cherry picked from commit 26d110ba04cba02b337beff53a83847320e4fcdb)
+ Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
+
+diff --git a/src/haproxy.c b/src/haproxy.c
+index 68367627..5c3febdd 100644
+--- a/src/haproxy.c
++++ b/src/haproxy.c
+@@ -1828,6 +1828,9 @@ static void init(int argc, char **argv)
+ global.hardmaxconn = global.maxconn; /* keep this max value */
+ global.maxsock += global.maxconn * 2; /* each connection needs two sockets */
+ global.maxsock += global.maxpipes * 2; /* each pipe needs two FDs */
++ global.maxsock += global.nbthread; /* one epoll_fd/kqueue_fd per thread */
++ global.maxsock += 2 * global.nbthread; /* one wake-up pipe (2 fd) per thread */
++
+ /* compute fd used by async engines */
+ if (global.ssl_used_async_engines) {
+ int sides = !!global.ssl_used_frontend + !!global.ssl_used_backend;
--- /dev/null
+commit a3cfe8f4bc2ec98fdbe25c49f2c21699b6d09d2b
+Author: Christopher Faulet <cfaulet@haproxy.com>
+Date: Mon Mar 18 13:57:42 2019 +0100
+
+ BUG/MAJOR: spoe: Fix initialization of thread-dependent fields
+
+ A bug was introduced in the commit b0769b ("BUG/MEDIUM: spoe: initialization
+ depending on nbthread must be done last"). The code depending on global.nbthread
+ was moved from cfg_parse_spoe_agent() to spoe_check() but the pointer on the
+ agent configuration was not updated to use the filter's one. The variable
+ curagent is a global variable only valid during the configuration parsing. In
+ spoe_check(), conf->agent must be used instead.
+
+ This patch must be backported to 1.9 and 1.8.
+
+ (cherry picked from commit fe261551b9980fe33990eb34d2153bf1de24b20f)
+ Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
+ (cherry picked from commit 7a93d271d549144a8ed8c816f5694a51ab62b90c)
+ Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
+
+diff --git a/src/flt_spoe.c b/src/flt_spoe.c
+index e4453882..66d26f34 100644
+--- a/src/flt_spoe.c
++++ b/src/flt_spoe.c
+@@ -2937,20 +2937,20 @@ spoe_check(struct proxy *px, struct flt_conf *fconf)
+ if (global.nbthread == 1)
+ conf->agent->flags |= SPOE_FL_ASYNC;
+
+- if ((curagent->rt = calloc(global.nbthread, sizeof(*curagent->rt))) == NULL) {
++ if ((conf->agent->rt = calloc(global.nbthread, sizeof(*conf->agent->rt))) == NULL) {
+ ha_alert("Proxy %s : out of memory initializing SPOE agent '%s' declared at %s:%d.\n",
+ px->id, conf->agent->id, conf->agent->conf.file, conf->agent->conf.line);
+ return 1;
+ }
+ for (i = 0; i < global.nbthread; ++i) {
+- curagent->rt[i].frame_size = curagent->max_frame_size;
+- curagent->rt[i].applets_act = 0;
+- curagent->rt[i].applets_idle = 0;
+- curagent->rt[i].sending_rate = 0;
+- LIST_INIT(&curagent->rt[i].applets);
+- LIST_INIT(&curagent->rt[i].sending_queue);
+- LIST_INIT(&curagent->rt[i].waiting_queue);
+- HA_SPIN_INIT(&curagent->rt[i].lock);
++ conf->agent->rt[i].frame_size = conf->agent->max_frame_size;
++ conf->agent->rt[i].applets_act = 0;
++ conf->agent->rt[i].applets_idle = 0;
++ conf->agent->rt[i].sending_rate = 0;
++ LIST_INIT(&conf->agent->rt[i].applets);
++ LIST_INIT(&conf->agent->rt[i].sending_queue);
++ LIST_INIT(&conf->agent->rt[i].waiting_queue);
++ HA_SPIN_INIT(&conf->agent->rt[i].lock);
+ }
+
+ free(conf->agent->b.name);
--- /dev/null
+--- a/src/ssl_sock.c
++++ b/src/ssl_sock.c
+@@ -39,6 +39,7 @@
+ #include <netdb.h>
+ #include <netinet/tcp.h>
+
++#include <openssl/bn.h>
+ #include <openssl/crypto.h>
+ #include <openssl/ssl.h>
+ #include <openssl/x509.h>
+@@ -60,6 +61,17 @@
+ #include <openssl/async.h>
+ #endif
+
++#ifndef OPENSSL_VERSION
++#define OPENSSL_VERSION SSLEAY_VERSION
++#define OpenSSL_version(x) SSLeay_version(x)
++#define OpenSSL_version_num SSLeay
++#endif
++
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#define X509_getm_notBefore X509_get_notBefore
++#define X509_getm_notAfter X509_get_notAfter
++#endif
++
+ #include <import/lru.h>
+ #include <import/xxhash.h>
+
+@@ -217,7 +229,7 @@ static struct {
+ .capture_cipherlist = 0,
+ };
+
+-#ifdef USE_THREAD
++#if defined(USE_THREAD) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
+
+ static HA_RWLOCK_T *ssl_rwlocks;
+
+@@ -1716,8 +1728,8 @@ ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL
+ ASN1_INTEGER_set(X509_get_serialNumber(newcrt), HA_ATOMIC_ADD(&ssl_ctx_serial, 1));
+
+ /* Set duration for the certificate */
+- if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
+- !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
++ if (!X509_gmtime_adj(X509_getm_notBefore(newcrt), (long)-60*60*24) ||
++ !X509_gmtime_adj(X509_getm_notAfter(newcrt),(long)60*60*24*365))
+ goto mkcert_error;
+
+ /* set public key in the certificate */
+@@ -6299,7 +6311,7 @@ smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char
+ goto out;
+
+ smp_trash = get_trash_chunk();
+- if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
++ if (ssl_sock_get_time(X509_getm_notAfter(crt), smp_trash) <= 0)
+ goto out;
+
+ smp->data.u.str = *smp_trash;
+@@ -6399,7 +6411,7 @@ smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char
+ goto out;
+
+ smp_trash = get_trash_chunk();
+- if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
++ if (ssl_sock_get_time(X509_getm_notBefore(crt), smp_trash) <= 0)
+ goto out;
+
+ smp->data.u.str = *smp_trash;
+@@ -8976,10 +8988,12 @@ static void __ssl_sock_init(void)
+ #endif
+
+ xprt_register(XPRT_SSL, &ssl_sock);
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ SSL_library_init();
++#endif
+ cm = SSL_COMP_get_compression_methods();
+ sk_SSL_COMP_zero(cm);
+-#ifdef USE_THREAD
++#if defined(USE_THREAD) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
+ ssl_locking_init();
+ #endif
+ #if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
+@@ -9008,8 +9022,8 @@ static void __ssl_sock_init(void)
+ #else /* OPENSSL_IS_BORINGSSL */
+ OPENSSL_VERSION_TEXT
+ "\nRunning on OpenSSL version : %s%s",
+- SSLeay_version(SSLEAY_VERSION),
+- ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
++ OpenSSL_version(OPENSSL_VERSION),
++ ((OPENSSL_VERSION_NUMBER ^ OpenSSL_version_num()) >> 8) ? " (VERSIONS DIFFER!)" : "");
+ #endif
+ memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
+ #if OPENSSL_VERSION_NUMBER < 0x00907000L
+@@ -9100,12 +9114,14 @@ static void __ssl_sock_deinit(void)
+ }
+ #endif
+
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ ERR_remove_state(0);
+ ERR_free_strings();
+
+ EVP_cleanup();
++#endif
+
+-#if OPENSSL_VERSION_NUMBER >= 0x00907000L
++#if OPENSSL_VERSION_NUMBER >= 0x00907000L && OPENSSL_VERSION_NUMBER < 0x10100000L
+ CRYPTO_cleanup_all_ex_data();
+ #endif
+ }