Compare commits

...

52 Commits

Author SHA1 Message Date
Roger A. Light 269756a171 Fix high CPU use on slow TLS connect.
Closes #2794. Thanks to Evgeny S.
2 years ago
Roger A. Light 3c51816009 Fix leak on error. 2 years ago
Roger A. Light 6d240a9d18 Fix bridges being expired after being restored.
This occurred with non-matching cleansession/local_cleansession being
expired on start after restoring from persistence.

Closes #2634. Thanks to everyone on the issue.
3 years ago
Roger A. Light 3b2f3c6d8a Windows: Increase connection limit to 8192 where supported.
Closes #2732. Thanks to zhousongsong.
3 years ago
Roger A. Light 4f9c5567ba Fix example plugin incorrect callback unregister.
Closes #2673. Thanks to Karl Palsson.
3 years ago
Roger A. Light 655f9e58b7 Update blog post with non-expired Lets Encrypt root.
Closes #2692. Thanks to Matt Turner.
3 years ago
Roger A. Light 5a748806d3 Default to max keepalive 0. 3 years ago
Roger A. Light cc97f433c1 Use line buffered mode for stdout.
Closes #2354.
Closes #2749.
3 years ago
Roger A. Light 1bf753e773 Fix confusing message on TLS certificate verification.
Closes #2746. Thanks to Akos Vandra-Meyer.
3 years ago
Roger A. Light 1195dd991e Clearer len calculation. 3 years ago
Roger Light ec6a56d759
Merge pull request #2734 from axos88/patch-1
Fix malloc size for file path
3 years ago
Roger A. Light 63da7472b5 Fix default settings incorrectly allowing TLS v1.1.
Closes #2722. Thanks to KramNamez.
3 years ago
Roger Light 5cae46d26d
Merge pull request #2745 from Hyeongon-Kim/fix-load-priv-key-file
fixed a bug where broker's private-key file was not loaded
3 years ago
Roger A. Light 7e35ac92ec Update changelog 3 years ago
Roger A. Light a991a8373f Merge branch 'Daedaluz-fixes' into fixes 3 years ago
Roger A. Light 6f61710fa7 Merge branch 'fixes' of github.com:Daedaluz/mosquitto into Daedaluz-fixes 3 years ago
Roger A. Light 103253deda Windows build for fixes branch. 3 years ago
Roger A. Light 28a39e62ff Remove unused header. 3 years ago
Tobias Assarsson 2e2a420099 use CLOCK_BOOTTIME when available.
Signed-off-by: Tobias Assarsson <tobias.assarsson@gmail.com>
3 years ago
Hyeongon Kim 19fbfee791 fixed a bug where broker's private-key file was not loaded
fixed a bug where the mosquitto-broker's private-key file(.pem)
dose not load with tls-engine.

Signed-off-by: Hyeongon Kim <khyeongon@gmail.com>
3 years ago
Akos Vandra-Meyer e0d8ef20fa
Fix malloc size for file path
We need 4 more characters to store the suffix.
3 years ago
Roger A. Light a6347cd7d2 Fix Coverity Scan 1501449. 3 years ago
Roger A. Light 48f276f88d Fix multiple domains in renewal. 3 years ago
Roger A. Light 0fb4e2bf6a Fix incorrect topic-alias property value in mosquitto_sub json output. 3 years ago
Roger A. Light 62b68364c7 Fix std* files not being redirected when daemonising
This could occur when built with assertions removed.

Closes #2708. Thanks to ckoehne.
3 years ago
Roger A. Light ec173fffe8 Merge branch 'podsvirov-make-man' into fixes 3 years ago
Roger A. Light c77fa4c089 Merge branch 'make-man' of https://github.com/podsvirov/mosquitto into podsvirov-make-man 3 years ago
Roger Light a54e5e3abc
Merge pull request #2689 from zivillian/patch-1
fix example JSON
3 years ago
Roger Light 80a4063bb4
Merge pull request #2683 from guillaumepellegrino/fixes_memleak
Fix memory leak in mosquitto_tls_opts_set()
3 years ago
Roger Light ed5a39dd93
Merge pull request #2690 from ronybc/patch-1
Removed repeated line
3 years ago
Roger Light 55e448e38d
Merge pull request #2699 from rswindell/include_inttypes
Fix build error: expected ‘)’ before ‘PRIu64’
3 years ago
Roger A. Light 06d5835270 Add more WITH_BROKER guards. 3 years ago
Rob Swindell 7ff744d60d Fix build error: expected ‘)’ before ‘PRIu64’
system with 'make WITH_TLS=no WITH_CJSON=no WITH_DOCS=no'

Signed-off-by: Rob Swindell <rob@synchro.net>
3 years ago
Roger A. Light 8285a57bb9 Fix some error handling related to the `bind_interface` option. 3 years ago
Roger A. Light c06599fab2 Fix some retained topic memory not being cleared immediately after used. 3 years ago
zivillian a562c93079 fix example JSON
Signed-off-by: zivillian <devel@zivillian.de>
3 years ago
Rony B Chandran d1cdaec963
Removed repeated line
<listitem><para><option>%I</option> ISO-8601 format date and time, e.g. 2016-08-10T09:47:38+0100</para></listitem>
3 years ago
Guillaume PELLEGRINO 9018f12dfc Fix memory leak in mosquitto_tls_opts_set()
When calling mosquitto_tls_opts_set() multiple time in a row
on the same mosquitto context (Example: trying to reconnect
to mqtt broker), some of the tls options are not free, resulting in a memory leak.

The TLS options (tls_version, tls_ciphers) must be free before being set.

Signed-off-by: Guillaume PELLEGRINO <guillaume.pellegrino@yahoo.com>
3 years ago
Roger Light 7ff2198c7d
Merge pull request #2648 from impulsdampf22/fixes
Fixed empty string crash in mosquitto_property_copy_all
3 years ago
Roger A. Light 0cee0d1d11 Fix Coverity Scan 1486944 (backport from develop) 3 years ago
Roger Light db114fa1d3
Merge pull request #2614 from HashimJVZ/patch-1
Correct a wrong example
3 years ago
Roger Light d4e69c41bf
Merge pull request #2621 from CastleOnTheHill/master
Fix comments errors, it is the client that sends PING to broker actively
3 years ago
Alexander Fiebig 28416da47a Fixed empty string crash in mosquitto_property_copy_all
Signed-off-by: Alexander Fiebig <alex.fiebig@online.de>
3 years ago
Roger A. Light 5c3c5d779f Fix Coverity 1486949 3 years ago
Roger A. Light f44d8fad50 Fix Coverity 1491742 and 1491741 3 years ago
Roger A. Light e22030bb2c Try to convince Coverity this string is terminated. 3 years ago
Arvin dcad2e410a Fix comments errors, it is the client that sends PING to broker actively 3 years ago
Roger A. Light 86fffa34a9 Fix $SYS messages being expired after 60 seconds
and hence unchanged values disappearing. Thanks to Wim Nelis and
Christoph Krey.
3 years ago
Roger A. Light ef44b22cef Fix local bridge session expiry interval. 3 years ago
Roger A. Light 1af3152ddc Fix persisted clients being restored without a session expiry time. 3 years ago
Muhammed Hashim b3e26c21d7
Correct a wrong example
mosquitto_ctrl example for setClientId was provided with wrong example (duplicate of setClientPassword).
3 years ago
Konstantin Podsvirov 0de3f3a3f7 Allow to build man pages on Windows
Why not if xsltproc available?
Moreover why try to install not existent files?

Signed-off-by: Konstantin Podsvirov <konstantin@podsvirov.pro>
4 years ago

@ -0,0 +1,81 @@
name: Windows build
on:
workflow_dispatch:
push:
branches: [ "master", "fixes" ]
tags: [ "v[0-9]+.*" ]
pull_request:
branches: [ "master", "fixes" ]
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
jobs:
cjson:
runs-on: windows-2022
steps:
- uses: actions/checkout@v3
with:
repository: DaveGamble/cJSON
ref: v1.7.15
- name: Configure CMake cJSON
run: cmake -B ${{github.workspace}}/build64 -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DENABLE_CJSON_TEST=OFF -DBUILD_SHARED_LIBS=OFF -DBUILD_SHARED_AND_STATIC_LIBS=OFF -DCJSON_BUILD_SHARED_LIBS=OFF -DCJSON_OVERRIDE_BUILD_SHARED_LIBS=OFF -DCMAKE_GENERATOR_PLATFORM=x64
- name: Build cJSON
run: cmake --build ${{github.workspace}}/build64 --config ${{env.BUILD_TYPE}}
- name: Install cJSON
run: cmake --install ${{github.workspace}}/build64 --config ${{env.BUILD_TYPE}}
- name: Upload cJSON
uses: actions/upload-artifact@v3
with:
name: cjson-bin
path: C:\Program Files\cJSON
mosquitto:
runs-on: windows-2022
needs:
- cjson
env:
CJSON_DIR: C:\Program Files\cJSON
steps:
- uses: actions/checkout@v3
- name: install openssl
run: choco install openssl
- name: Download cJSON
uses: actions/download-artifact@v3
with:
name: cjson-bin
path: C:\Program Files\cJSON
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build64 -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DWITH_TESTS=OFF -DCMAKE_GENERATOR_PLATFORM=x64 -DCJSON_INCLUDE_DIR="C:/Program Files/cJSON/include" -DCJSON_LIBRARY="C:/Program Files/cJSON/lib/cjson.lib"
- name: Build
run: cmake --build ${{github.workspace}}/build64 --config ${{env.BUILD_TYPE}}
- uses: suisei-cn/actions-download-file@v1.0.1
id: vcredist
name: Download VC redistributable
with:
url: https://aka.ms/vs/17/release/vc_redist.x64.exe
target: ${{github.workspace}}/installer/
- name: Installer
uses: joncloud/makensis-action@v3.7
with:
script-file: ${{github.workspace}}/installer/mosquitto.nsi
- name: Upload installer to artifacts
uses: actions/upload-artifact/@v2
with:
name: installer
path: ${{ github.workspace }}/installer/mosquitto*.exe

@ -1,3 +1,29 @@
Broker:
- Fix $SYS messages being expired after 60 seconds and hence unchanged values
disappearing.
- Fix some retained topic memory not being cleared immediately after used.
- Fix error handling related to the `bind_interface` option.
- Fix std* files not being redirected when daemonising, when built with
assertions removed. Closes #2708.
- Fix default settings incorrectly allowing TLS v1.1. Closes #2722.
- Use line buffered mode for stdout. Closes #2354. Closes #2749.
- Fix bridges with non-matching cleansession/local_cleansession being expired
on start after restoring from persistence. Closes #2634.
- Fix connections being limited to 2048 on Windows. The limit is now 8192,
where supported. Closes #2732.
Client library:
- Use CLOCK_BOOTTIME when available, to keep track of time. This solves the
problem of the client OS sleeping and the client hence not being able to
calculate the actual time for keepalive purposes. Closes #2760.
- Fix default settings incorrectly allowing TLS v1.1. Closes #2722.
- Fix high CPU use on slow TLS connect. Closes #2794.
Clients:
- Fix incorrect topic-alias property value in mosquitto_sub json output.
- Fix confusing message on TLS certificate verification. Closes #2746.
2.0.15 - 2022-08-16
===================

@ -16,7 +16,6 @@ Contributors:
Roger Light - initial implementation and documentation.
*/
#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>

@ -210,7 +210,7 @@ static int json_print_properties(cJSON *root, const mosquitto_property *properti
break;
case MQTT_PROP_TOPIC_ALIAS:
mosquitto_property_read_int16(prop, MQTT_PROP_MESSAGE_EXPIRY_INTERVAL, &i16value, false);
mosquitto_property_read_int16(prop, MQTT_PROP_TOPIC_ALIAS, &i16value, false);
tmp = cJSON_CreateNumber(i16value);
break;

@ -497,8 +497,8 @@ libmosq_EXPORT int mosquitto_username_pw_set(struct mosquitto *mosq, const char
* mosq - a valid mosquitto instance.
* host - the hostname or ip address of the broker to connect to.
* port - the network port to connect to. Usually 1883.
* keepalive - the number of seconds after which the broker should send a PING
* message to the client if no other messages have been exchanged
* keepalive - the number of seconds after which the client should send a PING
* message to the broker if no other messages have been exchanged
* in that time.
*
* Returns:
@ -529,8 +529,8 @@ libmosq_EXPORT int mosquitto_connect(struct mosquitto *mosq, const char *host, i
* mosq - a valid mosquitto instance.
* host - the hostname or ip address of the broker to connect to.
* port - the network port to connect to. Usually 1883.
* keepalive - the number of seconds after which the broker should send a PING
* message to the client if no other messages have been exchanged
* keepalive - the number of seconds after which the client should send a PING
* message to the broker if no other messages have been exchanged
* in that time.
* bind_address - the hostname or ip address of the local network interface to
* bind to. If you do not want to bind to a specific interface,
@ -573,8 +573,8 @@ libmosq_EXPORT int mosquitto_connect_bind(struct mosquitto *mosq, const char *ho
* mosq - a valid mosquitto instance.
* host - the hostname or ip address of the broker to connect to.
* port - the network port to connect to. Usually 1883.
* keepalive - the number of seconds after which the broker should send a PING
* message to the client if no other messages have been exchanged
* keepalive - the number of seconds after which the client should send a PING
* message to the broker if no other messages have been exchanged
* in that time.
* bind_address - the hostname or ip address of the local network interface to
* bind to. If you do not want to bind to a specific interface,
@ -614,8 +614,8 @@ libmosq_EXPORT int mosquitto_connect_bind_v5(struct mosquitto *mosq, const char
* mosq - a valid mosquitto instance.
* host - the hostname or ip address of the broker to connect to.
* port - the network port to connect to. Usually 1883.
* keepalive - the number of seconds after which the broker should send a PING
* message to the client if no other messages have been exchanged
* keepalive - the number of seconds after which the client should send a PING
* message to the broker if no other messages have been exchanged
* in that time.
*
* Returns:
@ -649,8 +649,8 @@ libmosq_EXPORT int mosquitto_connect_async(struct mosquitto *mosq, const char *h
* mosq - a valid mosquitto instance.
* host - the hostname or ip address of the broker to connect to.
* port - the network port to connect to. Usually 1883.
* keepalive - the number of seconds after which the broker should send a PING
* message to the client if no other messages have been exchanged
* keepalive - the number of seconds after which the client should send a PING
* message to the broker if no other messages have been exchanged
* in that time.
* bind_address - the hostname or ip address of the local network interface to
* bind to. If you do not want to bind to a specific interface,
@ -688,8 +688,8 @@ libmosq_EXPORT int mosquitto_connect_bind_async(struct mosquitto *mosq, const ch
* Parameters:
* mosq - a valid mosquitto instance.
* host - the hostname to search for an SRV record.
* keepalive - the number of seconds after which the broker should send a PING
* message to the client if no other messages have been exchanged
* keepalive - the number of seconds after which the client should send a PING
* message to the broker if no other messages have been exchanged
* in that time.
* bind_address - the hostname or ip address of the local network interface to
* bind to. If you do not want to bind to a specific interface,

@ -100,6 +100,7 @@ int handle__pubackcomp(struct mosquitto *mosq, const char *type)
&& reason_code != MQTT_RC_PAYLOAD_FORMAT_INVALID
){
mosquitto_property_free_all(&properties);
return MOSQ_ERR_PROTOCOL;
}
}else{
@ -107,14 +108,13 @@ int handle__pubackcomp(struct mosquitto *mosq, const char *type)
&& reason_code != MQTT_RC_PACKET_ID_NOT_FOUND
){
mosquitto_property_free_all(&properties);
return MOSQ_ERR_PROTOCOL;
}
}
}
if(mosq->in_packet.pos < mosq->in_packet.remaining_length){
#ifdef WITH_BROKER
mosquitto_property_free_all(&properties);
#endif
return MOSQ_ERR_MALFORMED_PACKET;
}

@ -63,20 +63,22 @@ int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets)
if(mosq->sock != INVALID_SOCKET){
maxfd = mosq->sock;
FD_SET(mosq->sock, &readfds);
pthread_mutex_lock(&mosq->current_out_packet_mutex);
pthread_mutex_lock(&mosq->out_packet_mutex);
if(mosq->out_packet || mosq->current_out_packet){
if(mosq->want_write){
FD_SET(mosq->sock, &writefds);
}
}else{
#ifdef WITH_TLS
if(mosq->ssl){
if(mosq->want_write){
FD_SET(mosq->sock, &writefds);
if(mosq->ssl == NULL || SSL_is_init_finished(mosq->ssl))
#endif
{
pthread_mutex_lock(&mosq->current_out_packet_mutex);
pthread_mutex_lock(&mosq->out_packet_mutex);
if(mosq->out_packet || mosq->current_out_packet){
FD_SET(mosq->sock, &writefds);
}
pthread_mutex_unlock(&mosq->out_packet_mutex);
pthread_mutex_unlock(&mosq->current_out_packet_mutex);
}
}
#endif
pthread_mutex_unlock(&mosq->out_packet_mutex);
pthread_mutex_unlock(&mosq->current_out_packet_mutex);
}else{
#ifdef WITH_SRV
if(mosq->achan){

@ -22,6 +22,8 @@ Contributors:
#include "config.h"
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@ -33,8 +35,10 @@ Contributors:
# include <io.h>
# include <lmcons.h>
# include <fcntl.h>
# define PATH_MAX MAX_PATH
#else
# include <sys/stat.h>
# include <unistd.h>
#endif
#include "misc_mosq.h"
@ -126,30 +130,33 @@ FILE *mosquitto__fopen(const char *path, const char *mode, bool restrict_read)
}
}
#else
if(mode[0] == 'r'){
struct stat statbuf;
if(stat(path, &statbuf) < 0){
return NULL;
}
if(!S_ISREG(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)){
log__printf(NULL, MOSQ_LOG_ERR, "Error: %s is not a file.", path);
return NULL;
}
}
FILE *fptr;
struct stat statbuf;
if (restrict_read) {
FILE *fptr;
mode_t old_mask;
old_mask = umask(0077);
fptr = fopen(path, mode);
umask(old_mask);
return fptr;
}else{
return fopen(path, mode);
fptr = fopen(path, mode);
}
if(!fptr) return NULL;
if(fstat(fileno(fptr), &statbuf) < 0){
fclose(fptr);
return NULL;
}
if(!S_ISREG(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)){
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_ERR, "Error: %s is not a file.", path);
#endif
fclose(fptr);
return NULL;
}
return fptr;
#endif
}

@ -61,8 +61,11 @@ int mosquitto_lib_init(void)
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);
#endif
srand((unsigned int)tp.tv_nsec);
#elif defined(__APPLE__)
uint64_t ticks;
@ -329,18 +332,7 @@ int mosquitto_socket(struct mosquitto *mosq)
bool mosquitto_want_write(struct mosquitto *mosq)
{
bool result = false;
if(mosq->out_packet || mosq->current_out_packet){
result = true;
}
#ifdef WITH_TLS
if(mosq->ssl){
if (mosq->want_write) {
result = true;
}
}
#endif
return result;
return mosq->out_packet || mosq->current_out_packet || mosq->want_write;
}

@ -684,7 +684,7 @@ static int net__init_ssl_ctx(struct mosquitto *mosq)
#endif
if(!mosq->tls_version){
SSL_CTX_set_options(mosq->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
SSL_CTX_set_options(mosq->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
#ifdef SSL_OP_NO_TLSv1_3
}else if(!strcmp(mosq->tls_version, "tlsv1.3")){
SSL_CTX_set_options(mosq->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2);

@ -228,19 +228,23 @@ int mosquitto_tls_opts_set(struct mosquitto *mosq, int cert_reqs, const char *tl
|| !strcasecmp(tls_version, "tlsv1.2")
|| !strcasecmp(tls_version, "tlsv1.1")){
mosquitto__free(mosq->tls_version);
mosq->tls_version = mosquitto__strdup(tls_version);
if(!mosq->tls_version) return MOSQ_ERR_NOMEM;
}else{
return MOSQ_ERR_INVAL;
}
}else{
mosquitto__free(mosq->tls_version);
mosq->tls_version = mosquitto__strdup("tlsv1.2");
if(!mosq->tls_version) return MOSQ_ERR_NOMEM;
}
if(ciphers){
mosquitto__free(mosq->tls_ciphers);
mosq->tls_ciphers = mosquitto__strdup(ciphers);
if(!mosq->tls_ciphers) return MOSQ_ERR_NOMEM;
}else{
mosquitto__free(mosq->tls_ciphers);
mosq->tls_ciphers = NULL;
}

@ -268,6 +268,8 @@ int packet__write(struct mosquitto *mosq)
return MOSQ_ERR_CONN_LOST;
case COMPAT_EINTR:
return MOSQ_ERR_SUCCESS;
case EPROTO:
return MOSQ_ERR_TLS;
default:
return MOSQ_ERR_ERRNO;
}

@ -141,7 +141,9 @@ static int property__read(struct mosquitto__packet *packet, uint32_t *len, mosqu
break;
default:
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_DEBUG, "Unsupported property type: %d", property_identifier);
#endif
return MOSQ_ERR_MALFORMED_PACKET;
}
@ -415,7 +417,9 @@ static int property__write(struct mosquitto__packet *packet, const mosquitto_pro
break;
default:
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_DEBUG, "Unsupported property type: %d", property->identifier);
#endif
return MOSQ_ERR_INVAL;
}
@ -1248,7 +1252,7 @@ int mosquitto_property_copy_all(mosquitto_property **dest, const mosquitto_prope
case MQTT_PROP_SERVER_REFERENCE:
case MQTT_PROP_REASON_STRING:
pnew->value.s.len = src->value.s.len;
pnew->value.s.v = strdup(src->value.s.v);
pnew->value.s.v = src->value.s.v ? strdup(src->value.s.v) : (char*)calloc(1,1);
if(!pnew->value.s.v){
mosquitto_property_free_all(dest);
return MOSQ_ERR_NOMEM;
@ -1268,14 +1272,14 @@ int mosquitto_property_copy_all(mosquitto_property **dest, const mosquitto_prope
case MQTT_PROP_USER_PROPERTY:
pnew->value.s.len = src->value.s.len;
pnew->value.s.v = strdup(src->value.s.v);
pnew->value.s.v = src->value.s.v ? strdup(src->value.s.v) : (char*)calloc(1,1);
if(!pnew->value.s.v){
mosquitto_property_free_all(dest);
return MOSQ_ERR_NOMEM;
}
pnew->name.len = src->name.len;
pnew->name.v = strdup(src->name.v);
pnew->name.v = src->name.v ? strdup(src->name.v) : (char*)calloc(1,1);
if(!pnew->name.v){
mosquitto_property_free_all(dest);
return MOSQ_ERR_NOMEM;

@ -177,7 +177,7 @@ int send__real_publish(struct mosquitto *mosq, uint16_t mid, const char *topic,
#ifdef WITH_BROKER
log__printf(NULL, MOSQ_LOG_NOTICE, "Dropping too large outgoing PUBLISH for %s (%d bytes)", SAFE_PRINT(mosq->id), packetlen);
#else
log__printf(NULL, MOSQ_LOG_NOTICE, "Dropping too large outgoing PUBLISH (%d bytes)", packetlen);
log__printf(mosq, MOSQ_LOG_NOTICE, "Dropping too large outgoing PUBLISH (%d bytes)", packetlen);
#endif
return MOSQ_ERR_OVERSIZE_PACKET;
}

@ -43,7 +43,11 @@ 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;
#elif defined(__APPLE__)
static mach_timebase_info_data_t tb;

@ -4,44 +4,45 @@
# could not be found, then the man pages will not be built or installed -
# because the install is optional.
if(NOT WIN32)
find_program(XSLTPROC xsltproc OPTIONAL)
if(XSLTPROC)
function(compile_manpage page)
add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/man/${page}
COMMAND xsltproc ${PROJECT_SOURCE_DIR}/man/${page}.xml -o ${PROJECT_SOURCE_DIR}/man/
MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/man/${page}.xml)
add_custom_target(${page} ALL DEPENDS ${PROJECT_SOURCE_DIR}/man/${page})
endfunction()
find_program(XSLTPROC xsltproc OPTIONAL)
if(XSLTPROC)
function(compile_manpage page)
add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/man/${page}
COMMAND xsltproc ${PROJECT_SOURCE_DIR}/man/${page}.xml -o ${PROJECT_SOURCE_DIR}/man/
MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/man/${page}.xml)
add_custom_target(${page} ALL DEPENDS ${PROJECT_SOURCE_DIR}/man/${page})
endfunction()
compile_manpage("mosquitto_ctrl.1")
compile_manpage("mosquitto_ctrl_dynsec.1")
compile_manpage("mosquitto_passwd.1")
compile_manpage("mosquitto_pub.1")
compile_manpage("mosquitto_sub.1")
compile_manpage("mosquitto_rr.1")
compile_manpage("libmosquitto.3")
compile_manpage("mosquitto.conf.5")
compile_manpage("mosquitto-tls.7")
compile_manpage("mqtt.7")
compile_manpage("mosquitto.8")
else()
message(FATAL_ERROR "xsltproc not found: manpages cannot be built")
endif()
compile_manpage("mosquitto_ctrl.1")
compile_manpage("mosquitto_ctrl_dynsec.1")
compile_manpage("mosquitto_passwd.1")
compile_manpage("mosquitto_pub.1")
compile_manpage("mosquitto_sub.1")
compile_manpage("mosquitto_rr.1")
compile_manpage("libmosquitto.3")
compile_manpage("mosquitto.conf.5")
compile_manpage("mosquitto-tls.7")
compile_manpage("mqtt.7")
compile_manpage("mosquitto.8")
endif()
install(FILES
mosquitto_ctrl.1
mosquitto_ctrl_dynsec.1
mosquitto_passwd.1
mosquitto_pub.1
mosquitto_sub.1
mosquitto_rr.1
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1
OPTIONAL)
install(FILES libmosquitto.3 DESTINATION ${CMAKE_INSTALL_MANDIR}/man3 OPTIONAL)
install(FILES mosquitto.conf.5 DESTINATION ${CMAKE_INSTALL_MANDIR}/man5 OPTIONAL)
install(FILES mosquitto-tls.7 mqtt.7 DESTINATION ${CMAKE_INSTALL_MANDIR}/man7 OPTIONAL)
install(FILES mosquitto.8 DESTINATION ${CMAKE_INSTALL_MANDIR}/man8 OPTIONAL)
install(FILES
mosquitto_ctrl.1
mosquitto_ctrl_dynsec.1
mosquitto_passwd.1
mosquitto_pub.1
mosquitto_sub.1
mosquitto_rr.1
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1
OPTIONAL)
elseif(WIN32)
message(WARNING "xsltproc not found: manpages cannot be built")
else()
message(FATAL_ERROR "xsltproc not found: manpages cannot be built")
endif()
install(FILES libmosquitto.3 DESTINATION ${CMAKE_INSTALL_MANDIR}/man3 OPTIONAL)
install(FILES mosquitto.conf.5 DESTINATION ${CMAKE_INSTALL_MANDIR}/man5 OPTIONAL)
install(FILES mosquitto-tls.7 mqtt.7 DESTINATION ${CMAKE_INSTALL_MANDIR}/man7 OPTIONAL)
install(FILES mosquitto.8 DESTINATION ${CMAKE_INSTALL_MANDIR}/man8 OPTIONAL)

@ -1458,7 +1458,7 @@ openssl dhparam -out dhparam.pem 2048</programlisting>
<replaceable>tlsv1.3</replaceable>,
<replaceable>tlsv1.2</replaceable> and
<replaceable>tlsv1.1</replaceable>. If left unset,
the default of allowing TLS v1.3 and v1.2.</para>
the default allows TLS v1.3 and v1.2.</para>
<para>In Mosquitto version 1.6.x and earlier, this
option set the only TLS protocol version that
was allowed, rather than the minimum.</para>

@ -938,7 +938,6 @@ mosquitto_sub -t 'bbc/#' -T bbc/bbc1 --remove-retained</programlisting>
<para>If the payload is not valid JSON, then the error message "Error: Message payload is not valid JSON on topic
&lt;topic&gt;" will be printed to stderr.</para></listitem>
<listitem><para><option>%I</option> ISO-8601 format date and time, e.g. 2016-08-10T09:47:38+0100</para></listitem>
<listitem><para><option>%U</option> Unix timestamp with nanoseconds, e.g. 1470818943.786368637</para></listitem>
</itemizedlist>
</refsect2>

@ -17,17 +17,19 @@ MY_DOMAIN=example.com
# Set the directory that the certificates will be copied to.
CERTIFICATE_DIR=/etc/mosquitto/certs
if [ "${RENEWED_DOMAINS}" = "${MY_DOMAIN}" ]; then
# Copy new certificate to Mosquitto directory
cp ${RENEWED_LINEAGE}/fullchain.pem ${CERTIFICATE_DIR}/server.pem
cp ${RENEWED_LINEAGE}/privkey.pem ${CERTIFICATE_DIR}/server.key
# Set ownership to Mosquitto
chown mosquitto: ${CERTIFICATE_DIR}/server.pem ${CERTIFICATE_DIR}/server.key
# Ensure permissions are restrictive
chmod 0600 ${CERTIFICATE_DIR}/server.pem ${CERTIFICATE_DIR}/server.key
# Tell Mosquitto to reload certificates and configuration
pkill -HUP -x mosquitto
fi
for D in ${RENEWED_DOMAINS}; do
if [ "${D}" = "${MY_DOMAIN}" ]; then
# Copy new certificate to Mosquitto directory
cp ${RENEWED_LINEAGE}/fullchain.pem ${CERTIFICATE_DIR}/server.pem
cp ${RENEWED_LINEAGE}/privkey.pem ${CERTIFICATE_DIR}/server.key
# Set ownership to Mosquitto
chown mosquitto: ${CERTIFICATE_DIR}/server.pem ${CERTIFICATE_DIR}/server.key
# Ensure permissions are restrictive
chmod 0600 ${CERTIFICATE_DIR}/server.pem ${CERTIFICATE_DIR}/server.key
# Tell Mosquitto to reload certificates and configuration
pkill -HUP -x mosquitto
fi
done

@ -106,5 +106,5 @@ int mosquitto_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int op
UNUSED(opts);
UNUSED(opt_count);
return mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_MESSAGE, basic_auth_callback, NULL);
return mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_BASIC_AUTH, basic_auth_callback, NULL);
}

@ -61,7 +61,7 @@ Command:
{
"commands":[
{
"command": "getDefaultACLAccess",
"command": "getDefaultACLAccess"
}
]
}
@ -244,7 +244,7 @@ Command:
mosquitto_ctrl example:
```
mosquitto_ctrl dynsec setClientPassword username password
mosquitto_ctrl dynsec setClientId username clientId
```
## Set Client Password
@ -523,7 +523,7 @@ Command:
{
"commands":[
{
"command": "getAnonymousGroup",
"command": "getAnonymousGroup"
}
]
}

@ -451,7 +451,7 @@ void dynsec__config_save(void)
json_str_len = strlen(json_str);
/* Save to file */
file_path_len = strlen(config_file) + 1;
file_path_len = strlen(config_file) + strlen(".new") + 1;
file_path = mosquitto_malloc(file_path_len);
if(file_path == NULL){
mosquitto_free(json_str);

@ -126,6 +126,9 @@ int bridge__new(struct mosquitto__bridge *bridge)
}
new_context->retain_available = bridge->outgoing_retain;
new_context->protocol = bridge->protocol_version;
if(!bridge->clean_start_local){
new_context->session_expiry_interval = UINT32_MAX;
}
bridges = mosquitto__realloc(db.bridges, (size_t)(db.bridge_count+1)*sizeof(struct mosquitto *));
if(bridges){

@ -187,7 +187,7 @@ static void config__init_reload(struct mosquitto__config *config)
config->log_timestamp = true;
mosquitto__free(config->log_timestamp_format);
config->log_timestamp_format = NULL;
config->max_keepalive = 65535;
config->max_keepalive = 0;
config->max_packet_size = 0;
config->max_inflight_messages = 20;
config->max_queued_messages = 1000;

@ -946,7 +946,13 @@ handle_connect_error:
mosquitto__free(will_struct->msg.topic);
mosquitto__free(will_struct);
}
context->will = NULL;
if(context->will){
mosquitto_property_free_all(&context->will->properties);
mosquitto__free(context->will->msg.payload);
mosquitto__free(context->will->msg.topic);
mosquitto__free(context->will);
context->will = NULL;
}
#ifdef WITH_TLS
if(client_cert) X509_free(client_cert);
#endif

@ -20,6 +20,7 @@ Contributors:
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#ifndef WIN32
#include <syslog.h>
#endif
@ -129,6 +130,9 @@ 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);
}
}
if(log_destinations & MQTT3_LOG_STDOUT){
setlinebuf(stdout);
}
#ifdef WITH_DLT
dlt_fifo_check();
if(dlt_allowed){
@ -291,7 +295,7 @@ static int log__vprintf(unsigned int priority, const char *fmt, va_list va)
log_line_pos = (size_t)snprintf(log_line, sizeof(log_line), "Time error");
}
}else{
log_line_pos = (size_t)snprintf(log_line, sizeof(log_line), "%d", (int)db.now_real_s);
log_line_pos = (size_t)snprintf(log_line, sizeof(log_line), "%" PRIu64, (uint64_t)db.now_real_s);
}
if(log_line_pos < sizeof(log_line)-3){
log_line[log_line_pos] = ':';

@ -160,9 +160,18 @@ static void mosquitto__daemonise(void)
exit(1);
}
assert(freopen("/dev/null", "r", stdin));
assert(freopen("/dev/null", "w", stdout));
assert(freopen("/dev/null", "w", stderr));
if(!freopen("/dev/null", "r", stdin)){
log__printf(NULL, MOSQ_LOG_ERR, "Error whilst daemonising (%s): %s", "stdin", strerror(errno));
exit(1);
}
if(!freopen("/dev/null", "w", stdout)){
log__printf(NULL, MOSQ_LOG_ERR, "Error whilst daemonising (%s): %s", "stdout", strerror(errno));
exit(1);
}
if(!freopen("/dev/null", "w", stderr)){
log__printf(NULL, MOSQ_LOG_ERR, "Error whilst daemonising (%s): %s", "stderr", strerror(errno));
exit(1);
}
#else
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Can't start in daemon mode in Windows.");
#endif
@ -475,7 +484,12 @@ int main(int argc, char *argv[])
#endif
#ifdef WIN32
_setmaxstdio(2048);
if(_setmaxstdio(8192) != 8192){
/* Old limit was 2048 */
if(_setmaxstdio(2048) != 2048){
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Unable to increase maximum allowed connections. This session may be limited to 512 connections.");
}
}
#endif
memset(&db, 0, sizeof(struct mosquitto_db));

@ -343,7 +343,7 @@ int net__tls_server_ctx(struct mosquitto__listener *listener)
#endif
if(listener->tls_version == NULL){
SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
#ifdef SSL_OP_NO_TLSv1_3
}else if(!strcmp(listener->tls_version, "tlsv1.3")){
SSL_CTX_set_options(listener->ssl_ctx, SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2);
@ -479,7 +479,7 @@ int net__load_certificates(struct mosquitto__listener *listener)
net__print_ssl_error(NULL);
return MOSQ_ERR_TLS;
}
if(listener->tls_engine == NULL){
if(listener->tls_engine == NULL || listener->tls_keyform == mosq_k_pem){
rc = SSL_CTX_use_PrivateKey_file(listener->ssl_ctx, listener->keyfile, SSL_FILETYPE_PEM);
if(rc != 1){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load server key file \"%s\". Check keyfile.", listener->keyfile);
@ -622,6 +622,8 @@ static int net__bind_interface(struct mosquitto__listener *listener, struct addr
* matching interface in the later bind().
*/
struct ifaddrs *ifaddr, *ifa;
bool have_interface = false;
if(getifaddrs(&ifaddr) < 0){
net__print_error(MOSQ_LOG_ERR, "Error: %s");
return MOSQ_ERR_ERRNO;
@ -632,49 +634,56 @@ static int net__bind_interface(struct mosquitto__listener *listener, struct addr
continue;
}
if(!strcasecmp(listener->bind_interface, ifa->ifa_name)
&& ifa->ifa_addr->sa_family == rp->ai_addr->sa_family){
if(!strcasecmp(listener->bind_interface, ifa->ifa_name)){
have_interface = true;
if(rp->ai_addr->sa_family == AF_INET){
if(listener->host &&
memcmp(&((struct sockaddr_in *)rp->ai_addr)->sin_addr,
&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
sizeof(struct in_addr))){
if(ifa->ifa_addr->sa_family == rp->ai_addr->sa_family){
if(rp->ai_addr->sa_family == AF_INET){
if(listener->host &&
memcmp(&((struct sockaddr_in *)rp->ai_addr)->sin_addr,
&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
sizeof(struct in_addr))){
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface address for %s does not match specified listener address (%s).",
listener->bind_interface, listener->host);
return MOSQ_ERR_INVAL;
}else{
memcpy(&((struct sockaddr_in *)rp->ai_addr)->sin_addr,
&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
sizeof(struct in_addr));
log__printf(NULL, MOSQ_LOG_ERR, "Error: Interface address for %s does not match specified listener address (%s).",
listener->bind_interface, listener->host);
return MOSQ_ERR_INVAL;
}else{
memcpy(&((struct sockaddr_in *)rp->ai_addr)->sin_addr,
&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
sizeof(struct in_addr));
freeifaddrs(ifaddr);
return MOSQ_ERR_SUCCESS;
}
}else if(rp->ai_addr->sa_family == AF_INET6){
if(listener->host &&
memcmp(&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr,
&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
sizeof(struct in6_addr))){
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface address for %s does not match specified listener address (%s).",
listener->bind_interface, listener->host);
return MOSQ_ERR_INVAL;
}else{
memcpy(&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr,
&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
sizeof(struct in6_addr));
freeifaddrs(ifaddr);
return MOSQ_ERR_SUCCESS;
freeifaddrs(ifaddr);
return MOSQ_ERR_SUCCESS;
}
}else if(rp->ai_addr->sa_family == AF_INET6){
if(listener->host &&
memcmp(&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr,
&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
sizeof(struct in6_addr))){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Interface address for %s does not match specified listener address (%s).",
listener->bind_interface, listener->host);
return MOSQ_ERR_INVAL;
}else{
memcpy(&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr,
&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
sizeof(struct in6_addr));
freeifaddrs(ifaddr);
return MOSQ_ERR_SUCCESS;
}
}
}
}
}
freeifaddrs(ifaddr);
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface %s does not support %s configuration.",
listener->bind_interface, rp->ai_addr->sa_family == AF_INET ? "IPv4" : "IPv6");
return MOSQ_ERR_NOT_FOUND;
if(have_interface){
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface %s does not support %s configuration.",
listener->bind_interface, rp->ai_addr->sa_family == AF_INET ? "IPv4" : "IPv6");
return MOSQ_ERR_NOT_SUPPORTED;
}else{
log__printf(NULL, MOSQ_LOG_ERR, "Error: Interface %s does not exist.", listener->bind_interface);
return MOSQ_ERR_NOT_FOUND;
}
}
#endif
@ -756,10 +765,16 @@ static int net__socket_listen_tcp(struct mosquitto__listener *listener)
if(listener->bind_interface){
/* It might be possible that an interface does not support all relevant sa_families.
* We should successfully find at least one. */
if(net__bind_interface(listener, rp)){
rc = net__bind_interface(listener, rp);
if(rc){
COMPAT_CLOSE(sock);
listener->sock_count--;
continue;
if(rc == MOSQ_ERR_NOT_FOUND || rc == MOSQ_ERR_INVAL){
freeaddrinfo(ainfo);
return rc;
}else{
continue;
}
}
interface_bound = true;
}

@ -180,9 +180,9 @@ int persist__chunk_msg_store_read_v234(FILE *db_fptr, struct P_msg_store *chunk,
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
return MOSQ_ERR_NOMEM;
}
read_e(db_fptr, chunk->payload, chunk->F.payloadlen);
/* Ensure zero terminated regardless of contents */
((uint8_t *)chunk->payload)[chunk->F.payloadlen] = 0;
read_e(db_fptr, chunk->payload, chunk->F.payloadlen);
}
return MOSQ_ERR_SUCCESS;

@ -203,9 +203,9 @@ int persist__chunk_msg_store_read_v56(FILE *db_fptr, struct P_msg_store *chunk,
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
return MOSQ_ERR_NOMEM;
}
read_e(db_fptr, chunk->payload, chunk->F.payloadlen);
/* Ensure zero terminated regardless of contents */
((uint8_t *)chunk->payload)[chunk->F.payloadlen] = 0;
read_e(db_fptr, chunk->payload, chunk->F.payloadlen);
}
if(length > 0){

@ -167,11 +167,14 @@ static int persist__client_save(FILE *db_fptr)
memset(&chunk, 0, sizeof(struct P_client));
HASH_ITER(hh_id, db.contexts_by_id, context, ctxt_tmp){
if(context && (context->clean_start == false
if(context &&
#ifdef WITH_BRIDGE
|| (context->bridge && context->bridge->clean_start_local == false)
((!context->bridge && context->clean_start == false)
|| (context->bridge && context->bridge->clean_start_local == false))
#else
context->clean_start == false
#endif
)){
){
chunk.F.session_expiry_time = context->session_expiry_time;
if(context->session_expiry_interval != 0 && context->session_expiry_interval != UINT32_MAX && context->session_expiry_time == 0){
chunk.F.session_expiry_time = context->session_expiry_interval + db.now_real_s;

@ -72,6 +72,25 @@ int retain__init(void)
}
void retain__clean_empty_hierarchy(struct mosquitto__retainhier *retainhier)
{
struct mosquitto__retainhier *parent;
while(retainhier){
if(retainhier->children || retainhier->retained || retainhier->parent == NULL){
/* Entry is being used */
return;
}else{
HASH_DELETE(hh, retainhier->parent->children, retainhier);
mosquitto__free(retainhier->topic);
parent = retainhier->parent;
mosquitto__free(retainhier);
retainhier = parent;
}
}
}
int retain__store(const char *topic, struct mosquitto_msg_store *stored, char **split_topics)
{
struct mosquitto__retainhier *retainhier;
@ -124,6 +143,7 @@ int retain__store(const char *topic, struct mosquitto_msg_store *stored, char **
#endif
}else{
retainhier->retained = NULL;
retain__clean_empty_hierarchy(retainhier);
}
return MOSQ_ERR_SUCCESS;

@ -43,6 +43,26 @@ static int session_expiry__cmp(struct session_expiry_list *i1, struct session_ex
}
static void set_session_expiry_time(struct mosquitto *context)
{
context->session_expiry_time = db.now_real_s;
if(db.config->persistent_client_expiration == 0){
/* No global expiry, so use the client expiration interval */
context->session_expiry_time += context->session_expiry_interval;
}else{
/* We have a global expiry interval */
if(db.config->persistent_client_expiration < context->session_expiry_interval){
/* The client expiry is longer than the global expiry, so use the global */
context->session_expiry_time += db.config->persistent_client_expiration;
}else{
/* The global expiry is longer than the client expiry, so use the client */
context->session_expiry_time += context->session_expiry_interval;
}
}
}
int session_expiry__add(struct mosquitto *context)
{
struct session_expiry_list *item;
@ -59,21 +79,7 @@ int session_expiry__add(struct mosquitto *context)
if(!item) return MOSQ_ERR_NOMEM;
item->context = context;
item->context->session_expiry_time = db.now_real_s;
if(db.config->persistent_client_expiration == 0){
/* No global expiry, so use the client expiration interval */
item->context->session_expiry_time += item->context->session_expiry_interval;
}else{
/* We have a global expiry interval */
if(db.config->persistent_client_expiration < item->context->session_expiry_interval){
/* The client expiry is longer than the global expiry, so use the global */
item->context->session_expiry_time += db.config->persistent_client_expiration;
}else{
/* The global expiry is longer than the client expiry, so use the client */
item->context->session_expiry_time += item->context->session_expiry_interval;
}
}
set_session_expiry_time(item->context);
context->expiry_list_item = item;
DL_INSERT_INORDER(expiry_list, item, session_expiry__cmp);
@ -98,7 +104,12 @@ int session_expiry__add_from_persistence(struct mosquitto *context, time_t expir
if(!item) return MOSQ_ERR_NOMEM;
item->context = context;
item->context->session_expiry_time = expiry_time;
if(expiry_time){
item->context->session_expiry_time = expiry_time;
}else{
set_session_expiry_time(item->context);
}
context->expiry_list_item = item;
DL_INSERT_INORDER(expiry_list, item, session_expiry__cmp);
@ -165,4 +176,3 @@ void session_expiry__check(void)
}
}
}

@ -23,6 +23,7 @@ Contributors:
#include <math.h>
#include <stdio.h>
#include <limits.h>
#include <inttypes.h>
#include "mosquitto_broker_internal.h"
#include "memory_mosq.h"
@ -76,31 +77,31 @@ static void sys_tree__update_clients(char *buf)
if(client_count != count_total){
client_count = count_total;
len = (uint32_t)snprintf(buf, BUFLEN, "%d", client_count);
db__messages_easy_queue(NULL, "$SYS/broker/clients/total", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/clients/total", SYS_TREE_QOS, len, buf, 1, 0, NULL);
if(client_count > client_max){
client_max = client_count;
len = (uint32_t)snprintf(buf, BUFLEN, "%d", client_max);
db__messages_easy_queue(NULL, "$SYS/broker/clients/maximum", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/clients/maximum", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
}
if(disconnected_count != count_total-count_by_sock){
disconnected_count = count_total-count_by_sock;
len = (uint32_t)snprintf(buf, BUFLEN, "%d", disconnected_count);
db__messages_easy_queue(NULL, "$SYS/broker/clients/inactive", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/clients/disconnected", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/clients/inactive", SYS_TREE_QOS, len, buf, 1, 0, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/clients/disconnected", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
if(connected_count != count_by_sock){
connected_count = count_by_sock;
len = (uint32_t)snprintf(buf, BUFLEN, "%d", connected_count);
db__messages_easy_queue(NULL, "$SYS/broker/clients/active", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/clients/connected", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/clients/active", SYS_TREE_QOS, len, buf, 1, 0, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/clients/connected", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
if(g_clients_expired != clients_expired){
clients_expired = g_clients_expired;
len = (uint32_t)snprintf(buf, BUFLEN, "%d", clients_expired);
db__messages_easy_queue(NULL, "$SYS/broker/clients/expired", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/clients/expired", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
}
@ -116,13 +117,13 @@ static void sys_tree__update_memory(char *buf)
if(current_heap != value_ul){
current_heap = value_ul;
len = (uint32_t)snprintf(buf, BUFLEN, "%lu", current_heap);
db__messages_easy_queue(NULL, "$SYS/broker/heap/current", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/heap/current", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
value_ul =mosquitto__max_memory_used();
if(max_heap != value_ul){
max_heap = value_ul;
len = (uint32_t)snprintf(buf, BUFLEN, "%lu", max_heap);
db__messages_easy_queue(NULL, "$SYS/broker/heap/maximum", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/heap/maximum", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
}
#endif
@ -135,12 +136,12 @@ static void calc_load(char *buf, const char *topic, bool initial, double exponen
if (initial) {
new_value = *current;
len = (uint32_t)snprintf(buf, BUFLEN, "%.2f", new_value);
db__messages_easy_queue(NULL, topic, SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, topic, SYS_TREE_QOS, len, buf, 1, 0, NULL);
} else {
new_value = interval + exponent*((*current) - interval);
if(fabs(new_value - (*current)) >= 0.01){
len = (uint32_t)snprintf(buf, BUFLEN, "%.2f", new_value);
db__messages_easy_queue(NULL, topic, SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, topic, SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
}
(*current) = new_value;
@ -217,8 +218,8 @@ void sys_tree__update(int interval, time_t start_time)
if(interval && db.now_s - interval > last_update){
uptime = db.now_s - start_time;
len = (uint32_t)snprintf(buf, BUFLEN, "%d seconds", (int)uptime);
db__messages_easy_queue(NULL, "$SYS/broker/uptime", SYS_TREE_QOS, len, buf, 1, 60, NULL);
len = (uint32_t)snprintf(buf, BUFLEN, "%" PRIu64 " seconds", (uint64_t)uptime);
db__messages_easy_queue(NULL, "$SYS/broker/uptime", SYS_TREE_QOS, len, buf, 1, 0, NULL);
sys_tree__update_clients(buf);
initial_publish = false;
@ -287,32 +288,32 @@ void sys_tree__update(int interval, time_t start_time)
if(db.msg_store_count != msg_store_count){
msg_store_count = db.msg_store_count;
len = (uint32_t)snprintf(buf, BUFLEN, "%d", msg_store_count);
db__messages_easy_queue(NULL, "$SYS/broker/messages/stored", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/store/messages/count", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/messages/stored", SYS_TREE_QOS, len, buf, 1, 0, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/store/messages/count", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
if (db.msg_store_bytes != msg_store_bytes){
msg_store_bytes = db.msg_store_bytes;
len = (uint32_t)snprintf(buf, BUFLEN, "%lu", msg_store_bytes);
db__messages_easy_queue(NULL, "$SYS/broker/store/messages/bytes", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/store/messages/bytes", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
if(db.subscription_count != subscription_count){
subscription_count = db.subscription_count;
len = (uint32_t)snprintf(buf, BUFLEN, "%d", subscription_count);
db__messages_easy_queue(NULL, "$SYS/broker/subscriptions/count", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/subscriptions/count", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
if(db.shared_subscription_count != shared_subscription_count){
shared_subscription_count = db.shared_subscription_count;
len = (uint32_t)snprintf(buf, BUFLEN, "%d", shared_subscription_count);
db__messages_easy_queue(NULL, "$SYS/broker/shared_subscriptions/count", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/shared_subscriptions/count", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
if(db.retained_count != retained_count){
retained_count = db.retained_count;
len = (uint32_t)snprintf(buf, BUFLEN, "%d", retained_count);
db__messages_easy_queue(NULL, "$SYS/broker/retained messages/count", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/retained messages/count", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
#ifdef REAL_WITH_MEMORY_TRACKING
@ -322,55 +323,55 @@ void sys_tree__update(int interval, time_t start_time)
if(msgs_received != g_msgs_received){
msgs_received = g_msgs_received;
len = (uint32_t)snprintf(buf, BUFLEN, "%lu", msgs_received);
db__messages_easy_queue(NULL, "$SYS/broker/messages/received", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/messages/received", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
if(msgs_sent != g_msgs_sent){
msgs_sent = g_msgs_sent;
len = (uint32_t)snprintf(buf, BUFLEN, "%lu", msgs_sent);
db__messages_easy_queue(NULL, "$SYS/broker/messages/sent", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/messages/sent", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
if(publish_dropped != g_msgs_dropped){
publish_dropped = g_msgs_dropped;
len = (uint32_t)snprintf(buf, BUFLEN, "%lu", publish_dropped);
db__messages_easy_queue(NULL, "$SYS/broker/publish/messages/dropped", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/publish/messages/dropped", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
if(pub_msgs_received != g_pub_msgs_received){
pub_msgs_received = g_pub_msgs_received;
len = (uint32_t)snprintf(buf, BUFLEN, "%lu", pub_msgs_received);
db__messages_easy_queue(NULL, "$SYS/broker/publish/messages/received", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/publish/messages/received", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
if(pub_msgs_sent != g_pub_msgs_sent){
pub_msgs_sent = g_pub_msgs_sent;
len = (uint32_t)snprintf(buf, BUFLEN, "%lu", pub_msgs_sent);
db__messages_easy_queue(NULL, "$SYS/broker/publish/messages/sent", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/publish/messages/sent", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
if(bytes_received != g_bytes_received){
bytes_received = g_bytes_received;
len = (uint32_t)snprintf(buf, BUFLEN, "%llu", bytes_received);
db__messages_easy_queue(NULL, "$SYS/broker/bytes/received", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/bytes/received", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
if(bytes_sent != g_bytes_sent){
bytes_sent = g_bytes_sent;
len = (uint32_t)snprintf(buf, BUFLEN, "%llu", bytes_sent);
db__messages_easy_queue(NULL, "$SYS/broker/bytes/sent", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/bytes/sent", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
if(pub_bytes_received != g_pub_bytes_received){
pub_bytes_received = g_pub_bytes_received;
len = (uint32_t)snprintf(buf, BUFLEN, "%llu", pub_bytes_received);
db__messages_easy_queue(NULL, "$SYS/broker/publish/bytes/received", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/publish/bytes/received", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
if(pub_bytes_sent != g_pub_bytes_sent){
pub_bytes_sent = g_pub_bytes_sent;
len = (uint32_t)snprintf(buf, BUFLEN, "%llu", pub_bytes_sent);
db__messages_easy_queue(NULL, "$SYS/broker/publish/bytes/sent", SYS_TREE_QOS, len, buf, 1, 60, NULL);
db__messages_easy_queue(NULL, "$SYS/broker/publish/bytes/sent", SYS_TREE_QOS, len, buf, 1, 0, NULL);
}
last_update = db.now_s;

@ -0,0 +1,80 @@
#!/usr/bin/env python3
# Exercise multi-level retain clearing
from mosq_test_helper import *
def send_retain(port, topic, payload):
connect_packet = mosq_test.gen_connect("retain-clear-test")
connack_packet = mosq_test.gen_connack(rc=0)
publish_packet = mosq_test.gen_publish(topic, qos=1, mid=1, payload=payload, retain=True)
puback_packet = mosq_test.gen_puback(mid=1)
sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=4, port=port)
mosq_test.do_send_receive(sock, publish_packet, puback_packet, f"set retain {topic}")
sock.close()
def do_test():
rc = 1
connect_packet = mosq_test.gen_connect("retain-clear-test")
connack_packet = mosq_test.gen_connack(rc=0)
subscribe_packet = mosq_test.gen_subscribe(1, "#", 0)
suback_packet = mosq_test.gen_suback(1, 0)
retain1_packet = mosq_test.gen_publish("1/2/3/4/5/6/7", qos=0, payload="retained message", retain=True)
retain2_packet = mosq_test.gen_publish("1/2/3/4", qos=0, payload="retained message", retain=True)
retain3_packet = mosq_test.gen_publish("1", qos=0, payload="retained message", retain=True)
port = mosq_test.get_port()
broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
try:
send_retain(port, "1/2/3/4/5/6/7", "retained message")
send_retain(port, "1/2/3/4", "retained message")
send_retain(port, "1", "retained message")
sock = mosq_test.do_client_connect(connect_packet, connack_packet, port=port)
mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback")
mosq_test.expect_packet(sock, "retain3", retain3_packet)
mosq_test.expect_packet(sock, "retain2", retain2_packet)
mosq_test.expect_packet(sock, "retain1", retain1_packet)
sock.close()
send_retain(port, "1/2/3/4", None)
sock = mosq_test.do_client_connect(connect_packet, connack_packet, port=port)
mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback")
mosq_test.expect_packet(sock, "retain3", retain3_packet)
mosq_test.expect_packet(sock, "retain1", retain1_packet)
sock.close()
send_retain(port, "1/2/3/4/5/6/7", None)
sock = mosq_test.do_client_connect(connect_packet, connack_packet, port=port)
mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback")
mosq_test.expect_packet(sock, "retain3", retain3_packet)
sock.close()
send_retain(port, "1", None)
sock = mosq_test.do_client_connect(connect_packet, connack_packet, port=port)
mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback")
mosq_test.do_ping(sock)
sock.close()
rc = 0
except mosq_test.TestError:
pass
finally:
broker.terminate()
broker.wait()
(stdo, stde) = broker.communicate()
if rc:
print(stde.decode('utf-8'))
exit(rc)
do_test()
exit(0)

@ -17,6 +17,7 @@ def write_config(filename, port1, port2, protocol_version):
f.write("address 127.0.0.1:%d\n" % (port1))
f.write("topic bridge/# out\n")
f.write("bridge_protocol_version %s\n" % (protocol_version))
f.write("cleansession false\n")
def do_test(proto_ver):

@ -90,6 +90,7 @@ msg_sequence_test:
./04-retain-check-source-persist-diff-port.py
./04-retain-check-source-persist.py
./04-retain-check-source.py
./04-retain-clear-multiple.py
./04-retain-qos0-clear.py
./04-retain-qos0-fresh.py
./04-retain-qos0-repeated.py

@ -68,6 +68,7 @@ tests = [
(1, './04-retain-check-source-persist.py'),
(1, './04-retain-check-source.py'),
(1, './04-retain-clear-multiple.py'),
(1, './04-retain-qos0-clear.py'),
(1, './04-retain-qos0-fresh.py'),
(1, './04-retain-qos0-repeated.py'),

@ -70,7 +70,7 @@ def start_broker(filename, cmd=None, port=0, use_conf=False, expect_fail=False,
print("FAIL: unable to start broker: %s" % errs)
raise IOError
else:
return None
return broker
def start_client(filename, cmd, env, port=1888):
if cmd is None:

@ -17,13 +17,14 @@ Then use the following for your mosquitto.conf:
```
listener 8883
cafile /etc/ssl/certs/DST_Root_CA_X3.pem
cafile /etc/ssl/certs/ISRG_Root_X1.pem
certfile /etc/letsencrypt/live/example.com/fullchain.pem
keyfile /etc/letsencrypt/live/example.com/privkey.pem
```
You need to be aware that current versions of mosquitto never update listener
settings when running, so when you regenerate the server certificates you will
need to completely restart the broker.
Since version 2.0 of Mosquitto, you can send a SIGHUP to the broker to cause it
to reload certificates. Prior to this version, mosquitto would never update
listener settings when running, so you will need to completely restart the
broker.
[Let's Encrypt]: https://letsencrypt.org/

Loading…
Cancel
Save