mirror of
https://github.com/eclipse-mosquitto/mosquitto.git
synced 2026-08-20 21:41:40 +08:00
Merge branch 'fixes'
This commit is contained in:
+1
-1
@@ -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/")
|
||||
|
||||
|
||||
@@ -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
|
||||
===================
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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{
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -2,7 +2,7 @@
|
||||
|
||||
MAJOR=2
|
||||
MINOR=0
|
||||
REVISION=21
|
||||
REVISION=22
|
||||
|
||||
sed -i "s/^VERSION=.*/VERSION=${MAJOR}.${MINOR}.${REVISION}/" config.mk
|
||||
|
||||
|
||||
+1
-1
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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
@@ -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 |
@@ -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
|
||||
Reference in New Issue
Block a user