Merge branch 'master' into develop

This commit is contained in:
Roger A. Light
2024-10-19 22:13:14 +01:00
60 changed files with 677 additions and 224 deletions
+1
View File
@@ -23,6 +23,7 @@ apps/db_dump/mosquitto_db_dump.a
apps/mosquitto_ctrl/mosquitto_ctrl
apps/mosquitto_passwd/mosquitto_passwd
apps/mosquitto_passwd/mosquitto_passwd.a
apps/mosquitto_signal/mosquitto_signal
build/
build64/
+7 -1
View File
@@ -26,7 +26,7 @@ if(WIN32)
endif()
if(APPLE)
set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS} -undefined dynamic_lookup")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -undefined dynamic_lookup")
endif()
add_library(common-options INTERFACE)
@@ -47,6 +47,12 @@ if (WITH_TLS)
find_package(OpenSSL REQUIRED)
add_definitions("-DWITH_TLS")
# mosquitto uses OpenSSL 1.1 API, so set OPENSSL_API_COMPAT accordingly:
# https://www.openssl.org/docs/manmaster/man7/OPENSSL_API_COMPAT.html
# TODO: migrate off ENGINE API (deprecated since OpenSSL 3.0), see:
# https://www.openssl.org/docs/manmaster/man7/migration_guide.html#Engines-and-METHOD-APIs
add_definitions("-DOPENSSL_API_COMPAT=0x10100000L")
if (WITH_TLS_PSK)
add_definitions("-DWITH_TLS_PSK")
endif (WITH_TLS_PSK)
+41 -1
View File
@@ -201,12 +201,47 @@ Build:
- Support for openssl < 3.0 removed.
2.0.19 - 2023-11-xx
2.0.20 - 2024-10-16
===================
Broker:
- Fix QoS 1 / QoS 2 publish incorrectly returning "no subscribers".
Closes #3128.
- Open files with appropriate access on Windows. Closes #3119.
- Don't allow invalid response topic values.
- Fix some strict protocol compliance issues. Closes #3052.
Client library:
- Fix cmake build on OS X. Closes #3125.
Build:
- Fix build on NetBSD
2.0.19 - 2024-10-02
===================
Security:
- Fix mismatched subscribe/unsubscribe with normal/shared topics.
- Fix crash on bridge using remapped topic being sent a crafted packet.
Broker:
- Fix assert failure when loading a persistence file that contains
subscriptions with no client id.
- Fix local bridges being incorrectly expired when
persistent_client_expiration is in use.
- Fix use of CLOCK_BOOTTIME for getting time. Closes #3089.
- Fix mismatched subscribe/unsubscribe with normal/shared topics.
- Fix crash on bridge using remapped topic being sent a crafted packet.
Client library:
- Fix some error codes being converted to string as "unknown". Closes #2579.
- Clear SSL error state to avoid spurious error reporting. Closes #3054.
- Fix "payload format invalid" not being allowed as a PUBREC reason code.
- Don't allow SUBACK with missing reason codes.
Build:
- Thread support is re-enabled on Windows.
2.0.18 - 2023-09-18
@@ -219,6 +254,11 @@ Broker:
Clients:
- Fix mosquitto_rr not honouring `-R`. Closes #2893.
Windows:
- Installer will start/stop the mosquitto service when installing and
uninstalling, to prevent problems with not being able to overwrite or remove
mosquitto.exe.
2.0.17 - 2023-08-22
===================
+18 -1
View File
@@ -30,7 +30,7 @@ various platforms.
## Quick start
If you have installed a binary package the broker should have been started
automatically. If not, it can be started with a basic configuration:
automatically. If not, it can be started with a very basic configuration:
mosquitto
@@ -42,6 +42,23 @@ And to publish a message:
mosquitto_pub -t 'test/topic' -m 'hello world'
Note that starting the broker like this allows anonymous/unauthenticated access
but only from the local computer, so it's only really useful for initial testing.
If you want to have clients from another computer connect, you will need to
provide a configuration file. If you have installed from a binary package, you
will probably already have a configuration file at somewhere like
`/etc/mosquitto/mosquitto.conf`. If you've compiled from source, you can write
your config file then run as `mosquitto -c /path/to/mosquitto.conf`.
To start your config file you define a listener and you will need to think
about what authentication you require. It is not advised to run your broker
with anonymous access when it is publically available.
For details on how to do this, look at the
[authentication methods](https://mosquitto.org/documentation/authentication-methods/)
available and the [dynamic security plugin](https://mosquitto.org/documentation/dynamic-security/).
## Documentation
Documentation for the broker, clients and client library API can be found in
+3 -1
View File
@@ -68,7 +68,9 @@ void json_init(void)
void json_print(void)
{
printf("%s\n", cJSON_Print(j_tree));
char *jstr = cJSON_Print(j_tree);
printf("%s\n", jstr);
free(jstr);
}
void json_cleanup(void)
-2
View File
@@ -7,8 +7,6 @@
#ifdef __APPLE__
# define __DARWIN_C_SOURCE
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__SYMBIAN32__)
# define _XOPEN_SOURCE 700
# define __BSD_VISIBLE 1
# define HAVE_NETINET_IN_H
#elif defined(__QNX__)
# define _XOPEN_SOURCE 600
+3 -3
View File
@@ -1,10 +1,10 @@
FROM alpine:3.18
FROM alpine:3.20
LABEL maintainer="Roger Light <roger@atchoo.org>" \
description="Eclipse Mosquitto MQTT Broker"
ENV VERSION=2.0.18 \
DOWNLOAD_SHA256=d665fe7d0032881b1371a47f34169ee4edab67903b2cd2b4c083822823f4448a \
ENV VERSION=2.0.20 \
DOWNLOAD_SHA256=ebd07d89d2a446a7f74100ad51272e4a8bf300b61634a7812e19f068f2759de8 \
GPG_KEYS=A0D6EEA1DCAE49A635A3B2F0779B22DFB3E717B7 \
LWS_VERSION=4.2.1 \
LWS_SHA256=842da21f73ccba2be59e680de10a8cce7928313048750eb6ad73b6fa50763c51
+3 -3
View File
@@ -1,10 +1,10 @@
FROM alpine:3.18
FROM alpine:3.20
LABEL maintainer="Roger Light <roger@atchoo.org>" \
description="Eclipse Mosquitto MQTT Broker"
ENV VERSION=2.0.18 \
DOWNLOAD_SHA256=d665fe7d0032881b1371a47f34169ee4edab67903b2cd2b4c083822823f4448a \
ENV VERSION=2.0.19 \
DOWNLOAD_SHA256=33af3637f119a61c509c01d2f8f6cc3d8be76f49e850132f2860af142abf82a9 \
GPG_KEYS=A0D6EEA1DCAE49A635A3B2F0779B22DFB3E717B7 \
LWS_VERSION=4.2.1 \
LWS_SHA256=842da21f73ccba2be59e680de10a8cce7928313048750eb6ad73b6fa50763c51
+1 -1
View File
@@ -17,7 +17,7 @@ Contributors:
*/
/*
* File: mosquitto/control.h
* File: mosquitto/broker_control.h
*
* This header contains functions for use by plugins using the CONTROL event.
*/
+6
View File
@@ -7,6 +7,12 @@ extern "C" {
#include <time.h>
/* Function: mosquitto_time_init
*
* Initialises the time source to use the best source available at run time.
*/
libmosqcommon_EXPORT void mosquitto_time_init(void);
/* Function: mosquitto_time
*
* Returns an indication of the current time in seconds. The exact type of
+2 -2
View File
@@ -56,7 +56,7 @@ extern "C" {
* * mosq == NULL
* * host == NULL
* * port < 0
* * keepalive < 5
* * keepalive < 5 (keepalive == 0 is allowed, for an infinite keepalive)
* MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno
* contains the error code, even on Windows.
* Use strerror_r() where available or FormatMessage() on
@@ -136,7 +136,7 @@ libmosq_EXPORT int mosquitto_connect_bind(struct mosquitto *mosq, const char *ho
* * mosq == NULL
* * host == NULL
* * port < 0
* * keepalive < 5
* * keepalive < 5 (keepalive == 0 is allowed, for an infinite keepalive)
* MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno
* contains the error code, even on Windows.
* Use strerror_r() where available or FormatMessage() on
+1 -1
View File
@@ -176,7 +176,7 @@ libmosq_EXPORT int mosquitto_int_option(struct mosquitto *mosq, enum mosq_opt_t
* 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
* MOSQ_OPT_TLS_ENGINE_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>.
+1 -1
View File
@@ -116,7 +116,7 @@ libmosq_EXPORT int mosquitto_subscribe_v5(struct mosquitto *mosq, int *mid, cons
* pointers nor the strings that they point to are mutable. If you aren't
* familiar with this, just think of it as a safer "char **",
* equivalent to "const char *" for a simple string pointer.
* Each string must not be NULL or an empty string.
* Each string must not be NULL nor an empty string.
* qos - the requested Quality of Service for each subscription.
* options - options to apply to this subscription, OR'd together. This
* argument is not used for MQTT v3 susbcriptions. Set to 0 to use
+1 -1
View File
@@ -113,7 +113,7 @@ libmosq_EXPORT int mosquitto_unsubscribe_v5(struct mosquitto *mosq, int *mid, co
* pointers nor the strings that they point to are mutable. If you aren't
* familiar with this, just think of it as a safer "char **",
* equivalent to "const char *" for a simple string pointer.
* Each sub must not be NULL or an empty string.
* Each sub must not be NULL nor an empty string.
* properties - a valid mosquitto_property list, or NULL. Only used with MQTT
* v5 clients.
*
+2 -2
View File
@@ -163,7 +163,7 @@ enum mqtt5_return_codes {
MQTT_RC_MESSAGE_RATE_TOO_HIGH = 150, /* DISCONNECT */
MQTT_RC_QUOTA_EXCEEDED = 151, /* PUBACK, PUBREC, SUBACK, DISCONNECT */
MQTT_RC_ADMINISTRATIVE_ACTION = 152, /* DISCONNECT */
MQTT_RC_PAYLOAD_FORMAT_INVALID = 153, /* CONNACK, DISCONNECT */
MQTT_RC_PAYLOAD_FORMAT_INVALID = 153, /* CONNACK, PUBACK, PUBREC, DISCONNECT */
MQTT_RC_RETAIN_NOT_SUPPORTED = 154, /* CONNACK, DISCONNECT */
MQTT_RC_QOS_NOT_SUPPORTED = 155, /* CONNACK, DISCONNECT */
MQTT_RC_USE_ANOTHER_SERVER = 156, /* CONNACK, DISCONNECT */
@@ -224,7 +224,7 @@ enum mqtt5_property {
MQTT_PROP_REQUEST_RESPONSE_INFORMATION = 25,/* Byte : CONNECT */
MQTT_PROP_RESPONSE_INFORMATION = 26, /* UTF-8 string : CONNACK */
MQTT_PROP_SERVER_REFERENCE = 28, /* UTF-8 string : CONNACK, DISCONNECT */
MQTT_PROP_REASON_STRING = 31, /* UTF-8 string : CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, UNSUBACK, DISCONNECT, AUTH */
MQTT_PROP_REASON_STRING = 31, /* UTF-8 string : All except Will properties */
MQTT_PROP_RECEIVE_MAXIMUM = 33, /* 2 byte int : CONNECT, CONNACK */
MQTT_PROP_TOPIC_ALIAS_MAXIMUM = 34, /* 2 byte int : CONNECT, CONNACK */
MQTT_PROP_TOPIC_ALIAS = 35, /* 2 byte int : PUBLISH */
+46 -27
View File
@@ -43,7 +43,12 @@ InstallDir "$PROGRAMFILES64\Mosquitto"
Section "Files" SecInstall
SectionIn RO
ExecWait 'sc stop mosquitto'
Sleep 1000
SetOutPath "$INSTDIR"
File "..\logo\mosquitto.ico"
File "..\build64\src\Release\mosquitto.exe"
File "..\build64\apps\mosquitto_ctrl\Release\mosquitto_ctrl.exe"
File "..\build64\apps\mosquitto_passwd\Release\mosquitto_passwd.exe"
@@ -114,6 +119,7 @@ Section "Files" SecInstall
WriteUninstaller "$INSTDIR\Uninstall.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto64" "DisplayName" "Eclipse Mosquitto MQTT broker (64 bit)"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto64" "DisplayIcon" "$INSTDIR\mosquitto.ico"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto64" "UninstallString" "$\"$INSTDIR\Uninstall.exe$\""
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto64" "QuietUninstallString" "$\"$INSTDIR\Uninstall.exe$\" /S"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Mosquitto64" "HelpLink" "https://mosquitto.org/"
@@ -135,10 +141,16 @@ SectionEnd
Section "Service" SecService
ExecWait '"$INSTDIR\mosquitto.exe" install'
ExecWait 'sc start mosquitto'
SectionEnd
Section "Uninstall"
ExecWait 'sc stop mosquitto'
Sleep 1000
ExecWait '"$INSTDIR\mosquitto.exe" uninstall'
Sleep 1000
Delete "$INSTDIR\mosquitto.dll"
Delete "$INSTDIR\mosquitto.exe"
Delete "$INSTDIR\mosquitto_common.dll"
Delete "$INSTDIR\mosquitto_ctrl.exe"
@@ -147,7 +159,6 @@ Section "Uninstall"
Delete "$INSTDIR\mosquitto_pub.exe"
Delete "$INSTDIR\mosquitto_rr.exe"
Delete "$INSTDIR\mosquitto_sub.exe"
Delete "$INSTDIR\mosquitto.dll"
Delete "$INSTDIR\mosquittopp.dll"
Delete "$INSTDIR\mosquitto_dynamic_security.dll"
Delete "$INSTDIR\mosquitto_persist_sqlite.dll"
@@ -163,6 +174,14 @@ Section "Uninstall"
Delete "$INSTDIR\SECURITY.md"
Delete "$INSTDIR\edl-v10"
Delete "$INSTDIR\epl-v20"
Delete "$INSTDIR\mosquitto.ico"
Delete "$INSTDIR\cjson.dll"
Delete "$INSTDIR\libcrypto-3-x64.dll"
Delete "$INSTDIR\libssl-3-x64.dll"
Delete "$INSTDIR\pthreadVC3.dll"
Delete "$INSTDIR\uv.dll"
Delete "$INSTDIR\websockets.dll"
Delete "$INSTDIR\argon2.dll"
Delete "$INSTDIR\cjson.dll"
@@ -172,32 +191,32 @@ Section "Uninstall"
Delete "$INSTDIR\sqlite3.dll"
Delete "$INSTDIR\devel\mosquitto.h"
Delete "$INSTDIR\devel\mosquitto/broker.h"
Delete "$INSTDIR\devel\mosquitto/broker_control.h"
Delete "$INSTDIR\devel\mosquitto/broker_plugin.h"
Delete "$INSTDIR\devel\mosquitto/defs.h"
Delete "$INSTDIR\devel\mosquitto/libcommon.h"
Delete "$INSTDIR\devel\mosquitto/libcommon_properties.h"
Delete "$INSTDIR\devel\mosquitto/libcommon_string.h"
Delete "$INSTDIR\devel\mosquitto/libcommon_topic.h"
Delete "$INSTDIR\devel\mosquitto/libcommon_utf8.h"
Delete "$INSTDIR\devel\mosquitto/libmosquitto.h"
Delete "$INSTDIR\devel\mosquitto/libmosquitto_auth.h"
Delete "$INSTDIR\devel\mosquitto/libmosquitto_callbacks.h"
Delete "$INSTDIR\devel\mosquitto/libmosquitto_connect.h"
Delete "$INSTDIR\devel\mosquitto/libmosquitto_create_delete.h"
Delete "$INSTDIR\devel\mosquitto/libmosquitto_helpers.h"
Delete "$INSTDIR\devel\mosquitto/libmosquitto_loop.h"
Delete "$INSTDIR\devel\mosquitto/libmosquitto_message.h"
Delete "$INSTDIR\devel\mosquitto/libmosquitto_options.h"
Delete "$INSTDIR\devel\mosquitto/libmosquitto_publish.h"
Delete "$INSTDIR\devel\mosquitto/libmosquitto_socks.h"
Delete "$INSTDIR\devel\mosquitto/libmosquitto_subscribe.h"
Delete "$INSTDIR\devel\mosquitto/libmosquitto_tls.h"
Delete "$INSTDIR\devel\mosquitto/libmosquitto_unsubscribe.h"
Delete "$INSTDIR\devel\mosquitto/libmosquitto_will.h"
Delete "$INSTDIR\devel\mosquitto/libmosquittopp.h"
Delete "$INSTDIR\devel\mosquitto/mqtt_protocol.h"
Delete "$INSTDIR\devel\mosquitto\broker.h"
Delete "$INSTDIR\devel\mosquitto\broker_control.h"
Delete "$INSTDIR\devel\mosquitto\broker_plugin.h"
Delete "$INSTDIR\devel\mosquitto\defs.h"
Delete "$INSTDIR\devel\mosquitto\libcommon.h"
Delete "$INSTDIR\devel\mosquitto\libcommon_properties.h"
Delete "$INSTDIR\devel\mosquitto\libcommon_string.h"
Delete "$INSTDIR\devel\mosquitto\libcommon_topic.h"
Delete "$INSTDIR\devel\mosquitto\libcommon_utf8.h"
Delete "$INSTDIR\devel\mosquitto\libmosquitto.h"
Delete "$INSTDIR\devel\mosquitto\libmosquitto_auth.h"
Delete "$INSTDIR\devel\mosquitto\libmosquitto_callbacks.h"
Delete "$INSTDIR\devel\mosquitto\libmosquitto_connect.h"
Delete "$INSTDIR\devel\mosquitto\libmosquitto_create_delete.h"
Delete "$INSTDIR\devel\mosquitto\libmosquitto_helpers.h"
Delete "$INSTDIR\devel\mosquitto\libmosquitto_loop.h"
Delete "$INSTDIR\devel\mosquitto\libmosquitto_message.h"
Delete "$INSTDIR\devel\mosquitto\libmosquitto_options.h"
Delete "$INSTDIR\devel\mosquitto\libmosquitto_publish.h"
Delete "$INSTDIR\devel\mosquitto\libmosquitto_socks.h"
Delete "$INSTDIR\devel\mosquitto\libmosquitto_subscribe.h"
Delete "$INSTDIR\devel\mosquitto\libmosquitto_tls.h"
Delete "$INSTDIR\devel\mosquitto\libmosquitto_unsubscribe.h"
Delete "$INSTDIR\devel\mosquitto\libmosquitto_will.h"
Delete "$INSTDIR\devel\mosquitto\libmosquittopp.h"
Delete "$INSTDIR\devel\mosquitto\mqtt_protocol.h"
Delete "$INSTDIR\devel\mosquitto_broker.h"
Delete "$INSTDIR\devel\mosquitto_plugin.h"
Delete "$INSTDIR\devel\mosquittopp.h"
+2 -1
View File
@@ -49,7 +49,7 @@ set(C_SRC
util_mosq.c util_mosq.h
will_mosq.c will_mosq.h)
set(LIBRARIES common-options)
set(LIBRARIES common-options ${OPENSSL_LIBRARIES})
if(WITH_TLS)
set (LIBRARIES ${LIBRARIES} OpenSSL::SSL)
@@ -103,6 +103,7 @@ target_include_directories(libmosquitto
"${mosquitto_SOURCE_DIR}"
"${mosquitto_SOURCE_DIR}/common"
"${mosquitto_SOURCE_DIR}/libcommon"
"${OPENSSL_INCLUDE_DIR}" # Required for cross compilation
)
if(WITH_BUNDLED_DEPS)
+46 -46
View File
@@ -25,114 +25,114 @@ Contributors:
void mosquitto_connect_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int))
{
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_connect = on_connect;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_connect_with_flags_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int))
{
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_connect_with_flags = on_connect;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_connect_v5_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int, const mosquitto_property *))
{
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_connect_v5 = on_connect;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_pre_connect_callback_set(struct mosquitto *mosq, void (*on_pre_connect)(struct mosquitto *, void *))
{
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_pre_connect = on_pre_connect;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_disconnect_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int))
{
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_disconnect = on_disconnect;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_disconnect_v5_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int, const mosquitto_property *))
{
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_disconnect_v5 = on_disconnect;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_publish_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int))
{
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_publish = on_publish;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_publish_v5_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int, int, const mosquitto_property *props))
{
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_publish_v5 = on_publish;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_message_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *))
{
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_message = on_message;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_message_v5_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *, const mosquitto_property *props))
{
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_message_v5 = on_message;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_subscribe_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *))
{
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_subscribe = on_subscribe;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_subscribe_v5_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *, const mosquitto_property *props))
{
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_subscribe_v5 = on_subscribe;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_unsubscribe_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int))
{
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_unsubscribe = on_unsubscribe;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_unsubscribe_v5_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int, const mosquitto_property *props))
{
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_unsubscribe_v5 = on_unsubscribe;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_unsubscribe2_v5_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int, int, const int *, const mosquitto_property *props))
{
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_unsubscribe2_v5 = on_unsubscribe;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
}
void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mosquitto *, void *, int, const char *))
{
pthread_mutex_lock(&mosq->log_callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->log_callback_mutex);
mosq->on_log = on_log;
pthread_mutex_unlock(&mosq->log_callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->log_callback_mutex);
}
@@ -140,9 +140,9 @@ void callback__on_pre_connect(struct mosquitto *mosq)
{
void (*on_pre_connect)(struct mosquitto *, void *userdata);
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
on_pre_connect = mosq->on_pre_connect;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
mosq->callback_depth++;
if(on_pre_connect){
@@ -158,11 +158,11 @@ void callback__on_connect(struct mosquitto *mosq, uint8_t reason_code, uint8_t c
void (*on_connect_with_flags)(struct mosquitto *, void *userdata, int rc, int flags);
void (*on_connect_v5)(struct mosquitto *, void *userdata, int rc, int flags, const mosquitto_property *props);
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
on_connect = mosq->on_connect;
on_connect_with_flags = mosq->on_connect_with_flags;
on_connect_v5 = mosq->on_connect_v5;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
mosq->callback_depth++;
if(on_connect){
@@ -183,10 +183,10 @@ void callback__on_publish(struct mosquitto *mosq, int mid, int reason_code, cons
void (*on_publish)(struct mosquitto *, void *userdata, int mid);
void (*on_publish_v5)(struct mosquitto *, void *userdata, int mid, int reason_code, const mosquitto_property *props);
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
on_publish = mosq->on_publish;
on_publish_v5 = mosq->on_publish_v5;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
mosq->callback_depth++;
if(on_publish){
@@ -204,10 +204,10 @@ void callback__on_message(struct mosquitto *mosq, const struct mosquitto_message
void (*on_message)(struct mosquitto *, void *userdata, const struct mosquitto_message *message);
void (*on_message_v5)(struct mosquitto *, void *userdata, const struct mosquitto_message *message, const mosquitto_property *props);
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
on_message = mosq->on_message;
on_message_v5 = mosq->on_message_v5;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
mosq->callback_depth++;
if(on_message){
@@ -225,10 +225,10 @@ void callback__on_subscribe(struct mosquitto *mosq, int mid, int qos_count, cons
void (*on_subscribe)(struct mosquitto *, void *userdata, int mid, int qos_count, const int *granted_qos) = NULL;
void (*on_subscribe_v5)(struct mosquitto *, void *userdata, int mid, int qos_count, const int *granted_qos, const mosquitto_property *props) = NULL;
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
on_subscribe = mosq->on_subscribe;
on_subscribe_v5 = mosq->on_subscribe_v5;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
mosq->callback_depth++;
if(on_subscribe){
@@ -247,11 +247,11 @@ void callback__on_unsubscribe(struct mosquitto *mosq, int mid, int reason_code_c
void (*on_unsubscribe_v5)(struct mosquitto *, void *userdata, int mid, const mosquitto_property *props) = NULL;
void (*on_unsubscribe2_v5)(struct mosquitto *, void *userdata, int mid, int reason_code_count, const int *reason_codes, const mosquitto_property *props) = NULL;
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
on_unsubscribe = mosq->on_unsubscribe;
on_unsubscribe_v5 = mosq->on_unsubscribe_v5;
on_unsubscribe2_v5 = mosq->on_unsubscribe2_v5;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
mosq->callback_depth++;
if(on_unsubscribe){
@@ -272,10 +272,10 @@ void callback__on_disconnect(struct mosquitto *mosq, int rc, const mosquitto_pro
void (*on_disconnect)(struct mosquitto *, void *, int) = NULL;
void (*on_disconnect_v5)(struct mosquitto *, void *, int, const mosquitto_property *) = NULL;
pthread_mutex_lock(&mosq->callback_mutex);
COMPAT_pthread_mutex_lock(&mosq->callback_mutex);
on_disconnect = mosq->on_disconnect;
on_disconnect_v5 = mosq->on_disconnect_v5;
pthread_mutex_unlock(&mosq->callback_mutex);
COMPAT_pthread_mutex_unlock(&mosq->callback_mutex);
mosq->callback_depth++;
if(on_disconnect){
-14
View File
@@ -1,14 +0,0 @@
#ifndef DUMMYPTHREAD_H
#define DUMMYPTHREAD_H
#define pthread_create(A, B, C, D)
#define pthread_join(A, B)
#define pthread_cancel(A)
#define pthread_testcancel()
#define pthread_mutex_init(A, B)
#define pthread_mutex_destroy(A)
#define pthread_mutex_lock(A)
#define pthread_mutex_unlock(A)
#endif
+2 -2
View File
@@ -57,9 +57,9 @@ int handle__pubackcomp(struct mosquitto *mosq, const char *type)
}
}
pthread_mutex_lock(&mosq->msgs_out.mutex);
COMPAT_pthread_mutex_lock(&mosq->msgs_out.mutex);
util__increment_send_quota(mosq);
pthread_mutex_unlock(&mosq->msgs_out.mutex);
COMPAT_pthread_mutex_unlock(&mosq->msgs_out.mutex);
rc = packet__read_uint16(&mosq->in_packet, &mid);
if(rc) return rc;
+2 -1
View File
@@ -68,7 +68,8 @@ int handle__pubrec(struct mosquitto *mosq)
&& reason_code != MQTT_RC_NOT_AUTHORIZED
&& reason_code != MQTT_RC_TOPIC_NAME_INVALID
&& reason_code != MQTT_RC_PACKET_ID_IN_USE
&& reason_code != MQTT_RC_QUOTA_EXCEEDED){
&& reason_code != MQTT_RC_QUOTA_EXCEEDED
&& reason_code != MQTT_RC_PAYLOAD_FORMAT_INVALID){
return MOSQ_ERR_PROTOCOL;
}
+1
View File
@@ -73,6 +73,7 @@ int handle__suback(struct mosquitto *mosq)
}
qos_count = (int)(mosq->in_packet.remaining_length - mosq->in_packet.pos);
if(qos_count == 0) return MOSQ_ERR_PROTOCOL;
granted_qos = mosquitto_malloc((size_t)qos_count*sizeof(int));
if(!granted_qos){
mosquitto_property_free_all(&properties);
+3 -3
View File
@@ -56,15 +56,15 @@ int mosquitto_lib_init(void)
int rc;
if (init_refcount == 0) {
mosquitto_time_init();
#ifdef WIN32
srand((unsigned int)GetTickCount64());
#elif _POSIX_TIMERS>0 && defined(_POSIX_MONOTONIC_CLOCK)
struct timespec tp;
#ifdef CLOCK_BOOTTIME
clock_gettime(CLOCK_BOOTTIME, &tp);
#else
clock_gettime(CLOCK_MONOTONIC, &tp);
if (clock_gettime(CLOCK_BOOTTIME, &tp) != 0)
#endif
clock_gettime(CLOCK_MONOTONIC, &tp);
srand((unsigned int)tp.tv_nsec);
#elif defined(__APPLE__)
uint64_t ticks;
+1 -5
View File
@@ -33,11 +33,7 @@ Contributors:
#endif
#include <stdlib.h>
#if defined(WITH_THREADING) && !defined(WITH_BROKER)
# include <pthread.h>
#else
# include <dummypthread.h>
#endif
#include <pthread_compat.h>
#ifdef WITH_SRV
# include <ares.h>
+2
View File
@@ -992,6 +992,7 @@ ssize_t net__read(struct mosquitto *mosq, void *buf, size_t count)
errno = 0;
#ifdef WITH_TLS
if(mosq->ssl){
ERR_clear_error();
ret = SSL_read(mosq->ssl, buf, (int)count);
if(ret <= 0){
ret = net__handle_ssl(mosq, ret);
@@ -1024,6 +1025,7 @@ ssize_t net__write(struct mosquitto *mosq, const void *buf, size_t count)
errno = 0;
#ifdef WITH_TLS
if(mosq->ssl){
ERR_clear_error();
mosq->want_write = false;
ret = SSL_write(mosq->ssl, buf, (int)count);
if(ret < 0){
+1
View File
@@ -572,6 +572,7 @@ int mosquitto_void_option(struct mosquitto *mosq, enum mosq_opt_t option, void *
}
break;
#else
UNUSED(value);
return MOSQ_ERR_NOT_SUPPORTED;
#endif
default:
+4 -2
View File
@@ -79,8 +79,10 @@ void packet__write_bytes(struct mosquitto__packet *packet, const void *bytes, ui
assert(packet);
assert(packet->pos+count <= packet->packet_length);
memcpy(&(packet->payload[packet->pos]), bytes, count);
packet->pos += count;
if(count > 0){
memcpy(&(packet->payload[packet->pos]), bytes, count);
packet->pos += count;
}
}
+14 -14
View File
@@ -128,9 +128,9 @@ void packet__cleanup_all_no_locks(struct mosquitto *mosq)
void packet__cleanup_all(struct mosquitto *mosq)
{
pthread_mutex_lock(&mosq->out_packet_mutex);
COMPAT_pthread_mutex_lock(&mosq->out_packet_mutex);
packet__cleanup_all_no_locks(mosq);
pthread_mutex_unlock(&mosq->out_packet_mutex);
COMPAT_pthread_mutex_unlock(&mosq->out_packet_mutex);
}
@@ -150,7 +150,7 @@ static void packet__queue_append(struct mosquitto *mosq, struct mosquitto__packe
}
#endif
pthread_mutex_lock(&mosq->out_packet_mutex);
COMPAT_pthread_mutex_lock(&mosq->out_packet_mutex);
if(mosq->out_packet){
mosq->out_packet_last->next = packet;
}else{
@@ -161,7 +161,7 @@ static void packet__queue_append(struct mosquitto *mosq, struct mosquitto__packe
mosq->out_packet_bytes += packet->packet_length;
metrics__int_inc(mosq_gauge_out_packets, 1);
metrics__int_inc(mosq_gauge_out_packet_bytes, packet->packet_length);
pthread_mutex_unlock(&mosq->out_packet_mutex);
COMPAT_pthread_mutex_unlock(&mosq->out_packet_mutex);
}
@@ -239,7 +239,7 @@ struct mosquitto__packet *packet__get_next_out(struct mosquitto *mosq)
{
struct mosquitto__packet *packet = NULL;
pthread_mutex_lock(&mosq->out_packet_mutex);
COMPAT_pthread_mutex_lock(&mosq->out_packet_mutex);
if(mosq->out_packet){
mosq->out_packet_count--;
mosq->out_packet_bytes -= mosq->out_packet->packet_length;
@@ -252,7 +252,7 @@ struct mosquitto__packet *packet__get_next_out(struct mosquitto *mosq)
}
packet = mosq->out_packet;
}
pthread_mutex_unlock(&mosq->out_packet_mutex);
COMPAT_pthread_mutex_unlock(&mosq->out_packet_mutex);
return packet;
}
@@ -269,9 +269,9 @@ int packet__write(struct mosquitto *mosq)
return MOSQ_ERR_NO_CONN;
}
pthread_mutex_lock(&mosq->out_packet_mutex);
COMPAT_pthread_mutex_lock(&mosq->out_packet_mutex);
packet = mosq->out_packet;
pthread_mutex_unlock(&mosq->out_packet_mutex);
COMPAT_pthread_mutex_unlock(&mosq->out_packet_mutex);
if(packet == NULL){
return MOSQ_ERR_SUCCESS;
@@ -335,9 +335,9 @@ int packet__write(struct mosquitto *mosq)
#ifdef WITH_BROKER
mosq->next_msg_out = db.now_s + mosq->keepalive;
#else
pthread_mutex_lock(&mosq->msgtime_mutex);
COMPAT_pthread_mutex_lock(&mosq->msgtime_mutex);
mosq->next_msg_out = mosquitto_time() + mosq->keepalive;
pthread_mutex_unlock(&mosq->msgtime_mutex);
COMPAT_pthread_mutex_unlock(&mosq->msgtime_mutex);
#endif
}
#ifdef WITH_BROKER
@@ -541,9 +541,9 @@ int packet__read(struct mosquitto *mosq)
#ifdef WITH_BROKER
keepalive__update(mosq);
#else
pthread_mutex_lock(&mosq->msgtime_mutex);
COMPAT_pthread_mutex_lock(&mosq->msgtime_mutex);
mosq->last_msg_in = mosquitto_time();
pthread_mutex_unlock(&mosq->msgtime_mutex);
COMPAT_pthread_mutex_unlock(&mosq->msgtime_mutex);
#endif
}
return MOSQ_ERR_SUCCESS;
@@ -573,9 +573,9 @@ int packet__read(struct mosquitto *mosq)
#ifdef WITH_BROKER
keepalive__update(mosq);
#else
pthread_mutex_lock(&mosq->msgtime_mutex);
COMPAT_pthread_mutex_lock(&mosq->msgtime_mutex);
mosq->last_msg_in = mosquitto_time();
pthread_mutex_unlock(&mosq->msgtime_mutex);
COMPAT_pthread_mutex_unlock(&mosq->msgtime_mutex);
#endif
return rc;
}
+28
View File
@@ -0,0 +1,28 @@
#ifndef PTHREAD_COMPAT_
#define PTHREAD_COMPAT_
#if defined(WITH_THREADING) && !defined(WITH_BROKER)
# include <pthread.h>
# define COMPAT_pthread_create(A, B, C, D) pthread_create((A), (B), (C), (D))
# define COMPAT_pthread_join(A, B) pthread_join((A), (B))
# define COMPAT_pthread_cancel(A) pthread_cancel((A))
# define COMPAT_pthread_testcancel() pthread_testcancel()
# define COMPAT_pthread_mutex_init(A, B) pthread_mutex_init((A), (B))
# define COMPAT_pthread_mutex_destroy(A) pthread_mutex_init((A))
# define COMPAT_pthread_mutex_lock(A) pthread_mutex_lock((A))
# define COMPAT_pthread_mutex_unlock(A) pthread_mutex_unlock((A))
#else
# define COMPAT_pthread_create(A, B, C, D)
# define COMPAT_pthread_join(A, B)
# define COMPAT_pthread_cancel(A)
# define COMPAT_pthread_testcancel()
# define COMPAT_pthread_mutex_init(A, B)
# define COMPAT_pthread_mutex_destroy(A)
# define COMPAT_pthread_mutex_lock(A)
# define COMPAT_pthread_mutex_unlock(A)
#endif
#endif
+14 -14
View File
@@ -87,10 +87,10 @@ int mosquitto__check_keepalive(struct mosquitto *mosq)
return MOSQ_ERR_SUCCESS;
}
#endif
pthread_mutex_lock(&mosq->msgtime_mutex);
COMPAT_pthread_mutex_lock(&mosq->msgtime_mutex);
next_msg_out = mosq->next_msg_out;
last_msg_in = mosq->last_msg_in;
pthread_mutex_unlock(&mosq->msgtime_mutex);
COMPAT_pthread_mutex_unlock(&mosq->msgtime_mutex);
if(mosq->keepalive && net__is_connected(mosq) &&
(now >= next_msg_out || now - last_msg_in >= mosq->keepalive)){
@@ -98,10 +98,10 @@ int mosquitto__check_keepalive(struct mosquitto *mosq)
if(state == mosq_cs_active && mosq->ping_t == 0){
send__pingreq(mosq);
/* Reset last msg times to give the server time to send a pingresp */
pthread_mutex_lock(&mosq->msgtime_mutex);
COMPAT_pthread_mutex_lock(&mosq->msgtime_mutex);
mosq->last_msg_in = now;
mosq->next_msg_out = now + mosq->keepalive;
pthread_mutex_unlock(&mosq->msgtime_mutex);
COMPAT_pthread_mutex_unlock(&mosq->msgtime_mutex);
}else{
#ifdef WITH_BROKER
# ifdef WITH_BRIDGE
@@ -139,11 +139,11 @@ uint16_t mosquitto__mid_generate(struct mosquitto *mosq)
uint16_t mid;
assert(mosq);
pthread_mutex_lock(&mosq->mid_mutex);
COMPAT_pthread_mutex_lock(&mosq->mid_mutex);
mosq->last_mid++;
if(mosq->last_mid == 0) mosq->last_mid++;
mid = mosq->last_mid;
pthread_mutex_unlock(&mosq->mid_mutex);
COMPAT_pthread_mutex_unlock(&mosq->mid_mutex);
return mid;
}
@@ -235,14 +235,14 @@ void util__decrement_send_quota(struct mosquitto *mosq)
int mosquitto__set_state(struct mosquitto *mosq, enum mosquitto_client_state state)
{
pthread_mutex_lock(&mosq->state_mutex);
COMPAT_pthread_mutex_lock(&mosq->state_mutex);
#ifdef WITH_BROKER
if(mosq->state != mosq_cs_disused)
#endif
{
mosq->state = state;
}
pthread_mutex_unlock(&mosq->state_mutex);
COMPAT_pthread_mutex_unlock(&mosq->state_mutex);
return MOSQ_ERR_SUCCESS;
}
@@ -251,9 +251,9 @@ enum mosquitto_client_state mosquitto__get_state(struct mosquitto *mosq)
{
enum mosquitto_client_state state;
pthread_mutex_lock(&mosq->state_mutex);
COMPAT_pthread_mutex_lock(&mosq->state_mutex);
state = mosq->state;
pthread_mutex_unlock(&mosq->state_mutex);
COMPAT_pthread_mutex_unlock(&mosq->state_mutex);
return state;
}
@@ -261,18 +261,18 @@ enum mosquitto_client_state mosquitto__get_state(struct mosquitto *mosq)
#ifndef WITH_BROKER
void mosquitto__set_request_disconnect(struct mosquitto *mosq, bool request_disconnect)
{
pthread_mutex_lock(&mosq->state_mutex);
COMPAT_pthread_mutex_lock(&mosq->state_mutex);
mosq->request_disconnect = request_disconnect;
pthread_mutex_unlock(&mosq->state_mutex);
COMPAT_pthread_mutex_unlock(&mosq->state_mutex);
}
bool mosquitto__get_request_disconnect(struct mosquitto *mosq)
{
bool request_disconnect;
pthread_mutex_lock(&mosq->state_mutex);
COMPAT_pthread_mutex_lock(&mosq->state_mutex);
request_disconnect = mosq->request_disconnect;
pthread_mutex_unlock(&mosq->state_mutex);
COMPAT_pthread_mutex_unlock(&mosq->state_mutex);
return request_disconnect;
}
+8 -1
View File
@@ -66,24 +66,31 @@ FILE *mosquitto_fopen(const char *path, const char *mode, bool restrict_read)
DWORD ulen = UNLEN;
SECURITY_DESCRIPTOR sd;
DWORD dwCreationDisposition;
DWORD dwShareMode;
int fd;
FILE *fptr;
switch(mode[0]){
case 'a':
dwCreationDisposition = OPEN_ALWAYS;
dwShareMode = GENERIC_WRITE;
flags = _O_APPEND;
break;
case 'r':
dwCreationDisposition = OPEN_EXISTING;
dwShareMode = GENERIC_READ;
flags = _O_RDONLY;
break;
case 'w':
dwCreationDisposition = CREATE_ALWAYS;
dwShareMode = GENERIC_WRITE;
break;
default:
return NULL;
}
if(mode[1] == '+'){
dwShareMode = GENERIC_READ | GENERIC_WRITE;
}
GetUserNameA(username, &ulen);
if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)){
@@ -103,7 +110,7 @@ FILE *mosquitto_fopen(const char *path, const char *mode, bool restrict_read)
sec.bInheritHandle = FALSE;
sec.lpSecurityDescriptor = &sd;
hfile = CreateFileA(buf, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
hfile = CreateFileA(buf, dwShareMode, FILE_SHARE_READ,
&sec,
dwCreationDisposition,
FILE_ATTRIBUTE_NORMAL,
+6 -4
View File
@@ -56,8 +56,7 @@ void mosquitto_property_free(mosquitto_property **property)
break;
}
mosquitto_free(*property);
*property = NULL;
mosquitto_FREE(*property);
}
@@ -652,6 +651,10 @@ BROKER_EXPORT int mosquitto_property_check_all(int command, const mosquitto_prop
if(p->value.i16 == 0){
return MOSQ_ERR_PROTOCOL;
}
}else if(p->identifier == MQTT_PROP_RESPONSE_TOPIC){
if(mosquitto_pub_topic_check(p->value.s.v) != MOSQ_ERR_SUCCESS){
return MOSQ_ERR_PROTOCOL;
}
}
/* Check for properties on incorrect commands */
@@ -892,8 +895,7 @@ BROKER_EXPORT const mosquitto_property *mosquitto_property_read_string_pair(cons
*value = mosquitto_calloc(1, (size_t)p->value.s.len+1);
if(!(*value)){
if(name){
mosquitto_free(*name);
*name = NULL;
mosquitto_FREE(*name);
}
return NULL;
}
+9 -1
View File
@@ -103,6 +103,8 @@ const char *mosquitto_strerror(int mosq_errno)
return "Entry already exists";
case MOSQ_ERR_PLUGIN_IGNORE:
return "Ignore plugin";
case MOSQ_ERR_HTTP_BAD_ORIGIN:
return "Bad http origin";
case MOSQ_ERR_UNSPECIFIED:
return "Unspecified error";
@@ -133,7 +135,13 @@ const char *mosquitto_strerror(int mosq_errno)
case MOSQ_ERR_CONNECTION_RATE_EXCEEDED:
return "Connection rate exceeded";
default:
return "Unknown error";
if(mosq_errno >= 128) {
// If mosq_errno is greater than 127,
// a mqtt5_return_code error was used
return mosquitto_reason_string(mosq_errno);
} else {
return "Unknown error";
}
}
}
+25 -6
View File
@@ -36,6 +36,27 @@ Contributors:
#include "mosquitto.h"
#if _POSIX_TIMERS>0 && defined(_POSIX_MONOTONIC_CLOCK)
static clockid_t time_clock = CLOCK_MONOTONIC;
#endif
void mosquitto_time_init(void)
{
#if _POSIX_TIMERS>0 && defined(_POSIX_MONOTONIC_CLOCK)
struct timespec tp;
#ifdef CLOCK_BOOTTIME
if (clock_gettime(CLOCK_BOOTTIME, &tp) == 0) {
time_clock = CLOCK_BOOTTIME;
} else {
time_clock = CLOCK_MONOTONIC;
}
#else
time_clock = CLOCK_MONOTONIC;
#endif
#endif
}
time_t mosquitto_time(void)
{
#ifdef WIN32
@@ -43,12 +64,10 @@ time_t mosquitto_time(void)
#elif _POSIX_TIMERS>0 && defined(_POSIX_MONOTONIC_CLOCK)
struct timespec tp;
#ifdef CLOCK_BOOTTIME
clock_gettime(CLOCK_BOOTTIME, &tp);
#else
clock_gettime(CLOCK_MONOTONIC, &tp);
#endif
return tp.tv_sec;
if (clock_gettime(time_clock, &tp) == 0)
return tp.tv_sec;
return (time_t) -1;
#elif defined(__APPLE__)
static mach_timebase_info_data_t tb;
uint64_t ticks;
+1 -1
View File
@@ -91,7 +91,7 @@
</member>
<member>
<citerefentry>
<refentrytitle><link xlink:href="mosquitto-conf-5.html">mosquitto-conf</link></refentrytitle>
<refentrytitle><link xlink:href="mosquitto-conf-5.html">mosquitto.conf</link></refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>
</member>
+2
View File
@@ -15,3 +15,5 @@ sed -i "s/^set (VERSION .*)/set (VERSION ${MAJOR}.${MINOR}.${REVISION})/" CMakeL
sed -i "s/^!define VERSION .*/!define VERSION ${MAJOR}.${MINOR}.${REVISION}/" installer/*.nsi
sed -i "s/^version: .*/version: ${MAJOR}.${MINOR}.${REVISION}/" snap/snapcraft.yaml
sed -i "s/\"version-string\": \".*\",/\"version-string\": \"${MAJOR}.${MINOR}.${REVISION}\",/" vcpkg.json
+6 -1
View File
@@ -128,7 +128,12 @@ static struct mosquitto *bridge__new(struct mosquitto__bridge *bridge)
new_context->protocol = bridge->protocol_version;
if(!bridge->clean_start_local){
new_context->session_expiry_interval = UINT32_MAX;
plugin_persist__handle_client_add(new_context);
plugin_persist__handle_client_add(new_context);
if(new_context->expiry_list_item){
/* We've restored from persistence and been added to the session
* expiry list, even though we should never be expired */
session_expiry__remove(new_context);
}
}
bridges = mosquitto_realloc(db.bridges, (size_t)(db.bridge_count+1)*sizeof(struct mosquitto *));
+18 -11
View File
@@ -195,12 +195,16 @@ int db__open(struct mosquitto__config *config)
/* Initialize the hashtable */
db.clientid_index_hash = NULL;
db.subs = NULL;
db.normal_subs = NULL;
db.shared_subs = NULL;
subhier = sub__add_hier_entry(NULL, &db.subs, "", 0);
subhier = sub__add_hier_entry(NULL, &db.shared_subs, "", 0);
if(!subhier) return MOSQ_ERR_NOMEM;
subhier = sub__add_hier_entry(NULL, &db.subs, "$SYS", (uint16_t)strlen("$SYS"));
subhier = sub__add_hier_entry(NULL, &db.normal_subs, "", 0);
if(!subhier) return MOSQ_ERR_NOMEM;
subhier = sub__add_hier_entry(NULL, &db.normal_subs, "$SYS", (uint16_t)strlen("$SYS"));
if(!subhier) return MOSQ_ERR_NOMEM;
retain__init();
@@ -235,7 +239,8 @@ static void subhier_clean(struct mosquitto__subhier **subhier)
int db__close(void)
{
subhier_clean(&db.subs);
subhier_clean(&db.normal_subs);
subhier_clean(&db.shared_subs);
retain__clean(&db.retains);
db__msg_store_clean();
@@ -817,14 +822,16 @@ int db__messages_easy_queue(struct mosquitto *context, const char *topic, uint8_
}
base_msg->data.payloadlen = payloadlen;
base_msg->data.payload = mosquitto_malloc(base_msg->data.payloadlen+1);
if(base_msg->data.payload == NULL){
db__msg_store_free(base_msg);
return MOSQ_ERR_NOMEM;
if(payloadlen > 0){
base_msg->data.payload = mosquitto_malloc(base_msg->data.payloadlen+1);
if(base_msg->data.payload == NULL){
db__msg_store_free(base_msg);
return MOSQ_ERR_NOMEM;
}
/* Ensure payload is always zero terminated, this is the reason for the extra byte above */
((uint8_t *)base_msg->data.payload)[base_msg->data.payloadlen] = 0;
memcpy(base_msg->data.payload, payload, base_msg->data.payloadlen);
}
/* Ensure payload is always zero terminated, this is the reason for the extra byte above */
((uint8_t *)base_msg->data.payload)[base_msg->data.payloadlen] = 0;
memcpy(base_msg->data.payload, payload, base_msg->data.payloadlen);
if(context && context->id){
source_id = context->id;
+5
View File
@@ -139,6 +139,11 @@ int handle__subscribe(struct mosquitto *context)
qos = sub.options & 0x03;
sub.options &= 0xFC;
if(MQTT_SUB_OPT_GET_NO_LOCAL(sub.options) && !strncmp(sub.topic_filter, "$share/", 7)){
mosquitto_FREE(sub.topic_filter);
mosquitto_FREE(payload);
return MOSQ_ERR_PROTOCOL;
}
retain_handling = MQTT_SUB_OPT_GET_SEND_RETAIN(sub.options);
if(retain_handling == 0x30 || (sub.options & 0xC0) != 0){
mosquitto_FREE(sub.topic_filter);
+2 -1
View File
@@ -467,7 +467,8 @@ struct mosquitto__message_v5{
struct mosquitto_db{
dbid_t last_db_id;
uint64_t node_id_shifted;
struct mosquitto__subhier *subs;
struct mosquitto__subhier *normal_subs;
struct mosquitto__subhier *shared_subs;
struct mosquitto__retainhier *retains;
struct mosquitto *contexts_by_id;
struct mosquitto *contexts_by_sock;
+7 -1
View File
@@ -260,7 +260,13 @@ static int persist__subs_save_all(FILE *db_fptr)
{
struct mosquitto__subhier *subhier, *subhier_tmp;
HASH_ITER(hh, db.subs, subhier, subhier_tmp){
HASH_ITER(hh, db.normal_subs, subhier, subhier_tmp){
if(subhier->children){
persist__subs_save(db_fptr, subhier->children, "", 0);
}
}
HASH_ITER(hh, db.shared_subs, subhier, subhier_tmp){
if(subhier->children){
persist__subs_save(db_fptr, subhier->children, "", 0);
}
+2 -1
View File
@@ -119,7 +119,8 @@ void signal__flag_check(void)
flag_reload = false;
}
if(flag_tree_print){
sub__tree_print(db.subs, 0);
sub__tree_print(db.normal_subs, 0);
sub__tree_print(db.shared_subs, 0);
flag_tree_print = false;
#ifdef WITH_XTREPORT
xtreport();
+48 -12
View File
@@ -565,16 +565,29 @@ int sub__add(struct mosquitto *context, const struct mosquitto_subscription *sub
mosquitto_FREE(topics);
return MOSQ_ERR_INVAL;
}
HASH_FIND(hh, db.subs, topics[0], topiclen, subhier);
if(!subhier){
subhier = sub__add_hier_entry(NULL, &db.subs, topics[0], (uint16_t)topiclen);
if(!subhier){
mosquitto_FREE(local_sub);
mosquitto_FREE(topics);
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
return MOSQ_ERR_NOMEM;
}
if(sharename){
HASH_FIND(hh, db.shared_subs, topics[0], topiclen, subhier);
if(!subhier){
subhier = sub__add_hier_entry(NULL, &db.shared_subs, topics[0], (uint16_t)topiclen);
if(!subhier){
mosquitto_FREE(local_sub);
mosquitto_FREE(topics);
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
return MOSQ_ERR_NOMEM;
}
}
}else{
HASH_FIND(hh, db.normal_subs, topics[0], topiclen, subhier);
if(!subhier){
subhier = sub__add_hier_entry(NULL, &db.normal_subs, topics[0], (uint16_t)topiclen);
if(!subhier){
mosquitto_FREE(local_sub);
mosquitto_FREE(topics);
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
return MOSQ_ERR_NOMEM;
}
}
}
rc = sub__add_context(context, sub, subhier, topics, sharename);
@@ -597,7 +610,11 @@ int sub__remove(struct mosquitto *context, const char *sub, uint8_t *reason)
rc = sub__topic_tokenise(sub, &local_sub, &topics, &sharename);
if(rc) return rc;
HASH_FIND(hh, db.subs, topics[0], strlen(topics[0]), subhier);
if(sharename){
HASH_FIND(hh, db.shared_subs, topics[0], strlen(topics[0]), subhier);
}else{
HASH_FIND(hh, db.normal_subs, topics[0], strlen(topics[0]), subhier);
}
if(subhier){
*reason = MQTT_RC_NO_SUBSCRIPTION_EXISTED;
rc = sub__remove_recurse(context, subhier, topics, reason, sharename);
@@ -612,6 +629,7 @@ int sub__remove(struct mosquitto *context, const char *sub, uint8_t *reason)
int sub__messages_queue(const char *source_id, const char *topic, uint8_t qos, int retain, struct mosquitto__base_msg **stored)
{
int rc = MOSQ_ERR_SUCCESS, rc2;
int rc_normal = MOSQ_ERR_NO_SUBSCRIBERS, rc_shared = MOSQ_ERR_NO_SUBSCRIBERS;
struct mosquitto__subhier *subhier;
char **split_topics = NULL;
char *local_topic = NULL;
@@ -626,9 +644,26 @@ int sub__messages_queue(const char *source_id, const char *topic, uint8_t qos, i
*/
db__msg_store_ref_inc(*stored);
HASH_FIND(hh, db.subs, split_topics[0], strlen(split_topics[0]), subhier);
HASH_FIND(hh, db.normal_subs, split_topics[0], strlen(split_topics[0]), subhier);
if(subhier){
rc = sub__search(subhier, split_topics, source_id, topic, qos, retain, *stored);
rc_normal = sub__search(subhier, split_topics, source_id, topic, qos, retain, *stored);
if(rc_normal > 0){
rc = rc_normal;
goto end;
}
}
HASH_FIND(hh, db.shared_subs, split_topics[0], strlen(split_topics[0]), subhier);
if(subhier){
rc_shared = sub__search(subhier, split_topics, source_id, topic, qos, retain, *stored);
if(rc_shared > 0){
rc = rc_shared;
goto end;
}
}
if(rc_normal == MOSQ_ERR_NO_SUBSCRIBERS && rc_shared == MOSQ_ERR_NO_SUBSCRIBERS){
rc = MOSQ_ERR_NO_SUBSCRIBERS;
}
if(retain){
@@ -636,6 +671,7 @@ int sub__messages_queue(const char *source_id, const char *topic, uint8_t qos, i
if(rc2) rc = rc2;
}
end:
mosquitto_FREE(split_topics);
mosquitto_FREE(local_topic);
/* Remove our reference and free if needed. */
+1 -1
View File
@@ -95,7 +95,7 @@ int sub__topic_tokenise(const char *subtopic, char **local_sub, char ***topics,
}
if(!strcmp((*topics)[0], "$share")){
if(count < 2){
if(count < 3 || (count == 3 && strlen((*topics)[2]) == 0)){
mosquitto_FREE(*local_sub);
mosquitto_FREE(*topics);
return MOSQ_ERR_PROTOCOL;
+107
View File
@@ -0,0 +1,107 @@
#!/usr/bin/env python3
# Does a bridge resend a QoS=1 message correctly after a disconnect?
from mosq_test_helper import *
def write_config(filename, port1, port2):
with open(filename, 'w') as f:
f.write(f"listener {port2}\n")
f.write("allow_anonymous true\n")
f.write("connection bridge1\n")
f.write(f"address 127.0.0.1:{port1}\n")
f.write("topic room1/# both 2 sensor/ myhouse/\n")
f.write("topic tst/ba both 2\n")
f.write("topic # both 2\n")
f.write("keepalive_interval 600\n")
f.write("remote_clientid mosquitto\n")
f.write("bridge_protocol_version mqttv50\n")
f.write("notifications false\n")
def do_test(proto_ver):
(port1, port2) = mosq_test.get_port(2)
conf_file = os.path.basename(__file__).replace('.py', '.conf')
write_config(conf_file, port1, port2)
rc = 1
keepalive = 600
client_id = "mosquitto"
properties = mqtt5_props.gen_uint16_prop(mqtt5_props.PROP_TOPIC_ALIAS_MAXIMUM, 10)
properties += mqtt5_props.gen_uint16_prop(mqtt5_props.PROP_RECEIVE_MAXIMUM, 20)
connect_packet = mosq_test.gen_connect(client_id, keepalive=keepalive, clean_session=False, proto_ver=proto_ver, properties=properties)
connack_packet = mosq_test.gen_connack(rc=0, proto_ver=proto_ver)
if proto_ver == 5:
opts = mqtt5_opts.MQTT_SUB_OPT_NO_LOCAL | mqtt5_opts.MQTT_SUB_OPT_RETAIN_AS_PUBLISHED
else:
opts = 0
mid = 1
subscribe_packet = mosq_test.gen_subscribe(mid, "myhouse/room1/#", 2 | opts, proto_ver=proto_ver)
suback_packet = mosq_test.gen_suback(mid, 2, proto_ver=proto_ver)
mid = 2
subscribe_packet2 = mosq_test.gen_subscribe(mid, "tst/ba", 2 | opts, proto_ver=proto_ver)
suback_packet2= mosq_test.gen_suback(mid, 2, proto_ver=proto_ver)
mid = 3
subscribe_packet3 = mosq_test.gen_subscribe(mid, "#", 2 | opts, proto_ver=proto_ver)
suback_packet3 = mosq_test.gen_suback(mid, 2, proto_ver=proto_ver)
ssock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
ssock.settimeout(40)
ssock.bind(('', port1))
ssock.listen(5)
broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port2, use_conf=True)
try:
(bridge, address) = ssock.accept()
bridge.settimeout(20)
mosq_test.expect_packet(bridge, "connect", connect_packet)
bridge.send(connack_packet)
mosq_test.expect_packet(bridge, "subscribe1", subscribe_packet)
bridge.send(suback_packet)
mosq_test.expect_packet(bridge, "subscribe2", subscribe_packet2)
bridge.send(suback_packet2)
mosq_test.expect_packet(bridge, "subscribe3", subscribe_packet3)
bridge.send(suback_packet3)
try:
bridge.send(bytes.fromhex("320c00062b2b2b2b2b2b00040033"))
#bridge.send(bytes.fromhex("320c00062b2b2b2b2b2b00040033"))
#bridge.send(bytes.fromhex("320c00062b2b2b2b2b2b00040033"))
mosq_test.do_ping(bridge)
except ConnectionResetError:
#expected behaviour
rc = 0
bridge.close()
except mosq_test.TestError:
pass
except Exception as e:
print(e)
finally:
os.remove(conf_file)
try:
bridge.close()
except NameError:
pass
broker.terminate()
broker.wait()
(stdo, stde) = broker.communicate()
ssock.close()
if rc:
print(stde.decode('utf-8'))
exit(rc)
do_test(proto_ver=5)
exit(0)
+6 -11
View File
@@ -56,17 +56,14 @@ try:
mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback")
pub = subprocess.Popen(['./c/08-tls-psk-bridge.test', str(port3)], env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
pub_terminate_rc = 0
if mosq_test.wait_for_subprocess(pub):
print("pub not terminated")
pub_terminate_rc = 1
pub = subprocess.run(['./c/08-tls-psk-bridge.test', str(port3)], env=env, capture_output=True, encoding='utf-8')
if pub.returncode != 0:
print("d")
print(pub.returncode)
raise ValueError
(stdo, stde) = pub.communicate()
mosq_test.expect_packet(sock, "publish", publish_packet)
rc = pub_terminate_rc
rc = pub.returncode
sock.close()
except mosq_test.TestError:
@@ -74,12 +71,10 @@ except mosq_test.TestError:
finally:
os.remove(conf_file1)
os.remove(conf_file2)
time.sleep(1)
broker.terminate()
if mosq_test.wait_for_subprocess(broker):
print("broker not terminated")
if rc == 0: rc=1
time.sleep(1)
bridge.terminate()
if mosq_test.wait_for_subprocess(bridge):
print("bridge not terminated")
@@ -90,8 +85,8 @@ finally:
(stdo, stde) = bridge.communicate()
print(stde.decode('utf-8'))
if pub:
(stdo, stde) = pub.communicate()
print(stdo.decode('utf-8'))
print(pub.stdout)
print(pub.stderr)
exit(rc)
+1
View File
@@ -137,6 +137,7 @@ msg_sequence_test:
./06-bridge-reconnect-local-out.py
./06-bridge-remote-shutdown.py
./06-bridge-config-reload.py
./06-bridge-remap-receive-wildcard.py
07 :
./07-will-control.py
+1
View File
@@ -75,6 +75,7 @@ int main(int argc, char *argv[])
mosquitto_loop(mosq, -1, 1);
}
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return run;
}
+4 -4
View File
@@ -45,8 +45,8 @@
{"type":"recv", "payload":"20 02 00 00", "comment": "CONNACK"},
{"type":"send", "payload":"10 0D 0004 4D515454 04 02 000A 0001 70", "comment":"minimal valid CONNECT"}
]},
{ "name": "10 missing client ID", "msgs":[{"type":"send", "payload":"10 08 0004 4D515454 04 02 000A"}]},
{ "name": "10 empty client ID", "expect_disconnect":false, "msgs":[
{ "name": "10 missing client ID", "connect":false, "msgs":[{"type":"send", "payload":"10 0A 0004 4D515454 04 02 000A"}]},
{ "name": "10 empty client ID", "connect":false, "expect_disconnect":false, "msgs":[
{"type":"send", "payload":"10 0C 0004 4D515454 04 02 000A 0000", "comment":"CONNECT clean session true, no client id"},
{"type":"recv", "payload":"20 02 00 00", "comment": "CONNACK"}
]},
@@ -758,9 +758,9 @@
{"type":"send", "payload":"10 16 0004 4D515454 05 06 000A 00 0001 70 01 08 0001 70 0001 70"},
{"type":"recv", "payload":"20 03 00 81 00"}
]},
{ "name": "response-topic (UTF-8 string) empty", "expect_disconnect":false, "msgs":[
{ "name": "response-topic (UTF-8 string) empty", "msgs":[
{"type":"send", "payload":"10 18 0004 4D515454 05 06 000A 00 0001 70 03 08 0000 0001 70 0001 70"},
{"type":"recv", "payload":"20 09 00 00 06 22000A 210014", "comment": "CONNACK"}
{"type":"recv", "payload":"20 03 00 82 00", "comment": "CONNACK"}
]},
{ "name": "correlation-data (binary)", "expect_disconnect":false, "msgs":[
+7 -3
View File
@@ -182,7 +182,7 @@
{"type":"recv", "payload":"40 03 1234 10"}
]},
{ "name": "2*message-expiry-interval=1 (four byte integer)", "msgs": [
{"type":"send", "payload":"32 1A 0005 746F706963 1234 0A 0200000001 0200000001 7061796C6F6164"},
{"type":"send", "payload":"32 1B 0005 746F706963 1234 0A 0200000001 0200000001 7061796C6F6164"},
{"type":"recv", "payload":"E0 01 82"}
]},
{ "name": "message-expiry-interval (four byte integer) missing", "msgs": [
@@ -215,6 +215,10 @@
{"type":"send", "payload":"32 15 0005 746F706963 1234 04 08000170 7061796C6F6164"},
{"type":"recv", "payload":"40 03 1234 10"}
]},
{ "name": "response-topic (UTF-8 string, with wildcard)", "ver":5, "msgs": [
{"type":"send", "payload":"32 15 0005 746F706963 1234 04 08000123 7061796C6F6164"},
{"type":"recv", "payload":"E0 01 82"}
]},
{ "name": "2*response-topic (UTF-8 string)", "msgs": [
{"type":"send", "payload":"32 19 0005 746F706963 1234 08 08000170 08000170 7061796C6F6164"},
{"type":"recv", "payload":"E0 01 82"}
@@ -223,9 +227,9 @@
{"type":"send", "payload":"32 12 0005 746F706963 1234 01 08 7061796C6F6164"},
{"type":"recv", "payload":"E0 01 81"}
]},
{ "name": "response-topic (UTF-8 string) empty", "expect_disconnect":false, "msgs": [
{ "name": "response-topic (UTF-8 string) empty", "msgs": [
{"type":"send", "payload":"32 14 0005 746F706963 1234 03 080000 7061796C6F6164"},
{"type":"recv", "payload":"40 03 1234 10"}
{"type":"recv", "payload":"E0 01 82"}
]},
{ "name": "correlation-data (binary data)", "expect_disconnect":false, "msgs": [

Some files were not shown because too many files have changed in this diff Show More