[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#985759: marked as done (unblock: mosquitto/2.0.9-1)



Your message dated Fri, 26 Mar 2021 19:28:38 +0000
with message-id <E1lPs8M-0006xE-1r@respighi.debian.org>
and subject line unblock mosquitto
has caused the Debian Bug report #985759,
regarding unblock: mosquitto/2.0.9-1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
985759: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=985759
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package mosquitto

[ Reason ]
Mosquitto 2.0.8 is currently in testing, Mosquitto 2.0.9 was released on
2021-03-11 and has sufficiently important fixes in it that I believe
should be in a Debian release.

The full debdiff is 1110 lines. If I reduce that to code-only changes it
drops to 387 (the remainder are documentation and extra tests), with
about 150 lines of actual affected code. It is a small bugfix release
with low risk but some reasonably important fixes.

[ Impact ]
I have listed the fixes below that I think are worth mentioning. The
other changes are of minor impact or are fixing strict compiler
warnings.

Client and library: There is a fairly minor security issue that affects
outgoing client connections only - if an empty or corrupt CA certificate
is provided to a client, then the initial connection would fail but
subsequent connections would succeed without verifying the remote server
certificate. There is a new test for this behaviour, but it is not in
the 2.0.9 release.

Build: The CMake build script was not enabling epoll(), so poll() was
being used instead which has a very detrimental impact on performance.

Server: Messages published with QoS 0 were not being delivered when
`max_queued_bytes` was configured. This has a big impact on users
wanting to use QoS 0, which is the most common QoS, but also set some
client limits. There is a new test to check this behaviour.

Server: If the `max_keepalive` option was set, this did not apply to
clients connecting with keepalive set to 0 (which means "infinite keepalive").
This gives a very straightforward means to circumvent the wishes of the
server operator, although in itself it isn't very important.

Server: The behaviour setting acceptable TLS versions did not match the
documentation.

Server: Messages to '$' prefixed MQTT topics were being rejected. This
is not security critical but very annoying for a user wanting to use
that feature.

[ Tests ]
The release introduces a new test that covers one issue. A test
exists for the CA issue but is not part of this release.

[ Risks ]
I believe this to be low risk. Most of the code changes are reasonably
simple.

shairport-sync, kamailio-mqtt-module, and baresip-core depend on
libmosquitto1. The changes to the library code are trivial.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing

[ Other info ]
mosquitto_2.0.8-mosquitto-2.0.9.debdiff is the full debdiff.
mosquitto_2.0.8-mosquitto-2.0.9-code.debdiff is the code only debdiff.

unblock mosquitto/2.0.9-1

-- System Information:
Debian Release: bullseye/sid
  APT prefers focal-updates
  APT policy: (500, 'focal-updates'), (500, 'focal-security'), (500, 'focal-proposed'), (500, 'focal'), (100, 'focal-backports')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 5.4.0-48-generic (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
diff -Nru mosquitto-2.0.8/ChangeLog.txt mosquitto-2.0.9/ChangeLog.txt
--- mosquitto-2.0.8/ChangeLog.txt	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/ChangeLog.txt	2021-03-11 22:37:20.000000000 +0000
@@ -1,3 +1,39 @@
+2.0.9 - 2021-03-11
+==================
+
+Security:
+- If an empty or invalid CA file was provided to the client library for
+  verifying the remote broker, then the initial connection would fail but
+  subsequent connections would succeed without verifying the remote broker
+  certificate. Closes #2130.
+- If an empty or invalid CA file was provided to the broker for verifying the
+  remote broker for an outgoing bridge connection then the initial connection
+  would fail but subsequent connections would succeed without verifying the
+  remote broker certificate. Closes #2130.
+
+Broker:
+- Fix encrypted bridge connections incorrectly connecting when `bridge_cafile`
+  is empty or invalid. Closes #2130.
+- Fix `tls_version` behaviour not matching documentation. It was setting the
+  exact TLS version to use, not the minimium TLS version to use. Closes #2110.
+- Fix messages to `$` prefixed topics being rejected. Closes #2111.
+- Fix QoS 0 messages not being delivered when max_queued_bytes was configured.
+  Closes #2123.
+- Fix bridge increasing backoff calculation.
+- Improve handling of invalid combinations of listener address and bind
+  interface configurations. Closes #2081.
+- Fix `max_keepalive` option not applying to clients connecting with keepalive
+  set to 0. Closes #2117.
+
+Client library:
+- Fix encrypted connections incorrectly connecting when the CA file passed to
+  `mosquitto_tls_set()` is empty or invalid. Closes #2130.
+- Fix connections retrying very rapidly in some situations.
+
+Build:
+- Fix cmake epoll detection.
+
+
 2.0.8 - 2021-02-25
 ==================
 
diff -Nru mosquitto-2.0.8/CMakeLists.txt mosquitto-2.0.9/CMakeLists.txt
--- mosquitto-2.0.8/CMakeLists.txt	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/CMakeLists.txt	2021-03-11 22:37:20.000000000 +0000
@@ -8,7 +8,7 @@
 cmake_policy(SET CMP0042 NEW)
 
 project(mosquitto)
-set (VERSION 2.0.8)
+set (VERSION 2.0.9)
 
 list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/")
 
diff -Nru mosquitto-2.0.8/config.mk mosquitto-2.0.9/config.mk
--- mosquitto-2.0.8/config.mk	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/config.mk	2021-03-11 22:37:20.000000000 +0000
@@ -127,7 +127,7 @@
 
 # Also bump lib/mosquitto.h, CMakeLists.txt,
 # installer/mosquitto.nsi, installer/mosquitto64.nsi
-VERSION=2.0.8
+VERSION=2.0.9
 
 # Client library SO version. Bump if incompatible API/ABI changes are made.
 SOVERSION=1
diff -Nru mosquitto-2.0.8/debian/changelog mosquitto-2.0.9/debian/changelog
--- mosquitto-2.0.8/debian/changelog	2021-02-25 18:56:57.000000000 +0000
+++ mosquitto-2.0.9/debian/changelog	2021-03-11 22:53:34.000000000 +0000
@@ -1,3 +1,9 @@
+mosquitto (2.0.9-1) unstable; urgency=medium
+
+  * New upstream release.
+
+ -- Roger A. Light <roger@atchoo.org>  Thu, 11 Mar 2021 22:53:34 +0000
+
 mosquitto (2.0.8-1) unstable; urgency=medium
 
   * New upstream release.
diff -Nru mosquitto-2.0.8/debian/control mosquitto-2.0.9/debian/control
--- mosquitto-2.0.8/debian/control	2021-02-25 18:56:53.000000000 +0000
+++ mosquitto-2.0.9/debian/control	2021-03-11 22:53:28.000000000 +0000
@@ -11,7 +11,7 @@
                libwebsockets-dev,
                libwrap0-dev,
                pkg-config,
-               uthash-dev (>=2.1.0),
+               uthash-dev,
                xsltproc,
                docbook-xsl
 Standards-Version: 4.5.0
diff -Nru mosquitto-2.0.8/include/mosquitto.h mosquitto-2.0.9/include/mosquitto.h
--- mosquitto-2.0.8/include/mosquitto.h	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/include/mosquitto.h	2021-03-11 22:37:20.000000000 +0000
@@ -66,7 +66,7 @@
 
 #define LIBMOSQUITTO_MAJOR 2
 #define LIBMOSQUITTO_MINOR 0
-#define LIBMOSQUITTO_REVISION 8
+#define LIBMOSQUITTO_REVISION 9
 /* LIBMOSQUITTO_VERSION_NUMBER looks like 1002001 for e.g. version 1.2.1. */
 #define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION)
 
@@ -1605,40 +1605,6 @@
 libmosq_EXPORT int mosquitto_void_option(struct mosquitto *mosq, enum mosq_opt_t option, void *value);
 
 /*
- * Function: mosquitto_string_option
- *
- * Used to set const char* options for the client.
- *
- * Parameters:
- *	mosq -   a valid mosquitto instance.
- *	option - the option to set.
- *	value -  the option specific value.
- *
- * Options:
- *	MOSQ_OPT_TLS_ENGINE
- *	          Configure the client for TLS Engine support. Pass a TLS Engine ID
- *	          to be used when creating TLS connections.
- *	          Must be set before <mosquitto_connect>.
- *	MOSQ_OPT_TLS_KEYFORM
- *            Configure the client to treat the keyfile differently depending
- *            on its type.  Must be set before <mosquitto_connect>.
- *	          Set as either "pem" or "engine", to determine from where the
- *	          private key for a TLS connection will be obtained. Defaults to
- *	          "pem", a normal private key file.
- *	MOSQ_OPT_TLS_KPASS_SHA1
- *	          Where the TLS Engine requires the use of a password to be
- *	          accessed, this option allows a hex encoded SHA1 hash of the
- *	          private key password to be passed to the engine directly.
- *	          Must be set before <mosquitto_connect>.
- *	MOSQ_OPT_TLS_ALPN
- *	          If the broker being connected to has multiple services available
- *	          on a single TLS port, such as both MQTT and WebSockets, use this
- *	          option to configure the ALPN option for the connection.
- */
-libmosq_EXPORT int mosquitto_string_option(struct mosquitto *mosq, enum mosq_opt_t option, const char *value);
-
-
-/*
  * Function: mosquitto_reconnect_delay_set
  *
  * Control the behaviour of the client when it has unexpectedly disconnected in
diff -Nru mosquitto-2.0.8/installer/mosquitto64.nsi mosquitto-2.0.9/installer/mosquitto64.nsi
--- mosquitto-2.0.8/installer/mosquitto64.nsi	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/installer/mosquitto64.nsi	2021-03-11 22:37:20.000000000 +0000
@@ -9,7 +9,7 @@
 !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
 
 Name "Eclipse Mosquitto"
-!define VERSION 2.0.8
+!define VERSION 2.0.9
 OutFile "mosquitto-${VERSION}-install-windows-x64.exe"
 
 !include "x64.nsh"
diff -Nru mosquitto-2.0.8/installer/mosquitto.nsi mosquitto-2.0.9/installer/mosquitto.nsi
--- mosquitto-2.0.8/installer/mosquitto.nsi	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/installer/mosquitto.nsi	2021-03-11 22:37:20.000000000 +0000
@@ -9,7 +9,7 @@
 !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
 
 Name "Eclipse Mosquitto"
-!define VERSION 2.0.8
+!define VERSION 2.0.9
 OutFile "mosquitto-${VERSION}-install-windows-x86.exe"
 
 InstallDir "$PROGRAMFILES\mosquitto"
diff -Nru mosquitto-2.0.8/lib/loop.c mosquitto-2.0.9/lib/loop.c
--- mosquitto-2.0.8/lib/loop.c	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/lib/loop.c	2021-03-11 22:37:20.000000000 +0000
@@ -203,6 +203,13 @@
 	char pairbuf;
 	int maxfd = 0;
 
+#ifndef WIN32
+	if(read(mosq->sockpairR, &pairbuf, 1) == 0){
+	}
+#else
+	recv(mosq->sockpairR, &pairbuf, 1, 0);
+#endif
+
 	local_timeout.tv_sec = reconnect_delay;
 #ifdef HAVE_PSELECT
 	local_timeout.tv_nsec = 0;
diff -Nru mosquitto-2.0.8/lib/mosquitto.c mosquitto-2.0.9/lib/mosquitto.c
--- mosquitto-2.0.8/lib/mosquitto.c	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/lib/mosquitto.c	2021-03-11 22:37:20.000000000 +0000
@@ -196,6 +196,7 @@
 #ifdef WITH_TLS
 	mosq->ssl = NULL;
 	mosq->ssl_ctx = NULL;
+	mosq->ssl_ctx_defaults = true;
 	mosq->tls_cert_reqs = SSL_VERIFY_PEER;
 	mosq->tls_insecure = false;
 	mosq->want_write = false;
diff -Nru mosquitto-2.0.8/lib/mosquitto_internal.h mosquitto-2.0.9/lib/mosquitto_internal.h
--- mosquitto-2.0.8/lib/mosquitto_internal.h	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/lib/mosquitto_internal.h	2021-03-11 22:37:20.000000000 +0000
@@ -190,8 +190,8 @@
 #ifdef WITH_BROKER
 	struct mosquitto_client_msg *inflight;
 	struct mosquitto_client_msg *queued;
-	unsigned long msg_bytes;
-	unsigned long msg_bytes12;
+	long msg_bytes;
+	long msg_bytes12;
 	int msg_count;
 	int msg_count12;
 #else
diff -Nru mosquitto-2.0.8/man/libmosquitto.3 mosquitto-2.0.9/man/libmosquitto.3
--- mosquitto-2.0.8/man/libmosquitto.3	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/man/libmosquitto.3	2021-03-11 22:37:20.000000000 +0000
@@ -1,13 +1,13 @@
 '\" t
 .\"     Title: libmosquitto
 .\"    Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/25/2021
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\"      Date: 03/11/2021
 .\"    Manual: Library calls
 .\"    Source: Mosquitto Project
 .\"  Language: English
 .\"
-.TH "LIBMOSQUITTO" "3" "02/25/2021" "Mosquitto Project" "Library calls"
+.TH "LIBMOSQUITTO" "3" "03/11/2021" "Mosquitto Project" "Library calls"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff -Nru mosquitto-2.0.8/man/mosquitto.8 mosquitto-2.0.9/man/mosquitto.8
--- mosquitto-2.0.8/man/mosquitto.8	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/man/mosquitto.8	2021-03-11 22:37:20.000000000 +0000
@@ -1,13 +1,13 @@
 '\" t
 .\"     Title: mosquitto
 .\"    Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/25/2021
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\"      Date: 03/11/2021
 .\"    Manual: System management commands
 .\"    Source: Mosquitto Project
 .\"  Language: English
 .\"
-.TH "MOSQUITTO" "8" "02/25/2021" "Mosquitto Project" "System management commands"
+.TH "MOSQUITTO" "8" "03/11/2021" "Mosquitto Project" "System management commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff -Nru mosquitto-2.0.8/man/mosquitto.conf.5 mosquitto-2.0.9/man/mosquitto.conf.5
--- mosquitto-2.0.8/man/mosquitto.conf.5	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/man/mosquitto.conf.5	2021-03-11 22:37:20.000000000 +0000
@@ -1,13 +1,13 @@
 '\" t
 .\"     Title: mosquitto.conf
 .\"    Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/25/2021
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\"      Date: 03/11/2021
 .\"    Manual: File formats and conventions
 .\"    Source: Mosquitto Project
 .\"  Language: English
 .\"
-.TH "MOSQUITTO\&.CONF" "5" "02/25/2021" "Mosquitto Project" "File formats and conventions"
+.TH "MOSQUITTO\&.CONF" "5" "03/11/2021" "Mosquitto Project" "File formats and conventions"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff -Nru mosquitto-2.0.8/man/mosquitto_ctrl.1 mosquitto-2.0.9/man/mosquitto_ctrl.1
--- mosquitto-2.0.8/man/mosquitto_ctrl.1	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/man/mosquitto_ctrl.1	2021-03-11 22:37:20.000000000 +0000
@@ -1,13 +1,13 @@
 '\" t
 .\"     Title: mosquitto_ctrl
 .\"    Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/25/2021
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\"      Date: 03/11/2021
 .\"    Manual: Commands
 .\"    Source: Mosquitto Project
 .\"  Language: English
 .\"
-.TH "MOSQUITTO_CTRL" "1" "02/25/2021" "Mosquitto Project" "Commands"
+.TH "MOSQUITTO_CTRL" "1" "03/11/2021" "Mosquitto Project" "Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff -Nru mosquitto-2.0.8/man/mosquitto_ctrl_dynsec.1 mosquitto-2.0.9/man/mosquitto_ctrl_dynsec.1
--- mosquitto-2.0.8/man/mosquitto_ctrl_dynsec.1	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/man/mosquitto_ctrl_dynsec.1	2021-03-11 22:37:20.000000000 +0000
@@ -1,13 +1,13 @@
 '\" t
 .\"     Title: mosquitto_ctrl_dynsec
 .\"    Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/25/2021
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\"      Date: 03/11/2021
 .\"    Manual: Commands
 .\"    Source: Mosquitto Project
 .\"  Language: English
 .\"
-.TH "MOSQUITTO_CTRL_DYNSE" "1" "02/25/2021" "Mosquitto Project" "Commands"
+.TH "MOSQUITTO_CTRL_DYNSE" "1" "03/11/2021" "Mosquitto Project" "Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff -Nru mosquitto-2.0.8/man/mosquitto_passwd.1 mosquitto-2.0.9/man/mosquitto_passwd.1
--- mosquitto-2.0.8/man/mosquitto_passwd.1	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/man/mosquitto_passwd.1	2021-03-11 22:37:20.000000000 +0000
@@ -1,13 +1,13 @@
 '\" t
 .\"     Title: mosquitto_passwd
 .\"    Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/25/2021
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\"      Date: 03/11/2021
 .\"    Manual: Commands
 .\"    Source: Mosquitto Project
 .\"  Language: English
 .\"
-.TH "MOSQUITTO_PASSWD" "1" "02/25/2021" "Mosquitto Project" "Commands"
+.TH "MOSQUITTO_PASSWD" "1" "03/11/2021" "Mosquitto Project" "Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff -Nru mosquitto-2.0.8/man/mosquitto_pub.1 mosquitto-2.0.9/man/mosquitto_pub.1
--- mosquitto-2.0.8/man/mosquitto_pub.1	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/man/mosquitto_pub.1	2021-03-11 22:37:20.000000000 +0000
@@ -1,13 +1,13 @@
 '\" t
 .\"     Title: mosquitto_pub
 .\"    Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/25/2021
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\"      Date: 03/11/2021
 .\"    Manual: Commands
 .\"    Source: Mosquitto Project
 .\"  Language: English
 .\"
-.TH "MOSQUITTO_PUB" "1" "02/25/2021" "Mosquitto Project" "Commands"
+.TH "MOSQUITTO_PUB" "1" "03/11/2021" "Mosquitto Project" "Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff -Nru mosquitto-2.0.8/man/mosquitto_rr.1 mosquitto-2.0.9/man/mosquitto_rr.1
--- mosquitto-2.0.8/man/mosquitto_rr.1	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/man/mosquitto_rr.1	2021-03-11 22:37:20.000000000 +0000
@@ -1,13 +1,13 @@
 '\" t
 .\"     Title: mosquitto_rr
 .\"    Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/25/2021
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\"      Date: 03/11/2021
 .\"    Manual: Commands
 .\"    Source: Mosquitto Project
 .\"  Language: English
 .\"
-.TH "MOSQUITTO_RR" "1" "02/25/2021" "Mosquitto Project" "Commands"
+.TH "MOSQUITTO_RR" "1" "03/11/2021" "Mosquitto Project" "Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -437,7 +437,7 @@
 \fBmqttv5\fR,
 \fBmqttv311\fR, or
 \fBmqttv31\fR\&. Defaults to
-\fB311\fR\&.
+\fB5\fR\&.
 .RE
 .PP
 \fB\-\-will\-payload\fR
diff -Nru mosquitto-2.0.8/man/mosquitto_rr.1.xml mosquitto-2.0.9/man/mosquitto_rr.1.xml
--- mosquitto-2.0.8/man/mosquitto_rr.1.xml	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/man/mosquitto_rr.1.xml	2021-03-11 22:37:20.000000000 +0000
@@ -632,7 +632,7 @@
 						<option>31</option>, or the more verbose
 						<option>mqttv5</option>, <option>mqttv311</option>, or
 						<option>mqttv31</option>.
-						Defaults to <option>311</option>.</para>
+						Defaults to <option>5</option>.</para>
 				</listitem>
 			</varlistentry>
 			<varlistentry>
diff -Nru mosquitto-2.0.8/man/mosquitto_sub.1 mosquitto-2.0.9/man/mosquitto_sub.1
--- mosquitto-2.0.8/man/mosquitto_sub.1	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/man/mosquitto_sub.1	2021-03-11 22:37:20.000000000 +0000
@@ -1,13 +1,13 @@
 '\" t
 .\"     Title: mosquitto_sub
 .\"    Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/25/2021
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\"      Date: 03/11/2021
 .\"    Manual: Commands
 .\"    Source: Mosquitto Project
 .\"  Language: English
 .\"
-.TH "MOSQUITTO_SUB" "1" "02/25/2021" "Mosquitto Project" "Commands"
+.TH "MOSQUITTO_SUB" "1" "03/11/2021" "Mosquitto Project" "Commands"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff -Nru mosquitto-2.0.8/man/mosquitto-tls.7 mosquitto-2.0.9/man/mosquitto-tls.7
--- mosquitto-2.0.8/man/mosquitto-tls.7	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/man/mosquitto-tls.7	2021-03-11 22:37:20.000000000 +0000
@@ -1,13 +1,13 @@
 '\" t
 .\"     Title: mosquitto-tls
 .\"    Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/25/2021
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\"      Date: 03/11/2021
 .\"    Manual: Conventions and miscellaneous
 .\"    Source: Mosquitto Project
 .\"  Language: English
 .\"
-.TH "MOSQUITTO\-TLS" "7" "02/25/2021" "Mosquitto Project" "Conventions and miscellaneous"
+.TH "MOSQUITTO\-TLS" "7" "03/11/2021" "Mosquitto Project" "Conventions and miscellaneous"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff -Nru mosquitto-2.0.8/man/mqtt.7 mosquitto-2.0.9/man/mqtt.7
--- mosquitto-2.0.8/man/mqtt.7	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/man/mqtt.7	2021-03-11 22:37:20.000000000 +0000
@@ -1,13 +1,13 @@
 '\" t
 .\"     Title: mqtt
 .\"    Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/25/2021
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\"      Date: 03/11/2021
 .\"    Manual: Conventions and miscellaneous
 .\"    Source: Mosquitto Project
 .\"  Language: English
 .\"
-.TH "MQTT" "7" "02/25/2021" "Mosquitto Project" "Conventions and miscellaneous"
+.TH "MQTT" "7" "03/11/2021" "Mosquitto Project" "Conventions and miscellaneous"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff -Nru mosquitto-2.0.8/snap/snapcraft.yaml mosquitto-2.0.9/snap/snapcraft.yaml
--- mosquitto-2.0.8/snap/snapcraft.yaml	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/snap/snapcraft.yaml	2021-03-11 22:37:20.000000000 +0000
@@ -1,5 +1,5 @@
 name: mosquitto
-version: 2.0.8
+version: 2.0.9
 summary: Eclipse Mosquitto MQTT broker
 description: This is a message broker that supports version 5.0, 3.1.1, and 3.1 of the MQTT
     protocol.
diff -Nru mosquitto-2.0.8/src/bridge.c mosquitto-2.0.9/src/bridge.c
--- mosquitto-2.0.8/src/bridge.c	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/src/bridge.c	2021-03-11 22:37:20.000000000 +0000
@@ -112,6 +112,7 @@
 	new_context->tls_alpn = new_context->bridge->tls_alpn;
 	new_context->tls_engine = db.config->default_listener.tls_engine;
 	new_context->tls_keyform = db.config->default_listener.tls_keyform;
+	new_context->ssl_ctx_defaults = true;
 #ifdef FINAL_WITH_TLS_PSK
 	new_context->tls_psk_identity = new_context->bridge->tls_psk_identity;
 	new_context->tls_psk = new_context->bridge->tls_psk;
@@ -313,10 +314,8 @@
 
 	rc = send__connect(context, context->keepalive, context->clean_start, NULL);
 	if(rc == MOSQ_ERR_SUCCESS){
-		bridge__backoff_reset(context);
 		return MOSQ_ERR_SUCCESS;
 	}else if(rc == MOSQ_ERR_ERRNO && errno == ENOTCONN){
-		bridge__backoff_reset(context);
 		return MOSQ_ERR_SUCCESS;
 	}else{
 		if(rc == MOSQ_ERR_TLS){
@@ -454,10 +453,8 @@
 
 	rc2 = send__connect(context, context->keepalive, context->clean_start, NULL);
 	if(rc2 == MOSQ_ERR_SUCCESS){
-		bridge__backoff_reset(context);
 		return rc;
 	}else if(rc2 == MOSQ_ERR_ERRNO && errno == ENOTCONN){
-		bridge__backoff_reset(context);
 		return MOSQ_ERR_SUCCESS;
 	}else{
 		if(rc2 == MOSQ_ERR_TLS){
@@ -562,6 +559,8 @@
 		}
 	}
 
+	bridge__backoff_reset(context);
+
 	return MOSQ_ERR_SUCCESS;
 }
 
@@ -646,11 +645,11 @@
 	packet__cleanup(&(context->in_packet));
 }
 
-static int rand_between(int base, int cap)
+static int rand_between(int low, int high)
 {
 	int r;
 	util__random_bytes(&r, sizeof(int));
-	return (r % (cap - base)) + base;
+	return (abs(r) % (high - low)) + low;
 }
 
 static void bridge__backoff_step(struct mosquitto *context)
@@ -685,6 +684,33 @@
 	}
 }
 
+
+static void bridge_check_pending(struct mosquitto *context)
+{
+	int err;
+	socklen_t len;
+
+	if(context->state == mosq_cs_connect_pending){
+		len = sizeof(int);
+		if(!getsockopt(context->sock, SOL_SOCKET, SO_ERROR, (char *)&err, &len)){
+			if(err == 0){
+				mosquitto__set_state(context, mosq_cs_new);
+#if defined(WITH_ADNS) && defined(WITH_BRIDGE)
+				if(context->bridge){
+					bridge__connect_step3(context);
+				}
+#endif
+			}else if(err == ECONNREFUSED){
+				do_disconnect(context, MOSQ_ERR_CONN_LOST);
+				return;
+			}
+		}else{
+			do_disconnect(context, MOSQ_ERR_CONN_LOST);
+			return;
+		}
+	}
+}
+
 void bridge_check(void)
 {
 	static time_t last_check = 0;
@@ -703,6 +729,7 @@
 
 		if(context->sock != INVALID_SOCKET){
 			mosquitto__check_keepalive(context);
+			bridge_check_pending(context);
 
 			/* Check for bridges that are not round robin and not currently
 			 * connected to their primary broker. */
diff -Nru mosquitto-2.0.8/src/CMakeLists.txt mosquitto-2.0.9/src/CMakeLists.txt
--- mosquitto-2.0.8/src/CMakeLists.txt	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/src/CMakeLists.txt	2021-03-11 22:37:20.000000000 +0000
@@ -77,6 +77,11 @@
 	include_directories(${mosquitto_SOURCE_DIR} ${mosquitto_SOURCE_DIR}/deps)
 endif (WITH_BUNDLED_DEPS)
 
+find_path(HAVE_SYS_EPOLL_H sys/epoll.h)
+if (HAVE_SYS_EPOLL_H)
+	add_definitions("-DWITH_EPOLL")
+endif()
+
 option(INC_BRIDGE_SUPPORT
 	"Include bridge support for connecting to other brokers?" ON)
 if (INC_BRIDGE_SUPPORT)
diff -Nru mosquitto-2.0.8/src/database.c mosquitto-2.0.9/src/database.c
--- mosquitto-2.0.8/src/database.c	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/src/database.c	2021-03-11 22:37:20.000000000 +0000
@@ -53,7 +53,7 @@
 		if(db.config->max_queued_messages == 0 && db.config->max_inflight_bytes == 0){
 			return true;
 		}
-		valid_bytes = msgs->msg_bytes - db.config->max_inflight_bytes < db.config->max_queued_bytes;
+		valid_bytes = ((msgs->msg_bytes - (ssize_t)db.config->max_inflight_bytes) < (ssize_t)db.config->max_queued_bytes);
 		valid_count = msgs->msg_count - msgs->inflight_maximum < db.config->max_queued_messages;
 
 		if(db.config->max_queued_messages == 0){
@@ -90,8 +90,8 @@
 {
 	int source_count;
 	int adjust_count;
-	size_t source_bytes;
-	size_t adjust_bytes = db.config->max_inflight_bytes;
+	long source_bytes;
+	ssize_t adjust_bytes = (ssize_t)db.config->max_inflight_bytes;
 	bool valid_bytes;
 	bool valid_count;
 
@@ -893,6 +893,26 @@
 }
 
 
+int db__message_remove_incoming(struct mosquitto* context, uint16_t mid)
+{
+	struct mosquitto_client_msg *tail, *tmp;
+
+	if(!context) return MOSQ_ERR_INVAL;
+
+	DL_FOREACH_SAFE(context->msgs_in.inflight, tail, tmp){
+		if(tail->mid == mid) {
+			if(tail->store->qos != 2){
+				return MOSQ_ERR_PROTOCOL;
+			}
+			db__message_remove(&context->msgs_in, tail);
+			return MOSQ_ERR_SUCCESS;
+		}
+	}
+
+	return MOSQ_ERR_NOT_FOUND;
+}
+
+
 int db__message_release_incoming(struct mosquitto *context, uint16_t mid)
 {
 	struct mosquitto_client_msg *tail, *tmp;
diff -Nru mosquitto-2.0.8/src/handle_connect.c mosquitto-2.0.9/src/handle_connect.c
--- mosquitto-2.0.8/src/handle_connect.c	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/src/handle_connect.c	2021-03-11 22:37:20.000000000 +0000
@@ -244,7 +244,9 @@
 				goto error;
 			}
 		}
-		if(context->keepalive > db.config->max_keepalive){
+		if(db.config->max_keepalive &&
+				(context->keepalive > db.config->max_keepalive || context->keepalive == 0)){
+
 			context->keepalive = db.config->max_keepalive;
 			if(mosquitto_property_add_int16(&connack_props, MQTT_PROP_SERVER_KEEP_ALIVE, context->keepalive)){
 				rc = MOSQ_ERR_NOMEM;
diff -Nru mosquitto-2.0.8/src/handle_publish.c mosquitto-2.0.9/src/handle_publish.c
--- mosquitto-2.0.8/src/handle_publish.c	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/src/handle_publish.c	2021-03-11 22:37:20.000000000 +0000
@@ -285,6 +285,18 @@
 	if(msg->qos > 0){
 		db__message_store_find(context, msg->source_mid, &stored);
 	}
+
+	if(stored && msg->source_mid != 0 &&
+			(stored->qos != msg->qos
+			 || stored->payloadlen != msg->payloadlen
+			 || strcmp(stored->topic, msg->topic)
+			 || memcmp(stored->payload, msg->payload, msg->payloadlen) )){
+
+		log__printf(NULL, MOSQ_LOG_WARNING, "Reused message ID %u from %s detected. Clearing from storage.", msg->source_mid, context->id);
+		db__message_remove_incoming(context, msg->source_mid);
+		stored = NULL;
+	}
+
 	if(!stored){
 		if(msg->qos == 0
 				|| db__ready_for_flight(&context->msgs_in, msg->qos)
diff -Nru mosquitto-2.0.8/src/mosquitto_broker_internal.h mosquitto-2.0.9/src/mosquitto_broker_internal.h
--- mosquitto-2.0.8/src/mosquitto_broker_internal.h	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/src/mosquitto_broker_internal.h	2021-03-11 22:37:20.000000000 +0000
@@ -642,6 +642,7 @@
 int db__message_count(int *count);
 int db__message_delete_outgoing(struct mosquitto *context, uint16_t mid, enum mosquitto_msg_state expect_state, int qos);
 int db__message_insert(struct mosquitto *context, uint16_t mid, enum mosquitto_msg_direction dir, uint8_t qos, bool retain, struct mosquitto_msg_store *stored, mosquitto_property *properties, bool update);
+int db__message_remove_incoming(struct mosquitto* context, uint16_t mid);
 int db__message_release_incoming(struct mosquitto *context, uint16_t mid);
 int db__message_update_outgoing(struct mosquitto *context, uint16_t mid, enum mosquitto_msg_state state, int qos);
 void db__message_dequeue_first(struct mosquitto *context, struct mosquitto_msg_data *msg_data);
diff -Nru mosquitto-2.0.8/src/net.c mosquitto-2.0.9/src/net.c
--- mosquitto-2.0.8/src/net.c	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/src/net.c	2021-03-11 22:37:20.000000000 +0000
@@ -335,14 +335,14 @@
 	}else if(!strcmp(listener->tls_version, "tlsv1.3")){
 		SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2);
 	}else if(!strcmp(listener->tls_version, "tlsv1.2")){
-		SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_3);
+		SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
 	}else if(!strcmp(listener->tls_version, "tlsv1.1")){
-		SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_3);
+		SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
 #else
 	}else if(!strcmp(listener->tls_version, "tlsv1.2")){
 		SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
 	}else if(!strcmp(listener->tls_version, "tlsv1.1")){
-		SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2);
+		SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
 #endif
 	}else{
 		log__printf(NULL, MOSQ_LOG_ERR, "Error: Unsupported tls_version \"%s\".", listener->tls_version);
@@ -624,23 +624,44 @@
 				&& ifa->ifa_addr->sa_family == rp->ai_addr->sa_family){
 
 			if(rp->ai_addr->sa_family == AF_INET){
-				memcpy(&((struct sockaddr_in *)rp->ai_addr)->sin_addr,
-						&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
-						sizeof(struct in_addr));
-
-				freeifaddrs(ifaddr);
-				return MOSQ_ERR_SUCCESS;
+				if(listener->host &&
+						memcmp(&((struct sockaddr_in *)rp->ai_addr)->sin_addr,
+							&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
+							sizeof(struct in_addr))){
+
+					log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface address for %s does not match specified listener address (%s).",
+							listener->bind_interface, listener->host);
+					return MOSQ_ERR_INVAL;
+				}else{
+					memcpy(&((struct sockaddr_in *)rp->ai_addr)->sin_addr,
+							&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
+							sizeof(struct in_addr));
+
+					freeifaddrs(ifaddr);
+					return MOSQ_ERR_SUCCESS;
+				}
 			}else if(rp->ai_addr->sa_family == AF_INET6){
-				memcpy(&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr,
-						&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
-						 sizeof(struct in6_addr));
-				freeifaddrs(ifaddr);
-				return MOSQ_ERR_SUCCESS;
+				if(listener->host &&
+						memcmp(&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr,
+							&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
+							sizeof(struct in6_addr))){
+
+					log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface address for %s does not match specified listener address (%s).",
+							listener->bind_interface, listener->host);
+					return MOSQ_ERR_INVAL;
+				}else{
+					memcpy(&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr,
+							&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
+							sizeof(struct in6_addr));
+					freeifaddrs(ifaddr);
+					return MOSQ_ERR_SUCCESS;
+				}
 			}
 		}
 	}
 	freeifaddrs(ifaddr);
-	log__printf(NULL, MOSQ_LOG_ERR, "Error: Interface %s not found.", listener->bind_interface);
+	log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface %s does not support %s configuration.",
+	            listener->bind_interface, rp->ai_addr->sa_family == AF_INET ? "IPv4" : "IPv6");
 	return MOSQ_ERR_NOT_FOUND;
 }
 #endif
@@ -654,6 +675,9 @@
 	char service[10];
 	int rc;
 	int ss_opt = 1;
+#ifndef WIN32
+	bool interface_bound = false;
+#endif
 
 	if(!listener) return MOSQ_ERR_INVAL;
 
@@ -718,12 +742,14 @@
 
 #ifndef WIN32
 		if(listener->bind_interface){
+			/* It might be possible that an interface does not support all relevant sa_families.
+			 * We should successfully find at least one. */
 			if(net__bind_interface(listener, rp)){
 				COMPAT_CLOSE(sock);
-				freeaddrinfo(ainfo);
-				mosquitto__free(listener->socks);
-				return 1;
+				listener->sock_count--;
+				continue;
 			}
+			interface_bound = true;
 		}
 #endif
 
@@ -745,6 +771,13 @@
 	}
 	freeaddrinfo(ainfo);
 
+#ifndef WIN32
+	if(listener->bind_interface && !interface_bound){
+		mosquitto__free(listener->socks);
+		return 1;
+	}
+#endif
+
 	return 0;
 }
 
diff -Nru mosquitto-2.0.8/src/retain.c mosquitto-2.0.9/src/retain.c
--- mosquitto-2.0.8/src/retain.c	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/src/retain.c	2021-03-11 22:37:20.000000000 +0000
@@ -83,7 +83,10 @@
 	assert(split_topics);
 
 	HASH_FIND(hh, db.retains, split_topics[0], strlen(split_topics[0]), retainhier);
-	if(retainhier == NULL) return MOSQ_ERR_NOT_FOUND;
+	if(retainhier == NULL){
+		retainhier = retain__add_hier_entry(NULL, &db.retains, split_topics[0], (uint16_t)strlen(split_topics[0]));
+		if(!retainhier) return MOSQ_ERR_NOMEM;
+	}
 
 	for(i=0; split_topics[i] != NULL; i++){
 		slen = strlen(split_topics[i]);
diff -Nru mosquitto-2.0.8/test/broker/02-subpub-qos0-queued-bytes.py mosquitto-2.0.9/test/broker/02-subpub-qos0-queued-bytes.py
--- mosquitto-2.0.8/test/broker/02-subpub-qos0-queued-bytes.py	1970-01-01 01:00:00.000000000 +0100
+++ mosquitto-2.0.9/test/broker/02-subpub-qos0-queued-bytes.py	2021-03-11 22:37:20.000000000 +0000
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+
+from mosq_test_helper import *
+
+def write_config(filename, port):
+    with open(filename, 'w') as f:
+        f.write("listener %d\n" % (port))
+        f.write("allow_anonymous true\n")
+        f.write("max_inflight_messages 20\n")
+        f.write("max_inflight_bytes 1000000\n")
+        f.write("max_queued_messages 20\n")
+        f.write("max_queued_bytes 1000000\n")
+
+def do_test(proto_ver):
+    rc = 1
+    keepalive = 60
+    connect_packet = mosq_test.gen_connect("subpub-qos0-bytes", keepalive=keepalive, proto_ver=proto_ver)
+    connack_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver)
+
+    connect_packet_helper = mosq_test.gen_connect("qos0-bytes-helper", keepalive=keepalive, proto_ver=proto_ver)
+
+    mid = 1
+    subscribe_packet = mosq_test.gen_subscribe(mid, "subpub/qos0/queued/bytes", 1, proto_ver=proto_ver)
+    suback_packet = mosq_test.gen_suback(mid, 1, proto_ver=proto_ver)
+
+    publish_packet0 = mosq_test.gen_publish("subpub/qos0/queued/bytes", qos=0, payload="message", proto_ver=proto_ver)
+
+
+    port = mosq_test.get_port()
+    conf_file = os.path.basename(__file__).replace('.py', '.conf')
+    write_config(conf_file, port)
+    broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port)
+
+    try:
+        sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=4, port=port, connack_error="connack 1")
+
+        mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback")
+
+        helper = mosq_test.do_client_connect(connect_packet_helper, connack_packet, timeout=4, port=port, connack_error="connack helper")
+
+        helper.send(publish_packet0)
+        mosq_test.expect_packet(sock, "publish0", publish_packet0)
+        rc = 0
+
+        sock.close()
+    except mosq_test.TestError:
+        pass
+    finally:
+        os.remove(conf_file)
+        broker.terminate()
+        broker.wait()
+        (stdo, stde) = broker.communicate()
+        if rc:
+            print(stde.decode('utf-8'))
+            print("proto_ver=%d" % (proto_ver))
+            exit(rc)
+
+
+do_test(proto_ver=4)
+do_test(proto_ver=5)
+exit(0)
diff -Nru mosquitto-2.0.8/test/broker/03-publish-b2c-timeout-qos1.py mosquitto-2.0.9/test/broker/03-publish-b2c-timeout-qos1.py
--- mosquitto-2.0.8/test/broker/03-publish-b2c-timeout-qos1.py	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/test/broker/03-publish-b2c-timeout-qos1.py	1970-01-01 01:00:00.000000000 +0100
@@ -1,71 +0,0 @@
-#!/usr/bin/env python3
-
-# Test whether a SUBSCRIBE to a topic with QoS 2 results in the correct SUBACK packet.
-
-from mosq_test_helper import *
-
-
-def helper(port):
-    connect_packet = mosq_test.gen_connect("test-helper", keepalive=60)
-    connack_packet = mosq_test.gen_connack(rc=0)
-
-    mid = 128
-    publish_packet = mosq_test.gen_publish("qos1/timeout/test", qos=1, mid=mid, payload="timeout-message")
-    puback_packet = mosq_test.gen_puback(mid)
-
-    sock = mosq_test.do_client_connect(connect_packet, connack_packet, connack_error="helper connack")
-    mosq_test.do_send_receive(sock, publish_packet, puback_packet, "helper puback")
-    sock.close()
-
-
-def do_test(proto_ver):
-    rc = 1
-    mid = 3265
-    keepalive = 60
-    connect_packet = mosq_test.gen_connect("pub-qos1-timeout-test", keepalive=keepalive, proto_ver=proto_ver)
-    connack_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver)
-
-    subscribe_packet = mosq_test.gen_subscribe(mid, "qos1/timeout/test", 1, proto_ver=proto_ver)
-    suback_packet = mosq_test.gen_suback(mid, 1, proto_ver=proto_ver)
-
-    mid = 1
-    publish_packet = mosq_test.gen_publish("qos1/timeout/test", qos=1, mid=mid, payload="timeout-message", proto_ver=proto_ver)
-    publish_dup_packet = mosq_test.gen_publish("qos1/timeout/test", qos=1, mid=mid, payload="timeout-message", dup=True, proto_ver=proto_ver)
-    puback_packet = mosq_test.gen_puback(mid, proto_ver=proto_ver)
-
-    port = mosq_test.get_port()
-    broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
-
-    try:
-        sock = mosq_test.do_client_connect(connect_packet, connack_packet)
-        mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback")
-
-        helper(port)
-        # Should have now received a publish command
-
-        mosq_test.expect_packet(sock, "publish", publish_packet)
-        # Wait for longer than 5 seconds to get republish with dup set
-        # This is covered by the 8 second timeout
-
-        mosq_test.expect_packet(sock, "dup publish", publish_dup_packet)
-        sock.send(puback_packet)
-        rc = 0
-
-        sock.close()
-    except mosq_test.TestError:
-        pass
-    finally:
-        broker.terminate()
-        broker.wait()
-        (stdo, stde) = broker.communicate()
-        if rc:
-            print(stde.decode('utf-8'))
-            print("proto_ver=%d" % (proto_ver))
-            exit(rc)
-
-
-do_test(proto_ver=4)
-do_test(proto_ver=5)
-
-exit(0)
-
diff -Nru mosquitto-2.0.8/test/broker/03-publish-b2c-timeout-qos2.py mosquitto-2.0.9/test/broker/03-publish-b2c-timeout-qos2.py
--- mosquitto-2.0.8/test/broker/03-publish-b2c-timeout-qos2.py	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/test/broker/03-publish-b2c-timeout-qos2.py	1970-01-01 01:00:00.000000000 +0100
@@ -1,81 +0,0 @@
-#!/usr/bin/env python3
-
-# Test whether a SUBSCRIBE to a topic with QoS 2 results in the correct SUBACK packet.
-
-from mosq_test_helper import *
-
-
-def helper(port):
-    connect_packet = mosq_test.gen_connect("test-helper", keepalive=60)
-    connack_packet = mosq_test.gen_connack(rc=0)
-
-    mid = 312
-    publish_packet = mosq_test.gen_publish("qos2/timeout/test", qos=2, mid=mid, payload="timeout-message")
-    pubrec_packet = mosq_test.gen_pubrec(mid)
-    pubrel_packet = mosq_test.gen_pubrel(mid)
-    pubcomp_packet = mosq_test.gen_pubcomp(mid)
-
-    sock = mosq_test.do_client_connect(connect_packet, connack_packet, connack_error="helper connack")
-    mosq_test.do_send_receive(sock, publish_packet, pubrec_packet, "helper pubrec")
-    mosq_test.do_send_receive(sock, pubrel_packet, pubcomp_packet, "helper pubcomp")
-    sock.close()
-
-
-def do_test(proto_ver):
-    rc = 1
-    mid = 3265
-    keepalive = 60
-    connect_packet = mosq_test.gen_connect("pub-qo2-timeout-test", keepalive=keepalive, proto_ver=proto_ver)
-    connack_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver)
-
-    subscribe_packet = mosq_test.gen_subscribe(mid, "qos2/timeout/test", 2, proto_ver=proto_ver)
-    suback_packet = mosq_test.gen_suback(mid, 2, proto_ver=proto_ver)
-
-    mid = 1
-    publish_packet = mosq_test.gen_publish("qos2/timeout/test", qos=2, mid=mid, payload="timeout-message", proto_ver=proto_ver)
-    publish_dup_packet = mosq_test.gen_publish("qos2/timeout/test", qos=2, mid=mid, payload="timeout-message", dup=True, proto_ver=proto_ver)
-    pubrec_packet = mosq_test.gen_pubrec(mid, proto_ver=proto_ver)
-    pubrel_packet = mosq_test.gen_pubrel(mid, proto_ver=proto_ver)
-    pubcomp_packet = mosq_test.gen_pubcomp(mid, proto_ver=proto_ver)
-
-    port = mosq_test.get_port()
-    broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
-
-    try:
-        sock = mosq_test.do_client_connect(connect_packet, connack_packet)
-        mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback")
-
-        helper(port)
-        # Should have now received a publish command
-
-        mosq_test.expect_packet(sock, "publish", publish_packet)
-        # Wait for longer than 5 seconds to get republish with dup set
-        # This is covered by the 8 second timeout
-
-        mosq_test.expect_packet(sock, "dup publish", publish_dup_packet)
-        mosq_test.do_send_receive(sock, pubrec_packet, pubrel_packet, "pubrel")
-
-        # Wait for longer than 5 seconds to get republish with dup set
-        # This is covered by the 8 second timeout
-
-        mosq_test.expect_packet(sock, "dup pubrel", pubrel_packet)
-        sock.send(pubcomp_packet)
-        rc = 0
-
-        sock.close()
-    except mosq_test.TestError:
-        pass
-    finally:
-        broker.terminate()
-        broker.wait()
-        (stdo, stde) = broker.communicate()
-        if rc:
-            print(stde.decode('utf-8'))
-            print("proto_ver=%d" % (proto_ver))
-            exit(rc)
-
-
-do_test(proto_ver=4)
-do_test(proto_ver=5)
-exit(0)
-
diff -Nru mosquitto-2.0.8/test/broker/03-publish-c2b-timeout-qos2.py mosquitto-2.0.9/test/broker/03-publish-c2b-timeout-qos2.py
--- mosquitto-2.0.8/test/broker/03-publish-c2b-timeout-qos2.py	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/test/broker/03-publish-c2b-timeout-qos2.py	1970-01-01 01:00:00.000000000 +0100
@@ -1,52 +0,0 @@
-#!/usr/bin/env python3
-
-# Test whether a PUBLISH to a topic with QoS 2 results in the correct packet
-# flow. This test introduces delays into the flow in order to force the broker
-# to send duplicate PUBREC and PUBCOMP messages.
-
-from mosq_test_helper import *
-
-
-def do_test(port):
-    rc = 1
-    keepalive = 600
-    connect_packet = mosq_test.gen_connect("pub-qos2-timeout-test", keepalive=keepalive, proto_ver=proto_ver)
-    connack_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver)
-
-    mid = 1926
-    publish_packet = mosq_test.gen_publish("pub/qos2/test", qos=2, mid=mid, payload="timeout-message", proto_ver=proto_ver)
-    pubrec_packet = mosq_test.gen_pubrec(mid, proto_ver=proto_ver)
-    pubrel_packet = mosq_test.gen_pubrel(mid, proto_ver=proto_ver)
-    pubcomp_packet = mosq_test.gen_pubcomp(mid, proto_ver=proto_ver)
-
-    port = mosq_test.get_port()
-    broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
-
-    try:
-        sock = mosq_test.do_client_connect(connect_packet, connack_packet)
-        mosq_test.do_send_receive(sock, publish_packet, pubrec_packet, "pubrec")
-
-        # Timeout is 8 seconds which means the broker should repeat the PUBREC.
-
-        mosq_test.expect_packet(sock, "pubrec", pubrec_packet)
-        mosq_test.do_send_receive(sock, pubrel_packet, pubcomp_packet, "pubcomp")
-
-        rc = 0
-
-        sock.close()
-    except mosq_test.TestError:
-        pass
-    finally:
-        broker.terminate()
-        broker.wait()
-        (stdo, stde) = broker.communicate()
-        if rc:
-            print(stde.decode('utf-8'))
-            print("proto_ver=%d" % (proto_ver))
-            exit(rc)
-
-
-do_test(proto_ver=4)
-do_test(proto_ver=5)
-exit(0)
-
diff -Nru mosquitto-2.0.8/test/broker/Makefile mosquitto-2.0.9/test/broker/Makefile
--- mosquitto-2.0.8/test/broker/Makefile	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/test/broker/Makefile	2021-03-11 22:37:20.000000000 +0000
@@ -45,6 +45,7 @@
 	./02-subhier-crash.py
 	./02-subpub-qos0-long-topic.py
 	./02-subpub-qos0-oversize-payload.py
+	./02-subpub-qos0-queued-bytes.py
 	./02-subpub-qos0-retain-as-publish.py
 	./02-subpub-qos0-send-retain.py
 	./02-subpub-qos0-subscription-id.py
diff -Nru mosquitto-2.0.8/test/broker/test.py mosquitto-2.0.9/test/broker/test.py
--- mosquitto-2.0.8/test/broker/test.py	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/test/broker/test.py	2021-03-11 22:37:20.000000000 +0000
@@ -28,6 +28,7 @@
     (1, './02-subhier-crash.py'),
     (1, './02-subpub-qos0-long-topic.py'),
     (1, './02-subpub-qos0-oversize-payload.py'),
+    (1, './02-subpub-qos0-queued-bytes.py'),
     (1, './02-subpub-qos0-retain-as-publish.py'),
     (1, './02-subpub-qos0-send-retain.py'),
     (1, './02-subpub-qos0-subscription-id.py'),
diff -Nru mosquitto-2.0.8/lib/loop.c mosquitto-2.0.9/lib/loop.c
--- mosquitto-2.0.8/lib/loop.c	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/lib/loop.c	2021-03-11 22:37:20.000000000 +0000
@@ -203,6 +203,13 @@
 	char pairbuf;
 	int maxfd = 0;
 
+#ifndef WIN32
+	if(read(mosq->sockpairR, &pairbuf, 1) == 0){
+	}
+#else
+	recv(mosq->sockpairR, &pairbuf, 1, 0);
+#endif
+
 	local_timeout.tv_sec = reconnect_delay;
 #ifdef HAVE_PSELECT
 	local_timeout.tv_nsec = 0;
diff -Nru mosquitto-2.0.8/lib/mosquitto.c mosquitto-2.0.9/lib/mosquitto.c
--- mosquitto-2.0.8/lib/mosquitto.c	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/lib/mosquitto.c	2021-03-11 22:37:20.000000000 +0000
@@ -196,6 +196,7 @@
 #ifdef WITH_TLS
 	mosq->ssl = NULL;
 	mosq->ssl_ctx = NULL;
+	mosq->ssl_ctx_defaults = true;
 	mosq->tls_cert_reqs = SSL_VERIFY_PEER;
 	mosq->tls_insecure = false;
 	mosq->want_write = false;
diff -Nru mosquitto-2.0.8/lib/mosquitto_internal.h mosquitto-2.0.9/lib/mosquitto_internal.h
--- mosquitto-2.0.8/lib/mosquitto_internal.h	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/lib/mosquitto_internal.h	2021-03-11 22:37:20.000000000 +0000
@@ -190,8 +190,8 @@
 #ifdef WITH_BROKER
 	struct mosquitto_client_msg *inflight;
 	struct mosquitto_client_msg *queued;
-	unsigned long msg_bytes;
-	unsigned long msg_bytes12;
+	long msg_bytes;
+	long msg_bytes12;
 	int msg_count;
 	int msg_count12;
 #else
diff -Nru mosquitto-2.0.8/src/bridge.c mosquitto-2.0.9/src/bridge.c
--- mosquitto-2.0.8/src/bridge.c	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/src/bridge.c	2021-03-11 22:37:20.000000000 +0000
@@ -112,6 +112,7 @@
 	new_context->tls_alpn = new_context->bridge->tls_alpn;
 	new_context->tls_engine = db.config->default_listener.tls_engine;
 	new_context->tls_keyform = db.config->default_listener.tls_keyform;
+	new_context->ssl_ctx_defaults = true;
 #ifdef FINAL_WITH_TLS_PSK
 	new_context->tls_psk_identity = new_context->bridge->tls_psk_identity;
 	new_context->tls_psk = new_context->bridge->tls_psk;
@@ -313,10 +314,8 @@
 
 	rc = send__connect(context, context->keepalive, context->clean_start, NULL);
 	if(rc == MOSQ_ERR_SUCCESS){
-		bridge__backoff_reset(context);
 		return MOSQ_ERR_SUCCESS;
 	}else if(rc == MOSQ_ERR_ERRNO && errno == ENOTCONN){
-		bridge__backoff_reset(context);
 		return MOSQ_ERR_SUCCESS;
 	}else{
 		if(rc == MOSQ_ERR_TLS){
@@ -454,10 +453,8 @@
 
 	rc2 = send__connect(context, context->keepalive, context->clean_start, NULL);
 	if(rc2 == MOSQ_ERR_SUCCESS){
-		bridge__backoff_reset(context);
 		return rc;
 	}else if(rc2 == MOSQ_ERR_ERRNO && errno == ENOTCONN){
-		bridge__backoff_reset(context);
 		return MOSQ_ERR_SUCCESS;
 	}else{
 		if(rc2 == MOSQ_ERR_TLS){
@@ -562,6 +559,8 @@
 		}
 	}
 
+	bridge__backoff_reset(context);
+
 	return MOSQ_ERR_SUCCESS;
 }
 
@@ -646,11 +645,11 @@
 	packet__cleanup(&(context->in_packet));
 }
 
-static int rand_between(int base, int cap)
+static int rand_between(int low, int high)
 {
 	int r;
 	util__random_bytes(&r, sizeof(int));
-	return (r % (cap - base)) + base;
+	return (abs(r) % (high - low)) + low;
 }
 
 static void bridge__backoff_step(struct mosquitto *context)
@@ -685,6 +684,33 @@
 	}
 }
 
+
+static void bridge_check_pending(struct mosquitto *context)
+{
+	int err;
+	socklen_t len;
+
+	if(context->state == mosq_cs_connect_pending){
+		len = sizeof(int);
+		if(!getsockopt(context->sock, SOL_SOCKET, SO_ERROR, (char *)&err, &len)){
+			if(err == 0){
+				mosquitto__set_state(context, mosq_cs_new);
+#if defined(WITH_ADNS) && defined(WITH_BRIDGE)
+				if(context->bridge){
+					bridge__connect_step3(context);
+				}
+#endif
+			}else if(err == ECONNREFUSED){
+				do_disconnect(context, MOSQ_ERR_CONN_LOST);
+				return;
+			}
+		}else{
+			do_disconnect(context, MOSQ_ERR_CONN_LOST);
+			return;
+		}
+	}
+}
+
 void bridge_check(void)
 {
 	static time_t last_check = 0;
@@ -703,6 +729,7 @@
 
 		if(context->sock != INVALID_SOCKET){
 			mosquitto__check_keepalive(context);
+			bridge_check_pending(context);
 
 			/* Check for bridges that are not round robin and not currently
 			 * connected to their primary broker. */
diff -Nru mosquitto-2.0.8/src/CMakeLists.txt mosquitto-2.0.9/src/CMakeLists.txt
--- mosquitto-2.0.8/src/CMakeLists.txt	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/src/CMakeLists.txt	2021-03-11 22:37:20.000000000 +0000
@@ -77,6 +77,11 @@
 	include_directories(${mosquitto_SOURCE_DIR} ${mosquitto_SOURCE_DIR}/deps)
 endif (WITH_BUNDLED_DEPS)
 
+find_path(HAVE_SYS_EPOLL_H sys/epoll.h)
+if (HAVE_SYS_EPOLL_H)
+	add_definitions("-DWITH_EPOLL")
+endif()
+
 option(INC_BRIDGE_SUPPORT
 	"Include bridge support for connecting to other brokers?" ON)
 if (INC_BRIDGE_SUPPORT)
diff -Nru mosquitto-2.0.8/src/database.c mosquitto-2.0.9/src/database.c
--- mosquitto-2.0.8/src/database.c	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/src/database.c	2021-03-11 22:37:20.000000000 +0000
@@ -53,7 +53,7 @@
 		if(db.config->max_queued_messages == 0 && db.config->max_inflight_bytes == 0){
 			return true;
 		}
-		valid_bytes = msgs->msg_bytes - db.config->max_inflight_bytes < db.config->max_queued_bytes;
+		valid_bytes = ((msgs->msg_bytes - (ssize_t)db.config->max_inflight_bytes) < (ssize_t)db.config->max_queued_bytes);
 		valid_count = msgs->msg_count - msgs->inflight_maximum < db.config->max_queued_messages;
 
 		if(db.config->max_queued_messages == 0){
@@ -90,8 +90,8 @@
 {
 	int source_count;
 	int adjust_count;
-	size_t source_bytes;
-	size_t adjust_bytes = db.config->max_inflight_bytes;
+	long source_bytes;
+	ssize_t adjust_bytes = (ssize_t)db.config->max_inflight_bytes;
 	bool valid_bytes;
 	bool valid_count;
 
@@ -893,6 +893,26 @@
 }
 
 
+int db__message_remove_incoming(struct mosquitto* context, uint16_t mid)
+{
+	struct mosquitto_client_msg *tail, *tmp;
+
+	if(!context) return MOSQ_ERR_INVAL;
+
+	DL_FOREACH_SAFE(context->msgs_in.inflight, tail, tmp){
+		if(tail->mid == mid) {
+			if(tail->store->qos != 2){
+				return MOSQ_ERR_PROTOCOL;
+			}
+			db__message_remove(&context->msgs_in, tail);
+			return MOSQ_ERR_SUCCESS;
+		}
+	}
+
+	return MOSQ_ERR_NOT_FOUND;
+}
+
+
 int db__message_release_incoming(struct mosquitto *context, uint16_t mid)
 {
 	struct mosquitto_client_msg *tail, *tmp;
diff -Nru mosquitto-2.0.8/src/handle_connect.c mosquitto-2.0.9/src/handle_connect.c
--- mosquitto-2.0.8/src/handle_connect.c	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/src/handle_connect.c	2021-03-11 22:37:20.000000000 +0000
@@ -244,7 +244,9 @@
 				goto error;
 			}
 		}
-		if(context->keepalive > db.config->max_keepalive){
+		if(db.config->max_keepalive &&
+				(context->keepalive > db.config->max_keepalive || context->keepalive == 0)){
+
 			context->keepalive = db.config->max_keepalive;
 			if(mosquitto_property_add_int16(&connack_props, MQTT_PROP_SERVER_KEEP_ALIVE, context->keepalive)){
 				rc = MOSQ_ERR_NOMEM;
diff -Nru mosquitto-2.0.8/src/handle_publish.c mosquitto-2.0.9/src/handle_publish.c
--- mosquitto-2.0.8/src/handle_publish.c	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/src/handle_publish.c	2021-03-11 22:37:20.000000000 +0000
@@ -285,6 +285,18 @@
 	if(msg->qos > 0){
 		db__message_store_find(context, msg->source_mid, &stored);
 	}
+
+	if(stored && msg->source_mid != 0 &&
+			(stored->qos != msg->qos
+			 || stored->payloadlen != msg->payloadlen
+			 || strcmp(stored->topic, msg->topic)
+			 || memcmp(stored->payload, msg->payload, msg->payloadlen) )){
+
+		log__printf(NULL, MOSQ_LOG_WARNING, "Reused message ID %u from %s detected. Clearing from storage.", msg->source_mid, context->id);
+		db__message_remove_incoming(context, msg->source_mid);
+		stored = NULL;
+	}
+
 	if(!stored){
 		if(msg->qos == 0
 				|| db__ready_for_flight(&context->msgs_in, msg->qos)
diff -Nru mosquitto-2.0.8/src/mosquitto_broker_internal.h mosquitto-2.0.9/src/mosquitto_broker_internal.h
--- mosquitto-2.0.8/src/mosquitto_broker_internal.h	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/src/mosquitto_broker_internal.h	2021-03-11 22:37:20.000000000 +0000
@@ -642,6 +642,7 @@
 int db__message_count(int *count);
 int db__message_delete_outgoing(struct mosquitto *context, uint16_t mid, enum mosquitto_msg_state expect_state, int qos);
 int db__message_insert(struct mosquitto *context, uint16_t mid, enum mosquitto_msg_direction dir, uint8_t qos, bool retain, struct mosquitto_msg_store *stored, mosquitto_property *properties, bool update);
+int db__message_remove_incoming(struct mosquitto* context, uint16_t mid);
 int db__message_release_incoming(struct mosquitto *context, uint16_t mid);
 int db__message_update_outgoing(struct mosquitto *context, uint16_t mid, enum mosquitto_msg_state state, int qos);
 void db__message_dequeue_first(struct mosquitto *context, struct mosquitto_msg_data *msg_data);
diff -Nru mosquitto-2.0.8/src/net.c mosquitto-2.0.9/src/net.c
--- mosquitto-2.0.8/src/net.c	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/src/net.c	2021-03-11 22:37:20.000000000 +0000
@@ -335,14 +335,14 @@
 	}else if(!strcmp(listener->tls_version, "tlsv1.3")){
 		SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2);
 	}else if(!strcmp(listener->tls_version, "tlsv1.2")){
-		SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_3);
+		SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
 	}else if(!strcmp(listener->tls_version, "tlsv1.1")){
-		SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_3);
+		SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
 #else
 	}else if(!strcmp(listener->tls_version, "tlsv1.2")){
 		SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
 	}else if(!strcmp(listener->tls_version, "tlsv1.1")){
-		SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2);
+		SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
 #endif
 	}else{
 		log__printf(NULL, MOSQ_LOG_ERR, "Error: Unsupported tls_version \"%s\".", listener->tls_version);
@@ -624,23 +624,44 @@
 				&& ifa->ifa_addr->sa_family == rp->ai_addr->sa_family){
 
 			if(rp->ai_addr->sa_family == AF_INET){
-				memcpy(&((struct sockaddr_in *)rp->ai_addr)->sin_addr,
-						&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
-						sizeof(struct in_addr));
-
-				freeifaddrs(ifaddr);
-				return MOSQ_ERR_SUCCESS;
+				if(listener->host &&
+						memcmp(&((struct sockaddr_in *)rp->ai_addr)->sin_addr,
+							&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
+							sizeof(struct in_addr))){
+
+					log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface address for %s does not match specified listener address (%s).",
+							listener->bind_interface, listener->host);
+					return MOSQ_ERR_INVAL;
+				}else{
+					memcpy(&((struct sockaddr_in *)rp->ai_addr)->sin_addr,
+							&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
+							sizeof(struct in_addr));
+
+					freeifaddrs(ifaddr);
+					return MOSQ_ERR_SUCCESS;
+				}
 			}else if(rp->ai_addr->sa_family == AF_INET6){
-				memcpy(&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr,
-						&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
-						 sizeof(struct in6_addr));
-				freeifaddrs(ifaddr);
-				return MOSQ_ERR_SUCCESS;
+				if(listener->host &&
+						memcmp(&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr,
+							&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
+							sizeof(struct in6_addr))){
+
+					log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface address for %s does not match specified listener address (%s).",
+							listener->bind_interface, listener->host);
+					return MOSQ_ERR_INVAL;
+				}else{
+					memcpy(&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr,
+							&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
+							sizeof(struct in6_addr));
+					freeifaddrs(ifaddr);
+					return MOSQ_ERR_SUCCESS;
+				}
 			}
 		}
 	}
 	freeifaddrs(ifaddr);
-	log__printf(NULL, MOSQ_LOG_ERR, "Error: Interface %s not found.", listener->bind_interface);
+	log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface %s does not support %s configuration.",
+	            listener->bind_interface, rp->ai_addr->sa_family == AF_INET ? "IPv4" : "IPv6");
 	return MOSQ_ERR_NOT_FOUND;
 }
 #endif
@@ -654,6 +675,9 @@
 	char service[10];
 	int rc;
 	int ss_opt = 1;
+#ifndef WIN32
+	bool interface_bound = false;
+#endif
 
 	if(!listener) return MOSQ_ERR_INVAL;
 
@@ -718,12 +742,14 @@
 
 #ifndef WIN32
 		if(listener->bind_interface){
+			/* It might be possible that an interface does not support all relevant sa_families.
+			 * We should successfully find at least one. */
 			if(net__bind_interface(listener, rp)){
 				COMPAT_CLOSE(sock);
-				freeaddrinfo(ainfo);
-				mosquitto__free(listener->socks);
-				return 1;
+				listener->sock_count--;
+				continue;
 			}
+			interface_bound = true;
 		}
 #endif
 
@@ -745,6 +771,13 @@
 	}
 	freeaddrinfo(ainfo);
 
+#ifndef WIN32
+	if(listener->bind_interface && !interface_bound){
+		mosquitto__free(listener->socks);
+		return 1;
+	}
+#endif
+
 	return 0;
 }
 
diff -Nru mosquitto-2.0.8/src/retain.c mosquitto-2.0.9/src/retain.c
--- mosquitto-2.0.8/src/retain.c	2021-02-25 17:28:19.000000000 +0000
+++ mosquitto-2.0.9/src/retain.c	2021-03-11 22:37:20.000000000 +0000
@@ -83,7 +83,10 @@
 	assert(split_topics);
 
 	HASH_FIND(hh, db.retains, split_topics[0], strlen(split_topics[0]), retainhier);
-	if(retainhier == NULL) return MOSQ_ERR_NOT_FOUND;
+	if(retainhier == NULL){
+		retainhier = retain__add_hier_entry(NULL, &db.retains, split_topics[0], (uint16_t)strlen(split_topics[0]));
+		if(!retainhier) return MOSQ_ERR_NOMEM;
+	}
 
 	for(i=0; split_topics[i] != NULL; i++){
 		slen = strlen(split_topics[i]);

--- End Message ---
--- Begin Message ---
Unblocked.

--- End Message ---

Reply to: