Merge branch 'fixes'

This commit is contained in:
Roger A. Light
2025-07-11 22:06:10 +01:00
38 changed files with 248 additions and 106 deletions
+1 -1
View File
@@ -7,7 +7,7 @@
cmake_minimum_required(VERSION 3.18)
project(mosquitto)
set (VERSION 2.0.21)
set (VERSION 2.0.22)
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/")
+43
View File
@@ -1,3 +1,46 @@
2.0.22 - 2025-07-11
===================
Broker:
- Windows: Fix broker crash on startup if using `log_dest stdout`
- Bridge: Fix idle_timeout never occurring for lazy bridges.
- Fix case where max_queued_messages = 0 was not treated as unlimited.
Closes #3244.
- Fix `--version` exit code and output. Closes #3267.
- Fix crash on receiving a $CONTROL message over a bridge, if
per_listener_settings is set true and the bridge is carrying out topic
remapping. Closes #3261.
- Fix incorrect reference clock being selected on startup on Linux.
Closes #3238.
- Fix reporting of client disconnections being incorrectly attributed to "out
of memory". Closes #3253.
- Fix compilation when using `WITH_OLD_KEEPALIVE`. Closes #3250.
- Add Windows linker file for the broker to the installer. Closes #3269.
- Fix Websockets PING not being sent on Windows. Closes #3272.
- Fix problems with secure websockets. Closes #1211.
- Fix crash on exit when using WITH_EPOLL=no. Closes #3302.
- Fix clients being incorrectly expired when they have keepalive ==
max_keepalive. Closes #3226, #3286.
Dynamic security plugin:
- Fix mismatch memory free when saving config which caused memory tracking to
be incorrect.
Client library:
- Fix C++ symbols being removed when compiled with link time optimisation.
Closes #3259.
- TLS error handling was incorrectly setting a protocol error for non-TLS
errors. This would cause the mosquitto_loop_start() thread to exit if no
broker was available on the first connection attempt. This has been fixed.
Closes #3258.
- Fix linker errors on some architectures using cmake. Closes #3167.
Tests:
- Fix 08-ssl-connect-cert-auth-expired and 08-ssl-connect-cert-auth-revoked
tests when running on a single CPU system. Closes #3230.
2.0.21 - 2025-03-06
===================
+1 -1
View File
@@ -43,7 +43,7 @@ if (WITH_TLS AND CJSON_FOUND)
endif (APPLE)
endif (UNIX)
target_link_libraries(mosquitto_ctrl ${OPENSSL_LIBRARIES} ${CJSON_LIBRARIES})
target_link_libraries(mosquitto_ctrl OpenSSL::SSL ${CJSON_LIBRARIES})
install(TARGETS mosquitto_ctrl RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
endif (WITH_TLS AND CJSON_FOUND)
+1 -1
View File
@@ -13,6 +13,6 @@ if (WITH_TLS)
)
target_link_libraries(mosquitto_passwd ${OPENSSL_LIBRARIES})
target_link_libraries(mosquitto_passwd OpenSSL::SSL)
install(TARGETS mosquitto_passwd RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
endif (WITH_TLS)
+1 -1
View File
@@ -134,7 +134,7 @@ WITH_ASAN=no
# Also bump lib/mosquitto.h, CMakeLists.txt,
# installer/mosquitto.nsi, installer/mosquitto64.nsi
VERSION=2.0.21
VERSION=2.0.22
# Client library SO version. Bump if incompatible API/ABI changes are made.
SOVERSION=1
+7 -1
View File
@@ -61,12 +61,18 @@ extern "C" {
# endif
#endif
#ifndef _MSC_VER
# define MOSQ_USED __attribute__((used))
#else
# define MOSQ_USED
#endif
#include <stddef.h>
#include <stdint.h>
#define LIBMOSQUITTO_MAJOR 2
#define LIBMOSQUITTO_MINOR 0
#define LIBMOSQUITTO_REVISION 21
#define LIBMOSQUITTO_REVISION 22
/* 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)
+3 -1
View File
@@ -9,7 +9,7 @@
!define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
Name "Eclipse Mosquitto"
!define VERSION 2.0.21
!define VERSION 2.0.22
OutFile "mosquitto-${VERSION}-install-windows-x86.exe"
InstallDir "$PROGRAMFILES\mosquitto"
@@ -73,8 +73,10 @@ Section "Files" SecInstall
File "..\build\vcpkg_installed\x86-windows\bin\pthreadVC3.dll"
File "..\build\vcpkg_installed\x86-windows\bin\uv.dll"
File "..\build\vcpkg_installed\x86-windows\bin\websockets.dll"
File "..\build\vcpkg_installed\x86-windows\bin\zlib1.dll"
SetOutPath "$INSTDIR\devel"
File /oname=mosquitto_broker.lib "..\build\src\Release\mosquitto.lib"
File "..\build\lib\Release\mosquitto.lib"
File "..\build\lib\cpp\Release\mosquittopp.lib"
File "..\include\mosquitto.h"
+3 -1
View File
@@ -9,7 +9,7 @@
!define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
Name "Eclipse Mosquitto"
!define VERSION 2.0.21
!define VERSION 2.0.22
OutFile "mosquitto-${VERSION}-install-windows-x64.exe"
!include "x64.nsh"
@@ -74,8 +74,10 @@ Section "Files" SecInstall
File "..\build64\vcpkg_installed\x64-windows-release\bin\pthreadVC3.dll"
File "..\build64\vcpkg_installed\x64-windows-release\bin\uv.dll"
File "..\build64\vcpkg_installed\x64-windows-release\bin\websockets.dll"
File "..\build64\vcpkg_installed\x64-windows-release\bin\zlib1.dll"
SetOutPath "$INSTDIR\devel"
File /oname=mosquitto_broker.lib "..\build64\src\Release\mosquitto.lib"
File "..\build64\lib\Release\mosquitto.lib"
File "..\build64\lib\cpp\Release\mosquittopp.lib"
File "..\include\mosquitto.h"
+2 -2
View File
@@ -60,7 +60,7 @@ set(C_SRC
util_mosq.c util_topic.c util_mosq.h
will_mosq.c will_mosq.h)
set (LIBRARIES ${OPENSSL_LIBRARIES})
set (LIBRARIES OpenSSL::SSL)
if (UNIX AND NOT APPLE AND NOT ANDROID)
find_library(LIBRT rt)
@@ -100,7 +100,7 @@ if (WITH_THREADING)
endif()
endif()
target_link_libraries(libmosquitto PRIVATE ${LIBRARIES})
target_link_libraries(libmosquitto ${LIBRARIES})
set_target_properties(libmosquitto PROPERTIES
OUTPUT_NAME mosquitto
+9 -9
View File
@@ -124,15 +124,15 @@ class mosqpp_EXPORT mosquittopp {
int socks5_set(const char *host, int port=1080, const char *username=NULL, const char *password=NULL);
// names in the functions commented to prevent unused parameter warning
virtual void on_connect(int /*rc*/) {return;}
virtual void on_connect_with_flags(int /*rc*/, int /*flags*/) {return;}
virtual void on_disconnect(int /*rc*/) {return;}
virtual void on_publish(int /*mid*/) {return;}
virtual void on_message(const struct mosquitto_message * /*message*/) {return;}
virtual void on_subscribe(int /*mid*/, int /*qos_count*/, const int * /*granted_qos*/) {return;}
virtual void on_unsubscribe(int /*mid*/) {return;}
virtual void on_log(int /*level*/, const char * /*str*/) {return;}
virtual void on_error() {return;}
virtual void MOSQ_USED on_connect(int /*rc*/) {return;}
virtual void MOSQ_USED on_connect_with_flags(int /*rc*/, int /*flags*/) {return;}
virtual void MOSQ_USED on_disconnect(int /*rc*/) {return;}
virtual void MOSQ_USED on_publish(int /*mid*/) {return;}
virtual void MOSQ_USED on_message(const struct mosquitto_message * /*message*/) {return;}
virtual void MOSQ_USED on_subscribe(int /*mid*/, int /*qos_count*/, const int * /*granted_qos*/) {return;}
virtual void MOSQ_USED on_unsubscribe(int /*mid*/) {return;}
virtual void MOSQ_USED on_log(int /*level*/, const char * /*str*/) {return;}
virtual void MOSQ_USED on_error() {return;}
};
}
+1 -1
View File
@@ -114,7 +114,7 @@ libmosq_EXPORT int mosquitto_subscribe_simple(
*messages = NULL;
userdata.messages = calloc(sizeof(struct mosquitto_message), (size_t)msg_count);
userdata.messages = calloc((size_t)msg_count, sizeof(struct mosquitto_message));
if(!userdata.messages){
return MOSQ_ERR_NOMEM;
}
+2 -6
View File
@@ -135,9 +135,7 @@ int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets)
fdcount = select(maxfd+1, &readfds, &writefds, NULL, &local_timeout);
#endif
if(fdcount == -1){
#ifdef WIN32
errno = WSAGetLastError();
#endif
WINDOWS_SET_ERRNO();
if(errno == EINTR){
return MOSQ_ERR_SUCCESS;
}else{
@@ -219,9 +217,7 @@ static int interruptible_sleep(struct mosquitto *mosq, time_t reconnect_delay)
fdcount = select(maxfd+1, &readfds, NULL, NULL, &local_timeout);
#endif
if(fdcount == -1){
#ifdef WIN32
errno = WSAGetLastError();
#endif
WINDOWS_SET_ERRNO();
if(errno == EINTR){
return MOSQ_ERR_SUCCESS;
}else{
+10
View File
@@ -68,6 +68,15 @@ typedef SOCKET mosq_sock_t;
typedef int mosq_sock_t;
#endif
#ifdef WIN32
# define WINDOWS_SET_ERRNO() \
if(errno != EAGAIN){ \
errno = WSAGetLastError(); \
}
#else
# define WINDOWS_SET_ERRNO()
#endif
#define SAFE_PRINT(A) (A)?(A):"null"
enum mosquitto_msg_direction {
@@ -356,6 +365,7 @@ struct mosquitto {
# ifndef WITH_OLD_KEEPALIVE
struct mosquitto *keepalive_next;
struct mosquitto *keepalive_prev;
time_t keepalive_add_time;
# endif
#endif
uint32_t events;
+9 -21
View File
@@ -361,9 +361,7 @@ int net__try_connect_step2(struct mosquitto *mosq, uint16_t port, mosq_sock_t *s
}
rc = connect(*sock, rp->ai_addr, rp->ai_addrlen);
#ifdef WIN32
errno = WSAGetLastError();
#endif
WINDOWS_SET_ERRNO();
if(rc == 0 || errno == EINPROGRESS || errno == COMPAT_EWOULDBLOCK){
if(rc < 0 && (errno == EINPROGRESS || errno == COMPAT_EWOULDBLOCK)){
rc = MOSQ_ERR_CONN_PENDING;
@@ -461,9 +459,7 @@ static int net__try_connect_tcp(const char *host, uint16_t port, mosq_sock_t *so
}
rc = connect(*sock, rp->ai_addr, rp->ai_addrlen);
#ifdef WIN32
errno = WSAGetLastError();
#endif
WINDOWS_SET_ERRNO();
if(rc == 0 || errno == EINPROGRESS || errno == COMPAT_EWOULDBLOCK){
if(rc < 0 && (errno == EINPROGRESS || errno == COMPAT_EWOULDBLOCK)){
rc = MOSQ_ERR_CONN_PENDING;
@@ -944,34 +940,30 @@ int net__socket_connect(struct mosquitto *mosq, const char *host, uint16_t port,
#ifdef WITH_TLS
static int net__handle_ssl(struct mosquitto* mosq, int ret)
static void net__handle_ssl(struct mosquitto* mosq, int ret)
{
int err;
err = SSL_get_error(mosq->ssl, ret);
if (err == SSL_ERROR_WANT_READ) {
ret = -1;
errno = EAGAIN;
}
else if (err == SSL_ERROR_WANT_WRITE) {
ret = -1;
#ifdef WITH_BROKER
mux__add_out(mosq);
#else
mosq->want_write = true;
#endif
errno = EAGAIN;
}
else {
}else if(err == SSL_ERROR_SSL){
net__print_ssl_error(mosq);
errno = EPROTO;
/* else if SSL_ERROR_SYSCALL leave errno alone */
}
ERR_clear_error();
#ifdef WIN32
WSASetLastError(errno);
#endif
return ret;
}
#endif
@@ -987,7 +979,7 @@ ssize_t net__read(struct mosquitto *mosq, void *buf, size_t count)
ERR_clear_error();
ret = SSL_read(mosq->ssl, buf, (int)count);
if(ret <= 0){
ret = net__handle_ssl(mosq, ret);
net__handle_ssl(mosq, ret);
}
return (ssize_t )ret;
}else{
@@ -1020,7 +1012,7 @@ ssize_t net__write(struct mosquitto *mosq, const void *buf, size_t count)
mosq->want_write = false;
ret = SSL_write(mosq->ssl, buf, (int)count);
if(ret < 0){
ret = net__handle_ssl(mosq, ret);
net__handle_ssl(mosq, ret);
}
return (ssize_t )ret;
}else{
@@ -1138,9 +1130,7 @@ int net__socketpair(mosq_sock_t *pairR, mosq_sock_t *pairW)
continue;
}
if(connect(spR, (struct sockaddr *)&ss, ss_len) < 0){
#ifdef WIN32
errno = WSAGetLastError();
#endif
WINDOWS_SET_ERRNO();
if(errno != EINPROGRESS && errno != COMPAT_EWOULDBLOCK){
COMPAT_CLOSE(spR);
COMPAT_CLOSE(listensock);
@@ -1149,9 +1139,7 @@ int net__socketpair(mosq_sock_t *pairR, mosq_sock_t *pairW)
}
spW = accept(listensock, NULL, 0);
if(spW == -1){
#ifdef WIN32
errno = WSAGetLastError();
#endif
WINDOWS_SET_ERRNO();
if(errno != EINPROGRESS && errno != COMPAT_EWOULDBLOCK){
COMPAT_CLOSE(spR);
COMPAT_CLOSE(listensock);
+5 -12
View File
@@ -267,9 +267,8 @@ int packet__write(struct mosquitto *mosq)
packet->to_process -= (uint32_t)write_length;
packet->pos += (uint32_t)write_length;
}else{
#ifdef WIN32
errno = WSAGetLastError();
#endif
WINDOWS_SET_ERRNO();
if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK
#ifdef WIN32
|| errno == WSAENOTCONN
@@ -411,9 +410,7 @@ int packet__read(struct mosquitto *mosq)
if(read_length == 0){
return MOSQ_ERR_CONN_LOST; /* EOF */
}
#ifdef WIN32
errno = WSAGetLastError();
#endif
WINDOWS_SET_ERRNO();
if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
return MOSQ_ERR_SUCCESS;
}else{
@@ -456,9 +453,7 @@ int packet__read(struct mosquitto *mosq)
if(read_length == 0){
return MOSQ_ERR_CONN_LOST; /* EOF */
}
#ifdef WIN32
errno = WSAGetLastError();
#endif
WINDOWS_SET_ERRNO();
if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
return MOSQ_ERR_SUCCESS;
}else{
@@ -533,9 +528,7 @@ int packet__read(struct mosquitto *mosq)
mosq->in_packet.to_process -= (uint32_t)read_length;
mosq->in_packet.pos += (uint32_t)read_length;
}else{
#ifdef WIN32
errno = WSAGetLastError();
#endif
WINDOWS_SET_ERRNO();
if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
if(mosq->in_packet.to_process > 1000){
/* Update last_msg_in time if more than 1000 bytes left to
+3 -9
View File
@@ -281,9 +281,7 @@ int socks5__read(struct mosquitto *mosq)
mosq->in_packet.pos += (uint32_t)len;
mosq->in_packet.to_process -= (uint32_t)len;
}else{
#ifdef WIN32
errno = WSAGetLastError();
#endif
WINDOWS_SET_ERRNO();
if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
return MOSQ_ERR_SUCCESS;
}else{
@@ -323,9 +321,7 @@ int socks5__read(struct mosquitto *mosq)
mosq->in_packet.pos += (uint32_t)len;
mosq->in_packet.to_process -= (uint32_t)len;
}else{
#ifdef WIN32
errno = WSAGetLastError();
#endif
WINDOWS_SET_ERRNO();
if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
return MOSQ_ERR_SUCCESS;
}else{
@@ -379,9 +375,7 @@ int socks5__read(struct mosquitto *mosq)
mosq->in_packet.pos += (uint32_t)len;
mosq->in_packet.to_process -= (uint32_t)len;
}else{
#ifdef WIN32
errno = WSAGetLastError();
#endif
WINDOWS_SET_ERRNO();
if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){
return MOSQ_ERR_SUCCESS;
}else{
+1 -1
View File
@@ -80,7 +80,7 @@ int mosquitto__check_keepalive(struct mosquitto *mosq)
/* Check if a lazy bridge should be timed out due to idle. */
if(mosq->bridge && mosq->bridge->start_type == bst_lazy
&& mosq->sock != INVALID_SOCKET
&& now - mosq->next_msg_out - mosq->keepalive >= mosq->bridge->idle_timeout){
&& now - mosq->last_msg_in >= mosq->bridge->idle_timeout){
log__printf(NULL, MOSQ_LOG_NOTICE, "Bridge connection %s has exceeded idle timeout, disconnecting.", mosq->id);
net__socket_close(mosq);
+1 -1
View File
@@ -32,7 +32,7 @@ if (CJSON_FOUND AND WITH_TLS)
)
set_target_properties(mosquitto_dynamic_security PROPERTIES PREFIX "")
target_link_libraries(mosquitto_dynamic_security ${CJSON_LIBRARIES} ${OPENSSL_LIBRARIES})
target_link_libraries(mosquitto_dynamic_security ${CJSON_LIBRARIES} OpenSSL::SSL)
if(WIN32)
target_link_libraries(mosquitto_dynamic_security mosquitto)
install(TARGETS mosquitto_dynamic_security
+1 -1
View File
@@ -629,7 +629,7 @@ void dynsec__config_save(void)
return;
}
fwrite(json_str, 1, json_str_len, fptr);
mosquitto_free(json_str);
cJSON_free(json_str);
fclose(fptr);
/* Everything is ok, so move new file over proper file */
+1 -1
View File
@@ -2,7 +2,7 @@
MAJOR=2
MINOR=0
REVISION=21
REVISION=22
sed -i "s/^VERSION=.*/VERSION=${MAJOR}.${MINOR}.${REVISION}/" config.mk
+1 -1
View File
@@ -1,5 +1,5 @@
name: mosquitto
version: 2.0.21
version: 2.0.22
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.
MQTT provides a method of carrying out messaging using a publish/subscribe
+7 -1
View File
@@ -113,6 +113,12 @@ if (WITH_PERSISTENCE)
add_definitions("-DWITH_PERSISTENCE")
endif (WITH_PERSISTENCE)
option(WITH_OLD_KEEPALIVE
"Use legacy keepalive check mechanism?" OFF)
if (WITH_OLD_KEEPALIVE)
add_definitions("-DWITH_OLD_KEEPALIVE")
endif (WITH_OLD_KEEPALIVE)
option(WITH_SYS_TREE
"Include $SYS tree support?" ON)
if (WITH_SYS_TREE)
@@ -157,7 +163,7 @@ if (WITH_DLT)
set (MOSQ_LIBS ${MOSQ_LIBS} ${DLT_LIBRARIES})
endif (WITH_DLT)
set (MOSQ_LIBS ${MOSQ_LIBS} ${OPENSSL_LIBRARIES})
set (MOSQ_LIBS ${MOSQ_LIBS} OpenSSL::SSL)
# Check for getaddrinfo_a
include(CheckLibraryExists)
check_library_exists(anl getaddrinfo_a "" HAVE_GETADDRINFO_A)
+13 -1
View File
@@ -356,6 +356,13 @@ void config__cleanup(struct mosquitto__config *config)
}
}
static void print_version(void)
{
printf("mosquitto %s\n", VERSION);
printf("Copyright © 2025 Roger Light.\n");
printf("License EPL-2.0 OR BSD-3-Clause.\n");
}
static void print_usage(void)
{
printf("mosquitto version %s\n\n", VERSION);
@@ -393,7 +400,10 @@ int config__parse_args(struct mosquitto__config *config, int argc, char *argv[])
config->daemon = true;
}else if(!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")){
print_usage();
return MOSQ_ERR_INVAL;
return MOSQ_ERR_UNKNOWN;
}else if(!strcmp(argv[i], "--version")){
print_version();
return MOSQ_ERR_UNKNOWN;
}else if(!strcmp(argv[i], "-p") || !strcmp(argv[i], "--port")){
if(i<argc-1){
port_tmp = atoi(argv[i+1]);
@@ -2313,6 +2323,7 @@ static int config__check(struct mosquitto__config *config)
}
}
#ifdef WITH_TLS
/* Check for missing TLS cafile/capath/certfile/keyfile */
for(int i=0; i<config->listener_count; i++){
bool cafile = !!config->listeners[i].cafile;
@@ -2333,6 +2344,7 @@ static int config__check(struct mosquitto__config *config)
return MOSQ_ERR_INVAL;
}
}
#endif
return MOSQ_ERR_SUCCESS;
}
+6
View File
@@ -37,10 +37,16 @@ int control__process(struct mosquitto *context, struct mosquitto_msg_store *stor
int rc = MOSQ_ERR_SUCCESS;
if(db.config->per_listener_settings){
if(!context->listener){
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: $CONTROL command received from client with no listener, when per_listener_settings is true.");
log__printf(NULL, MOSQ_LOG_WARNING, " If this is a bridge, please be aware this does not work.");
return MOSQ_ERR_SUCCESS;
}
opts = &context->listener->security_options;
}else{
opts = &db.config->security_options;
}
HASH_FIND(hh, opts->plugin_callbacks.control, stored->topic, strlen(stored->topic), cb_found);
if(cb_found){
memset(&event_data, 0, sizeof(event_data));
+9 -7
View File
@@ -328,16 +328,18 @@ int handle__publish(struct mosquitto *context)
switch(stored->qos){
case 0:
rc2 = sub__messages_queue(context->id, stored->topic, stored->qos, stored->retain, &stored);
if(rc2 > 0) rc = 1;
if(rc2 > 0) rc = rc2;
break;
case 1:
util__decrement_receive_quota(context);
rc2 = sub__messages_queue(context->id, stored->topic, stored->qos, stored->retain, &stored);
/* stored may now be free, so don't refer to it */
if(rc2 == MOSQ_ERR_SUCCESS || context->protocol != mosq_p_mqtt5){
if(send__puback(context, mid, 0, NULL)) rc = 1;
rc2 = send__puback(context, mid, 0, NULL);
if(rc2) rc = rc2;
}else if(rc2 == MOSQ_ERR_NO_SUBSCRIBERS){
if(send__puback(context, mid, MQTT_RC_NO_MATCHING_SUBSCRIBERS, NULL)) rc = 1;
rc2 = send__puback(context, mid, MQTT_RC_NO_MATCHING_SUBSCRIBERS, NULL);
if(rc2) rc = rc2;
}else{
rc = rc2;
}
@@ -359,8 +361,8 @@ int handle__publish(struct mosquitto *context)
}else{
return MOSQ_ERR_PROTOCOL;
}
}else if(res == 1){
rc = 1;
}else{
rc = res;
}
break;
}
@@ -368,7 +370,7 @@ int handle__publish(struct mosquitto *context)
db__message_write_queued_in(context);
return rc;
process_bad_message:
rc = 1;
rc = MOSQ_ERR_UNKNOWN;
if(msg){
switch(msg->qos){
case 0:
@@ -383,7 +385,7 @@ process_bad_message:
}
db__msg_store_free(msg);
}
if(context->out_packet_count >= db.config->max_queued_messages){
if(db.config->max_queued_messages > 0 && context->out_packet_count >= db.config->max_queued_messages){
rc = MQTT_RC_QUOTA_EXCEEDED;
}
return rc;
+13 -10
View File
@@ -75,7 +75,6 @@ int keepalive__init(void)
#ifndef WITH_OLD_KEEPALIVE
struct mosquitto *context, *ctxt_tmp;
last_keepalive_check = db.now_s;
if(db.config->max_keepalive <= 0){
keepalive_list_max = (UINT16_MAX * 3)/2 + 1;
}else{
@@ -95,12 +94,19 @@ int keepalive__init(void)
}
}
#endif
last_keepalive_check = db.now_s;
return MOSQ_ERR_SUCCESS;
}
void keepalive__cleanup(void)
{
#ifndef WITH_OLD_KEEPALIVE
for(int idx=0; idx<keepalive_list_max; idx++){
struct mosquitto *context, *ctxt_tmp;
DL_FOREACH_SAFE2(keepalive_list[idx], context, ctxt_tmp, keepalive_next){
DL_DELETE2(keepalive_list[idx], context, keepalive_prev, keepalive_next);
}
}
mosquitto_free(keepalive_list);
keepalive_list = NULL;
keepalive_list_max = 0;
@@ -116,6 +122,7 @@ int keepalive__add(struct mosquitto *context)
#endif
DL_APPEND2(keepalive_list[calc_index(context)], context, keepalive_prev, keepalive_next);
context->keepalive_add_time = db.now_s;
#else
UNUSED(context);
#endif
@@ -132,7 +139,11 @@ void keepalive__check(void)
int idx = (int)(i % keepalive_list_max);
if(keepalive_list[idx]){
DL_FOREACH_SAFE2(keepalive_list[idx], context, ctxt_tmp, keepalive_next){
if(net__is_connected(context)){
/* keepalive_add_time lets us account for the client adding itself to the keepalive
* list when its last_msg_in value is greater than the last_keepalive_check.
* Without this, the client would be expired if it has keepalive == max_keepalive.
*/
if(context->keepalive_add_time <= last_keepalive_check && net__is_connected(context)){
/* Client has exceeded keepalive*1.5 */
do_disconnect(context, MOSQ_ERR_KEEPALIVE);
}
@@ -146,15 +157,7 @@ void keepalive__check(void)
void keepalive__check(void)
{
struct mosquitto *context, *ctxt_tmp;
time_t timeout;
if(db.contexts_by_sock){
timeout = (last_keepalive_check + 5 - db.now_s);
if(timeout <= 0){
timeout = 5;
}
loop__update_next_event(timeout*1000);
}
if(last_keepalive_check + 5 <= db.now_s){
last_keepalive_check = db.now_s;
+2
View File
@@ -130,9 +130,11 @@ int log__init(struct mosquitto__config *config)
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open log file %s for writing.", config->log_file);
}
}
#ifndef WIN32
if(log_destinations & MQTT3_LOG_STDOUT){
setvbuf(stdout, NULL, _IOLBF, 0);
}
#endif
#ifdef WITH_DLT
if(log_destinations & MQTT3_LOG_DLT){
dlt_fifo_check();
-2
View File
@@ -272,8 +272,6 @@ int mosquitto_main_loop(struct mosquitto__listener_sock *listensock, int listens
plugin__handle_tick();
}
mux__cleanup();
return MOSQ_ERR_SUCCESS;
}
+8 -1
View File
@@ -465,6 +465,7 @@ int main(int argc, char *argv[])
#endif
struct mosquitto *ctxt, *ctxt_tmp;
mosquitto_time_init();
#if defined(WIN32) || defined(__CYGWIN__)
if(argc == 2){
if(!strcmp(argv[1], "run")){
@@ -506,7 +507,11 @@ int main(int argc, char *argv[])
config__init(&config);
rc = config__parse_args(&config, argc, argv);
if(rc != MOSQ_ERR_SUCCESS) return rc;
if(rc == MOSQ_ERR_UNKNOWN){
return MOSQ_ERR_SUCCESS;
}else if(rc != MOSQ_ERR_SUCCESS){
return rc;
}
db.config = &config;
rc = keepalive__init();
@@ -633,6 +638,8 @@ int main(int argc, char *argv[])
(void)remove(config.pid_file);
}
mux__cleanup();
log__close(&config);
config__cleanup(db.config);
net__broker_cleanup();
+1 -1
View File
@@ -126,7 +126,7 @@ struct mosquitto *net__socket_accept(struct mosquitto__listener_sock *listensock
new_sock = accept(listensock->sock, NULL, 0);
if(new_sock == INVALID_SOCKET){
#ifdef WIN32
errno = WSAGetLastError();
WINDOWS_SET_ERRNO();
if(errno == WSAEMFILE){
#else
if(errno == EMFILE || errno == ENFILE){
+4
View File
@@ -711,6 +711,10 @@ void mosq_websockets_init(struct mosquitto__listener *listener, const struct mos
info.ssl_cert_filepath = listener->certfile;
info.ssl_private_key_filepath = listener->keyfile;
info.ssl_cipher_list = listener->ciphers;
/* HTTP 1 only, due to HTTP 2 issues in Firefox:
https://github.com/eclipse-mosquitto/mosquitto/issues/1211
*/
info.alpn = "h1";
#if defined(WITH_WEBSOCKETS) && LWS_LIBRARY_VERSION_NUMBER>=3001000
info.tls1_3_plus_cipher_list = listener->ciphers_tls13;
#endif
@@ -24,8 +24,6 @@ conf_file = os.path.basename(__file__).replace('.py', '.conf')
write_config(conf_file, port1, port2)
rc = 1
connect_packet = mosq_test.gen_connect("connect-success-test")
broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port2, use_conf=True)
ssl_eof = False
@@ -36,7 +34,7 @@ try:
ssock = context.wrap_socket(sock, server_hostname="localhost", suppress_ragged_eofs=True)
ssock.settimeout(None)
try:
mosq_test.do_send_receive(ssock, connect_packet, "", "connack")
ssock.read(1)
except ssl.SSLEOFError:
# Under load, sometimes the broker closes the connection after the
# handshake has failed, but before we have chance to send our
@@ -23,9 +23,6 @@ conf_file = os.path.basename(__file__).replace('.py', '.conf')
write_config(conf_file, port1, port2)
rc = 1
keepalive = 10
connect_packet = mosq_test.gen_connect("connect-revoked-test", keepalive=keepalive)
broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port2, use_conf=True)
ssl_eof = False
@@ -38,7 +35,7 @@ try:
try:
ssock.connect(("localhost", port1))
try:
mosq_test.do_send_receive(ssock, connect_packet, "", "connack")
ssock.read(1)
except ssl.SSLEOFError:
# Under load, sometimes the broker closes the connection after the
# handshake has failed, but before we have chance to send our
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "mosquitto",
"version-string": "2.0.21",
"version-string": "2.0.22",
"dependencies": [
"cjson",
"libwebsockets",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 422 KiB

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 4.5 KiB

+4 -3
View File
@@ -11,7 +11,7 @@
# Source
* [mosquitto-2.0.21.tar.gz](https://mosquitto.org/files/source/mosquitto-2.0.21.tar.gz) ([GPG signature](https://mosquitto.org/files/source/mosquitto-2.0.21.tar.gz.asc))
* [mosquitto-2.0.22.tar.gz](https://mosquitto.org/files/source/mosquitto-2.0.22.tar.gz) ([GPG signature](https://mosquitto.org/files/source/mosquitto-2.0.22.tar.gz.asc))
* [Git source code repository](https://github.com/eclipse/mosquitto) (github.com)
Older downloads are available at [https://mosquitto.org/files/](../files/)
@@ -24,8 +24,8 @@ distributions.
## Windows
* [mosquitto-2.0.21-install-windows-x64.exe](https://mosquitto.org/files/binary/win64/mosquitto-2.0.21-install-windows-x64.exe)
* [mosquitto-2.0.21-install-windows-x86.exe](https://mosquitto.org/files/binary/win32/mosquitto-2.0.21-install-windows-x86.exe)
* [mosquitto-2.0.22-install-windows-x64.exe](https://mosquitto.org/files/binary/win64/mosquitto-2.0.22-install-windows-x64.exe)
* [mosquitto-2.0.22-install-windows-x86.exe](https://mosquitto.org/files/binary/win32/mosquitto-2.0.22-install-windows-x86.exe)
Older installers can be found at [https://mosquitto.org/files/binary/](https://mosquitto.org/files/binary/).
@@ -42,6 +42,7 @@ Mosquitto can be installed from the homebrew project. See
## Debian
* Mosquitto is now in Debian proper. There will be a short delay between a new
release and it appearing in Debian as part of the normal Debian procedures.
The tracker for the package is at <https://tracker.debian.org/pkg/mosquitto>.
* There are also Debian repositories provided by the mosquitto project, as
described at <https://mosquitto.org/2013/01/mosquitto-debian-repository>
@@ -0,0 +1,69 @@
<!--
.. title: Version 2.0.22 released.
.. slug: version-2-0-22-released
.. date: 2025-07-11 21:40:38 UTC
.. tags: Releases
.. category:
.. link:
.. description:
.. type: text
-->
Version 2.0.22 of Mosquitto has been released. This is a bugfix release.
# Broker
- Windows: Fix broker crash on startup if using `log_dest stdout`
- Bridge: Fix `idle_timeout` never occurring for lazy bridges.
- Fix case where `max_queued_messages = 0` was not treated as unlimited.
Closes [#3244].
- Fix `--version` exit code and output. Closes [#3267].
- Fix crash on receiving a $CONTROL message over a bridge, if
`per_listener_settings` is set true and the bridge is carrying out topic
remapping. Closes [#3261].
- Fix incorrect reference clock being selected on startup on Linux.
Closes [#3238].
- Fix reporting of client disconnections being incorrectly attributed to "out
of memory". Closes [#3253].
- Fix compilation when using `WITH_OLD_KEEPALIVE`. Closes [#3250].
- Add Windows linker file for the broker to the installer. Closes [#3269].
- Fix Websockets PING not being sent on Windows. Closes [#3272].
- Fix problems with secure websockets. Closes [#1211].
- Fix crash on exit when using `WITH_EPOLL=no`. Closes [#3302].
- Fix clients being incorrectly expired when they have keepalive ==
`max_keepalive`. Closes [#3226], [#3286].
# Dynamic security plugin
- Fix mismatch memory free when saving config which caused memory tracking to
be incorrect.
# Client library
- Fix C++ symbols being removed when compiled with link time optimisation.
Closes [#3259].
- TLS error handling was incorrectly setting a protocol error for non-TLS
errors. This would cause the `mosquitto_loop_start()` thread to exit if no
broker was available on the first connection attempt. This has been fixed.
Closes [#3258].
- Fix linker errors on some architectures using cmake. Closes [#3167].
Tests:
- Fix 08-ssl-connect-cert-auth-expired and 08-ssl-connect-cert-auth-revoked
tests when running on a single CPU system. Closes [#3230].
[#1211]: https://github.com/eclipse/mosquitto/issues/1211
[#3167]: https://github.com/eclipse/mosquitto/issues/3167
[#3226]: https://github.com/eclipse/mosquitto/issues/3226
[#3230]: https://github.com/eclipse/mosquitto/issues/3230
[#3238]: https://github.com/eclipse/mosquitto/issues/3238
[#3244]: https://github.com/eclipse/mosquitto/issues/3244
[#3250]: https://github.com/eclipse/mosquitto/issues/3250
[#3253]: https://github.com/eclipse/mosquitto/issues/3253
[#3258]: https://github.com/eclipse/mosquitto/issues/3258
[#3259]: https://github.com/eclipse/mosquitto/issues/3259
[#3261]: https://github.com/eclipse/mosquitto/issues/3261
[#3267]: https://github.com/eclipse/mosquitto/issues/3267
[#3269]: https://github.com/eclipse/mosquitto/issues/3269
[#3272]: https://github.com/eclipse/mosquitto/issues/3272
[#3286]: https://github.com/eclipse/mosquitto/issues/3286
[#3302]: https://github.com/eclipse/mosquitto/issues/3302