Package: release.debian.org
Severity: normal
User: release.debian....@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 <ro...@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]);

Reply via email to