From a3ebeff9d732458a4dac7513fac10a52a97cf4d1 Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Wed, 18 Dec 2019 17:44:26 +0100 Subject: [PATCH 001/113] fix: replace sleep with (p)select in loop_forever sleep was blocking loop_stop(force=false) since it was uniteruptible Signed-off-by: Christian Schneider --- lib/connect.c | 14 -------------- lib/loop.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ lib/mosquitto.c | 12 ++++++++---- lib/net_mosq.c | 3 +++ 4 files changed, 53 insertions(+), 24 deletions(-) diff --git a/lib/connect.c b/lib/connect.c index fd5c4979..f70babe6 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -78,20 +78,6 @@ static int mosquitto__connect_init(struct mosquitto *mosq, const char *host, int mosq->msgs_in.inflight_quota = mosq->msgs_in.inflight_maximum; mosq->msgs_out.inflight_quota = mosq->msgs_out.inflight_maximum; - if(mosq->sockpairR != INVALID_SOCKET){ - COMPAT_CLOSE(mosq->sockpairR); - mosq->sockpairR = INVALID_SOCKET; - } - if(mosq->sockpairW != INVALID_SOCKET){ - COMPAT_CLOSE(mosq->sockpairW); - mosq->sockpairW = INVALID_SOCKET; - } - - if(net__socketpair(&mosq->sockpairR, &mosq->sockpairW)){ - log__printf(mosq, MOSQ_LOG_WARNING, - "Warning: Unable to open socket pair, outgoing publish commands may be delayed."); - } - return MOSQ_ERR_SUCCESS; } diff --git a/lib/loop.c b/lib/loop.c index ad9bc0f3..b65be410 100644 --- a/lib/loop.c +++ b/lib/loop.c @@ -193,6 +193,15 @@ int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets) int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets) { +#ifdef HAVE_PSELECT + struct timespec local_timeout; +#else + struct timeval local_timeout; +#endif + fd_set readfds; + int fdcount; + char pairbuf; + int maxfd = 0; int run = 1; int rc; unsigned long reconnect_delay; @@ -252,15 +261,42 @@ int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets) mosq->reconnects++; } -#ifdef WIN32 - Sleep(reconnect_delay*1000); + local_timeout.tv_sec = reconnect_delay; +#ifdef HAVE_PSELECT + local_timeout.tv_nsec = 0; #else - req.tv_sec = reconnect_delay; - req.tv_nsec = 0; - while(nanosleep(&req, &rem) == -1 && errno == EINTR){ - req = rem; + local_timeout.tv_usec = 0; +#endif + FD_ZERO(&readfds); + maxfd = 0; + if(mosq->sockpairR != INVALID_SOCKET){ + /* sockpairR is used to break out of select() before the + * timeout, when mosquitto_loop_stop() is called */ + FD_SET(mosq->sockpairR, &readfds); + maxfd = mosq->sockpairR; } +#ifdef HAVE_PSELECT + fdcount = pselect(maxfd+1, &readfds, NULL, NULL, &local_timeout, NULL); +#else + fdcount = select(maxfd+1, &readfds, NULL, NULL, &local_timeout); +#endif + if(fdcount == -1){ +#ifdef WIN32 + errno = WSAGetLastError(); #endif + if(errno == EINTR){ + return MOSQ_ERR_SUCCESS; + }else{ + return MOSQ_ERR_ERRNO; + } + }else if(mosq->sockpairR != INVALID_SOCKET && FD_ISSET(mosq->sockpairR, &readfds)){ +#ifndef WIN32 + if(read(mosq->sockpairR, &pairbuf, 1) == 0){ + } +#else + recv(mosq->sockpairR, &pairbuf, 1, 0); +#endif + } state = mosquitto__get_state(mosq); if(state == mosq_cs_disconnecting || state == mosq_cs_disconnected){ diff --git a/lib/mosquitto.c b/lib/mosquitto.c index 795013eb..1586367c 100644 --- a/lib/mosquitto.c +++ b/lib/mosquitto.c @@ -92,8 +92,10 @@ struct mosquitto *mosquitto_new(const char *id, bool clean_start, void *userdata mosq = (struct mosquitto *)mosquitto__calloc(1, sizeof(struct mosquitto)); if(mosq){ mosq->sock = INVALID_SOCKET; - mosq->sockpairR = INVALID_SOCKET; - mosq->sockpairW = INVALID_SOCKET; + if(net__socketpair(&mosq->sockpairR, &mosq->sockpairW)){ + log__printf(mosq, MOSQ_LOG_WARNING, + "Warning: Unable to open socket pair, outgoing publish commands may be delayed."); + } #ifdef WITH_THREADING mosq->thread_id = pthread_self(); #endif @@ -131,8 +133,10 @@ int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_st } mosq->protocol = mosq_p_mqtt311; mosq->sock = INVALID_SOCKET; - mosq->sockpairR = INVALID_SOCKET; - mosq->sockpairW = INVALID_SOCKET; + if(net__socketpair(&mosq->sockpairR, &mosq->sockpairW)){ + log__printf(mosq, MOSQ_LOG_WARNING, + "Warning: Unable to open socket pair, outgoing publish commands may be delayed."); + } mosq->keepalive = 60; mosq->clean_start = clean_start; if(id){ diff --git a/lib/net_mosq.c b/lib/net_mosq.c index 051240dd..155f25aa 100644 --- a/lib/net_mosq.c +++ b/lib/net_mosq.c @@ -1079,6 +1079,9 @@ int net__socketpair(mosq_sock_t *pairR, mosq_sock_t *pairW) #else int sv[2]; + *pairR = INVALID_SOCKET; + *pairW = INVALID_SOCKET; + if(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1){ return MOSQ_ERR_ERRNO; } From 68c1e51035467ade10533c7bb88aa9765241c104 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 3 Mar 2020 21:26:29 +0000 Subject: [PATCH 002/113] Bump dockerfile for 1.6.9. --- docker/1.6/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/1.6/Dockerfile b/docker/1.6/Dockerfile index bd3bac23..5c7db1e8 100644 --- a/docker/1.6/Dockerfile +++ b/docker/1.6/Dockerfile @@ -3,8 +3,8 @@ FROM alpine:3.8 LABEL maintainer="Roger Light " \ description="Eclipse Mosquitto MQTT Broker" -ENV VERSION=1.6.8 \ - DOWNLOAD_SHA256=7df23c81ca37f0e070574fe74414403cf25183016433d07add6134366fb45df6 \ +ENV VERSION=1.6.9 \ + DOWNLOAD_SHA256=412979b2db0a0020bd02fa64f0a0de9e7000b84462586e32b67f29bb1f6c1685 \ GPG_KEYS=A0D6EEA1DCAE49A635A3B2F0779B22DFB3E717B7 \ LWS_VERSION=2.4.2 From c175e836a7b59e8a663e12d963453dc1844c5012 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 5 Mar 2020 10:54:13 +0000 Subject: [PATCH 003/113] Print openssl error when unable to load server key. --- src/net.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/net.c b/src/net.c index 8a8e3445..21060db6 100644 --- a/src/net.c +++ b/src/net.c @@ -527,6 +527,7 @@ int net__tls_load_verify(struct mosquitto__listener *listener) 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); + net__print_ssl_error(NULL); #if !defined(OPENSSL_NO_ENGINE) ENGINE_FINISH(engine); #endif From c84d175b3dcd436ad341321959a77402dffb9ab3 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 12 Mar 2020 10:29:11 +0000 Subject: [PATCH 004/113] Fixes for the poor souls stuck on mem_limit){ return NULL; } #endif - void *mem = calloc(nmemb, size); + mem = calloc(nmemb, size); #ifdef REAL_WITH_MEMORY_TRACKING if(mem){ @@ -79,12 +80,15 @@ void mosquitto__free(void *mem) void *mosquitto__malloc(size_t size) { + void *mem; + #ifdef REAL_WITH_MEMORY_TRACKING if(mem_limit && memcount + size > mem_limit){ return NULL; } #endif - void *mem = malloc(size); + + mem = malloc(size); #ifdef REAL_WITH_MEMORY_TRACKING if(mem){ @@ -112,13 +116,11 @@ unsigned long mosquitto__max_memory_used(void) void *mosquitto__realloc(void *ptr, size_t size) { + void *mem; #ifdef REAL_WITH_MEMORY_TRACKING if(mem_limit && memcount + size > mem_limit){ return NULL; } -#endif - void *mem; -#ifdef REAL_WITH_MEMORY_TRACKING if(ptr){ memcount -= malloc_usable_size(ptr); } @@ -139,12 +141,13 @@ void *mosquitto__realloc(void *ptr, size_t size) char *mosquitto__strdup(const char *s) { + char *str; #ifdef REAL_WITH_MEMORY_TRACKING if(mem_limit && memcount + strlen(s) > mem_limit){ return NULL; } #endif - char *str = strdup(s); + str = strdup(s); #ifdef REAL_WITH_MEMORY_TRACKING if(str){ @@ -157,4 +160,3 @@ char *mosquitto__strdup(const char *s) return str; } - diff --git a/lib/mosquitto_internal.h b/lib/mosquitto_internal.h index 5df0b491..2a97506b 100644 --- a/lib/mosquitto_internal.h +++ b/lib/mosquitto_internal.h @@ -165,7 +165,6 @@ struct mosquitto_message_all{ struct mosquitto_message_all *prev; mosquitto_property *properties; time_t timestamp; - //enum mosquitto_msg_direction direction; enum mosquitto_msg_state state; bool dup; struct mosquitto_message msg; @@ -321,7 +320,7 @@ struct mosquitto { void (*on_unsubscribe)(struct mosquitto *, void *userdata, int mid); void (*on_unsubscribe_v5)(struct mosquitto *, void *userdata, int mid, const mosquitto_property *props); void (*on_log)(struct mosquitto *, void *userdata, int level, const char *str); - //void (*on_error)(); + /*void (*on_error)();*/ char *host; int port; char *bind_address; diff --git a/lib/net_mosq.c b/lib/net_mosq.c index 9012646b..c6b46238 100644 --- a/lib/net_mosq.c +++ b/lib/net_mosq.c @@ -482,11 +482,11 @@ void net__print_ssl_error(struct mosquitto *mosq) int net__socket_connect_tls(struct mosquitto *mosq) { int ret, err; + long res; ERR_clear_error(); - long res; if (mosq->tls_ocsp_required) { - // Note: OCSP is available in all currently supported OpenSSL versions. + /* Note: OCSP is available in all currently supported OpenSSL versions. */ if ((res=SSL_set_tlsext_status_type(mosq->ssl, TLSEXT_STATUSTYPE_ocsp)) != 1) { log__printf(mosq, MOSQ_LOG_ERR, "Could not activate OCSP (error: %ld)", res); return MOSQ_ERR_OCSP; @@ -537,6 +537,9 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) ENGINE *engine = NULL; uint8_t tls_alpn_wire[256]; uint8_t tls_alpn_len; +#if !defined(OPENSSL_NO_ENGINE) + EVP_PKEY *pkey; +#endif if(mosq->ssl_ctx){ if(!mosq->ssl_ctx_defaults){ @@ -595,7 +598,7 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) /* Set ALPN */ if(mosq->tls_alpn) { tls_alpn_len = (uint8_t) strnlen(mosq->tls_alpn, 254); - tls_alpn_wire[0] = tls_alpn_len; // first byte is length of string + tls_alpn_wire[0] = tls_alpn_len; /* first byte is length of string */ memcpy(tls_alpn_wire + 1, mosq->tls_alpn, tls_alpn_len); SSL_CTX_set_alpn_protos(mosq->ssl_ctx, tls_alpn_wire, tls_alpn_len + 1); } @@ -718,7 +721,7 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) } ui_method = NULL; } - EVP_PKEY *pkey = ENGINE_load_private_key(engine, mosq->tls_keyfile, ui_method, NULL); + pkey = ENGINE_load_private_key(engine, mosq->tls_keyfile, ui_method, NULL); if(!pkey){ log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load engine private key file \"%s\".", mosq->tls_keyfile); ENGINE_FINISH(engine); diff --git a/lib/net_mosq_ocsp.c b/lib/net_mosq_ocsp.c index de7dab6a..af1511f6 100644 --- a/lib/net_mosq_ocsp.c +++ b/lib/net_mosq_ocsp.c @@ -64,7 +64,7 @@ int mosquitto__verify_ocsp_status_cb(SSL * ssl, void *arg) long len = SSL_get_tlsext_status_ocsp_resp(mosq->ssl, &p); log__printf(mosq, MOSQ_LOG_DEBUG, "OCSP: SSL_get_tlsext_status_ocsp_resp returned %ld bytes", len); - // the following functions expect a const pointer + /* the following functions expect a const pointer */ cp = (const unsigned char *)p; if (!cp || len <= 0) { @@ -100,9 +100,10 @@ int mosquitto__verify_ocsp_status_cb(SSL * ssl, void *arg) st = SSL_CTX_get_cert_store(mosq->ssl_ctx); - // Note: - // Other checkers often fix problems in OpenSSL before 1.0.2a (e.g. libcurl). - // For all currently supported versions of the OpenSSL project, this is not needed anymore. + /* Note: + * Other checkers often fix problems in OpenSSL before 1.0.2a (e.g. libcurl). + * For all currently supported versions of the OpenSSL project, this is not needed anymore. + */ if ((result2=OCSP_basic_verify(br, ch, st, 0)) <= 0) { log__printf(mosq, MOSQ_LOG_DEBUG, "OCSP: response verification failed (error: %d)", result2); @@ -126,7 +127,7 @@ int mosquitto__verify_ocsp_status_cb(SSL * ssl, void *arg) switch(cert_status) { case V_OCSP_CERTSTATUS_GOOD: - // Note: A OCSP stapling result will be accepted up to 5 minutes after it expired! + /* Note: A OCSP stapling result will be accepted up to 5 minutes after it expired! */ if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) { log__printf(mosq, MOSQ_LOG_DEBUG, "OCSP: OCSP response has expired"); goto end; @@ -149,11 +150,11 @@ int mosquitto__verify_ocsp_status_cb(SSL * ssl, void *arg) if (br!=NULL) OCSP_BASICRESP_free(br); if (rsp!=NULL) OCSP_RESPONSE_free(rsp); - return 1; // OK + return 1; /* OK */ end: if (br!=NULL) OCSP_BASICRESP_free(br); if (rsp!=NULL) OCSP_RESPONSE_free(rsp); - return 0; // Not OK + return 0; /* Not OK */ } #endif diff --git a/lib/utf8_mosq.c b/lib/utf8_mosq.c index ca7de490..47867868 100644 --- a/lib/utf8_mosq.c +++ b/lib/utf8_mosq.c @@ -45,11 +45,11 @@ int mosquitto_validate_utf8(const char *str, int len) codelen = 2; codepoint = (ustr[i] & 0x1F); }else if((ustr[i] & 0xF0) == 0xE0){ - // 1110xxxx - 3 byte sequence + /* 1110xxxx - 3 byte sequence */ codelen = 3; codepoint = (ustr[i] & 0x0F); }else if((ustr[i] & 0xF8) == 0xF0){ - // 11110xxx - 4 byte sequence + /* 11110xxx - 4 byte sequence */ if(ustr[i] > 0xF4){ /* Invalid, this would produce values > 0x10FFFF. */ return MOSQ_ERR_MALFORMED_UTF8; diff --git a/src/conf.c b/src/conf.c index f4038422..cd571d4c 100644 --- a/src/conf.c +++ b/src/conf.c @@ -778,6 +778,10 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct struct mosquitto__listener *cur_listener = &config->default_listener; int i; int lineno_ext = 0; + char **files; + int file_count; + char *kpass_sha = NULL, *kpass_sha_bin = NULL; + char *keyform ; *lineno = 0; @@ -798,7 +802,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct if(conf__parse_string(&token, "acl_file", &cur_security_options->acl_file, saveptr)) return MOSQ_ERR_INVAL; }else if(!strcmp(token, "address") || !strcmp(token, "addresses")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge || cur_bridge->addresses){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -860,7 +864,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct conf__set_cur_security_options(config, cur_listener, &cur_security_options); if(conf__parse_bool(&token, "allow_zero_length_clientid", &cur_security_options->allow_zero_length_clientid, saveptr)) return MOSQ_ERR_INVAL; }else if(!strncmp(token, "auth_opt_", 9)){ - if(reload) continue; // Auth plugin not currently valid for reloading. + if(reload) continue; /* Auth plugin not currently valid for reloading. */ if(!cur_auth_plugin_config){ log__printf(NULL, MOSQ_LOG_ERR, "Error: An auth_opt_ option exists in the config file without an auth_plugin."); return MOSQ_ERR_INVAL; @@ -903,7 +907,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct return MOSQ_ERR_INVAL; } }else if(!strcmp(token, "auth_plugin")){ - if(reload) continue; // Auth plugin not currently valid for reloading. + if(reload) continue; /* Auth plugin not currently valid for reloading. */ conf__set_cur_security_options(config, cur_listener, &cur_security_options); cur_security_options->auth_plugin_configs = mosquitto__realloc(cur_security_options->auth_plugin_configs, (cur_security_options->auth_plugin_config_count+1)*sizeof(struct mosquitto__auth_plugin_config)); if(!cur_security_options->auth_plugin_configs){ @@ -919,7 +923,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct cur_security_options->auth_plugin_config_count++; if(conf__parse_string(&token, "auth_plugin", &cur_auth_plugin_config->path, saveptr)) return MOSQ_ERR_INVAL; }else if(!strcmp(token, "auth_plugin_deny_special_chars")){ - if(reload) continue; // Auth plugin not currently valid for reloading. + if(reload) continue; /* Auth plugin not currently valid for reloading. */ if(!cur_auth_plugin_config){ log__printf(NULL, MOSQ_LOG_ERR, "Error: An auth_plugin_deny_special_chars option exists in the config file without an auth_plugin."); return MOSQ_ERR_INVAL; @@ -939,14 +943,14 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct }else if(!strcmp(token, "autosave_on_changes")){ if(conf__parse_bool(&token, "autosave_on_changes", &config->autosave_on_changes, saveptr)) return MOSQ_ERR_INVAL; }else if(!strcmp(token, "bind_address")){ - if(reload) continue; // Listener not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(conf__parse_string(&token, "default listener bind_address", &config->default_listener.host, saveptr)) return MOSQ_ERR_INVAL; if(conf__attempt_resolve(config->default_listener.host, "bind_address", MOSQ_LOG_ERR, "Error")){ return MOSQ_ERR_INVAL; } }else if(!strcmp(token, "bind_interface")){ #ifdef SO_BINDTODEVICE - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(conf__parse_string(&token, "bind_interface", &cur_listener->bind_interface, saveptr)) return MOSQ_ERR_INVAL; #else log__printf(NULL, MOSQ_LOG_ERR, "Error: bind_interface specified but socket option not available."); @@ -954,7 +958,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "bridge_attempt_unsubscribe")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -965,7 +969,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "bridge_cafile")){ #if defined(WITH_BRIDGE) && defined(WITH_TLS) - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -982,7 +986,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "bridge_alpn")){ #if defined(WITH_BRIDGE) && defined(WITH_TLS) - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -993,7 +997,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "bridge_capath")){ #if defined(WITH_BRIDGE) && defined(WITH_TLS) - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1010,7 +1014,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "bridge_certfile")){ #if defined(WITH_BRIDGE) && defined(WITH_TLS) - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1027,7 +1031,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "bridge_identity")){ #if defined(WITH_BRIDGE) && defined(FINAL_WITH_TLS_PSK) - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1042,7 +1046,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "bridge_insecure")){ #if defined(WITH_BRIDGE) && defined(WITH_TLS) - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1056,7 +1060,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "bridge_require_ocsp")){ #if defined(WITH_BRIDGE) && defined(WITH_TLS) - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1067,7 +1071,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "bridge_keyfile")){ #if defined(WITH_BRIDGE) && defined(WITH_TLS) - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1084,7 +1088,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "bridge_protocol_version")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1108,7 +1112,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "bridge_psk")){ #if defined(WITH_BRIDGE) && defined(FINAL_WITH_TLS_PSK) - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1123,7 +1127,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "bridge_tls_version")){ #if defined(WITH_BRIDGE) && defined(WITH_TLS) - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1134,7 +1138,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "cafile")){ #if defined(WITH_TLS) - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(cur_listener->psk_hint){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Cannot use both certificate and psk encryption in a single listener."); return MOSQ_ERR_INVAL; @@ -1145,14 +1149,14 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "capath")){ #ifdef WITH_TLS - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(conf__parse_string(&token, "capath", &cur_listener->capath, saveptr)) return MOSQ_ERR_INVAL; #else log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available."); #endif }else if(!strcmp(token, "certfile")){ #ifdef WITH_TLS - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(cur_listener->psk_hint){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Cannot use both certificate and psk encryption in a single listener."); return MOSQ_ERR_INVAL; @@ -1166,14 +1170,14 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct if(conf__parse_bool(&token, "check_retain_source", &config->check_retain_source, saveptr)) return MOSQ_ERR_INVAL; }else if(!strcmp(token, "ciphers")){ #ifdef WITH_TLS - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(conf__parse_string(&token, "ciphers", &cur_listener->ciphers, saveptr)) return MOSQ_ERR_INVAL; #else log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available."); #endif }else if(!strcmp(token, "clientid") || !strcmp(token, "remote_clientid")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1184,7 +1188,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "cleansession")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1201,7 +1205,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct if(conf__parse_string(&token, "clientid_prefixes", &config->clientid_prefixes, saveptr)) return MOSQ_ERR_INVAL; }else if(!strcmp(token, "connection")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ token = strtok_r(NULL, " ", &saveptr); if(token){ /* Check for existing bridge name. */ @@ -1249,28 +1253,28 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct if(conf__parse_bool(&token, token, &config->connection_messages, saveptr)) return MOSQ_ERR_INVAL; }else if(!strcmp(token, "crlfile")){ #ifdef WITH_TLS - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(conf__parse_string(&token, "crlfile", &cur_listener->crlfile, saveptr)) return MOSQ_ERR_INVAL; #else log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available."); #endif }else if(!strcmp(token, "dhparamfile")){ #ifdef WITH_TLS - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(conf__parse_string(&token, "dhparamfile", &cur_listener->dhparamfile, saveptr)) return MOSQ_ERR_INVAL; #else log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available."); #endif }else if(!strcmp(token, "http_dir")){ #ifdef WITH_WEBSOCKETS - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(conf__parse_string(&token, "http_dir", &cur_listener->http_dir, saveptr)) return MOSQ_ERR_INVAL; #else log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Websockets support not available."); #endif }else if(!strcmp(token, "idle_timeout")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1292,8 +1296,6 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct return 1; } - char **files; - int file_count; rc = config__get_dir_files(token, &files, &file_count); if(rc) return rc; @@ -1317,7 +1319,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct } }else if(!strcmp(token, "keepalive_interval")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1332,7 +1334,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "keyfile")){ #ifdef WITH_TLS - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(conf__parse_string(&token, "keyfile", &cur_listener->keyfile, saveptr)) return MOSQ_ERR_INVAL; #else log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available."); @@ -1392,7 +1394,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct } }else if(!strcmp(token, "local_clientid")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1403,7 +1405,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "local_password")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1414,7 +1416,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "local_username")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1549,7 +1551,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_ERR, "Error: Empty log_type value in configuration."); } }else if(!strcmp(token, "max_connections")){ - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ token = strtok_r(NULL, " ", &saveptr); if(token){ cur_listener->max_connections = atoi(token); @@ -1558,7 +1560,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_ERR, "Error: Empty max_connections value in configuration."); } }else if(!strcmp(token, "maximum_qos")){ - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(conf__parse_int(&token, "maximum_qos", &tmp_int, saveptr)) return MOSQ_ERR_INVAL; if(tmp_int < 0 || tmp_int > 2){ log__printf(NULL, MOSQ_LOG_ERR, "Error: maximum_qos must be between 0 and 2 inclusive."); @@ -1625,7 +1627,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct return MOSQ_ERR_INVAL; } }else if(!strcmp(token, "mount_point")){ - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(config->listener_count == 0){ log__printf(NULL, MOSQ_LOG_ERR, "Error: You must use create a listener before using the mount_point option in the configuration file."); return MOSQ_ERR_INVAL; @@ -1639,7 +1641,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct } }else if(!strcmp(token, "notifications")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1650,7 +1652,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "notifications_local_only")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration"); return MOSQ_ERR_INVAL; @@ -1661,7 +1663,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "notification_topic")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1672,7 +1674,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "password") || !strcmp(token, "remote_password")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1733,10 +1735,10 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_ERR, "Error: Empty persistent_client_expiration value in configuration."); } }else if(!strcmp(token, "pid_file")){ - if(reload) continue; // pid file not valid for reloading. + if(reload) continue; /* pid file not valid for reloading. */ if(conf__parse_string(&token, "pid_file", &config->pid_file, saveptr)) return MOSQ_ERR_INVAL; }else if(!strcmp(token, "port")){ - if(reload) continue; // Listener not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(config->default_listener.port){ log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Default listener port specified multiple times. Only the latest will be used."); } @@ -1783,7 +1785,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "psk_hint")){ #ifdef FINAL_WITH_TLS_PSK - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(conf__parse_string(&token, "psk_hint", &cur_listener->psk_hint, saveptr)) return MOSQ_ERR_INVAL; #else log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS/TLS-PSK support not available."); @@ -1792,14 +1794,14 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct if(conf__parse_bool(&token, token, &config->queue_qos0_messages, saveptr)) return MOSQ_ERR_INVAL; }else if(!strcmp(token, "require_certificate")){ #ifdef WITH_TLS - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(conf__parse_bool(&token, "require_certificate", &cur_listener->require_certificate, saveptr)) return MOSQ_ERR_INVAL; #else log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available."); #endif }else if(!strcmp(token, "restart_timeout")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1832,7 +1834,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_WARNING, "Warning: The retry_interval option is no longer available."); }else if(!strcmp(token, "round_robin")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1845,7 +1847,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct if(conf__parse_bool(&token, "set_tcp_nodelay", &config->set_tcp_nodelay, saveptr)) return MOSQ_ERR_INVAL; }else if(!strcmp(token, "start_type")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1873,7 +1875,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Bridge support not available."); #endif }else if(!strcmp(token, "socket_domain")){ - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ token = strtok_r(NULL, " ", &saveptr); if(token){ if(!strcmp(token, "ipv4")){ @@ -1898,7 +1900,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct } }else if(!strcmp(token, "threshold")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -1913,15 +1915,14 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "tls_engine")){ #ifdef WITH_TLS - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(conf__parse_string(&token, "tls_engine", &cur_listener->tls_engine, saveptr)) return MOSQ_ERR_INVAL; #else log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available."); #endif }else if(!strcmp(token, "tls_engine_kpass_sha1")){ #ifdef WITH_TLS - if(reload) continue; // Listeners not valid for reloading. - char *kpass_sha = NULL, *kpass_sha_bin = NULL; + if(reload) continue; /* Listeners not valid for reloading. */ if(conf__parse_string(&token, "tls_engine_kpass_sha1", &kpass_sha, saveptr)) return MOSQ_ERR_INVAL; if(mosquitto__hex2bin_sha1(kpass_sha, (unsigned char**)&kpass_sha_bin) != MOSQ_ERR_SUCCESS){ mosquitto__free(kpass_sha); @@ -1934,8 +1935,8 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "tls_keyform")){ #ifdef WITH_TLS - if(reload) continue; // Listeners not valid for reloading. - char *keyform = NULL; + if(reload) continue; /* Listeners not valid for reloading. */ + keyform = NULL; if(conf__parse_string(&token, "tls_keyform", &keyform, saveptr)) return MOSQ_ERR_INVAL; cur_listener->tls_keyform = mosq_k_pem; if(!strcmp(keyform, "engine")) cur_listener->tls_keyform = mosq_k_engine; @@ -1945,14 +1946,14 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct #endif }else if(!strcmp(token, "tls_version")){ #if defined(WITH_TLS) - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(conf__parse_string(&token, "tls_version", &cur_listener->tls_version, saveptr)) return MOSQ_ERR_INVAL; #else log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available."); #endif }else if(!strcmp(token, "topic")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -2105,7 +2106,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Bridge support not available."); #endif }else if(!strcmp(token, "max_topic_alias")){ - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ token = strtok_r(NULL, " ", &saveptr); if(token){ cur_listener->max_topic_alias = atoi(token); @@ -2114,7 +2115,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct } }else if(!strcmp(token, "try_private")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; @@ -2127,28 +2128,28 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct if(conf__parse_bool(&token, token, &config->upgrade_outgoing_qos, saveptr)) return MOSQ_ERR_INVAL; }else if(!strcmp(token, "use_identity_as_username")){ #ifdef WITH_TLS - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(conf__parse_bool(&token, "use_identity_as_username", &cur_listener->use_identity_as_username, saveptr)) return MOSQ_ERR_INVAL; #else log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available."); #endif }else if(!strcmp(token, "use_subject_as_username")){ #ifdef WITH_TLS - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(conf__parse_bool(&token, "use_subject_as_username", &cur_listener->use_subject_as_username, saveptr)) return MOSQ_ERR_INVAL; #else log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS support not available."); #endif }else if(!strcmp(token, "user")){ - if(reload) continue; // Drop privileges user not valid for reloading. + if(reload) continue; /* Drop privileges user not valid for reloading. */ mosquitto__free(config->user); if(conf__parse_string(&token, "user", &config->user, saveptr)) return MOSQ_ERR_INVAL; }else if(!strcmp(token, "use_username_as_clientid")){ - if(reload) continue; // Listeners not valid for reloading. + if(reload) continue; /* Listeners not valid for reloading. */ if(conf__parse_bool(&token, "use_username_as_clientid", &cur_listener->use_username_as_clientid, saveptr)) return MOSQ_ERR_INVAL; }else if(!strcmp(token, "username") || !strcmp(token, "remote_username")){ #ifdef WITH_BRIDGE - if(reload) continue; // FIXME + if(reload) continue; /* FIXME */ if(!cur_bridge){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration."); return MOSQ_ERR_INVAL; diff --git a/src/database.c b/src/database.c index a6c4ad2c..11980d7a 100644 --- a/src/database.c +++ b/src/database.c @@ -74,6 +74,8 @@ static bool db__ready_for_queue(struct mosquitto *context, int qos, struct mosqu int adjust_count; unsigned long source_bytes; unsigned long adjust_bytes = max_inflight_bytes; + bool valid_bytes; + bool valid_count; if(max_queued == 0 && max_queued_bytes == 0){ return true; @@ -94,8 +96,8 @@ static bool db__ready_for_queue(struct mosquitto *context, int qos, struct mosqu adjust_count = 0; } - bool valid_bytes = source_bytes - adjust_bytes < max_queued_bytes; - bool valid_count = source_count - adjust_count < max_queued; + valid_bytes = source_bytes - adjust_bytes < max_queued_bytes; + valid_count = source_count - adjust_count < max_queued; if(max_queued_bytes == 0){ return valid_count; @@ -124,7 +126,7 @@ int db__open(struct mosquitto__config *config, struct mosquitto_db *db) db->bridge_count = 0; #endif - // Initialize the hashtable + /* Initialize the hashtable */ db->clientid_index_hash = NULL; db->subs = NULL; diff --git a/src/handle_connect.c b/src/handle_connect.c index 4d8d6a27..99f1f1c3 100644 --- a/src/handle_connect.c +++ b/src/handle_connect.c @@ -378,12 +378,17 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) uint16_t auth_data_len = 0; void *auth_data_out = NULL; uint16_t auth_data_out_len = 0; + bool allow_zero_length_clientid; #ifdef WITH_TLS int i; X509 *client_cert = NULL; X509_NAME *name; X509_NAME_ENTRY *name_entry; ASN1_STRING *name_asn1 = NULL; + BIO *subject_bio; + char *data_start; + long name_length; + char *subject; #endif G_CONNECTION_COUNT_INC(); @@ -494,7 +499,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) rc = MOSQ_ERR_PROTOCOL; goto handle_connect_error; } - will_retain = ((connect_flags & 0x20) == 0x20); // Temporary hack because MSVC<1800 doesn't have stdbool.h. + will_retain = ((connect_flags & 0x20) == 0x20); password_flag = connect_flags & 0x40; username_flag = connect_flags & 0x80; @@ -537,7 +542,6 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) mosquitto__free(client_id); client_id = NULL; - bool allow_zero_length_clientid; if(db->config->per_listener_settings){ allow_zero_length_clientid = context->listener->security_options.allow_zero_length_clientid; }else{ @@ -687,7 +691,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) rc = 1; goto handle_connect_error; } - if (context->listener->use_identity_as_username) { //use_identity_as_username + if (context->listener->use_identity_as_username) { /* use_identity_as_username */ i = X509_NAME_get_index_by_NID(name, NID_commonName, -1); if(i == -1){ if(context->protocol == mosq_p_mqtt5){ @@ -735,12 +739,12 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) goto handle_connect_error; } } - } else { // use_subject_as_username - BIO *subject_bio = BIO_new(BIO_s_mem()); + } else { /* use_subject_as_username */ + subject_bio = BIO_new(BIO_s_mem()); X509_NAME_print_ex(subject_bio, X509_get_subject_name(client_cert), 0, XN_FLAG_RFC2253); - char *data_start = NULL; - long name_length = BIO_get_mem_data(subject_bio, &data_start); - char *subject = mosquitto__malloc(sizeof(char)*name_length+1); + data_start = NULL; + name_length = BIO_get_mem_data(subject_bio, &data_start); + subject = mosquitto__malloc(sizeof(char)*name_length+1); if(!subject){ BIO_free(subject_bio); rc = MOSQ_ERR_NOMEM; diff --git a/src/net.c b/src/net.c index 21060db6..153c6956 100644 --- a/src/net.c +++ b/src/net.c @@ -444,6 +444,10 @@ int net__tls_load_verify(struct mosquitto__listener *listener) { #ifdef WITH_TLS ENGINE *engine = NULL; +# if !defined(OPENSSL_NO_ENGINE) + UI_METHOD *ui_method; + EVP_PKEY *pkey; +# endif int rc; rc = SSL_CTX_load_verify_locations(listener->ssl_ctx, listener->cafile, listener->capath); @@ -493,7 +497,7 @@ int net__tls_load_verify(struct mosquitto__listener *listener) } if(listener->tls_engine && listener->tls_keyform == mosq_k_engine){ #if !defined(OPENSSL_NO_ENGINE) - UI_METHOD *ui_method = net__get_ui_method(); + ui_method = net__get_ui_method(); if(listener->tls_engine_kpass_sha1){ if(!ENGINE_ctrl_cmd(engine, ENGINE_SECRET_MODE, ENGINE_SECRET_MODE_SHA, NULL, NULL, 0)){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to set engine secret mode sha"); @@ -509,7 +513,7 @@ int net__tls_load_verify(struct mosquitto__listener *listener) } ui_method = NULL; } - EVP_PKEY *pkey = ENGINE_load_private_key(engine, listener->keyfile, ui_method, NULL); + pkey = ENGINE_load_private_key(engine, listener->keyfile, ui_method, NULL); if(!pkey){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load engine private key file \"%s\".", listener->keyfile); net__print_ssl_error(NULL); diff --git a/src/persist_read.c b/src/persist_read.c index 9e4b1816..fd87d825 100644 --- a/src/persist_read.c +++ b/src/persist_read.c @@ -408,7 +408,7 @@ int persist__restore(struct mosquitto_db *db) goto error; } if(!memcmp(header, magic, 15)){ - // Restore DB as normal + /* Restore DB as normal */ read_e(fptr, &crc, sizeof(uint32_t)); read_e(fptr, &i32temp, sizeof(uint32_t)); db_version = ntohl(i32temp); diff --git a/src/persist_read_v234.c b/src/persist_read_v234.c index b0987282..27f52bd5 100644 --- a/src/persist_read_v234.c +++ b/src/persist_read_v234.c @@ -57,8 +57,8 @@ int persist__chunk_header_read_v234(FILE *db_fptr, int *chunk, int *length) int persist__chunk_cfg_read_v234(FILE *db_fptr, struct PF_cfg *chunk) { - read_e(db_fptr, &chunk->shutdown, sizeof(uint8_t)); // shutdown - read_e(db_fptr, &chunk->dbid_size, sizeof(uint8_t)); // sizeof(dbid_t) + read_e(db_fptr, &chunk->shutdown, sizeof(uint8_t)); /* shutdown */ + read_e(db_fptr, &chunk->dbid_size, sizeof(uint8_t)); /* sizeof(dbid_t) */ read_e(db_fptr, &chunk->last_db_id, sizeof(dbid_t)); return MOSQ_ERR_SUCCESS; diff --git a/src/security.c b/src/security.c index eb37c88d..7779ca55 100644 --- a/src/security.c +++ b/src/security.c @@ -549,7 +549,7 @@ int mosquitto_security_cleanup(struct mosquitto_db *db, bool reload) } -//int mosquitto_acl_check(struct mosquitto_db *db, struct mosquitto *context, const char *topic, int access) +/* int mosquitto_acl_check(struct mosquitto_db *db, struct mosquitto *context, const char *topic, int access) */ static int acl__check_single(struct mosquitto__auth_plugin_config *auth_plugin, struct mosquitto *context, struct mosquitto_acl_msg *msg, int access) { const char *username; @@ -610,7 +610,7 @@ static int acl__check_dollar(const char *topic, int access) }else if(!strncmp(topic, "$share", 6)){ /* Only allow sub/unsub to shared subscriptions */ if(access == MOSQ_ACL_SUBSCRIBE){ - //FIXME if(access == MOSQ_ACL_SUBSCRIBE || access == MOSQ_ACL_UNSUBSCRIBE){ + /* FIXME if(access == MOSQ_ACL_SUBSCRIBE || access == MOSQ_ACL_UNSUBSCRIBE){ */ return MOSQ_ERR_SUCCESS; }else{ return MOSQ_ERR_ACL_DENIED; diff --git a/src/security_default.c b/src/security_default.c index 7cc10614..3eacce75 100644 --- a/src/security_default.c +++ b/src/security_default.c @@ -396,7 +396,7 @@ int mosquitto_acl_check_default(struct mosquitto_db *db, struct mosquitto *conte len = tlen + acl_root->ccount*(clen-2); } local_acl = mosquitto__malloc(len+1); - if(!local_acl) return 1; // FIXME + if(!local_acl) return 1; /* FIXME */ s = local_acl; for(i=0; itopic[i] == '%'){ @@ -465,8 +465,9 @@ static int aclfile__parse(struct mosquitto_db *db, struct mosquitto__security_op return 1; } - // topic [read|write] - // user + /* topic [read|write] + * user + */ while(fgets_extending(&buf, &buflen, aclfptr)){ slen = strlen(buf); @@ -1000,6 +1001,10 @@ int mosquitto_security_apply_default(struct mosquitto_db *db) X509_NAME_ENTRY *name_entry; ASN1_STRING *name_asn1 = NULL; struct mosquitto__listener *listener; + BIO *subject_bio; + char *data_start; + long name_length; + char *subject; #endif if(!db) return MOSQ_ERR_INVAL; @@ -1078,7 +1083,7 @@ int mosquitto_security_apply_default(struct mosquitto_db *db) security__disconnect_auth(db, context); continue; } - if (context->listener->use_identity_as_username) { //use_identity_as_username + if (context->listener->use_identity_as_username) { /* use_identity_as_username */ i = X509_NAME_get_index_by_NID(name, NID_commonName, -1); if(i == -1){ X509_free(client_cert); @@ -1114,12 +1119,12 @@ int mosquitto_security_apply_default(struct mosquitto_db *db) continue; } } - } else { // use_subject_as_username - BIO *subject_bio = BIO_new(BIO_s_mem()); + } else { /* use_subject_as_username */ + subject_bio = BIO_new(BIO_s_mem()); X509_NAME_print_ex(subject_bio, X509_get_subject_name(client_cert), 0, XN_FLAG_RFC2253); - char *data_start = NULL; - long name_length = BIO_get_mem_data(subject_bio, &data_start); - char *subject = mosquitto__malloc(sizeof(char)*name_length+1); + data_start = NULL; + name_length = BIO_get_mem_data(subject_bio, &data_start); + subject = mosquitto__malloc(sizeof(char)*name_length+1); if(!subject){ BIO_free(subject_bio); X509_free(client_cert); @@ -1227,7 +1232,7 @@ int pw__digest(const char *password, const unsigned char *salt, unsigned int sal digest = EVP_get_digestbyname("sha512"); if(!digest){ - // FIXME fprintf(stderr, "Error: Unable to create openssl digest.\n"); + /* FIXME fprintf(stderr, "Error: Unable to create openssl digest.\n"); */ return 1; } @@ -1243,7 +1248,7 @@ int pw__digest(const char *password, const unsigned char *salt, unsigned int sal digest = EVP_get_digestbyname("sha512"); if(!digest){ - // FIXME fprintf(stderr, "Error: Unable to create openssl digest.\n"); + /* FIXME fprintf(stderr, "Error: Unable to create openssl digest.\n"); */ return 1; } diff --git a/src/sys_tree.c b/src/sys_tree.c index c7d746f5..4e11cfd4 100644 --- a/src/sys_tree.c +++ b/src/sys_tree.c @@ -213,6 +213,7 @@ void sys_tree__update(struct mosquitto_db *db, int interval, time_t start_time) double exponent; double i_mult; + bool initial_publish; now = mosquitto_time(); @@ -222,7 +223,7 @@ void sys_tree__update(struct mosquitto_db *db, int interval, time_t start_time) db__messages_easy_queue(db, NULL, "$SYS/broker/uptime", SYS_TREE_QOS, strlen(buf), buf, 1, 60, NULL); sys_tree__update_clients(db, buf); - bool initial_publish = false; + initial_publish = false; if(last_update == 0){ initial_publish = true; last_update = 1; diff --git a/src/websockets.c b/src/websockets.c index fd2330b0..fccece30 100644 --- a/src/websockets.c +++ b/src/websockets.c @@ -694,7 +694,7 @@ static int callback_http(struct libwebsocket_context *context, static void log_wrap(int level, const char *line) { char *l = (char *)line; - l[strlen(line)-1] = '\0'; // Remove \n + l[strlen(line)-1] = '\0'; /* Remove \n */ log__printf(NULL, MOSQ_LOG_WEBSOCKETS, "%s", l); } From 7f41e37f0f0c83dcbe19370c7e3d5ade02d1bd02 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 12 Mar 2020 11:52:58 +0000 Subject: [PATCH 005/113] Fix use of sed on BSD. Closes #1614. Thanks to Christoph Krey. --- ChangeLog.txt | 1 + config.mk | 2 ++ lib/Makefile | 2 +- lib/cpp/Makefile | 2 +- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index f131f058..203c27fb 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,5 +1,6 @@ Build: - Various fixes for building with Date: Tue, 10 Mar 2020 04:05:50 +0800 Subject: [PATCH 006/113] Fix potential memory leak. WebSocket context may lost since db->ll_for_free = NULL; operation on the bottom of context__free_disused() function. Signed-off-by: Michael Liu --- src/context.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/context.c b/src/context.c index d1db7f68..fd9ac17b 100644 --- a/src/context.c +++ b/src/context.c @@ -259,12 +259,8 @@ void context__add_to_disused(struct mosquitto_db *db, struct mosquitto *context) context->id = NULL; } - if(db->ll_for_free){ - context->for_free_next = db->ll_for_free; - db->ll_for_free = context; - }else{ - db->ll_for_free = context; - } + context->for_free_next = db->ll_for_free; + db->ll_for_free = context; } void context__free_disused(struct mosquitto_db *db) @@ -276,6 +272,7 @@ void context__free_disused(struct mosquitto_db *db) assert(db); context = db->ll_for_free; + db->ll_for_free = NULL; while(context){ #ifdef WITH_WEBSOCKETS if(context->wsi){ @@ -297,7 +294,6 @@ void context__free_disused(struct mosquitto_db *db) context = next; } } - db->ll_for_free = NULL; } From 24e34434a4347d690c2ffe7fbc4aae088e89f334 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 7 Mar 2020 00:28:32 +0800 Subject: [PATCH 007/113] Move SSL prepare and accept operations out of deep loop Since all resources are ready, do not need lookup again. Signed-off-by: Michael Liu --- src/net.c | 64 +++++++++++++++++++++++++------------------------------ 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/src/net.c b/src/net.c index 153c6956..689c43cc 100644 --- a/src/net.c +++ b/src/net.c @@ -199,43 +199,37 @@ int net__socket_accept(struct mosquitto_db *db, mosq_sock_t listensock) #ifdef WITH_TLS /* TLS init */ - for(i=0; iconfig->listener_count; i++){ - for(j=0; jconfig->listeners[i].sock_count; j++){ - if(db->config->listeners[i].socks[j] == listensock){ - if(db->config->listeners[i].ssl_ctx){ - new_context->ssl = SSL_new(db->config->listeners[i].ssl_ctx); - if(!new_context->ssl){ - context__cleanup(db, new_context, true); - return -1; - } - SSL_set_ex_data(new_context->ssl, tls_ex_index_context, new_context); - SSL_set_ex_data(new_context->ssl, tls_ex_index_listener, &db->config->listeners[i]); - new_context->want_write = true; - bio = BIO_new_socket(new_sock, BIO_NOCLOSE); - SSL_set_bio(new_context->ssl, bio, bio); - ERR_clear_error(); - rc = SSL_accept(new_context->ssl); - if(rc != 1){ - rc = SSL_get_error(new_context->ssl, rc); - if(rc == SSL_ERROR_WANT_READ){ - /* We always want to read. */ - }else if(rc == SSL_ERROR_WANT_WRITE){ - new_context->want_write = true; - }else{ - if(db->config->connection_messages == true){ - e = ERR_get_error(); - while(e){ - log__printf(NULL, MOSQ_LOG_NOTICE, - "Client connection from %s failed: %s.", - new_context->address, ERR_error_string(e, ebuf)); - e = ERR_get_error(); - } - } - context__cleanup(db, new_context, true); - return -1; - } + if(new_context->listener->ssl_ctx){ + new_context->ssl = SSL_new(new_context->listener->ssl_ctx); + if(!new_context->ssl){ + context__cleanup(db, new_context, true); + return -1; + } + SSL_set_ex_data(new_context->ssl, tls_ex_index_context, new_context); + SSL_set_ex_data(new_context->ssl, tls_ex_index_listener, new_context->listener); + new_context->want_write = true; + bio = BIO_new_socket(new_sock, BIO_NOCLOSE); + SSL_set_bio(new_context->ssl, bio, bio); + ERR_clear_error(); + rc = SSL_accept(new_context->ssl); + if(rc != 1){ + rc = SSL_get_error(new_context->ssl, rc); + if(rc == SSL_ERROR_WANT_READ){ + /* We always want to read. */ + }else if(rc == SSL_ERROR_WANT_WRITE){ + new_context->want_write = true; + }else{ + if(db->config->connection_messages == true){ + e = ERR_get_error(); + while(e){ + log__printf(NULL, MOSQ_LOG_NOTICE, + "Client connection from %s failed: %s.", + new_context->address, ERR_error_string(e, ebuf)); + e = ERR_get_error(); } } + context__cleanup(db, new_context, true); + return -1; } } } From 2488d6acf18ed9ddfd14070719ff51f3d4d807f2 Mon Sep 17 00:00:00 2001 From: Stavros Vagionitis Date: Fri, 14 Feb 2020 09:59:46 +0000 Subject: [PATCH 008/113] mosquitto.service: mosquitto starts even if the network is offline This patch changes the behavior of how mosquitto is starting using systemd. Currently it is starting only when the network is online, meaning that the network is configured to a routable IP address. With this patch, mosquitto is starting when the network is offline, does not need to be configured. This is needed because the MQTT broker might be used as an internal message bus which does not need the network to be online. Signed-off-by: Stavros Vagionitis --- service/systemd/mosquitto.service.notify | 4 ++-- service/systemd/mosquitto.service.simple | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/service/systemd/mosquitto.service.notify b/service/systemd/mosquitto.service.notify index d409887d..584a1101 100644 --- a/service/systemd/mosquitto.service.notify +++ b/service/systemd/mosquitto.service.notify @@ -1,8 +1,8 @@ [Unit] Description=Mosquitto MQTT v3.1/v3.1.1 Broker Documentation=man:mosquitto.conf(5) man:mosquitto(8) -After=network-online.target -Wants=network-online.target +After=network.target +Wants=network.target [Service] Type=notify diff --git a/service/systemd/mosquitto.service.simple b/service/systemd/mosquitto.service.simple index 71ab4c16..4346ea14 100644 --- a/service/systemd/mosquitto.service.simple +++ b/service/systemd/mosquitto.service.simple @@ -1,8 +1,8 @@ [Unit] Description=Mosquitto MQTT v3.1/v3.1.1 Broker Documentation=man:mosquitto.conf(5) man:mosquitto(8) -After=network-online.target -Wants=network-online.target +After=network.target +Wants=network.target [Service] ExecStart=/usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf From 346f695937d0eb05b6fafeaef0fd2ab52a3dbc32 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 12 Mar 2020 13:51:01 +0000 Subject: [PATCH 009/113] Separate out delay code from previous commit. Plus add missing header. --- lib/loop.c | 86 ++++++++++++++++++++++++++----------------------- lib/mosquitto.c | 1 + 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/lib/loop.c b/lib/loop.c index dffb254b..048b8211 100644 --- a/lib/loop.c +++ b/lib/loop.c @@ -191,7 +191,7 @@ int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets) } -int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets) +static int interruptible_sleep(struct mosquitto *mosq, unsigned long reconnect_delay) { #ifdef HAVE_PSELECT struct timespec local_timeout; @@ -202,12 +202,52 @@ int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets) int fdcount; char pairbuf; int maxfd = 0; + + local_timeout.tv_sec = reconnect_delay; +#ifdef HAVE_PSELECT + local_timeout.tv_nsec = 0; +#else + local_timeout.tv_usec = 0; +#endif + FD_ZERO(&readfds); + maxfd = 0; + if(mosq->sockpairR != INVALID_SOCKET){ + /* sockpairR is used to break out of select() before the + * timeout, when mosquitto_loop_stop() is called */ + FD_SET(mosq->sockpairR, &readfds); + maxfd = mosq->sockpairR; + } +#ifdef HAVE_PSELECT + fdcount = pselect(maxfd+1, &readfds, NULL, NULL, &local_timeout, NULL); +#else + fdcount = select(maxfd+1, &readfds, NULL, NULL, &local_timeout); +#endif + if(fdcount == -1){ +#ifdef WIN32 + errno = WSAGetLastError(); +#endif + if(errno == EINTR){ + return MOSQ_ERR_SUCCESS; + }else{ + return MOSQ_ERR_ERRNO; + } + }else if(mosq->sockpairR != INVALID_SOCKET && FD_ISSET(mosq->sockpairR, &readfds)){ +#ifndef WIN32 + if(read(mosq->sockpairR, &pairbuf, 1) == 0){ + } +#else + recv(mosq->sockpairR, &pairbuf, 1, 0); +#endif + } + return MOSQ_ERR_SUCCESS; +} + + +int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets) +{ int run = 1; int rc; unsigned long reconnect_delay; -#ifndef WIN32 - struct timespec req, rem; -#endif int state; if(!mosq) return MOSQ_ERR_INVAL; @@ -261,42 +301,8 @@ int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets) mosq->reconnects++; } - local_timeout.tv_sec = reconnect_delay; -#ifdef HAVE_PSELECT - local_timeout.tv_nsec = 0; -#else - local_timeout.tv_usec = 0; -#endif - FD_ZERO(&readfds); - maxfd = 0; - if(mosq->sockpairR != INVALID_SOCKET){ - /* sockpairR is used to break out of select() before the - * timeout, when mosquitto_loop_stop() is called */ - FD_SET(mosq->sockpairR, &readfds); - maxfd = mosq->sockpairR; - } -#ifdef HAVE_PSELECT - fdcount = pselect(maxfd+1, &readfds, NULL, NULL, &local_timeout, NULL); -#else - fdcount = select(maxfd+1, &readfds, NULL, NULL, &local_timeout); -#endif - if(fdcount == -1){ -#ifdef WIN32 - errno = WSAGetLastError(); -#endif - if(errno == EINTR){ - return MOSQ_ERR_SUCCESS; - }else{ - return MOSQ_ERR_ERRNO; - } - }else if(mosq->sockpairR != INVALID_SOCKET && FD_ISSET(mosq->sockpairR, &readfds)){ -#ifndef WIN32 - if(read(mosq->sockpairR, &pairbuf, 1) == 0){ - } -#else - recv(mosq->sockpairR, &pairbuf, 1, 0); -#endif - } + rc = interruptible_sleep(mosq, reconnect_delay); + if(rc) return rc; state = mosquitto__get_state(mosq); if(state == mosq_cs_disconnecting || state == mosq_cs_disconnected){ diff --git a/lib/mosquitto.c b/lib/mosquitto.c index 173e716e..c49c53cf 100644 --- a/lib/mosquitto.c +++ b/lib/mosquitto.c @@ -24,6 +24,7 @@ Contributors: #include #endif +#include "logging_mosq.h" #include "mosquitto.h" #include "mosquitto_internal.h" #include "memory_mosq.h" From a16d7e0661d74e8c4e53e12bbfc24f22878aee25 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 19 Mar 2020 15:38:29 +0000 Subject: [PATCH 010/113] iDon't treat an unexpected PUBREL as fatal. Issue #1629. Thanks to radcrabs. --- ChangeLog.txt | 3 + lib/handle_pubrel.c | 8 ++- test/lib/Makefile | 1 + .../c/03-publish-b2c-qos2-unexpected-pubrel.c | 72 +++++++++++++++++++ test/lib/c/Makefile | 1 + test/lib/test.py | 1 + 6 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 test/lib/c/03-publish-b2c-qos2-unexpected-pubrel.c diff --git a/ChangeLog.txt b/ChangeLog.txt index 203c27fb..aa07c672 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,6 @@ +Client library: +- Don't treat an unexpected PUBREL as a fatal error. Issue #1629. + Build: - Various fixes for building with callback_mutex); @@ -120,6 +118,10 @@ int handle__pubrel(struct mosquitto_db *db, struct mosquitto *mosq) pthread_mutex_unlock(&mosq->callback_mutex); mosquitto_property_free_all(&properties); message__cleanup(&message); + }else if(rc == MOSQ_ERR_NOT_FOUND){ + return MOSQ_ERR_SUCCESS; + }else{ + return rc; } #endif diff --git a/test/lib/Makefile b/test/lib/Makefile index 3462e252..941bf02d 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -41,6 +41,7 @@ c : test-compile ./03-publish-b2c-qos1.py $@/03-publish-b2c-qos1.test ./03-publish-b2c-qos2-len.py $@/03-publish-b2c-qos2-len.test ./03-publish-b2c-qos2.py $@/03-publish-b2c-qos2.test + ./03-publish-b2c-qos2-unexpected-pubrel.py $@/03-publish-b2c-qos2-unexpected-pubrel.test ./03-publish-c2b-qos1-disconnect.py $@/03-publish-c2b-qos1-disconnect.test ./03-publish-c2b-qos1-len.py $@/03-publish-c2b-qos1-len.test ./03-publish-c2b-qos1-receive-maximum.py $@/03-publish-c2b-qos1-receive-maximum.test diff --git a/test/lib/c/03-publish-b2c-qos2-unexpected-pubrel.c b/test/lib/c/03-publish-b2c-qos2-unexpected-pubrel.c new file mode 100644 index 00000000..091a6045 --- /dev/null +++ b/test/lib/c/03-publish-b2c-qos2-unexpected-pubrel.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include + +static int run = -1; + +void on_connect(struct mosquitto *mosq, void *obj, int rc) +{ + if(rc){ + exit(1); + } +} + +void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg) +{ + if(msg->mid != 13423){ + printf("Invalid mid (%d)\n", msg->mid); + exit(1); + } + if(msg->qos != 2){ + printf("Invalid qos (%d)\n", msg->qos); + exit(1); + } + if(strcmp(msg->topic, "pub/qos2/receive")){ + printf("Invalid topic (%s)\n", msg->topic); + exit(1); + } + if(strcmp(msg->payload, "message")){ + printf("Invalid payload (%s)\n", (char *)msg->payload); + exit(1); + } + if(msg->payloadlen != 7){ + printf("Invalid payloadlen (%d)\n", msg->payloadlen); + exit(1); + } + if(msg->retain != false){ + printf("Invalid retain (%d)\n", msg->retain); + exit(1); + } + + run = 0; +} + +int main(int argc, char *argv[]) +{ + int rc; + struct mosquitto *mosq; + + int port = atoi(argv[1]); + + mosquitto_lib_init(); + + mosq = mosquitto_new("publish-qos2-test", true, &run); + mosquitto_connect_callback_set(mosq, on_connect); + mosquitto_message_callback_set(mosq, on_message); + mosquitto_message_retry_set(mosq, 5); + + rc = mosquitto_connect(mosq, "localhost", port, 60); + + while(run == -1){ + rc = mosquitto_loop(mosq, 300, 1); + if(rc){ + printf("%d:%s\n", rc, mosquitto_strerror(rc)); + exit(1); + } + } + + mosquitto_lib_cleanup(); + return run; +} diff --git a/test/lib/c/Makefile b/test/lib/c/Makefile index 79d1fc03..91d5a95c 100644 --- a/test/lib/c/Makefile +++ b/test/lib/c/Makefile @@ -27,6 +27,7 @@ SRC = \ 03-publish-c2b-qos2-disconnect.c \ 03-publish-c2b-qos2-len.c \ 03-publish-b2c-qos2-len.c \ + 03-publish-b2c-qos2-unexpected-pubrel.c \ 03-publish-c2b-qos1-receive-maximum.c \ 03-publish-c2b-qos2-receive-maximum-1.c \ 03-publish-c2b-qos2-receive-maximum-2.c \ diff --git a/test/lib/test.py b/test/lib/test.py index d61b01c0..885055a7 100755 --- a/test/lib/test.py +++ b/test/lib/test.py @@ -23,6 +23,7 @@ tests = [ (1, ['./03-publish-b2c-qos1.py', 'c/03-publish-b2c-qos1.test']), (1, ['./03-publish-b2c-qos2-len.py', 'c/03-publish-b2c-qos2-len.test']), + (1, ['./03-publish-b2c-qos2-unexpected-pubrel.py', 'c/03-publish-b2c-qos2-unexpected-pubrel.test']), (1, ['./03-publish-b2c-qos2.py', 'c/03-publish-b2c-qos2.test']), (1, ['./03-publish-c2b-qos1-disconnect.py', 'c/03-publish-c2b-qos1-disconnect.test']), (1, ['./03-publish-c2b-qos1-len.py', 'c/03-publish-c2b-qos1-len.test']), From 22e0a4ba9bd6b0ce0f430638a54e6d9d1ca4af59 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 19 Mar 2020 15:45:18 +0000 Subject: [PATCH 011/113] Updated pull rqeuest text. --- .github/pull_request_template.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 7a283e07..9a93dc05 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,8 +1,18 @@ +Thank you for contributing your time to the Mosquitto project! + +Before you go any further, please note that we cannot accept contributions if +you haven't signed the [Eclipse Contributor Agreement](https://www.eclipse.org/legal/ECA.php). +If you aren't able to do that, or just don't want to, please describe your bug +fix/feature change in an issue. For simple bug fixes it is can be just as easy +for us to be told about the problem and then go fix it directly. + +Then please check the following list of things we ask for in your pull request: + +- [ ] Have you signed the [Eclipse Contributor Agreement](https://www.eclipse.org/legal/ECA.php), using the same email address as you used in your commits? +- [ ] Do each of your commits have a "Signed-off-by" line, with the correct email address? Use "git commit -s" to generate this line for you. - [ ] If you are contributing a new feature, is your work based off the develop branch? - [ ] If you are contributing a bugfix, is your work based off the fixes branch? - [ ] Have you added an explanation of what your changes do and why you'd like us to include them? - [ ] Have you successfully run `make test` with your changes locally? -- [ ] Have you signed the [Eclipse Contributor Agreement](https://www.eclipse.org/legal/ECA.php), using the same email address as you used in your commits? -- [ ] Do each of your commits have a "Signed-off-by" line, with the correct email address? Use "git commit -s" to generate this line for you. ----- From 4ab0f4bd3979fc196b2cec04a9298ecc7a38f62a Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Fri, 27 Mar 2020 21:44:19 +0000 Subject: [PATCH 012/113] Fix bundled deps option not being propagated to library. Issue #1641. --- CMakeLists.txt | 1 + src/CMakeLists.txt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f5b9f661..26b3e7a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,7 @@ endif (WIN32) include(GNUInstallDirs) +option(WITH_BUNDLED_DEPS "Build with bundled dependencies?" ON) option(WITH_TLS "Include SSL/TLS support?" ON) option(WITH_TLS_PSK diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5774c1fa..ee34673b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -64,7 +64,6 @@ set (MOSQ_SRCS ../lib/will_mosq.c ../lib/will_mosq.h) -option(WITH_BUNDLED_DEPS "Build with bundled dependencies?" ON) if (WITH_BUNDLED_DEPS) include_directories(${mosquitto_SOURCE_DIR} ${mosquitto_SOURCE_DIR}/src/deps) endif (WITH_BUNDLED_DEPS) From de25ff694ed01203d61d8773c237679ed373dc77 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Sat, 28 Mar 2020 22:39:56 +0000 Subject: [PATCH 013/113] Report invalid bridge prefix+pattern combinations at config parsing time Rather than letting the bridge fail later. Issue #1635. Thanks to pokerazor. --- ChangeLog.txt | 4 ++++ src/conf.c | 32 ++++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index aa07c672..5dc3fc23 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,7 @@ +Broker: +- Report invalid bridge prefix+pattern combinations at config parsing time + rather than letting the bridge fail later. Issue #1635. + Client library: - Don't treat an unexpected PUBREL as a fatal error. Issue #1629. diff --git a/src/conf.c b/src/conf.c index cd571d4c..b8c61ffc 100644 --- a/src/conf.c +++ b/src/conf.c @@ -2021,11 +2021,22 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge topic local prefix '%s'.", token); return MOSQ_ERR_INVAL; } - cur_topic->local_prefix = mosquitto__strdup(token); - if(!cur_topic->local_prefix){ + cur_topic->local_prefix = malloc(strlen(cur_topic->topic) + strlen(token) + 1); + if(cur_topic == NULL){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); return MOSQ_ERR_NOMEM; } + /* Print prefix+pattern to check for validity */ + snprintf(cur_topic->local_prefix, strlen(cur_topic->topic) + strlen(token)+1, + "%s%s", token, cur_topic->topic); + if(mosquitto_sub_topic_check(cur_topic->local_prefix) != MOSQ_ERR_SUCCESS){ + log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge topic local prefix and pattern combination '%s'.", cur_topic->local_prefix); + return MOSQ_ERR_INVAL; + } + + /* Print just the prefix for storage */ + snprintf(cur_topic->local_prefix, strlen(cur_topic->topic) + strlen(token)+1, + "%s", token); } token = strtok_r(NULL, " ", &saveptr); @@ -2037,11 +2048,24 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge topic remote prefix '%s'.", token); return MOSQ_ERR_INVAL; } - cur_topic->remote_prefix = mosquitto__strdup(token); - if(!cur_topic->remote_prefix){ + cur_topic->remote_prefix = malloc(strlen(cur_topic->topic) + strlen(token) + 1); + if(cur_topic == NULL){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); return MOSQ_ERR_NOMEM; } + /* Print prefix+pattern to check for validity */ + snprintf(cur_topic->remote_prefix, strlen(cur_topic->topic) + strlen(token)+1, + "%s%s", token, cur_topic->topic); + if(mosquitto_sub_topic_check(cur_topic->remote_prefix) != MOSQ_ERR_SUCCESS){ + log__printf(NULL, MOSQ_LOG_ERR, + "Error: Invalid bridge topic remote prefix and pattern combination '%s'.", + cur_topic->remote_prefix); + return MOSQ_ERR_INVAL; + } + + /* Print just the prefix for storage */ + snprintf(cur_topic->remote_prefix, strlen(cur_topic->topic) + strlen(token)+1, + "%s", token); } } } From 21f203b91a8ff4622d1a33066b4c87007ceeb1de Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Sat, 28 Mar 2020 23:33:01 +0000 Subject: [PATCH 014/113] Don't treact unexpected PUBACK/COMP as fatal. --- ChangeLog.txt | 3 +- lib/handle_pubackcomp.c | 6 +- .../03-publish-b2c-qos1-unexpected-puback.py | 62 +++++++++++++++++++ .../03-publish-b2c-qos2-unexpected-pubcomp.py | 62 +++++++++++++++++++ test/lib/Makefile | 2 + .../c/03-publish-b2c-qos1-unexpected-puback.c | 40 ++++++++++++ .../03-publish-b2c-qos2-unexpected-pubcomp.c | 40 ++++++++++++ test/lib/c/Makefile | 44 ++++++------- test/lib/test.py | 2 + 9 files changed, 236 insertions(+), 25 deletions(-) create mode 100755 test/lib/03-publish-b2c-qos1-unexpected-puback.py create mode 100755 test/lib/03-publish-b2c-qos2-unexpected-pubcomp.py create mode 100644 test/lib/c/03-publish-b2c-qos1-unexpected-puback.c create mode 100644 test/lib/c/03-publish-b2c-qos2-unexpected-pubcomp.c diff --git a/ChangeLog.txt b/ChangeLog.txt index 5dc3fc23..31076c58 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -3,7 +3,8 @@ Broker: rather than letting the bridge fail later. Issue #1635. Client library: -- Don't treat an unexpected PUBREL as a fatal error. Issue #1629. +- Don't treat an unexpected PUBACK, PUBREL, or PUBCOMP as a fatal error. + Issue #1629. Build: - Various fixes for building with id, type, mid, reason_code); rc = message__delete(mosq, mid, mosq_md_out, qos); - if(rc){ - return rc; - }else{ + if(rc == MOSQ_ERR_SUCCESS){ /* Only inform the client the message has been sent once. */ pthread_mutex_lock(&mosq->callback_mutex); if(mosq->on_publish){ @@ -109,6 +107,8 @@ int handle__pubackcomp(struct mosquitto *mosq, const char *type) } pthread_mutex_unlock(&mosq->callback_mutex); mosquitto_property_free_all(&properties); + }else if(rc != MOSQ_ERR_NOT_FOUND){ + return rc; } pthread_mutex_lock(&mosq->msgs_out.mutex); message__release_to_inflight(mosq, mosq_md_out); diff --git a/test/lib/03-publish-b2c-qos1-unexpected-puback.py b/test/lib/03-publish-b2c-qos1-unexpected-puback.py new file mode 100755 index 00000000..58921e98 --- /dev/null +++ b/test/lib/03-publish-b2c-qos1-unexpected-puback.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 + +from mosq_test_helper import * + +port = mosq_test.get_lib_port() + +rc = 1 +keepalive = 5 +connect_packet = mosq_test.gen_connect("publish-qos1-test", keepalive=keepalive) +connack_packet = mosq_test.gen_connack(rc=0) + +disconnect_packet = mosq_test.gen_disconnect() + +mid = 13423 +puback_packet = mosq_test.gen_puback(mid) +pingreq_packet = mosq_test.gen_pingreq() + +sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +sock.settimeout(10) +sock.bind(('', port)) +sock.listen(5) + +client_args = sys.argv[1:] +env = dict(os.environ) +env['LD_LIBRARY_PATH'] = '../../lib:../../lib/cpp' +try: + pp = env['PYTHONPATH'] +except KeyError: + pp = '' +env['PYTHONPATH'] = '../../lib/python:'+pp +client = mosq_test.start_client(filename=sys.argv[1].replace('/', '-'), cmd=client_args, env=env, port=port) + +try: + (conn, address) = sock.accept() + conn.settimeout(10) + + if mosq_test.expect_packet(conn, "connect", connect_packet): + conn.send(connack_packet) + conn.send(puback_packet) + + if mosq_test.expect_packet(conn, "pingreq", pingreq_packet): + rc = 0 + + conn.close() +finally: + for i in range(0, 5): + if client.returncode != None: + break + time.sleep(0.1) + + try: + client.terminate() + except OSError: + pass + + client.wait() + sock.close() + if rc != 0 or client.returncode != 0: + exit(1) + +exit(rc) diff --git a/test/lib/03-publish-b2c-qos2-unexpected-pubcomp.py b/test/lib/03-publish-b2c-qos2-unexpected-pubcomp.py new file mode 100755 index 00000000..8e73c7cd --- /dev/null +++ b/test/lib/03-publish-b2c-qos2-unexpected-pubcomp.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 + +from mosq_test_helper import * + +port = mosq_test.get_lib_port() + +rc = 1 +keepalive = 5 +connect_packet = mosq_test.gen_connect("publish-qos2-test", keepalive=keepalive) +connack_packet = mosq_test.gen_connack(rc=0) + +disconnect_packet = mosq_test.gen_disconnect() + +mid = 13423 +pubcomp_packet = mosq_test.gen_pubcomp(mid) +pingreq_packet = mosq_test.gen_pingreq() + +sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +sock.settimeout(10) +sock.bind(('', port)) +sock.listen(5) + +client_args = sys.argv[1:] +env = dict(os.environ) +env['LD_LIBRARY_PATH'] = '../../lib:../../lib/cpp' +try: + pp = env['PYTHONPATH'] +except KeyError: + pp = '' +env['PYTHONPATH'] = '../../lib/python:'+pp +client = mosq_test.start_client(filename=sys.argv[1].replace('/', '-'), cmd=client_args, env=env, port=port) + +try: + (conn, address) = sock.accept() + conn.settimeout(10) + + if mosq_test.expect_packet(conn, "connect", connect_packet): + conn.send(connack_packet) + conn.send(pubcomp_packet) + + if mosq_test.expect_packet(conn, "pingreq", pingreq_packet): + rc = 0 + + conn.close() +finally: + for i in range(0, 5): + if client.returncode != None: + break + time.sleep(0.1) + + try: + client.terminate() + except OSError: + pass + + client.wait() + sock.close() + if rc != 0 or client.returncode != 0: + exit(1) + +exit(rc) diff --git a/test/lib/Makefile b/test/lib/Makefile index 941bf02d..93603f5b 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -39,9 +39,11 @@ c : test-compile ./02-unsubscribe-v5.py $@/02-unsubscribe-v5.test ./02-unsubscribe.py $@/02-unsubscribe.test ./03-publish-b2c-qos1.py $@/03-publish-b2c-qos1.test + ./03-publish-b2c-qos1-unexpected-puback.py $@/03-publish-b2c-qos1-unexpected-puback.test ./03-publish-b2c-qos2-len.py $@/03-publish-b2c-qos2-len.test ./03-publish-b2c-qos2.py $@/03-publish-b2c-qos2.test ./03-publish-b2c-qos2-unexpected-pubrel.py $@/03-publish-b2c-qos2-unexpected-pubrel.test + ./03-publish-b2c-qos2-unexpected-pubcomp.py $@/03-publish-b2c-qos2-unexpected-pubcomp.test ./03-publish-c2b-qos1-disconnect.py $@/03-publish-c2b-qos1-disconnect.test ./03-publish-c2b-qos1-len.py $@/03-publish-c2b-qos1-len.test ./03-publish-c2b-qos1-receive-maximum.py $@/03-publish-c2b-qos1-receive-maximum.test diff --git a/test/lib/c/03-publish-b2c-qos1-unexpected-puback.c b/test/lib/c/03-publish-b2c-qos1-unexpected-puback.c new file mode 100644 index 00000000..688b0907 --- /dev/null +++ b/test/lib/c/03-publish-b2c-qos1-unexpected-puback.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include + +static int run = -1; + +void on_connect(struct mosquitto *mosq, void *obj, int rc) +{ + if(rc){ + printf("Connect error: %d\n", rc); + exit(1); + } +} + +int main(int argc, char *argv[]) +{ + int rc; + struct mosquitto *mosq; + + int port = atoi(argv[1]); + + mosquitto_lib_init(); + + mosq = mosquitto_new("publish-qos1-test", true, &run); + mosquitto_connect_callback_set(mosq, on_connect); + + rc = mosquitto_connect(mosq, "localhost", port, 5); + + while(run == -1){ + rc = mosquitto_loop(mosq, 300, 1); + if(rc){ + exit(0); + } + } + + mosquitto_lib_cleanup(); + return 0; +} diff --git a/test/lib/c/03-publish-b2c-qos2-unexpected-pubcomp.c b/test/lib/c/03-publish-b2c-qos2-unexpected-pubcomp.c new file mode 100644 index 00000000..414c181c --- /dev/null +++ b/test/lib/c/03-publish-b2c-qos2-unexpected-pubcomp.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include + +static int run = -1; + +void on_connect(struct mosquitto *mosq, void *obj, int rc) +{ + if(rc){ + printf("Connect error: %d\n", rc); + exit(1); + } +} + +int main(int argc, char *argv[]) +{ + int rc; + struct mosquitto *mosq; + + int port = atoi(argv[1]); + + mosquitto_lib_init(); + + mosq = mosquitto_new("publish-qos2-test", true, &run); + mosquitto_connect_callback_set(mosq, on_connect); + + rc = mosquitto_connect(mosq, "localhost", port, 5); + + while(run == -1){ + rc = mosquitto_loop(mosq, 300, 1); + if(rc){ + exit(0); + } + } + + mosquitto_lib_cleanup(); + return 0; +} diff --git a/test/lib/c/Makefile b/test/lib/c/Makefile index 91d5a95c..7cae716d 100644 --- a/test/lib/c/Makefile +++ b/test/lib/c/Makefile @@ -5,45 +5,47 @@ LIBS=../../../lib/libmosquitto.so.1 SRC = \ 01-con-discon-success.c \ - 01-will-set.c \ - 01-unpwd-set.c \ - 01-will-unpwd-set.c \ - 01-no-clean-session.c \ 01-keepalive-pingreq.c \ + 01-no-clean-session.c \ 01-server-keepalive-pingreq.c \ + 01-unpwd-set.c \ + 01-will-set.c \ + 01-will-unpwd-set.c \ 02-subscribe-qos0.c \ - 02-subscribe-qos1.c \ 02-subscribe-qos1-async1.c \ 02-subscribe-qos1-async2.c \ + 02-subscribe-qos1.c \ 02-subscribe-qos2.c \ - 02-unsubscribe.c \ - 02-unsubscribe-v5.c \ 02-unsubscribe-multiple-v5.c \ - 03-publish-qos0.c \ - 03-publish-qos0-no-payload.c \ + 02-unsubscribe-v5.c \ + 02-unsubscribe.c \ + 03-publish-b2c-qos1-unexpected-puback.c \ + 03-publish-b2c-qos1.c \ + 03-publish-b2c-qos2-len.c \ + 03-publish-b2c-qos2-unexpected-pubrel.c \ + 03-publish-b2c-qos2-unexpected-pubcomp.c \ + 03-publish-b2c-qos2.c \ 03-publish-c2b-qos1-disconnect.c \ 03-publish-c2b-qos1-len.c \ - 03-publish-c2b-qos2.c \ + 03-publish-c2b-qos1-receive-maximum.c \ 03-publish-c2b-qos2-disconnect.c \ 03-publish-c2b-qos2-len.c \ - 03-publish-b2c-qos2-len.c \ - 03-publish-b2c-qos2-unexpected-pubrel.c \ - 03-publish-c2b-qos1-receive-maximum.c \ - 03-publish-c2b-qos2-receive-maximum-1.c \ - 03-publish-c2b-qos2-receive-maximum-2.c \ - 03-publish-c2b-qos2-pubrec-error.c \ 03-publish-c2b-qos2-maximum-qos-0.c \ 03-publish-c2b-qos2-maximum-qos-1.c \ - 03-publish-b2c-qos1.c \ - 03-publish-b2c-qos2.c \ + 03-publish-c2b-qos2-pubrec-error.c \ + 03-publish-c2b-qos2-receive-maximum-1.c \ + 03-publish-c2b-qos2-receive-maximum-2.c \ + 03-publish-c2b-qos2.c \ + 03-publish-qos0-no-payload.c \ + 03-publish-qos0.c \ 03-request-response-1.c \ 03-request-response-2.c \ 03-request-response-correlation-1.c \ 04-retain-qos0.c \ - 08-ssl-connect-no-auth.c \ - 08-ssl-connect-cert-auth.c \ - 08-ssl-connect-cert-auth-enc.c \ 08-ssl-bad-cacert.c \ + 08-ssl-connect-cert-auth-enc.c \ + 08-ssl-connect-cert-auth.c \ + 08-ssl-connect-no-auth.c \ 08-ssl-fake-cacert.c \ 09-util-topic-tokenise.c \ 11-prop-oversize-packet.c \ diff --git a/test/lib/test.py b/test/lib/test.py index 885055a7..eb56e718 100755 --- a/test/lib/test.py +++ b/test/lib/test.py @@ -22,8 +22,10 @@ tests = [ (1, ['./02-unsubscribe.py', 'c/02-unsubscribe.test']), (1, ['./03-publish-b2c-qos1.py', 'c/03-publish-b2c-qos1.test']), + (1, ['./03-publish-b2c-qos1-unexpected-puback.py', 'c/03-publish-b2c-qos1-unexpected-puback.test']), (1, ['./03-publish-b2c-qos2-len.py', 'c/03-publish-b2c-qos2-len.test']), (1, ['./03-publish-b2c-qos2-unexpected-pubrel.py', 'c/03-publish-b2c-qos2-unexpected-pubrel.test']), + (1, ['./03-publish-b2c-qos2-unexpected-pubcomp.py', 'c/03-publish-b2c-qos2-unexpected-pubcomp.test']), (1, ['./03-publish-b2c-qos2.py', 'c/03-publish-b2c-qos2.test']), (1, ['./03-publish-c2b-qos1-disconnect.py', 'c/03-publish-c2b-qos1-disconnect.test']), (1, ['./03-publish-c2b-qos1-len.py', 'c/03-publish-c2b-qos1-len.test']), From 904284595f033292130decc764590a9368c3c488 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 30 Mar 2020 20:47:30 +0100 Subject: [PATCH 015/113] Add missing test file. --- .../03-publish-b2c-qos2-unexpected-pubrel.py | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100755 test/lib/03-publish-b2c-qos2-unexpected-pubrel.py diff --git a/test/lib/03-publish-b2c-qos2-unexpected-pubrel.py b/test/lib/03-publish-b2c-qos2-unexpected-pubrel.py new file mode 100755 index 00000000..1d25199d --- /dev/null +++ b/test/lib/03-publish-b2c-qos2-unexpected-pubrel.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 + +from mosq_test_helper import * + +port = mosq_test.get_lib_port() + +rc = 1 +keepalive = 60 +connect_packet = mosq_test.gen_connect("publish-qos2-test", keepalive=keepalive) +connack_packet = mosq_test.gen_connack(rc=0) + +disconnect_packet = mosq_test.gen_disconnect() + +pubrel_unexpected = mosq_test.gen_pubrel(1000) +pubcomp_unexpected = mosq_test.gen_pubcomp(1000) + +mid = 13423 +publish_packet = mosq_test.gen_publish("pub/qos2/receive", qos=2, mid=mid, payload="message") +pubrec_packet = mosq_test.gen_pubrec(mid) +pubrel_packet = mosq_test.gen_pubrel(mid) +pubcomp_packet = mosq_test.gen_pubcomp(mid) + +sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +sock.settimeout(10) +sock.bind(('', port)) +sock.listen(5) + +client_args = sys.argv[1:] +env = dict(os.environ) +env['LD_LIBRARY_PATH'] = '../../lib:../../lib/cpp' +try: + pp = env['PYTHONPATH'] +except KeyError: + pp = '' +env['PYTHONPATH'] = '../../lib/python:'+pp +client = mosq_test.start_client(filename=sys.argv[1].replace('/', '-'), cmd=client_args, env=env, port=port) + +try: + (conn, address) = sock.accept() + conn.settimeout(10) + + if mosq_test.expect_packet(conn, "connect", connect_packet): + conn.send(connack_packet) + + conn.send(pubrel_unexpected) + if mosq_test.expect_packet(conn, "pubcomp", pubcomp_unexpected): + + conn.send(publish_packet) + + if mosq_test.expect_packet(conn, "pubrec", pubrec_packet): + conn.send(pubrel_packet) + + if mosq_test.expect_packet(conn, "pubcomp", pubcomp_packet): + rc = 0 + + conn.close() +finally: + for i in range(0, 5): + if client.returncode != None: + break + time.sleep(0.1) + + try: + client.terminate() + except OSError: + pass + + client.wait() + sock.close() + if client.returncode != 0: + exit(1) + +exit(rc) From 3e9eae401eca45b5a524bd673d306c6993693491 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 31 Mar 2020 10:13:20 +0100 Subject: [PATCH 016/113] Missing / in bridge remapping doc. --- man/mosquitto.conf.5.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/mosquitto.conf.5.xml b/man/mosquitto.conf.5.xml index c4c728ae..4b7843c0 100644 --- a/man/mosquitto.conf.5.xml +++ b/man/mosquitto.conf.5.xml @@ -1830,7 +1830,7 @@ topic # both 2 local/topic/ remote/topic/ connection test-mosquitto-org address test.mosquitto.org cleansession true -topic clients/total in 0 test/mosquitto/org $SYS/broker/ +topic clients/total in 0 test/mosquitto/org/ $SYS/broker/ From fdaeaee6dd5982df2e3f581012985ca494e81a47 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 7 Apr 2020 16:10:02 +0100 Subject: [PATCH 017/113] Fix test. --- test/broker/06-bridge-br2b-remapping.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/broker/06-bridge-br2b-remapping.py b/test/broker/06-bridge-br2b-remapping.py index ab29a08b..83e13f50 100755 --- a/test/broker/06-bridge-br2b-remapping.py +++ b/test/broker/06-bridge-br2b-remapping.py @@ -15,8 +15,6 @@ def write_config(filename, port1, port2): f.write("topic prefix/# out 0 local2/topic/ remote2/topic/\n") f.write("topic +/value out 0 local3/topic/ remote3/topic/\n") f.write("topic ic/+ out 0 local4/top remote4/tip\n") - f.write("# this one is invalid\n") - f.write("topic +/value out 0 local5/top remote5/tip\n") f.write("notifications false\n") f.write("restart_timeout 5\n") From 3758e0c3285c9155f281e71c26435cb1c8117205 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 8 Apr 2020 12:38:15 +0100 Subject: [PATCH 018/113] Fix mosquitto_passwd not being able to create pwfile with -b. --- src/mosquitto_passwd.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/mosquitto_passwd.c b/src/mosquitto_passwd.c index 155ef0af..207996d1 100644 --- a/src/mosquitto_passwd.c +++ b/src/mosquitto_passwd.c @@ -133,7 +133,7 @@ void print_usage(void) { printf("mosquitto_passwd is a tool for managing password files for mosquitto.\n\n"); printf("Usage: mosquitto_passwd [-c | -D] passwordfile username\n"); - printf(" mosquitto_passwd -b passwordfile username password\n"); + printf(" mosquitto_passwd [-c] -b passwordfile username password\n"); printf(" mosquitto_passwd -U passwordfile\n"); printf(" -b : run in batch mode to allow passing passwords on the command line.\n"); printf(" -c : create a new password file. This will overwrite existing files.\n"); @@ -331,10 +331,8 @@ static int update_pwuser_cb(FILE *fptr, FILE *ftmp, const char *username, const { int rc = 0; - printf("%s\n", username); if(strcmp(username, helper->username)){ /* If this isn't the matching user, then writing out the exiting line */ - printf("%s\n", line); fprintf(ftmp, "%s", line); }else{ /* Write out a new line for our matching username */ @@ -539,12 +537,22 @@ int main(int argc, char *argv[]) if(!strcmp(argv[1], "-c")){ create_new = true; - if(argc != 4){ - fprintf(stderr, "Error: -c argument given but password file or username missing.\n"); - return 1; - }else{ + if(argc == 4){ password_file_tmp = argv[2]; username = argv[3]; + }else if(argc == 6){ + if(!strcmp(argv[2], "-b")){ + batch_mode = true; + password_file_tmp = argv[3]; + username = argv[4]; + password_cmd = argv[5]; + }else{ + fprintf(stderr, "Error: Incorrect number of arguments.\n"); + return 1; + } + }else{ + fprintf(stderr, "Error: -c argument given but password file or username missing.\n"); + return 1; } }else if(!strcmp(argv[1], "-D")){ delete_user = true; @@ -612,10 +620,13 @@ int main(int argc, char *argv[]) #endif if(create_new){ - rc = get_password(password, MAX_BUFFER_LEN); - if(rc){ - free(password_file); - return rc; + if(batch_mode == false){ + rc = get_password(password, MAX_BUFFER_LEN); + if(rc){ + free(password_file); + return rc; + } + password_cmd = password; } fptr = fopen(password_file, "wt"); if(!fptr){ @@ -624,7 +635,7 @@ int main(int argc, char *argv[]) return 1; } free(password_file); - rc = output_new_password(fptr, username, password); + rc = output_new_password(fptr, username, password_cmd); fclose(fptr); return rc; }else{ From 40bad1a999fd7388510fe1bd558cca6fc2330a9b Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 16 Apr 2020 23:26:14 +0100 Subject: [PATCH 019/113] Fix conversion warnings in client code Issue #1653. --- client/client_props.c | 37 +++++++++++++++++++++---- client/client_shared.c | 57 +++++++++++++++++++++++++------------- client/client_shared.h | 6 ++-- client/pub_client.c | 10 +++---- client/pub_shared.c | 30 ++++++++++++++------ client/sub_client_output.c | 4 +-- 6 files changed, 100 insertions(+), 44 deletions(-) diff --git a/client/client_props.c b/client/client_props.c index 4d187425..efe25ccc 100644 --- a/client/client_props.c +++ b/client/client_props.c @@ -65,6 +65,8 @@ int cfg_parse_property(struct mosq_config *cfg, int argc, char *argv[], int *idx int cmd, identifier, type; mosquitto_property **proplist; int rc; + long tmpl; + size_t szt; /* idx now points to "command" */ if((*idx)+2 > argc-1){ @@ -161,19 +163,44 @@ int cfg_parse_property(struct mosq_config *cfg, int argc, char *argv[], int *idx switch(type){ case MQTT_PROP_TYPE_BYTE: - rc = mosquitto_property_add_byte(proplist, identifier, atoi(value)); + tmpl = atol(value); + if(tmpl < 0 || tmpl > UINT8_MAX){ + fprintf(stderr, "Error: Property value (%ld) out of range for property %s.\n\n", tmpl, propname); + return MOSQ_ERR_INVAL; + } + rc = mosquitto_property_add_byte(proplist, identifier, (uint8_t )tmpl); break; case MQTT_PROP_TYPE_INT16: - rc = mosquitto_property_add_int16(proplist, identifier, atoi(value)); + tmpl = atol(value); + if(tmpl < 0 || tmpl > UINT16_MAX){ + fprintf(stderr, "Error: Property value (%ld) out of range for property %s.\n\n", tmpl, propname); + return MOSQ_ERR_INVAL; + } + rc = mosquitto_property_add_int16(proplist, identifier, (uint16_t )tmpl); break; case MQTT_PROP_TYPE_INT32: - rc = mosquitto_property_add_int32(proplist, identifier, atoi(value)); + tmpl = atol(value); + if(tmpl < 0 || tmpl > UINT32_MAX){ + fprintf(stderr, "Error: Property value (%ld) out of range for property %s.\n\n", tmpl, propname); + return MOSQ_ERR_INVAL; + } + rc = mosquitto_property_add_int32(proplist, identifier, (uint32_t )tmpl); break; case MQTT_PROP_TYPE_VARINT: - rc = mosquitto_property_add_varint(proplist, identifier, atoi(value)); + tmpl = atol(value); + if(tmpl < 0 || tmpl > UINT32_MAX){ + fprintf(stderr, "Error: Property value (%ld) out of range for property %s.\n\n", tmpl, propname); + return MOSQ_ERR_INVAL; + } + rc = mosquitto_property_add_varint(proplist, identifier, (uint32_t )tmpl); break; case MQTT_PROP_TYPE_BINARY: - rc = mosquitto_property_add_binary(proplist, identifier, value, strlen(value)); + szt = strlen(value); + if(szt > UINT16_MAX){ + fprintf(stderr, "Error: Property value too long for property %s.\n\n", propname); + return MOSQ_ERR_INVAL; + } + rc = mosquitto_property_add_binary(proplist, identifier, value, (uint16_t )szt); break; case MQTT_PROP_TYPE_STRING: rc = mosquitto_property_add_string(proplist, identifier, value); diff --git a/client/client_shared.c b/client/client_shared.c index 8239b40b..0f24ce5e 100644 --- a/client/client_shared.c +++ b/client/client_shared.c @@ -45,7 +45,7 @@ static int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int static int check_format(const char *str) { int i; - int len; + size_t len; len = strlen(str); for(i=0; iconnect_props, MQTT_PROP_SESSION_EXPIRY_INTERVAL, cfg->session_expiry_interval); + rc = mosquitto_property_add_int32(&cfg->connect_props, MQTT_PROP_SESSION_EXPIRY_INTERVAL, (uint32_t )cfg->session_expiry_interval); if(rc){ fprintf(stderr, "Error adding property session-expiry-interval\n"); } @@ -425,7 +425,7 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char * int cfg_add_topic(struct mosq_config *cfg, int type, char *topic, const char *arg) { - if(mosquitto_validate_utf8(topic, strlen(topic))){ + if(mosquitto_validate_utf8(topic, (int )strlen(topic))){ fprintf(stderr, "Error: Malformed UTF-8 in %s argument.\n\n", arg); return 1; } @@ -447,7 +447,7 @@ int cfg_add_topic(struct mosq_config *cfg, int type, char *topic, const char *ar return 1; } cfg->topic_count++; - cfg->topics = realloc(cfg->topics, cfg->topic_count*sizeof(char *)); + cfg->topics = realloc(cfg->topics, (size_t )cfg->topic_count*sizeof(char *)); if(!cfg->topics){ err_printf(cfg, "Error: Out of memory.\n"); return 1; @@ -461,7 +461,9 @@ int cfg_add_topic(struct mosq_config *cfg, int type, char *topic, const char *ar int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, char *argv[]) { int i; + int tmpi; float f; + size_t szt; for(i=1; imessage = strdup(argv[i+1]); - cfg->msglen = strlen(cfg->message); + if(cfg->message == NULL){ + fprintf(stderr, "Error: Out of memory.\n\n"); + return 1; + } + szt = strlen(cfg->message); + if(szt > MQTT_MAX_PAYLOAD){ + fprintf(stderr, "Error: Message length must be less than %u bytes.\n\n", MQTT_MAX_PAYLOAD); + return 1; + } + cfg->msglen = (int )szt; cfg->pub_mode = MSGMODE_CMD; } i++; @@ -737,7 +748,12 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c fprintf(stderr, "Error: -M argument given but max_inflight not specified.\n\n"); return 1; }else{ - cfg->max_inflight = atoi(argv[i+1]); + tmpi = atoi(argv[i+1]); + if(tmpi < 1){ + fprintf(stderr, "Error: Maximum inflight messages must be greater than 0.\n\n"); + return 1; + } + cfg->max_inflight = (unsigned int )tmpi; } i++; }else if(!strcmp(argv[i], "-n") || !strcmp(argv[i], "--null-message")){ @@ -858,13 +874,13 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c fprintf(stderr, "Error: --repeat-delay argument given but no time specified.\n\n"); return 1; }else{ - f = atof(argv[i+1]); + f = (float )atof(argv[i+1]); if(f < 0.0f){ fprintf(stderr, "Error: --repeat-delay argument must be >=0.0.\n\n"); return 1; } - f *= 1.0e6; - cfg->repeat_delay.tv_sec = (int)f/1e6; + f *= 1.0e6f; + cfg->repeat_delay.tv_sec = (int)f/1000000; cfg->repeat_delay.tv_usec = (int)f%1000000; } i++; @@ -909,7 +925,7 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c fprintf(stderr, "Error: -T argument given but no topic filter specified.\n\n"); return 1; }else{ - if(mosquitto_validate_utf8(argv[i+1], strlen(argv[i+1]))){ + if(mosquitto_validate_utf8(argv[i+1], (int )strlen(argv[i+1]))){ fprintf(stderr, "Error: Malformed UTF-8 in -T argument.\n\n"); return 1; } @@ -918,7 +934,7 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c return 1; } cfg->filter_out_count++; - cfg->filter_outs = realloc(cfg->filter_outs, cfg->filter_out_count*sizeof(char *)); + cfg->filter_outs = realloc(cfg->filter_outs, (size_t )cfg->filter_out_count*sizeof(char *)); if(!cfg->filter_outs){ fprintf(stderr, "Error: Out of memory.\n"); return 1; @@ -968,7 +984,7 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c fprintf(stderr, "Error: -U argument given but no unsubscribe topic specified.\n\n"); return 1; }else{ - if(mosquitto_validate_utf8(argv[i+1], strlen(argv[i+1]))){ + if(mosquitto_validate_utf8(argv[i+1], (int )strlen(argv[i+1]))){ fprintf(stderr, "Error: Malformed UTF-8 in -U argument.\n\n"); return 1; } @@ -977,7 +993,7 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c return 1; } cfg->unsub_topic_count++; - cfg->unsub_topics = realloc(cfg->unsub_topics, cfg->unsub_topic_count*sizeof(char *)); + cfg->unsub_topics = realloc(cfg->unsub_topics, (size_t )cfg->unsub_topic_count*sizeof(char *)); if(!cfg->unsub_topics){ fprintf(stderr, "Error: Out of memory.\n"); return 1; @@ -1023,11 +1039,12 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c fprintf(stderr, "Error: -W argument given but no timeout specified.\n\n"); return 1; }else{ - cfg->timeout = atoi(argv[i+1]); - if(cfg->timeout < 1){ - fprintf(stderr, "Error: Invalid timeout \"%d\".\n\n", cfg->msg_count); + tmpi = atoi(argv[i+1]); + if(tmpi < 1){ + fprintf(stderr, "Error: Invalid timeout \"%d\".\n\n", tmpi); return 1; } + cfg->timeout = (unsigned int )tmpi; } i++; } @@ -1037,7 +1054,7 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c return 1; }else{ cfg->will_payload = strdup(argv[i+1]); - cfg->will_payloadlen = strlen(cfg->will_payload); + cfg->will_payloadlen = (int )strlen(cfg->will_payload); } i++; }else if(!strcmp(argv[i], "--will-qos")){ @@ -1059,7 +1076,7 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c fprintf(stderr, "Error: --will-topic argument given but no will topic specified.\n\n"); return 1; }else{ - if(mosquitto_validate_utf8(argv[i+1], strlen(argv[i+1]))){ + if(mosquitto_validate_utf8(argv[i+1], (int )strlen(argv[i+1]))){ fprintf(stderr, "Error: Malformed UTF-8 in --will-topic argument.\n\n"); return 1; } @@ -1241,7 +1258,7 @@ int client_connect(struct mosquitto *mosq, struct mosq_config *cfg) static int mosquitto__urldecode(char *str) { int i, j; - int len; + size_t len; if(!str) return 0; if(!strchr(str, '%')) return 0; diff --git a/client/client_shared.h b/client/client_shared.h index 772a053d..ed917107 100644 --- a/client/client_shared.h +++ b/client/client_shared.h @@ -50,7 +50,7 @@ struct mosq_config { int pub_mode; /* pub, rr */ char *file_input; /* pub, rr */ char *message; /* pub, rr */ - long msglen; /* pub, rr */ + int msglen; /* pub, rr */ char *topic; /* pub, rr */ char *bind_address; int repeat_count; /* pub */ @@ -65,7 +65,7 @@ struct mosq_config { char *password; char *will_topic; char *will_payload; - long will_payloadlen; + int will_payloadlen; int will_qos; bool will_retain; #ifdef WITH_TLS @@ -100,7 +100,7 @@ struct mosq_config { bool eol; /* sub */ int msg_count; /* sub */ char *format; /* sub */ - int timeout; /* sub */ + unsigned int timeout; /* sub */ int sub_opts; /* sub */ long session_expiry_interval; #ifdef WITH_SOCKS diff --git a/client/pub_client.c b/client/pub_client.c index cb8f54c7..ef0bf16e 100644 --- a/client/pub_client.c +++ b/client/pub_client.c @@ -76,7 +76,7 @@ static void set_repeat_time(void) next_publish_tv.tv_sec += cfg.repeat_delay.tv_sec; next_publish_tv.tv_usec += cfg.repeat_delay.tv_usec; - next_publish_tv.tv_sec += next_publish_tv.tv_usec/1e6; + next_publish_tv.tv_sec += next_publish_tv.tv_usec/1000000; next_publish_tv.tv_usec = next_publish_tv.tv_usec%1000000; } @@ -211,7 +211,7 @@ void my_publish_callback(struct mosquitto *mosq, void *obj, int mid, int reason_ int pub_shared_init(void) { - line_buf = malloc(line_buf_len); + line_buf = malloc((size_t )line_buf_len); if(!line_buf){ err_printf(&cfg, "Error: Out of memory.\n"); return 1; @@ -236,7 +236,7 @@ int pub_stdin_line_loop(struct mosquitto *mosq) pos = 0; read_len = line_buf_len; while(status == STATUS_CONNACK_RECVD && fgets(&line_buf[pos], read_len, stdin)){ - buf_len_actual = strlen(line_buf); + buf_len_actual = (int )strlen(line_buf); if(line_buf[buf_len_actual-1] == '\n'){ line_buf[buf_len_actual-1] = '\0'; rc = my_publish(mosq, &mid_sent, cfg.topic, buf_len_actual-1, line_buf, cfg.qos, cfg.retain); @@ -250,7 +250,7 @@ int pub_stdin_line_loop(struct mosquitto *mosq) line_buf_len += 1024; pos += 1023; read_len = 1024; - buf2 = realloc(line_buf, line_buf_len); + buf2 = realloc(line_buf, (size_t )line_buf_len); if(!buf2){ err_printf(&cfg, "Error: Out of memory.\n"); return MOSQ_ERR_NOMEM; @@ -313,7 +313,7 @@ int pub_other_loop(struct mosquitto *mosq) int loop_delay = 1000; if(cfg.repeat_count > 1 && (cfg.repeat_delay.tv_sec == 0 || cfg.repeat_delay.tv_usec != 0)){ - loop_delay = cfg.repeat_delay.tv_usec / 2000; + loop_delay = (int )cfg.repeat_delay.tv_usec / 2000; } do{ diff --git a/client/pub_shared.c b/client/pub_shared.c index 81996a4f..ae4cb277 100644 --- a/client/pub_shared.c +++ b/client/pub_shared.c @@ -50,7 +50,7 @@ void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *s int load_stdin(void) { - long pos = 0, rlen; + size_t pos = 0, rlen; char buf[1024]; char *aux_message = NULL; @@ -70,7 +70,12 @@ int load_stdin(void) memcpy(&(cfg.message[pos]), buf, rlen); pos += rlen; } - cfg.msglen = pos; + if(pos > MQTT_MAX_PAYLOAD){ + err_printf(&cfg, "Error: Message length must be less that %u bytes.\n\n", MQTT_MAX_PAYLOAD); + free(cfg.message); + return 1; + } + cfg.msglen = (int )pos; if(!cfg.msglen){ err_printf(&cfg, "Error: Zero length input.\n"); @@ -82,8 +87,9 @@ int load_stdin(void) int load_file(const char *filename) { - long pos, rlen; + size_t pos, rlen; FILE *fptr = NULL; + long flen; fptr = fopen(filename, "rb"); if(!fptr){ @@ -92,22 +98,28 @@ int load_file(const char *filename) } cfg.pub_mode = MSGMODE_FILE; fseek(fptr, 0, SEEK_END); - cfg.msglen = ftell(fptr); - if(cfg.msglen > 268435455){ + flen = ftell(fptr); + if(flen > MQTT_MAX_PAYLOAD){ + err_printf(&cfg, "Error: Message length must be less that %u bytes.\n\n", MQTT_MAX_PAYLOAD); + free(cfg.message); + return 1; + } + if(flen > 268435455){ fclose(fptr); err_printf(&cfg, "Error: File \"%s\" is too large (>268,435,455 bytes).\n", filename); return 1; - }else if(cfg.msglen == 0){ + }else if(flen == 0){ fclose(fptr); err_printf(&cfg, "Error: File \"%s\" is empty.\n", filename); return 1; - }else if(cfg.msglen < 0){ + }else if(flen < 0){ fclose(fptr); err_printf(&cfg, "Error: Unable to determine size of file \"%s\".\n", filename); return 1; } + cfg.msglen = (int )flen; fseek(fptr, 0, SEEK_SET); - cfg.message = malloc(cfg.msglen); + cfg.message = malloc((size_t )cfg.msglen); if(!cfg.message){ fclose(fptr); err_printf(&cfg, "Error: Out of memory.\n"); @@ -115,7 +127,7 @@ int load_file(const char *filename) } pos = 0; while(pos < cfg.msglen){ - rlen = fread(&(cfg.message[pos]), sizeof(char), cfg.msglen-pos, fptr); + rlen = fread(&(cfg.message[pos]), sizeof(char), (size_t )cfg.msglen-pos, fptr); pos += rlen; } fclose(fptr); diff --git a/client/sub_client_output.c b/client/sub_client_output.c index 5b639e95..6d9d82d7 100644 --- a/client/sub_client_output.c +++ b/client/sub_client_output.c @@ -83,7 +83,7 @@ static void write_payload(const unsigned char *payload, int payloadlen, int hex) int i; if(hex == 0){ - (void)fwrite(payload, 1, payloadlen, stdout); + (void)fwrite(payload, 1, (size_t )payloadlen, stdout); }else if(hex == 1){ for(i=0; i Date: Thu, 23 Apr 2020 13:10:11 +0100 Subject: [PATCH 020/113] Update example Docker ports. Port 9001 is used by Intel drivers on Windows, so some users are suddenly seeing a problem. Issue #1580. --- docker/1.4.12/README.md | 4 ++-- docker/1.5/README.md | 2 +- docker/1.6/README.md | 2 +- docker/generic/README.md | 4 ++-- docker/local/README.md | 5 +++-- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/docker/1.4.12/README.md b/docker/1.4.12/README.md index 1ad42798..d5b68a45 100644 --- a/docker/1.4.12/README.md +++ b/docker/1.4.12/README.md @@ -15,7 +15,7 @@ Three mount points have been created in the image to be used for configuration, When running the image, the default configuration values are used. To use a custom configuration file, mount a **local** configuration file to `/mosquitto/config/mosquitto.conf` ``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto:1.4.12 +docker run -it -p 1883:1883 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto:1.4.12 ``` Configuration can be changed to: @@ -42,7 +42,7 @@ docker build -t eclipse-mosquitto:1.4.12 . ##Run Run a container using the new image: ``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log eclipse-mosquitto:1.4.12 +docker run -it -p 1883:1883 -v :/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log eclipse-mosquitto:1.4.12 ``` :boom: if the mosquitto configuration (mosquitto.conf) was modified to use non-default ports, the docker run command will need to be updated diff --git a/docker/1.5/README.md b/docker/1.5/README.md index ce91cd03..8a54a86b 100644 --- a/docker/1.5/README.md +++ b/docker/1.5/README.md @@ -30,7 +30,7 @@ to use non-default ports, the docker run command will need to be updated to expose the ports that have been configured, for example: ``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: +docker run -it -p 1883:1883 -p 8080:8080 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: ``` Configuration can be changed to: diff --git a/docker/1.6/README.md b/docker/1.6/README.md index ce91cd03..8a54a86b 100644 --- a/docker/1.6/README.md +++ b/docker/1.6/README.md @@ -30,7 +30,7 @@ to use non-default ports, the docker run command will need to be updated to expose the ports that have been configured, for example: ``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: +docker run -it -p 1883:1883 -p 8080:8080 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: ``` Configuration can be changed to: diff --git a/docker/generic/README.md b/docker/generic/README.md index 421cb91d..4e0279c7 100644 --- a/docker/generic/README.md +++ b/docker/generic/README.md @@ -13,7 +13,7 @@ Three docker volumes have been created in the image to be used for configuration When creating a container from the image, the default configuration values are used. To use a custom configuration file, mount a **local** configuration file to `/mosquitto/config/mosquitto.conf` ``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: +docker run -it -p 1883:1883 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: ``` Configuration can be changed to: @@ -40,7 +40,7 @@ docker build -t eclipse-mosquitto: --build-arg VERSION="" . ## Run Run a container using the new image: ``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log eclipse-mosquitto: +docker run -it -p 1883:1883 -v :/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log eclipse-mosquitto: ``` :boom: if the mosquitto configuration (mosquitto.conf) was modified to use non-default ports, the docker run command will need to be updated diff --git a/docker/local/README.md b/docker/local/README.md index f11086aa..210455f9 100644 --- a/docker/local/README.md +++ b/docker/local/README.md @@ -29,10 +29,11 @@ docker run -it -p 1883:1883 -v :/mosquitto/ :boom: if the mosquitto configuration (mosquitto.conf) was modified to use non-default ports, the docker run command will need to be updated -to expose the ports that have been configured, for example: +to expose the ports that have been configured, for example if you use port 8080 +for websockets as well as port 1883: ``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: +docker run -it -p 1883:1883 -p 8080:8080 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: ``` Configuration can be changed to: From 5908585afda812b58bd8e37f41107ebe09a3975a Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Sun, 26 Apr 2020 22:44:21 +0100 Subject: [PATCH 021/113] Fix mosquitto_passwd -b not updating passwords for existing users Closes #1664. Thanks to Leon Kiefer. --- ChangeLog.txt | 3 +++ src/mosquitto_passwd.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 31076c58..8888be82 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,6 +1,9 @@ Broker: - Report invalid bridge prefix+pattern combinations at config parsing time rather than letting the bridge fail later. Issue #1635. +- Fix `mosquitto_passwd -b` not updating passwords for existing users + correctly. Creating a new user with `-b` worked without problem. + Closes #1664. Client library: - Don't treat an unexpected PUBACK, PUBREL, or PUBCOMP as a fatal error. diff --git a/src/mosquitto_passwd.c b/src/mosquitto_passwd.c index 207996d1..a86071f9 100644 --- a/src/mosquitto_passwd.c +++ b/src/mosquitto_passwd.c @@ -337,7 +337,7 @@ static int update_pwuser_cb(FILE *fptr, FILE *ftmp, const char *username, const }else{ /* Write out a new line for our matching username */ helper->found = true; - rc = output_new_password(ftmp, username, password); + rc = output_new_password(ftmp, username, helper->password); } return rc; } @@ -349,6 +349,7 @@ int update_pwuser(FILE *fptr, FILE *ftmp, const char *username, const char *pass memset(&helper, 0, sizeof(helper)); helper.username = username; + helper.password = password; rc = pwfile_iterate(fptr, ftmp, update_pwuser_cb, &helper); if(helper.found){ From eeaafed48599d556ac8d09c8dac48cc749c92bff Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 30 Apr 2020 17:31:13 +0100 Subject: [PATCH 022/113] Fix memory leak when connecting clients rejected. --- ChangeLog.txt | 1 + src/handle_connect.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index 8888be82..22de95ef 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -4,6 +4,7 @@ Broker: - Fix `mosquitto_passwd -b` not updating passwords for existing users correctly. Creating a new user with `-b` worked without problem. Closes #1664. +- Fix memory leak when connecting clients rejected. Client library: - Don't treat an unexpected PUBACK, PUBREL, or PUBCOMP as a fatal error. diff --git a/src/handle_connect.c b/src/handle_connect.c index 99f1f1c3..6a9e198a 100644 --- a/src/handle_connect.c +++ b/src/handle_connect.c @@ -886,5 +886,7 @@ handle_connect_error: if(client_cert) X509_free(client_cert); #endif /* We return an error here which means the client is freed later on. */ + context->clean_start = true; + context->session_expiry_interval = 0; return rc; } From 4960fc0702738a4f875e864bdbd200fc4d330412 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 18 Dec 2019 23:24:06 +0000 Subject: [PATCH 023/113] Don't disconnect clients that are already disconnected. This prevents the session expiry being extended on SIGHUP. Closes #1521. Thanks to Christoph Krey. --- ChangeLog.txt | 5 +++++ src/context.c | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index 22de95ef..3e56770a 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -5,6 +5,11 @@ Broker: correctly. Creating a new user with `-b` worked without problem. Closes #1664. - Fix memory leak when connecting clients rejected. +- Don't disconnect clients that are already disconnected. This prevents the + session expiry being extended on SIGHUP. Closes #1521. + + 1.6.8 - 20191128 + ================ Client library: - Don't treat an unexpected PUBACK, PUBREL, or PUBCOMP as a fatal error. diff --git a/src/context.c b/src/context.c index fd9ac17b..32ceca5b 100644 --- a/src/context.c +++ b/src/context.c @@ -226,6 +226,10 @@ void context__send_will(struct mosquitto_db *db, struct mosquitto *ctxt) void context__disconnect(struct mosquitto_db *db, struct mosquitto *context) { + if(mosquitto__get_state(context) == mosq_cs_disconnected){ + return; + } + net__socket_close(db, context); context__send_will(db, context); From bfc82ea91a133d9a8cb936194078e5bf65663091 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 5 May 2020 13:13:24 +0100 Subject: [PATCH 024/113] Fix incorrect check. --- src/conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/conf.c b/src/conf.c index b8c61ffc..ea5651f8 100644 --- a/src/conf.c +++ b/src/conf.c @@ -2022,7 +2022,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct return MOSQ_ERR_INVAL; } cur_topic->local_prefix = malloc(strlen(cur_topic->topic) + strlen(token) + 1); - if(cur_topic == NULL){ + if(cur_topic->local_prefix == NULL){ log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); return MOSQ_ERR_NOMEM; } From b2e72a7e7c51a61b324756f963984db894c08bab Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 5 May 2020 11:56:10 +0100 Subject: [PATCH 025/113] Fix memory leaks only in tests. --- test/lib/c/02-subscribe-qos2.c | 1 + test/lib/c/02-unsubscribe.c | 1 + test/lib/c/03-publish-b2c-qos2-len.c | 1 + test/lib/c/03-publish-b2c-qos2-unexpected-pubrel.c | 1 + test/lib/c/03-publish-b2c-qos2.c | 1 + test/lib/c/03-publish-c2b-qos1-len.c | 1 + test/lib/c/03-publish-c2b-qos1-receive-maximum.c | 1 + test/lib/c/03-publish-c2b-qos2-len.c | 1 + test/lib/c/03-publish-c2b-qos2-maximum-qos-0.c | 1 + test/lib/c/03-publish-c2b-qos2-maximum-qos-1.c | 1 + test/lib/c/03-publish-c2b-qos2-pubrec-error.c | 1 + test/lib/c/03-publish-c2b-qos2-receive-maximum-1.c | 1 + test/lib/c/03-publish-c2b-qos2-receive-maximum-2.c | 1 + test/lib/c/03-publish-qos0.c | 1 + test/lib/c/03-request-response-2.c | 1 + test/lib/c/08-ssl-bad-cacert.c | 1 + test/lib/c/09-util-topic-tokenise.c | 8 ++++++++ test/lib/c/11-prop-send-content-type.c | 2 ++ test/lib/c/11-prop-send-payload-format.c | 1 + test/lib/cpp/01-con-discon-success.cpp | 1 + test/lib/cpp/01-keepalive-pingreq.cpp | 1 + test/lib/cpp/01-no-clean-session.cpp | 1 + test/lib/cpp/01-unpwd-set.cpp | 1 + test/lib/cpp/01-will-set.cpp | 1 + test/lib/cpp/01-will-unpwd-set.cpp | 1 + test/lib/cpp/02-subscribe-qos0.cpp | 1 + test/lib/cpp/02-subscribe-qos1.cpp | 1 + test/lib/cpp/02-subscribe-qos2.cpp | 1 + test/lib/cpp/03-publish-b2c-qos1.cpp | 1 + test/lib/cpp/03-publish-b2c-qos2.cpp | 1 + test/lib/cpp/03-publish-c2b-qos1-disconnect.cpp | 1 + test/lib/cpp/03-publish-c2b-qos2-disconnect.cpp | 1 + test/lib/cpp/03-publish-c2b-qos2.cpp | 1 + test/lib/cpp/03-publish-qos0-no-payload.cpp | 1 + test/lib/cpp/03-publish-qos0.cpp | 1 + test/lib/cpp/04-retain-qos0.cpp | 1 + test/lib/cpp/08-ssl-bad-cacert.cpp | 1 + test/lib/cpp/08-ssl-connect-cert-auth-enc.cpp | 1 + test/lib/cpp/08-ssl-connect-cert-auth.cpp | 1 + test/lib/cpp/08-ssl-connect-no-auth.cpp | 1 + test/lib/cpp/08-ssl-fake-cacert.cpp | 1 + test/lib/cpp/09-util-topic-tokenise.cpp | 8 ++++++++ 42 files changed, 57 insertions(+) diff --git a/test/lib/c/02-subscribe-qos2.c b/test/lib/c/02-subscribe-qos2.c index 68660301..ceb416c9 100644 --- a/test/lib/c/02-subscribe-qos2.c +++ b/test/lib/c/02-subscribe-qos2.c @@ -44,6 +44,7 @@ int main(int argc, char *argv[]) mosquitto_loop(mosq, -1, 1); } + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return run; } diff --git a/test/lib/c/02-unsubscribe.c b/test/lib/c/02-unsubscribe.c index c757f510..6b28f217 100644 --- a/test/lib/c/02-unsubscribe.c +++ b/test/lib/c/02-unsubscribe.c @@ -44,6 +44,7 @@ int main(int argc, char *argv[]) mosquitto_loop(mosq, -1, 1); } + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return run; } diff --git a/test/lib/c/03-publish-b2c-qos2-len.c b/test/lib/c/03-publish-b2c-qos2-len.c index 3975d914..b5a7f49c 100644 --- a/test/lib/c/03-publish-b2c-qos2-len.c +++ b/test/lib/c/03-publish-b2c-qos2-len.c @@ -69,6 +69,7 @@ int main(int argc, char *argv[]) mosquitto_loop(mosq, 100, 1); } + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return run; } diff --git a/test/lib/c/03-publish-b2c-qos2-unexpected-pubrel.c b/test/lib/c/03-publish-b2c-qos2-unexpected-pubrel.c index 091a6045..f51b814a 100644 --- a/test/lib/c/03-publish-b2c-qos2-unexpected-pubrel.c +++ b/test/lib/c/03-publish-b2c-qos2-unexpected-pubrel.c @@ -67,6 +67,7 @@ int main(int argc, char *argv[]) } } + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return run; } diff --git a/test/lib/c/03-publish-b2c-qos2.c b/test/lib/c/03-publish-b2c-qos2.c index 3c2f340d..2345b6b5 100644 --- a/test/lib/c/03-publish-b2c-qos2.c +++ b/test/lib/c/03-publish-b2c-qos2.c @@ -63,6 +63,7 @@ int main(int argc, char *argv[]) mosquitto_loop(mosq, 300, 1); } + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return run; } diff --git a/test/lib/c/03-publish-c2b-qos1-len.c b/test/lib/c/03-publish-c2b-qos1-len.c index 66fe76e6..fb3ae056 100644 --- a/test/lib/c/03-publish-c2b-qos1-len.c +++ b/test/lib/c/03-publish-c2b-qos1-len.c @@ -47,6 +47,7 @@ int main(int argc, char *argv[]) mosquitto_loop(mosq, 300, 1); } + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return run; } diff --git a/test/lib/c/03-publish-c2b-qos1-receive-maximum.c b/test/lib/c/03-publish-c2b-qos1-receive-maximum.c index 5ef072a7..bfbbd529 100644 --- a/test/lib/c/03-publish-c2b-qos1-receive-maximum.c +++ b/test/lib/c/03-publish-c2b-qos1-receive-maximum.c @@ -49,6 +49,7 @@ int main(int argc, char *argv[]) mosquitto_loop(mosq, 300, 1); } + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return run; } diff --git a/test/lib/c/03-publish-c2b-qos2-len.c b/test/lib/c/03-publish-c2b-qos2-len.c index ab59adb7..1b2eb2e5 100644 --- a/test/lib/c/03-publish-c2b-qos2-len.c +++ b/test/lib/c/03-publish-c2b-qos2-len.c @@ -47,6 +47,7 @@ int main(int argc, char *argv[]) mosquitto_loop(mosq, 300, 1); } + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return run; } diff --git a/test/lib/c/03-publish-c2b-qos2-maximum-qos-0.c b/test/lib/c/03-publish-c2b-qos2-maximum-qos-0.c index cfe7ab1d..49049ac6 100644 --- a/test/lib/c/03-publish-c2b-qos2-maximum-qos-0.c +++ b/test/lib/c/03-publish-c2b-qos2-maximum-qos-0.c @@ -53,6 +53,7 @@ int main(int argc, char *argv[]) mosquitto_loop(mosq, 50, 1); } + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return run; } diff --git a/test/lib/c/03-publish-c2b-qos2-maximum-qos-1.c b/test/lib/c/03-publish-c2b-qos2-maximum-qos-1.c index b4c0981e..0f7c4eb6 100644 --- a/test/lib/c/03-publish-c2b-qos2-maximum-qos-1.c +++ b/test/lib/c/03-publish-c2b-qos2-maximum-qos-1.c @@ -54,6 +54,7 @@ int main(int argc, char *argv[]) } mosquitto_loop(mosq, 50, 1); + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return run; } diff --git a/test/lib/c/03-publish-c2b-qos2-pubrec-error.c b/test/lib/c/03-publish-c2b-qos2-pubrec-error.c index f7a64b17..170ee842 100644 --- a/test/lib/c/03-publish-c2b-qos2-pubrec-error.c +++ b/test/lib/c/03-publish-c2b-qos2-pubrec-error.c @@ -44,6 +44,7 @@ int main(int argc, char *argv[]) mosquitto_loop(mosq, 100, 1); } + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return run; } diff --git a/test/lib/c/03-publish-c2b-qos2-receive-maximum-1.c b/test/lib/c/03-publish-c2b-qos2-receive-maximum-1.c index ab507986..1d49b271 100644 --- a/test/lib/c/03-publish-c2b-qos2-receive-maximum-1.c +++ b/test/lib/c/03-publish-c2b-qos2-receive-maximum-1.c @@ -49,6 +49,7 @@ int main(int argc, char *argv[]) mosquitto_loop(mosq, 300, 1); } + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return run; } diff --git a/test/lib/c/03-publish-c2b-qos2-receive-maximum-2.c b/test/lib/c/03-publish-c2b-qos2-receive-maximum-2.c index ab507986..1d49b271 100644 --- a/test/lib/c/03-publish-c2b-qos2-receive-maximum-2.c +++ b/test/lib/c/03-publish-c2b-qos2-receive-maximum-2.c @@ -49,6 +49,7 @@ int main(int argc, char *argv[]) mosquitto_loop(mosq, 300, 1); } + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return run; } diff --git a/test/lib/c/03-publish-qos0.c b/test/lib/c/03-publish-qos0.c index 5d4a2464..1562b3c3 100644 --- a/test/lib/c/03-publish-qos0.c +++ b/test/lib/c/03-publish-qos0.c @@ -45,6 +45,7 @@ int main(int argc, char *argv[]) rc = mosquitto_loop(mosq, -1, 1); } + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return run; } diff --git a/test/lib/c/03-request-response-2.c b/test/lib/c/03-request-response-2.c index 3419f395..d548ebaf 100644 --- a/test/lib/c/03-request-response-2.c +++ b/test/lib/c/03-request-response-2.c @@ -61,6 +61,7 @@ int main(int argc, char *argv[]) rc = mosquitto_loop(mosq, -1, 1); } + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return run; } diff --git a/test/lib/c/08-ssl-bad-cacert.c b/test/lib/c/08-ssl-bad-cacert.c index d32a8dd0..b7291221 100644 --- a/test/lib/c/08-ssl-bad-cacert.c +++ b/test/lib/c/08-ssl-bad-cacert.c @@ -15,6 +15,7 @@ int main(int argc, char *argv[]) if(mosquitto_tls_set(mosq, "this/file/doesnt/exist", NULL, NULL, NULL, NULL) == MOSQ_ERR_INVAL){ rc = 0; } + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return rc; } diff --git a/test/lib/c/09-util-topic-tokenise.c b/test/lib/c/09-util-topic-tokenise.c index 24baf07f..39e335d3 100644 --- a/test/lib/c/09-util-topic-tokenise.c +++ b/test/lib/c/09-util-topic-tokenise.c @@ -30,6 +30,7 @@ int main(int argc, char *argv[]) print_error("topic", topics, topic_count); return 1; } + mosquitto_sub_topic_tokens_free(&topics, topic_count); if(mosquitto_sub_topic_tokenise("a/deep/topic/hierarchy", &topics, &topic_count)){ printf("Out of memory.\n"); @@ -43,6 +44,7 @@ int main(int argc, char *argv[]) print_error("a/deep/topic/hierarchy", topics, topic_count); return 1; } + mosquitto_sub_topic_tokens_free(&topics, topic_count); if(mosquitto_sub_topic_tokenise("/a/deep/topic/hierarchy", &topics, &topic_count)){ printf("Out of memory.\n"); @@ -57,6 +59,7 @@ int main(int argc, char *argv[]) print_error("/a/deep/topic/hierarchy", topics, topic_count); return 1; } + mosquitto_sub_topic_tokens_free(&topics, topic_count); if(mosquitto_sub_topic_tokenise("a/b/c", &topics, &topic_count)){ printf("Out of memory.\n"); @@ -69,6 +72,7 @@ int main(int argc, char *argv[]) print_error("a/b/c", topics, topic_count); return 1; } + mosquitto_sub_topic_tokens_free(&topics, topic_count); if(mosquitto_sub_topic_tokenise("/a/b/c", &topics, &topic_count)){ printf("Out of memory.\n"); @@ -82,6 +86,7 @@ int main(int argc, char *argv[]) print_error("/a/b/c", topics, topic_count); return 1; } + mosquitto_sub_topic_tokens_free(&topics, topic_count); if(mosquitto_sub_topic_tokenise("a///hierarchy", &topics, &topic_count)){ printf("Out of memory.\n"); @@ -95,6 +100,7 @@ int main(int argc, char *argv[]) print_error("a///hierarchy", topics, topic_count); return 1; } + mosquitto_sub_topic_tokens_free(&topics, topic_count); if(mosquitto_sub_topic_tokenise("/a///hierarchy", &topics, &topic_count)){ printf("Out of memory.\n"); @@ -109,6 +115,7 @@ int main(int argc, char *argv[]) print_error("/a///hierarchy", topics, topic_count); return 1; } + mosquitto_sub_topic_tokens_free(&topics, topic_count); if(mosquitto_sub_topic_tokenise("/a///hierarchy/", &topics, &topic_count)){ printf("Out of memory.\n"); @@ -124,6 +131,7 @@ int main(int argc, char *argv[]) print_error("/a///hierarchy/", topics, topic_count); return 1; } + mosquitto_sub_topic_tokens_free(&topics, topic_count); return 0; } diff --git a/test/lib/c/11-prop-send-content-type.c b/test/lib/c/11-prop-send-content-type.c index d60c8b5a..3222d9d5 100644 --- a/test/lib/c/11-prop-send-content-type.c +++ b/test/lib/c/11-prop-send-content-type.c @@ -18,6 +18,7 @@ void on_connect(struct mosquitto *mosq, void *obj, int rc) }else{ rc2 = mosquitto_property_add_string(&proplist, MQTT_PROP_CONTENT_TYPE, "application/json"); mosquitto_publish_v5(mosq, &sent_mid, "prop/qos0", strlen("message"), "message", 0, false, proplist); + mosquitto_property_free_all(&proplist); } } @@ -53,6 +54,7 @@ int main(int argc, char *argv[]) rc = mosquitto_loop(mosq, -1, 1); } + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return run; } diff --git a/test/lib/c/11-prop-send-payload-format.c b/test/lib/c/11-prop-send-payload-format.c index 516d86d4..3630f4a6 100644 --- a/test/lib/c/11-prop-send-payload-format.c +++ b/test/lib/c/11-prop-send-payload-format.c @@ -18,6 +18,7 @@ void on_connect(struct mosquitto *mosq, void *obj, int rc) }else{ rc2 = mosquitto_property_add_byte(&proplist, MQTT_PROP_PAYLOAD_FORMAT_INDICATOR, 1); mosquitto_publish_v5(mosq, &sent_mid, "prop/qos0", strlen("message"), "message", 0, false, proplist); + mosquitto_property_free_all(&proplist); } } diff --git a/test/lib/cpp/01-con-discon-success.cpp b/test/lib/cpp/01-con-discon-success.cpp index 82cc8b4f..45dedb78 100644 --- a/test/lib/cpp/01-con-discon-success.cpp +++ b/test/lib/cpp/01-con-discon-success.cpp @@ -48,6 +48,7 @@ int main(int argc, char *argv[]) while(run == -1){ mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); diff --git a/test/lib/cpp/01-keepalive-pingreq.cpp b/test/lib/cpp/01-keepalive-pingreq.cpp index 677066b2..97657c42 100644 --- a/test/lib/cpp/01-keepalive-pingreq.cpp +++ b/test/lib/cpp/01-keepalive-pingreq.cpp @@ -37,6 +37,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/01-no-clean-session.cpp b/test/lib/cpp/01-no-clean-session.cpp index 0a6f4987..ce58b556 100644 --- a/test/lib/cpp/01-no-clean-session.cpp +++ b/test/lib/cpp/01-no-clean-session.cpp @@ -29,6 +29,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/01-unpwd-set.cpp b/test/lib/cpp/01-unpwd-set.cpp index 24e53f43..df6046a2 100644 --- a/test/lib/cpp/01-unpwd-set.cpp +++ b/test/lib/cpp/01-unpwd-set.cpp @@ -30,6 +30,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/01-will-set.cpp b/test/lib/cpp/01-will-set.cpp index 1b9f7132..b1af2bd3 100644 --- a/test/lib/cpp/01-will-set.cpp +++ b/test/lib/cpp/01-will-set.cpp @@ -33,6 +33,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/01-will-unpwd-set.cpp b/test/lib/cpp/01-will-unpwd-set.cpp index f3ee1fe5..81b22c17 100644 --- a/test/lib/cpp/01-will-unpwd-set.cpp +++ b/test/lib/cpp/01-will-unpwd-set.cpp @@ -31,6 +31,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/02-subscribe-qos0.cpp b/test/lib/cpp/02-subscribe-qos0.cpp index 5a1582bc..c61b437d 100644 --- a/test/lib/cpp/02-subscribe-qos0.cpp +++ b/test/lib/cpp/02-subscribe-qos0.cpp @@ -51,6 +51,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/02-subscribe-qos1.cpp b/test/lib/cpp/02-subscribe-qos1.cpp index 3b53bf22..67dc84f5 100644 --- a/test/lib/cpp/02-subscribe-qos1.cpp +++ b/test/lib/cpp/02-subscribe-qos1.cpp @@ -52,6 +52,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/02-subscribe-qos2.cpp b/test/lib/cpp/02-subscribe-qos2.cpp index 3b2d1116..609bd380 100644 --- a/test/lib/cpp/02-subscribe-qos2.cpp +++ b/test/lib/cpp/02-subscribe-qos2.cpp @@ -52,6 +52,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/03-publish-b2c-qos1.cpp b/test/lib/cpp/03-publish-b2c-qos1.cpp index d7e3cb24..3930a81b 100644 --- a/test/lib/cpp/03-publish-b2c-qos1.cpp +++ b/test/lib/cpp/03-publish-b2c-qos1.cpp @@ -71,6 +71,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return 1; diff --git a/test/lib/cpp/03-publish-b2c-qos2.cpp b/test/lib/cpp/03-publish-b2c-qos2.cpp index a4feeed9..9ac221cf 100644 --- a/test/lib/cpp/03-publish-b2c-qos2.cpp +++ b/test/lib/cpp/03-publish-b2c-qos2.cpp @@ -73,6 +73,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/03-publish-c2b-qos1-disconnect.cpp b/test/lib/cpp/03-publish-c2b-qos1-disconnect.cpp index c17eae12..7f70d5c5 100644 --- a/test/lib/cpp/03-publish-c2b-qos1-disconnect.cpp +++ b/test/lib/cpp/03-publish-c2b-qos1-disconnect.cpp @@ -63,6 +63,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/03-publish-c2b-qos2-disconnect.cpp b/test/lib/cpp/03-publish-c2b-qos2-disconnect.cpp index 96991f24..2ec53b51 100644 --- a/test/lib/cpp/03-publish-c2b-qos2-disconnect.cpp +++ b/test/lib/cpp/03-publish-c2b-qos2-disconnect.cpp @@ -63,6 +63,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/03-publish-c2b-qos2.cpp b/test/lib/cpp/03-publish-c2b-qos2.cpp index 9fe606e8..52da8d53 100644 --- a/test/lib/cpp/03-publish-c2b-qos2.cpp +++ b/test/lib/cpp/03-publish-c2b-qos2.cpp @@ -54,6 +54,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/03-publish-qos0-no-payload.cpp b/test/lib/cpp/03-publish-qos0-no-payload.cpp index acd97e05..ab4bb4c6 100644 --- a/test/lib/cpp/03-publish-qos0-no-payload.cpp +++ b/test/lib/cpp/03-publish-qos0-no-payload.cpp @@ -52,6 +52,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/03-publish-qos0.cpp b/test/lib/cpp/03-publish-qos0.cpp index fba30baa..82503c4a 100644 --- a/test/lib/cpp/03-publish-qos0.cpp +++ b/test/lib/cpp/03-publish-qos0.cpp @@ -52,6 +52,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/04-retain-qos0.cpp b/test/lib/cpp/04-retain-qos0.cpp index 6b7b61ee..8e6a87ef 100644 --- a/test/lib/cpp/04-retain-qos0.cpp +++ b/test/lib/cpp/04-retain-qos0.cpp @@ -41,6 +41,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/08-ssl-bad-cacert.cpp b/test/lib/cpp/08-ssl-bad-cacert.cpp index b54d4fc5..d6367d7c 100644 --- a/test/lib/cpp/08-ssl-bad-cacert.cpp +++ b/test/lib/cpp/08-ssl-bad-cacert.cpp @@ -25,6 +25,7 @@ int main(int argc, char *argv[]) if(mosq->tls_set("this/file/doesnt/exist") == MOSQ_ERR_INVAL){ rc = 0; } + delete mosq; mosqpp::lib_cleanup(); return rc; diff --git a/test/lib/cpp/08-ssl-connect-cert-auth-enc.cpp b/test/lib/cpp/08-ssl-connect-cert-auth-enc.cpp index 55d8bc73..d512fe04 100644 --- a/test/lib/cpp/08-ssl-connect-cert-auth-enc.cpp +++ b/test/lib/cpp/08-ssl-connect-cert-auth-enc.cpp @@ -58,6 +58,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/08-ssl-connect-cert-auth.cpp b/test/lib/cpp/08-ssl-connect-cert-auth.cpp index 8e041510..5c51b8b8 100644 --- a/test/lib/cpp/08-ssl-connect-cert-auth.cpp +++ b/test/lib/cpp/08-ssl-connect-cert-auth.cpp @@ -49,6 +49,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/08-ssl-connect-no-auth.cpp b/test/lib/cpp/08-ssl-connect-no-auth.cpp index cfa0402f..d6fbd9df 100644 --- a/test/lib/cpp/08-ssl-connect-no-auth.cpp +++ b/test/lib/cpp/08-ssl-connect-no-auth.cpp @@ -49,6 +49,7 @@ int main(int argc, char *argv[]) mosq->loop(); } + delete mosq; mosqpp::lib_cleanup(); return run; diff --git a/test/lib/cpp/08-ssl-fake-cacert.cpp b/test/lib/cpp/08-ssl-fake-cacert.cpp index d4aa0dda..3b385caa 100644 --- a/test/lib/cpp/08-ssl-fake-cacert.cpp +++ b/test/lib/cpp/08-ssl-fake-cacert.cpp @@ -36,6 +36,7 @@ int main(int argc, char *argv[]) mosq->connect("localhost", port, 60); rc = mosq->loop_forever(); + delete mosq; if(rc == MOSQ_ERR_ERRNO && errno == EPROTO){ return 0; }else{ diff --git a/test/lib/cpp/09-util-topic-tokenise.cpp b/test/lib/cpp/09-util-topic-tokenise.cpp index 3094d29d..469994d2 100644 --- a/test/lib/cpp/09-util-topic-tokenise.cpp +++ b/test/lib/cpp/09-util-topic-tokenise.cpp @@ -29,6 +29,7 @@ int main(int argc, char *argv[]) print_error("topic", topics, topic_count); return 1; } + mosqpp::sub_topic_tokens_free(&topics, topic_count); if(mosqpp::sub_topic_tokenise("a/deep/topic/hierarchy", &topics, &topic_count)){ printf("Out of memory.\n"); @@ -42,6 +43,7 @@ int main(int argc, char *argv[]) print_error("a/deep/topic/hierarchy", topics, topic_count); return 1; } + mosqpp::sub_topic_tokens_free(&topics, topic_count); if(mosqpp::sub_topic_tokenise("/a/deep/topic/hierarchy", &topics, &topic_count)){ printf("Out of memory.\n"); @@ -56,6 +58,7 @@ int main(int argc, char *argv[]) print_error("/a/deep/topic/hierarchy", topics, topic_count); return 1; } + mosqpp::sub_topic_tokens_free(&topics, topic_count); if(mosqpp::sub_topic_tokenise("a/b/c", &topics, &topic_count)){ printf("Out of memory.\n"); @@ -68,6 +71,7 @@ int main(int argc, char *argv[]) print_error("a/b/c", topics, topic_count); return 1; } + mosqpp::sub_topic_tokens_free(&topics, topic_count); if(mosqpp::sub_topic_tokenise("/a/b/c", &topics, &topic_count)){ printf("Out of memory.\n"); @@ -81,6 +85,7 @@ int main(int argc, char *argv[]) print_error("/a/b/c", topics, topic_count); return 1; } + mosqpp::sub_topic_tokens_free(&topics, topic_count); if(mosqpp::sub_topic_tokenise("a///hierarchy", &topics, &topic_count)){ printf("Out of memory.\n"); @@ -94,6 +99,7 @@ int main(int argc, char *argv[]) print_error("a///hierarchy", topics, topic_count); return 1; } + mosqpp::sub_topic_tokens_free(&topics, topic_count); if(mosqpp::sub_topic_tokenise("/a///hierarchy", &topics, &topic_count)){ printf("Out of memory.\n"); @@ -108,6 +114,7 @@ int main(int argc, char *argv[]) print_error("/a///hierarchy", topics, topic_count); return 1; } + mosqpp::sub_topic_tokens_free(&topics, topic_count); if(mosqpp::sub_topic_tokenise("/a///hierarchy/", &topics, &topic_count)){ printf("Out of memory.\n"); @@ -123,6 +130,7 @@ int main(int argc, char *argv[]) print_error("/a///hierarchy/", topics, topic_count); return 1; } + mosqpp::sub_topic_tokens_free(&topics, topic_count); return 0; } From 946257bf30311dcd58a2ed2f8004a199a31f68ed Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 5 May 2020 16:01:17 +0100 Subject: [PATCH 026/113] Remove spurious version heading. --- ChangeLog.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 3e56770a..448bc990 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -8,9 +8,6 @@ Broker: - Don't disconnect clients that are already disconnected. This prevents the session expiry being extended on SIGHUP. Closes #1521. - 1.6.8 - 20191128 - ================ - Client library: - Don't treat an unexpected PUBACK, PUBREL, or PUBCOMP as a fatal error. Issue #1629. From c343812c420fbff5ed508680a78897778110208e Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 5 May 2020 23:24:06 +0100 Subject: [PATCH 027/113] Improve client test for unexpected pubrel. --- test/lib/03-publish-b2c-qos2-unexpected-pubrel.py | 3 +++ test/lib/c/03-publish-b2c-qos2-unexpected-pubrel.c | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/test/lib/03-publish-b2c-qos2-unexpected-pubrel.py b/test/lib/03-publish-b2c-qos2-unexpected-pubrel.py index 1d25199d..960a0d9f 100755 --- a/test/lib/03-publish-b2c-qos2-unexpected-pubrel.py +++ b/test/lib/03-publish-b2c-qos2-unexpected-pubrel.py @@ -20,6 +20,8 @@ pubrec_packet = mosq_test.gen_pubrec(mid) pubrel_packet = mosq_test.gen_pubrel(mid) pubcomp_packet = mosq_test.gen_pubcomp(mid) +publish_quit_packet = mosq_test.gen_publish("quit", qos=0, payload="quit") + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.settimeout(10) @@ -52,6 +54,7 @@ try: conn.send(pubrel_packet) if mosq_test.expect_packet(conn, "pubcomp", pubcomp_packet): + conn.send(publish_quit_packet) rc = 0 conn.close() diff --git a/test/lib/c/03-publish-b2c-qos2-unexpected-pubrel.c b/test/lib/c/03-publish-b2c-qos2-unexpected-pubrel.c index f51b814a..467d9b23 100644 --- a/test/lib/c/03-publish-b2c-qos2-unexpected-pubrel.c +++ b/test/lib/c/03-publish-b2c-qos2-unexpected-pubrel.c @@ -15,6 +15,10 @@ void on_connect(struct mosquitto *mosq, void *obj, int rc) void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg) { + if(!strcmp(msg->topic, "quit")){ + run = 0; + return; + } if(msg->mid != 13423){ printf("Invalid mid (%d)\n", msg->mid); exit(1); @@ -40,7 +44,6 @@ void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_messag exit(1); } - run = 0; } int main(int argc, char *argv[]) From 24049b1a1e874a2d8f0c10f23c410b5b01dad1c0 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 6 May 2020 22:24:58 +0100 Subject: [PATCH 028/113] Fix mosquitto_sub %j or %J not working on Windows. Closes #1674. Thanks to amigian74. --- ChangeLog.txt | 3 +++ client/sub_client_output.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 448bc990..08921778 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -12,6 +12,9 @@ Client library: - Don't treat an unexpected PUBACK, PUBREL, or PUBCOMP as a fatal error. Issue #1629. +Clients: +- Fix mosquitto_sub %j or %J not working on Windows. Closes #1674. + Build: - Various fixes for building with topic, message->qos, message->retain, message->payloadlen); if(message->qos > 0){ printf("\"mid\":%d,", message->mid); From 762ad432e8d243dac8934603186efe10c500e76b Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 12 May 2020 13:39:49 +0100 Subject: [PATCH 029/113] Fix support for openssl 3.0 --- ChangeLog.txt | 2 ++ lib/net_mosq.c | 79 ++++++++++++++++++++++++++++++++++++-------------- src/net.c | 20 +++++++++++++ 3 files changed, 80 insertions(+), 21 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 08921778..a075207b 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,10 +7,12 @@ Broker: - Fix memory leak when connecting clients rejected. - Don't disconnect clients that are already disconnected. This prevents the session expiry being extended on SIGHUP. Closes #1521. +- Fix support for openssl 3.0. Client library: - Don't treat an unexpected PUBACK, PUBREL, or PUBCOMP as a fatal error. Issue #1629. +- Fix support for openssl 3.0. Clients: - Fix mosquitto_sub %j or %J not working on Windows. Closes #1674. diff --git a/lib/net_mosq.c b/lib/net_mosq.c index 8d9d9a7c..35650024 100644 --- a/lib/net_mosq.c +++ b/lib/net_mosq.c @@ -531,6 +531,60 @@ int net__socket_connect_tls(struct mosquitto *mosq) #ifdef WITH_TLS +static int net__tls_load_ca(struct mosquitto *mosq) +{ + int ret; + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + ret = SSL_CTX_load_verify_locations(mosq->ssl_ctx, mosq->tls_cafile, mosq->tls_capath); + if(ret == 0){ +# ifdef WITH_BROKER + if(mosq->tls_cafile && mosq->tls_capath){ + log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\" and bridge_capath \"%s\".", mosq->tls_cafile, mosq->tls_capath); + }else if(mosq->tls_cafile){ + log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\".", mosq->tls_cafile); + }else{ + log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_capath \"%s\".", mosq->tls_capath); + } +# else + if(mosq->tls_cafile && mosq->tls_capath){ + log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\" and capath \"%s\".", mosq->tls_cafile, mosq->tls_capath); + }else if(mosq->tls_cafile){ + log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\".", mosq->tls_cafile); + }else{ + log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check capath \"%s\".", mosq->tls_capath); + } +# endif + return MOSQ_ERR_TLS; + } +#else + if(mosq->tls_cafile){ + ret = SSL_CTX_load_verify_file(mosq->ssl_ctx, mosq->tls_cafile); + if(ret == 0){ +# ifdef WITH_BROKER + log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\".", mosq->tls_cafile); +# else + log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\".", mosq->tls_cafile); +# endif + return MOSQ_ERR_TLS; + } + } + if(mosq->tls_capath){ + ret = SSL_CTX_load_verify_dir(mosq->ssl_ctx, mosq->tls_capath); + if(ret == 0){ +# ifdef WITH_BROKER + log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_capath \"%s\".", mosq->tls_capath); +# else + log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check capath \"%s\".", mosq->tls_capath); +# endif + return MOSQ_ERR_TLS; + } + } +#endif + return MOSQ_ERR_SUCCESS; +} + + static int net__init_ssl_ctx(struct mosquitto *mosq) { int ret; @@ -643,28 +697,11 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) } } if(mosq->tls_cafile || mosq->tls_capath){ - ret = SSL_CTX_load_verify_locations(mosq->ssl_ctx, mosq->tls_cafile, mosq->tls_capath); - if(ret == 0){ -#ifdef WITH_BROKER - if(mosq->tls_cafile && mosq->tls_capath){ - log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\" and bridge_capath \"%s\".", mosq->tls_cafile, mosq->tls_capath); - }else if(mosq->tls_cafile){ - log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\".", mosq->tls_cafile); - }else{ - log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_capath \"%s\".", mosq->tls_capath); - } -#else - if(mosq->tls_cafile && mosq->tls_capath){ - log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\" and capath \"%s\".", mosq->tls_cafile, mosq->tls_capath); - }else if(mosq->tls_cafile){ - log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\".", mosq->tls_cafile); - }else{ - log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check capath \"%s\".", mosq->tls_capath); - } -#endif -#if !defined(OPENSSL_NO_ENGINE) + ret = net__tls_load_ca(mosq); + if(ret != MOSQ_ERR_SUCCESS){ +# if !defined(OPENSSL_NO_ENGINE) ENGINE_FINISH(engine); -#endif +# endif COMPAT_CLOSE(mosq->sock); mosq->sock = INVALID_SOCKET; net__print_ssl_error(mosq); diff --git a/src/net.c b/src/net.c index 689c43cc..169c0a99 100644 --- a/src/net.c +++ b/src/net.c @@ -444,6 +444,7 @@ int net__tls_load_verify(struct mosquitto__listener *listener) # endif int rc; +#if OPENSSL_VERSION_NUMBER < 0x30000000L rc = SSL_CTX_load_verify_locations(listener->ssl_ctx, listener->cafile, listener->capath); if(rc == 0){ if(listener->cafile && listener->capath){ @@ -456,6 +457,25 @@ int net__tls_load_verify(struct mosquitto__listener *listener) net__print_ssl_error(NULL); return 1; } +#else + if(listener->cafile){ + rc = SSL_CTX_load_verify_file(listener->ssl_ctx, listener->cafile); + if(rc == 0){ + log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load CA certificates. Check cafile \"%s\".", listener->cafile); + net__print_ssl_error(NULL); + return MOSQ_ERR_TLS; + } + } + if(listener->capath){ + rc = SSL_CTX_load_verify_dir(listener->ssl_ctx, listener->capath); + if(rc == 0){ + log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load CA certificates. Check capath \"%s\".", listener->capath); + net__print_ssl_error(NULL); + return MOSQ_ERR_TLS; + } + } +#endif + if(listener->tls_engine){ #if !defined(OPENSSL_NO_ENGINE) engine = ENGINE_by_id(listener->tls_engine); From eae8c9aab4807bb31534b8faaa264fe357dedff8 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Fri, 15 May 2020 22:11:26 +0100 Subject: [PATCH 030/113] Fix check when loading persistence file of a different version Closes #1684. Thanks to grekhss. --- ChangeLog.txt | 2 ++ src/persist_read.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index a075207b..e321848a 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -8,6 +8,8 @@ Broker: - Don't disconnect clients that are already disconnected. This prevents the session expiry being extended on SIGHUP. Closes #1521. - Fix support for openssl 3.0. +- Fix check when loading persistence file of a different version than the + native version. Closes #1684. Client library: - Don't treat an unexpected PUBACK, PUBREL, or PUBCOMP as a fatal error. diff --git a/src/persist_read.c b/src/persist_read.c index fd87d825..ad0c78e3 100644 --- a/src/persist_read.c +++ b/src/persist_read.c @@ -415,7 +415,7 @@ int persist__restore(struct mosquitto_db *db) /* IMPORTANT - this is where compatibility checks are made. * Is your DB change still compatible with previous versions? */ - if(db_version > MOSQ_DB_VERSION && db_version != 0){ + if(db_version != MOSQ_DB_VERSION){ if(db_version == 4){ }else if(db_version == 3){ /* Addition of source_username and source_port to msg_store chunk in v4, v1.5.6 */ From 61a50c60d2351a2732cc15c3ef4a8bbc460bcfe7 Mon Sep 17 00:00:00 2001 From: Martin Kelly Date: Fri, 15 May 2020 17:35:58 -0700 Subject: [PATCH 031/113] add a refcount to library init/cleanup Add a refcount around mosquitto_lib_init and mosquitto_lib_cleanup so that multiple calls to init/cleanup don't trigger memory leaks or double-frees. Signed-off-by: Martin Kelly --- lib/mosquitto.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/lib/mosquitto.c b/lib/mosquitto.c index c49c53cf..f1f200fd 100644 --- a/lib/mosquitto.c +++ b/lib/mosquitto.c @@ -34,6 +34,7 @@ Contributors: #include "packet_mosq.h" #include "will_mosq.h" +static unsigned int init_refcount = 0; void mosquitto__destroy(struct mosquitto *mosq); @@ -47,31 +48,47 @@ int mosquitto_lib_version(int *major, int *minor, int *revision) int mosquitto_lib_init(void) { + int rc; + + if (init_refcount == 0) { #ifdef WIN32 - srand(GetTickCount64()); + srand(GetTickCount64()); #elif _POSIX_TIMERS>0 && defined(_POSIX_MONOTONIC_CLOCK) - struct timespec tp; + struct timespec tp; - clock_gettime(CLOCK_MONOTONIC, &tp); - srand(tp.tv_nsec); + clock_gettime(CLOCK_MONOTONIC, &tp); + srand(tp.tv_nsec); #elif defined(__APPLE__) - uint64_t ticks; + uint64_t ticks; - ticks = mach_absolute_time(); - srand((unsigned int)ticks); + ticks = mach_absolute_time(); + srand((unsigned int)ticks); #else - struct timeval tv; + struct timeval tv; - gettimeofday(&tv, NULL); - srand(tv.tv_sec*1000 + tv.tv_usec/1000); + gettimeofday(&tv, NULL); + srand(tv.tv_sec*1000 + tv.tv_usec/1000); #endif - return net__init(); + rc = net__init(); + if (rc != MOSQ_ERR_SUCCESS) { + return rc; + } + } + + init_refcount++; + return MOSQ_ERR_SUCCESS; } int mosquitto_lib_cleanup(void) { - net__cleanup(); + if (init_refcount == 1) { + net__cleanup(); + } + + if (init_refcount > 0) { + --init_refcount; + } return MOSQ_ERR_SUCCESS; } From d103174b5cfe55d784f862e02b6f6393ba8e98d4 Mon Sep 17 00:00:00 2001 From: Martin Kelly Date: Fri, 15 May 2020 17:16:02 -0700 Subject: [PATCH 032/113] correct mosquitto.h return code documentation We currently erroneously claim that mosquitto_lib_init cannot fail, while it can fail on Windows, if WSAStartup fails in net__init. Correct this. Signed-off-by: Martin Kelly --- lib/mosquitto.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/mosquitto.h b/lib/mosquitto.h index 5b639cb3..dd1ae6d9 100644 --- a/lib/mosquitto.h +++ b/lib/mosquitto.h @@ -202,7 +202,8 @@ libmosq_EXPORT int mosquitto_lib_version(int *major, int *minor, int *revision); * This function is *not* thread safe. * * Returns: - * MOSQ_ERR_SUCCESS - always + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_UNKNOWN - on Windows, if sockets couldn't be initialized. * * See Also: * , From ce463c185bab8926ddeb990ee30a5595df971bd1 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 20 May 2020 11:02:11 +0100 Subject: [PATCH 033/113] Update changelog. --- ChangeLog.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index e321848a..d3d3da02 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -15,6 +15,10 @@ Client library: - Don't treat an unexpected PUBACK, PUBREL, or PUBCOMP as a fatal error. Issue #1629. - Fix support for openssl 3.0. +- Fix memory leaks from multiple calls to + `mosquitto_lib_init()`/`mosquitto_lib_cleanup()`. Closes #1691. +- Fix documentation on return code of `mosquitto_lib_init()` for Windows. + Closes #1690. Clients: - Fix mosquitto_sub %j or %J not working on Windows. Closes #1674. From 6bd435d721c2dcc02a2722d845dc4cbe547d258a Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 25 May 2020 23:01:25 +0100 Subject: [PATCH 034/113] Fix possible assert crash associated with bridge reconnecting. This only occurs when compiled without epoll support. Closes #1700. Thanks to Matthias Urlichs. --- ChangeLog.txt | 2 + src/loop.c | 217 +++++++++++++++++++++++++------------------------- 2 files changed, 111 insertions(+), 108 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index d3d3da02..d94258c6 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,8 @@ Broker: - Fix support for openssl 3.0. - Fix check when loading persistence file of a different version than the native version. Closes #1684. +- Fix possible assert crash associated with bridge reconnecting when compiled + without epoll support. Closes #1700. Client library: - Don't treat an unexpected PUBACK, PUBREL, or PUBCOMP as a fatal error. diff --git a/src/loop.c b/src/loop.c index 36fa3114..823ffa6f 100644 --- a/src/loop.c +++ b/src/loop.c @@ -222,114 +222,6 @@ int mosquitto_main_loop(struct mosquitto_db *db, mosq_sock_t *listensock, int li } #endif - time_count = 0; - HASH_ITER(hh_sock, db->contexts_by_sock, context, ctxt_tmp){ - if(time_count > 0){ - time_count--; - }else{ - time_count = 1000; - now = mosquitto_time(); - } - context->pollfd_index = -1; - - if(context->sock != INVALID_SOCKET){ -#ifdef WITH_BRIDGE - if(context->bridge){ - mosquitto__check_keepalive(db, context); - if(context->bridge->round_robin == false - && context->bridge->cur_address != 0 - && context->bridge->primary_retry - && now > context->bridge->primary_retry){ - - if(context->bridge->primary_retry_sock == INVALID_SOCKET){ - rc = net__try_connect(context->bridge->addresses[0].address, - context->bridge->addresses[0].port, - &context->bridge->primary_retry_sock, NULL, false); - - if(rc == 0){ - COMPAT_CLOSE(context->bridge->primary_retry_sock); - context->bridge->primary_retry_sock = INVALID_SOCKET; - context->bridge->primary_retry = 0; - net__socket_close(db, context); - context->bridge->cur_address = 0; - } - }else{ - len = sizeof(int); - if(!getsockopt(context->bridge->primary_retry_sock, SOL_SOCKET, SO_ERROR, (char *)&err, &len)){ - if(err == 0){ - COMPAT_CLOSE(context->bridge->primary_retry_sock); - context->bridge->primary_retry_sock = INVALID_SOCKET; - context->bridge->primary_retry = 0; - net__socket_close(db, context); - context->bridge->cur_address = context->bridge->address_count-1; - }else{ - COMPAT_CLOSE(context->bridge->primary_retry_sock); - context->bridge->primary_retry_sock = INVALID_SOCKET; - context->bridge->primary_retry = now+5; - } - }else{ - COMPAT_CLOSE(context->bridge->primary_retry_sock); - context->bridge->primary_retry_sock = INVALID_SOCKET; - context->bridge->primary_retry = now+5; - } - } - } - } -#endif - - /* Local bridges never time out in this fashion. */ - if(!(context->keepalive) - || context->bridge - || now - context->last_msg_in <= (time_t)(context->keepalive)*3/2){ - - if(db__message_write(db, context) == MOSQ_ERR_SUCCESS){ -#ifdef WITH_EPOLL - if(context->current_out_packet || context->state == mosq_cs_connect_pending || context->ws_want_write){ - if(!(context->events & EPOLLOUT)) { - ev.data.fd = context->sock; - ev.events = EPOLLIN | EPOLLOUT; - if(epoll_ctl(db->epollfd, EPOLL_CTL_ADD, context->sock, &ev) == -1) { - if((errno != EEXIST)||(epoll_ctl(db->epollfd, EPOLL_CTL_MOD, context->sock, &ev) == -1)) { - log__printf(NULL, MOSQ_LOG_DEBUG, "Error in epoll re-registering to EPOLLOUT: %s", strerror(errno)); - } - } - context->events = EPOLLIN | EPOLLOUT; - } - context->ws_want_write = false; - } - else{ - if(context->events & EPOLLOUT) { - ev.data.fd = context->sock; - ev.events = EPOLLIN; - if(epoll_ctl(db->epollfd, EPOLL_CTL_ADD, context->sock, &ev) == -1) { - if((errno != EEXIST)||(epoll_ctl(db->epollfd, EPOLL_CTL_MOD, context->sock, &ev) == -1)) { - log__printf(NULL, MOSQ_LOG_DEBUG, "Error in epoll re-registering to EPOLLIN: %s", strerror(errno)); - } - } - context->events = EPOLLIN; - } - } -#else - pollfds[pollfd_index].fd = context->sock; - pollfds[pollfd_index].events = POLLIN; - pollfds[pollfd_index].revents = 0; - if(context->current_out_packet || context->state == mosq_cs_connect_pending || context->ws_want_write){ - pollfds[pollfd_index].events |= POLLOUT; - context->ws_want_write = false; - } - context->pollfd_index = pollfd_index; - pollfd_index++; -#endif - }else{ - do_disconnect(db, context, MOSQ_ERR_CONN_LOST); - } - }else{ - /* Client has exceeded keepalive*1.5 */ - do_disconnect(db, context, MOSQ_ERR_KEEPALIVE); - } - } - } - #ifdef WITH_BRIDGE time_count = 0; for(i=0; ibridge_count; i++){ @@ -466,6 +358,115 @@ int mosquitto_main_loop(struct mosquitto_db *db, mosq_sock_t *listensock, int li } #endif + time_count = 0; + HASH_ITER(hh_sock, db->contexts_by_sock, context, ctxt_tmp){ + if(time_count > 0){ + time_count--; + }else{ + time_count = 1000; + now = mosquitto_time(); + } + context->pollfd_index = -1; + + if(context->sock != INVALID_SOCKET){ +#ifdef WITH_BRIDGE + if(context->bridge){ + mosquitto__check_keepalive(db, context); + if(context->bridge->round_robin == false + && context->bridge->cur_address != 0 + && context->bridge->primary_retry + && now > context->bridge->primary_retry){ + + if(context->bridge->primary_retry_sock == INVALID_SOCKET){ + rc = net__try_connect(context->bridge->addresses[0].address, + context->bridge->addresses[0].port, + &context->bridge->primary_retry_sock, NULL, false); + + if(rc == 0){ + COMPAT_CLOSE(context->bridge->primary_retry_sock); + context->bridge->primary_retry_sock = INVALID_SOCKET; + context->bridge->primary_retry = 0; + net__socket_close(db, context); + context->bridge->cur_address = 0; + } + }else{ + len = sizeof(int); + if(!getsockopt(context->bridge->primary_retry_sock, SOL_SOCKET, SO_ERROR, (char *)&err, &len)){ + if(err == 0){ + COMPAT_CLOSE(context->bridge->primary_retry_sock); + context->bridge->primary_retry_sock = INVALID_SOCKET; + context->bridge->primary_retry = 0; + net__socket_close(db, context); + context->bridge->cur_address = context->bridge->address_count-1; + }else{ + COMPAT_CLOSE(context->bridge->primary_retry_sock); + context->bridge->primary_retry_sock = INVALID_SOCKET; + context->bridge->primary_retry = now+5; + } + }else{ + COMPAT_CLOSE(context->bridge->primary_retry_sock); + context->bridge->primary_retry_sock = INVALID_SOCKET; + context->bridge->primary_retry = now+5; + } + } + } + } +#endif + + /* Local bridges never time out in this fashion. */ + if(!(context->keepalive) + || context->bridge + || now - context->last_msg_in <= (time_t)(context->keepalive)*3/2){ + + if(db__message_write(db, context) == MOSQ_ERR_SUCCESS){ +#ifdef WITH_EPOLL + if(context->current_out_packet || context->state == mosq_cs_connect_pending || context->ws_want_write){ + if(!(context->events & EPOLLOUT)) { + ev.data.fd = context->sock; + ev.events = EPOLLIN | EPOLLOUT; + if(epoll_ctl(db->epollfd, EPOLL_CTL_ADD, context->sock, &ev) == -1) { + if((errno != EEXIST)||(epoll_ctl(db->epollfd, EPOLL_CTL_MOD, context->sock, &ev) == -1)) { + log__printf(NULL, MOSQ_LOG_DEBUG, "Error in epoll re-registering to EPOLLOUT: %s", strerror(errno)); + } + } + context->events = EPOLLIN | EPOLLOUT; + } + context->ws_want_write = false; + } + else{ + if(context->events & EPOLLOUT) { + ev.data.fd = context->sock; + ev.events = EPOLLIN; + if(epoll_ctl(db->epollfd, EPOLL_CTL_ADD, context->sock, &ev) == -1) { + if((errno != EEXIST)||(epoll_ctl(db->epollfd, EPOLL_CTL_MOD, context->sock, &ev) == -1)) { + log__printf(NULL, MOSQ_LOG_DEBUG, "Error in epoll re-registering to EPOLLIN: %s", strerror(errno)); + } + } + context->events = EPOLLIN; + } + } +#else + pollfds[pollfd_index].fd = context->sock; + pollfds[pollfd_index].events = POLLIN; + pollfds[pollfd_index].revents = 0; + if(context->current_out_packet || context->state == mosq_cs_connect_pending || context->ws_want_write){ + pollfds[pollfd_index].events |= POLLOUT; + context->ws_want_write = false; + } + context->pollfd_index = pollfd_index; + pollfd_index++; +#endif + }else{ + do_disconnect(db, context, MOSQ_ERR_CONN_LOST); + } + }else{ + /* Client has exceeded keepalive*1.5 */ + do_disconnect(db, context, MOSQ_ERR_KEEPALIVE); + } + } + } + + #ifndef WIN32 sigprocmask(SIG_SETMASK, &sigblock, &origsig); #ifdef WITH_EPOLL From cea0423e6976ad2e582818f6b3966fa751fb9ba8 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 25 May 2020 23:40:15 +0100 Subject: [PATCH 035/113] Update changelog and version. --- CMakeLists.txt | 2 +- ChangeLog.txt | 3 +++ config.mk | 2 +- installer/mosquitto.nsi | 2 +- installer/mosquitto64.nsi | 2 +- lib/mosquitto.h | 2 +- set-version.sh | 2 +- snap/snapcraft.yaml | 2 +- 8 files changed, 10 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 26b3e7a1..d326ea2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ project(mosquitto) cmake_minimum_required(VERSION 2.8) # Only for version 3 and up. cmake_policy(SET CMP0042 NEW) -set (VERSION 1.6.9) +set (VERSION 1.6.10) add_definitions (-DCMAKE -DVERSION=\"${VERSION}\") diff --git a/ChangeLog.txt b/ChangeLog.txt index d94258c6..a40e202b 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,6 @@ +1.6.10 - 2020-05-25 +=================== + Broker: - Report invalid bridge prefix+pattern combinations at config parsing time rather than letting the bridge fail later. Issue #1635. diff --git a/config.mk b/config.mk index 41a06ac7..89e0c319 100644 --- a/config.mk +++ b/config.mk @@ -109,7 +109,7 @@ WITH_COVERAGE:=no # Also bump lib/mosquitto.h, CMakeLists.txt, # installer/mosquitto.nsi, installer/mosquitto64.nsi -VERSION=1.6.9 +VERSION=1.6.10 # Client library SO version. Bump if incompatible API/ABI changes are made. SOVERSION=1 diff --git a/installer/mosquitto.nsi b/installer/mosquitto.nsi index 077485a4..4df8ac3d 100644 --- a/installer/mosquitto.nsi +++ b/installer/mosquitto.nsi @@ -9,7 +9,7 @@ !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' Name "Eclipse Mosquitto" -!define VERSION 1.6.9 +!define VERSION 1.6.10 OutFile "mosquitto-${VERSION}-install-windows-x86.exe" InstallDir "$PROGRAMFILES\mosquitto" diff --git a/installer/mosquitto64.nsi b/installer/mosquitto64.nsi index 5c5fa0a5..cd4ddc8f 100644 --- a/installer/mosquitto64.nsi +++ b/installer/mosquitto64.nsi @@ -9,7 +9,7 @@ !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' Name "Eclipse Mosquitto" -!define VERSION 1.6.9 +!define VERSION 1.6.10 OutFile "mosquitto-${VERSION}-install-windows-x64.exe" !include "x64.nsh" diff --git a/lib/mosquitto.h b/lib/mosquitto.h index dd1ae6d9..879184dc 100644 --- a/lib/mosquitto.h +++ b/lib/mosquitto.h @@ -48,7 +48,7 @@ extern "C" { #define LIBMOSQUITTO_MAJOR 1 #define LIBMOSQUITTO_MINOR 6 -#define LIBMOSQUITTO_REVISION 9 +#define LIBMOSQUITTO_REVISION 10 /* LIBMOSQUITTO_VERSION_NUMBER looks like 1002001 for e.g. version 1.2.1. */ #define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION) diff --git a/set-version.sh b/set-version.sh index a86f197c..2d081eeb 100755 --- a/set-version.sh +++ b/set-version.sh @@ -2,7 +2,7 @@ MAJOR=1 MINOR=6 -REVISION=9 +REVISION=10 sed -i "s/^VERSION=.*/VERSION=${MAJOR}.${MINOR}.${REVISION}/" config.mk diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 87e35280..5cabb807 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,5 +1,5 @@ name: mosquitto -version: 1.6.9 +version: 1.6.10 summary: Eclipse Mosquitto MQTT broker description: This is a message broker that supports version 3.1 and 3.1.1 of the MQTT protocol. From d95513ae15c16e26a435f59213bbf9e584c7f41b Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 25 May 2020 23:41:17 +0100 Subject: [PATCH 036/113] Man pages generated as part of web page, so no need to copy. --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 40691a09..125e24c2 100644 --- a/Makefile +++ b/Makefile @@ -110,7 +110,6 @@ sign : dist copy : sign cd dist; scp mosquitto-${VERSION}.tar.gz mosquitto-${VERSION}.tar.gz.asc mosquitto:site/mosquitto.org/files/source/ - cd dist; scp *.html mosquitto:site/mosquitto.org/man/ scp ChangeLog.txt mosquitto:site/mosquitto.org/ coverage : From 8123e767dec0dc5ed00446e1127ab1064c6412d6 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 25 May 2020 23:48:51 +0100 Subject: [PATCH 037/113] Release post. --- www/posts/2020/05/version-1-6-10-released.md | 55 ++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 www/posts/2020/05/version-1-6-10-released.md diff --git a/www/posts/2020/05/version-1-6-10-released.md b/www/posts/2020/05/version-1-6-10-released.md new file mode 100644 index 00000000..ff91b364 --- /dev/null +++ b/www/posts/2020/05/version-1-6-10-released.md @@ -0,0 +1,55 @@ + + +Mosquitto 1.6.10 has been released, this is a bugfix release. + +# Broker +- Report invalid bridge prefix+pattern combinations at config parsing time + rather than letting the bridge fail later. Issue [#1635]. +- Fix `mosquitto_passwd -b` not updating passwords for existing users + correctly. Creating a new user with `-b` worked without problem. + Closes [#1664]. +- Fix memory leak when connecting clients rejected. +- Don't disconnect clients that are already disconnected. This prevents the + session expiry being extended on SIGHUP. Closes [#1521]. +- Fix support for openssl 3.0. +- Fix check when loading persistence file of a different version than the + native version. Closes [#1684]. +- Fix possible assert crash associated with bridge reconnecting when compiled + without epoll support. Closes [#1700]. + +# Client library +- Don't treat an unexpected PUBACK, PUBREL, or PUBCOMP as a fatal error. + Issue [#1629]. +- Fix support for openssl 3.0. +- Fix memory leaks from multiple calls to + `mosquitto_lib_init()`/`mosquitto_lib_cleanup()`. Closes [#1691]. +- Fix documentation on return code of `mosquitto_lib_init()` for Windows. + Closes [#1690]. + +# Clients +- Fix mosquitto_sub `%j` or `%J` not working on Windows. Closes [#1674]. + +# Build +- Various fixes for building with below C99 support. Closes [#1622]. +- Fix use of sed on BSD. Closes [#1614]. + +[#1521]: https://github.com/eclipse/mosquitto/issues/1521 +[#1614]: https://github.com/eclipse/mosquitto/issues/1614 +[#1622]: https://github.com/eclipse/mosquitto/issues/1622 +[#1629]: https://github.com/eclipse/mosquitto/issues/1629 +[#1635]: https://github.com/eclipse/mosquitto/issues/1635 +[#1664]: https://github.com/eclipse/mosquitto/issues/1664 +[#1674]: https://github.com/eclipse/mosquitto/issues/1674 +[#1684]: https://github.com/eclipse/mosquitto/issues/1684 +[#1690]: https://github.com/eclipse/mosquitto/issues/1690 +[#1691]: https://github.com/eclipse/mosquitto/issues/1691 +[#1700]: https://github.com/eclipse/mosquitto/issues/1700 From f39bf49f9059bfbf2b802fbe8ea435dab42ebf0c Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 2 Jun 2020 19:04:26 +0100 Subject: [PATCH 038/113] Docker: update to 1.6.10. Also: * Update to alpine:3.12. * Use openssl. * Enable TLS-PSK. * Remove obsolete 1.4.12 dockerfile. --- docker/1.4.12/Dockerfile | 14 --------- docker/1.4.12/README.md | 49 ------------------------------ docker/1.4.12/docker-entrypoint.sh | 5 --- docker/1.5/Dockerfile | 5 ++- docker/1.6/Dockerfile | 9 +++--- docker/README.md | 3 -- docker/local/Dockerfile | 5 ++- 7 files changed, 8 insertions(+), 82 deletions(-) delete mode 100644 docker/1.4.12/Dockerfile delete mode 100644 docker/1.4.12/README.md delete mode 100755 docker/1.4.12/docker-entrypoint.sh diff --git a/docker/1.4.12/Dockerfile b/docker/1.4.12/Dockerfile deleted file mode 100644 index fb662061..00000000 --- a/docker/1.4.12/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM alpine:3.6 -MAINTAINER David Audet - -LABEL Description="Eclipse Mosquitto MQTT Broker" - -RUN apk --no-cache add mosquitto=1.4.12-r0 ca-certificates && \ - mkdir -p /mosquitto/config /mosquitto/data /mosquitto/log && \ - cp /etc/mosquitto/mosquitto.conf /mosquitto/config && \ - chown -R mosquitto:mosquitto /mosquitto - -COPY docker-entrypoint.sh / -EXPOSE 1883 -ENTRYPOINT ["/docker-entrypoint.sh"] -CMD ["/usr/sbin/mosquitto", "-c", "/mosquitto/config/mosquitto.conf"] diff --git a/docker/1.4.12/README.md b/docker/1.4.12/README.md deleted file mode 100644 index d5b68a45..00000000 --- a/docker/1.4.12/README.md +++ /dev/null @@ -1,49 +0,0 @@ -#Eclipse Mosquitto v1.4.12 Docker Image - -##Mount Points - -Three mount points have been created in the image to be used for configuration, persistent storage and logs. -``` -/mosquitto/config -/mosquitto/data -/mosquitto/log -``` - - -##Configuration - -When running the image, the default configuration values are used. -To use a custom configuration file, mount a **local** configuration file to `/mosquitto/config/mosquitto.conf` -``` -docker run -it -p 1883:1883 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto:1.4.12 -``` - -Configuration can be changed to: - -* persist data to `/mosquitto/data` -* log to `/mosquitto/log/mosquitto.log` - -i.e. add the following to `mosquitto.conf`: -``` -persistence true -persistence_location /mosquitto/data/ - -log_dest file /mosquitto/log/mosquitto.log -``` - -**Note**: If a volume is used, the data will persist between containers. - -##Build -Build the image: -``` -docker build -t eclipse-mosquitto:1.4.12 . -``` - -##Run -Run a container using the new image: -``` -docker run -it -p 1883:1883 -v :/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log eclipse-mosquitto:1.4.12 -``` -:boom: if the mosquitto configuration (mosquitto.conf) was modified -to use non-default ports, the docker run command will need to be updated -to expose the ports that have been configured. diff --git a/docker/1.4.12/docker-entrypoint.sh b/docker/1.4.12/docker-entrypoint.sh deleted file mode 100755 index 1a9fc8d0..00000000 --- a/docker/1.4.12/docker-entrypoint.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/ash - -set -e -exec "$@" - diff --git a/docker/1.5/Dockerfile b/docker/1.5/Dockerfile index b57b2747..e0061276 100644 --- a/docker/1.5/Dockerfile +++ b/docker/1.5/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.8 +FROM alpine:3.12 LABEL maintainer="Roger Light " \ description="Eclipse Mosquitto MQTT Broker" @@ -13,7 +13,7 @@ RUN set -x && \ build-base \ cmake \ gnupg \ - libressl-dev \ + openssl-dev \ util-linux-dev && \ wget https://github.com/warmcat/libwebsockets/archive/v${LWS_VERSION}.tar.gz -O /tmp/lws.tar.gz && \ mkdir -p /build/lws && \ @@ -62,7 +62,6 @@ RUN set -x && \ WITH_SHARED_LIBRARIES=yes \ WITH_SRV=no \ WITH_STRIP=yes \ - WITH_TLS_PSK=no \ WITH_WEBSOCKETS=yes \ prefix=/usr \ binary && \ diff --git a/docker/1.6/Dockerfile b/docker/1.6/Dockerfile index 5c7db1e8..8cc94464 100644 --- a/docker/1.6/Dockerfile +++ b/docker/1.6/Dockerfile @@ -1,10 +1,10 @@ -FROM alpine:3.8 +FROM alpine:3.12 LABEL maintainer="Roger Light " \ description="Eclipse Mosquitto MQTT Broker" -ENV VERSION=1.6.9 \ - DOWNLOAD_SHA256=412979b2db0a0020bd02fa64f0a0de9e7000b84462586e32b67f29bb1f6c1685 \ +ENV VERSION=1.6.10 \ + DOWNLOAD_SHA256=92d1807717f0f6d57d1ac1207ffdb952e8377e916c7b0bb4718f745239774232 \ GPG_KEYS=A0D6EEA1DCAE49A635A3B2F0779B22DFB3E717B7 \ LWS_VERSION=2.4.2 @@ -13,7 +13,7 @@ RUN set -x && \ build-base \ cmake \ gnupg \ - libressl-dev \ + openssl-dev \ util-linux-dev && \ wget https://github.com/warmcat/libwebsockets/archive/v${LWS_VERSION}.tar.gz -O /tmp/lws.tar.gz && \ mkdir -p /build/lws && \ @@ -62,7 +62,6 @@ RUN set -x && \ WITH_SHARED_LIBRARIES=yes \ WITH_SRV=no \ WITH_STRIP=yes \ - WITH_TLS_PSK=no \ WITH_WEBSOCKETS=yes \ prefix=/usr \ binary && \ diff --git a/docker/README.md b/docker/README.md index 6d3f2a14..ff53a2b4 100644 --- a/docker/README.md +++ b/docker/README.md @@ -5,9 +5,6 @@ This directory contains Docker files for Mosquitto. The `1.5` directory contains the latest version of Mosquitto for that series, and provide the basis of the official image. -`1.4.12` is the version using Alpine packaged Mosquitto, which will be removed -at the next minor release. - The `generic` directory contains a generic Dockerfile that can be used to build arbitrary versions of Mosquitto based on the released tarballs as follows: diff --git a/docker/local/Dockerfile b/docker/local/Dockerfile index ffb17c21..18913daa 100644 --- a/docker/local/Dockerfile +++ b/docker/local/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.8 +FROM alpine:3.12 LABEL maintainer="Roger Light " \ description="Eclipse Mosquitto MQTT Broker" @@ -12,7 +12,7 @@ RUN set -x && \ build-base \ cmake \ gnupg \ - libressl-dev \ + openssl-dev \ util-linux-dev && \ wget https://github.com/warmcat/libwebsockets/archive/v${LWS_VERSION}.tar.gz -O /tmp/lws.tar.gz && \ mkdir -p /build/lws && \ @@ -43,7 +43,6 @@ RUN set -x && \ WITH_SHARED_LIBRARIES=yes \ WITH_SRV=no \ WITH_STRIP=yes \ - WITH_TLS_PSK=no \ WITH_WEBSOCKETS=yes \ prefix=/usr \ binary && \ From 316f0be77a785fd9ebec3d4e9b7d8e571dec0314 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 9 Jun 2020 12:43:31 +0100 Subject: [PATCH 039/113] Add post on test.mosquitto.org cert update. --- www/pages/download.md | 8 +++---- www/posts/2020/05/version-1-6-10-released.md | 2 +- .../06/test-mosquitto-org-cert-updated.md | 22 +++++++++++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 www/posts/2020/06/test-mosquitto-org-cert-updated.md diff --git a/www/pages/download.md b/www/pages/download.md index 66130412..3dbec293 100644 --- a/www/pages/download.md +++ b/www/pages/download.md @@ -1,7 +1,7 @@ + +The CA certificate and server certificate for the broker running at +[test.mosquitto.org] has been updated to use a stronger key. + +This means that if you have downloaded the CA certificate, you will need to do +so again. + +Likewise, if you have used the [client certificate generator] then your +certificate will no longer be accepted and you must generate a new one. + +[test.mosquitto.org]: https://test.mosquitto.org +[client certificate generator]: https://test.mosquitto.org/ssl/ From ee634e4f843b36e3007e2386555524c2532c3413 Mon Sep 17 00:00:00 2001 From: matt Date: Fri, 5 Jun 2020 11:05:29 -0500 Subject: [PATCH 040/113] replace broken ssl-libs Signed-off-by: matt --- docker/generic/Dockerfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docker/generic/Dockerfile b/docker/generic/Dockerfile index 305f3f0f..cc467946 100644 --- a/docker/generic/Dockerfile +++ b/docker/generic/Dockerfile @@ -6,7 +6,7 @@ RUN test -n "${VERSION}" RUN apk --no-cache add \ build-base \ - libressl-dev \ + openssl-dev \ c-ares-dev \ curl \ util-linux-dev \ @@ -48,8 +48,7 @@ LABEL maintainer="Jonathan Hanson " \ RUN apk --no-cache add \ busybox \ ca-certificates \ - libcrypto1.0 \ - libssl1.0 \ + openssl \ libuuid \ libwebsockets \ musl From 4b541ad5ca46b79aebe3af524cfccc077be3541b Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 9 Jun 2020 15:42:51 +0100 Subject: [PATCH 041/113] Fix usage message not mentioning v5.0. Closes #1713. Thanks to whnr. --- ChangeLog.txt | 4 ++++ src/conf.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index a40e202b..e7c3b4ed 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,7 @@ +Broker: +- Fix usage message only mentioning v3.1.1. Closes #1713. + + 1.6.10 - 2020-05-25 =================== diff --git a/src/conf.c b/src/conf.c index ea5651f8..42614956 100644 --- a/src/conf.c +++ b/src/conf.c @@ -356,7 +356,7 @@ void config__cleanup(struct mosquitto__config *config) static void print_usage(void) { printf("mosquitto version %s\n\n", VERSION); - printf("mosquitto is an MQTT v3.1.1 broker.\n\n"); + printf("mosquitto is an MQTT v5.0/v3.1.1/v3.1 broker.\n\n"); printf("Usage: mosquitto [-c config_file] [-d] [-h] [-p port]\n\n"); printf(" -c : specify the broker config file.\n"); printf(" -d : put the broker into the background after starting.\n"); @@ -365,7 +365,7 @@ static void print_usage(void) printf(" Not recommended in conjunction with the -c option.\n"); printf(" -v : verbose mode - enable all logging types. This overrides\n"); printf(" any logging options given in the config file.\n"); - printf("\nSee http://mosquitto.org/ for more information.\n\n"); + printf("\nSee https://mosquitto.org/ for more information.\n\n"); } int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config, int argc, char *argv[]) From a9c97efaa48c385f070b4eec926f63b4bc14b56c Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 10 Jun 2020 15:21:01 +0100 Subject: [PATCH 042/113] Document that keepalive must be >= 5 seconds. --- lib/mosquitto.h | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/mosquitto.h b/lib/mosquitto.h index 879184dc..7267b605 100644 --- a/lib/mosquitto.h +++ b/lib/mosquitto.h @@ -434,7 +434,11 @@ libmosq_EXPORT int mosquitto_username_pw_set(struct mosquitto *mosq, const char * * Returns: * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_INVAL - if the input parameters were invalid, which could be any of: + * * mosq == NULL + * * host == NULL + * * port < 0 + * * keepalive < 5 * 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 @@ -500,7 +504,11 @@ libmosq_EXPORT int mosquitto_connect_bind(struct mosquitto *mosq, const char *ho * * Returns: * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_INVAL - if the input parameters were invalid, which could be any of: + * * mosq == NULL + * * host == NULL + * * port < 0 + * * keepalive < 5 * 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 @@ -570,7 +578,11 @@ libmosq_EXPORT int mosquitto_connect_async(struct mosquitto *mosq, const char *h * * Returns: * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_INVAL - if the input parameters were invalid, which could be any of: + * * mosq == NULL + * * host == NULL + * * port < 0 + * * keepalive < 5 * 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 @@ -604,7 +616,11 @@ libmosq_EXPORT int mosquitto_connect_bind_async(struct mosquitto *mosq, const ch * * Returns: * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_INVAL - if the input parameters were invalid, which could be any of: + * * mosq == NULL + * * host == NULL + * * port < 0 + * * keepalive < 5 * 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 From 6084685e0c5b09d67e4c801e9f346408c5bba446 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 16 Jun 2020 00:16:11 +0100 Subject: [PATCH 043/113] Revert docker change to openssl. Add extra targets to support openssl. --- docker/1.5-openssl/Dockerfile | 90 ++++++++++++++++++++++++ docker/1.5-openssl/README.md | 49 +++++++++++++ docker/1.5-openssl/docker-entrypoint.sh | 4 ++ docker/1.5/Dockerfile | 3 +- docker/1.6-openssl/Dockerfile | 91 +++++++++++++++++++++++++ docker/1.6-openssl/README.md | 49 +++++++++++++ docker/1.6-openssl/docker-entrypoint.sh | 4 ++ docker/1.6/Dockerfile | 3 +- 8 files changed, 291 insertions(+), 2 deletions(-) create mode 100644 docker/1.5-openssl/Dockerfile create mode 100644 docker/1.5-openssl/README.md create mode 100755 docker/1.5-openssl/docker-entrypoint.sh create mode 100644 docker/1.6-openssl/Dockerfile create mode 100644 docker/1.6-openssl/README.md create mode 100755 docker/1.6-openssl/docker-entrypoint.sh diff --git a/docker/1.5-openssl/Dockerfile b/docker/1.5-openssl/Dockerfile new file mode 100644 index 00000000..e0061276 --- /dev/null +++ b/docker/1.5-openssl/Dockerfile @@ -0,0 +1,90 @@ +FROM alpine:3.12 + +LABEL maintainer="Roger Light " \ + description="Eclipse Mosquitto MQTT Broker" + +ENV VERSION=1.5.9 \ + DOWNLOAD_SHA256=d7b62aa0ca680b0d869d6883373903362f98326a6465fc6cd01a0b9e0e8f0333 \ + GPG_KEYS=A0D6EEA1DCAE49A635A3B2F0779B22DFB3E717B7 \ + LWS_VERSION=2.4.2 + +RUN set -x && \ + apk --no-cache add --virtual build-deps \ + build-base \ + cmake \ + gnupg \ + openssl-dev \ + util-linux-dev && \ + wget https://github.com/warmcat/libwebsockets/archive/v${LWS_VERSION}.tar.gz -O /tmp/lws.tar.gz && \ + mkdir -p /build/lws && \ + tar --strip=1 -xf /tmp/lws.tar.gz -C /build/lws && \ + rm /tmp/lws.tar.gz && \ + cd /build/lws && \ + cmake . \ + -DCMAKE_BUILD_TYPE=MinSizeRel \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DLWS_IPV6=ON \ + -DLWS_WITHOUT_BUILTIN_GETIFADDRS=ON \ + -DLWS_WITHOUT_CLIENT=ON \ + -DLWS_WITHOUT_EXTENSIONS=ON \ + -DLWS_WITHOUT_TESTAPPS=ON \ + -DLWS_WITH_SHARED=OFF \ + -DLWS_WITH_ZIP_FOPS=OFF \ + -DLWS_WITH_ZLIB=OFF && \ + make -j "$(nproc)" && \ + rm -rf /root/.cmake && \ + wget https://mosquitto.org/files/source/mosquitto-${VERSION}.tar.gz -O /tmp/mosq.tar.gz && \ + echo "$DOWNLOAD_SHA256 /tmp/mosq.tar.gz" | sha256sum -c - && \ + wget https://mosquitto.org/files/source/mosquitto-${VERSION}.tar.gz.asc -O /tmp/mosq.tar.gz.asc && \ + export GNUPGHOME="$(mktemp -d)" && \ + found=''; \ + for server in \ + ha.pool.sks-keyservers.net \ + hkp://keyserver.ubuntu.com:80 \ + hkp://p80.pool.sks-keyservers.net:80 \ + pgp.mit.edu \ + ; do \ + echo "Fetching GPG key $GPG_KEYS from $server"; \ + gpg --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$GPG_KEYS" && found=yes && break; \ + done; \ + test -z "$found" && echo >&2 "error: failed to fetch GPG key $GPG_KEYS" && exit 1; \ + gpg --batch --verify /tmp/mosq.tar.gz.asc /tmp/mosq.tar.gz && \ + gpgconf --kill all && \ + rm -rf "$GNUPGHOME" /tmp/mosq.tar.gz.asc && \ + mkdir -p /build/mosq && \ + tar --strip=1 -xf /tmp/mosq.tar.gz -C /build/mosq && \ + rm /tmp/mosq.tar.gz && \ + make -C /build/mosq -j "$(nproc)" \ + CFLAGS="-Wall -O2 -I/build/lws/include -flto" \ + LDFLAGS="-L/build/lws/lib -flto" \ + WITH_ADNS=no \ + WITH_DOCS=no \ + WITH_SHARED_LIBRARIES=yes \ + WITH_SRV=no \ + WITH_STRIP=yes \ + WITH_WEBSOCKETS=yes \ + prefix=/usr \ + binary && \ + addgroup -S -g 1883 mosquitto 2>/dev/null && \ + adduser -S -u 1883 -D -H -h /var/empty -s /sbin/nologin -G mosquitto -g mosquitto mosquitto 2>/dev/null && \ + mkdir -p /mosquitto/config /mosquitto/data /mosquitto/log && \ + install -d /usr/sbin/ && \ + install -s -m755 /build/mosq/client/mosquitto_pub /usr/bin/mosquitto_pub && \ + install -s -m755 /build/mosq/client/mosquitto_sub /usr/bin/mosquitto_sub && \ + install -s -m644 /build/mosq/lib/libmosquitto.so.1 /usr/lib/libmosquitto.so.1 && \ + install -s -m755 /build/mosq/src/mosquitto /usr/sbin/mosquitto && \ + install -s -m755 /build/mosq/src/mosquitto_passwd /usr/bin/mosquitto_passwd && \ + install -m644 /build/mosq/mosquitto.conf /mosquitto/config/mosquitto.conf && \ + chown -R mosquitto:mosquitto /mosquitto && \ + apk --no-cache add \ + ca-certificates libuuid && \ + apk del build-deps && \ + rm -rf /build + +VOLUME ["/mosquitto/data", "/mosquitto/log"] + +# Set up the entry point script and default command +COPY docker-entrypoint.sh / +EXPOSE 1883 +ENTRYPOINT ["/docker-entrypoint.sh"] +CMD ["/usr/sbin/mosquitto", "-c", "/mosquitto/config/mosquitto.conf"] diff --git a/docker/1.5-openssl/README.md b/docker/1.5-openssl/README.md new file mode 100644 index 00000000..8a54a86b --- /dev/null +++ b/docker/1.5-openssl/README.md @@ -0,0 +1,49 @@ +# Eclipse Mosquitto Docker Image +Containers built with this Dockerfile build as source from published tarballs. + +## Mount Points +A docker mount point has been created in the image to be used for configuration. +``` +/mosquitto/config +``` + +Two docker volumes have been created in the image to be used for persistent storage and logs. +``` +/mosquitto/data +/mosquitto/log +``` + +## User/Group + +The image runs mosquitto under the mosquitto user and group, which are created +with a uid and gid of 1883. + +## Configuration +When creating a container from the image, the default configuration values are used. +To use a custom configuration file, mount a **local** configuration file to `/mosquitto/config/mosquitto.conf` +``` +docker run -it -p 1883:1883 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: +``` + +:boom: if the mosquitto configuration (mosquitto.conf) was modified +to use non-default ports, the docker run command will need to be updated +to expose the ports that have been configured, for example: + +``` +docker run -it -p 1883:1883 -p 8080:8080 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: +``` + +Configuration can be changed to: + +* persist data to `/mosquitto/data` +* log to `/mosquitto/log/mosquitto.log` + +i.e. add the following to `mosquitto.conf`: +``` +persistence true +persistence_location /mosquitto/data/ + +log_dest file /mosquitto/log/mosquitto.log +``` + +**Note**: For any volume used, the data will be persistent between containers. diff --git a/docker/1.5-openssl/docker-entrypoint.sh b/docker/1.5-openssl/docker-entrypoint.sh new file mode 100755 index 00000000..b381ac57 --- /dev/null +++ b/docker/1.5-openssl/docker-entrypoint.sh @@ -0,0 +1,4 @@ +#!/bin/ash +set -e + +exec "$@" diff --git a/docker/1.5/Dockerfile b/docker/1.5/Dockerfile index e0061276..7a0a10a3 100644 --- a/docker/1.5/Dockerfile +++ b/docker/1.5/Dockerfile @@ -13,7 +13,7 @@ RUN set -x && \ build-base \ cmake \ gnupg \ - openssl-dev \ + libressl-dev \ util-linux-dev && \ wget https://github.com/warmcat/libwebsockets/archive/v${LWS_VERSION}.tar.gz -O /tmp/lws.tar.gz && \ mkdir -p /build/lws && \ @@ -62,6 +62,7 @@ RUN set -x && \ WITH_SHARED_LIBRARIES=yes \ WITH_SRV=no \ WITH_STRIP=yes \ + WITH_TLS_PSK=no \ WITH_WEBSOCKETS=yes \ prefix=/usr \ binary && \ diff --git a/docker/1.6-openssl/Dockerfile b/docker/1.6-openssl/Dockerfile new file mode 100644 index 00000000..8cc94464 --- /dev/null +++ b/docker/1.6-openssl/Dockerfile @@ -0,0 +1,91 @@ +FROM alpine:3.12 + +LABEL maintainer="Roger Light " \ + description="Eclipse Mosquitto MQTT Broker" + +ENV VERSION=1.6.10 \ + DOWNLOAD_SHA256=92d1807717f0f6d57d1ac1207ffdb952e8377e916c7b0bb4718f745239774232 \ + GPG_KEYS=A0D6EEA1DCAE49A635A3B2F0779B22DFB3E717B7 \ + LWS_VERSION=2.4.2 + +RUN set -x && \ + apk --no-cache add --virtual build-deps \ + build-base \ + cmake \ + gnupg \ + openssl-dev \ + util-linux-dev && \ + wget https://github.com/warmcat/libwebsockets/archive/v${LWS_VERSION}.tar.gz -O /tmp/lws.tar.gz && \ + mkdir -p /build/lws && \ + tar --strip=1 -xf /tmp/lws.tar.gz -C /build/lws && \ + rm /tmp/lws.tar.gz && \ + cd /build/lws && \ + cmake . \ + -DCMAKE_BUILD_TYPE=MinSizeRel \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DLWS_IPV6=ON \ + -DLWS_WITHOUT_BUILTIN_GETIFADDRS=ON \ + -DLWS_WITHOUT_CLIENT=ON \ + -DLWS_WITHOUT_EXTENSIONS=ON \ + -DLWS_WITHOUT_TESTAPPS=ON \ + -DLWS_WITH_SHARED=OFF \ + -DLWS_WITH_ZIP_FOPS=OFF \ + -DLWS_WITH_ZLIB=OFF && \ + make -j "$(nproc)" && \ + rm -rf /root/.cmake && \ + wget https://mosquitto.org/files/source/mosquitto-${VERSION}.tar.gz -O /tmp/mosq.tar.gz && \ + echo "$DOWNLOAD_SHA256 /tmp/mosq.tar.gz" | sha256sum -c - && \ + wget https://mosquitto.org/files/source/mosquitto-${VERSION}.tar.gz.asc -O /tmp/mosq.tar.gz.asc && \ + export GNUPGHOME="$(mktemp -d)" && \ + found=''; \ + for server in \ + ha.pool.sks-keyservers.net \ + hkp://keyserver.ubuntu.com:80 \ + hkp://p80.pool.sks-keyservers.net:80 \ + pgp.mit.edu \ + ; do \ + echo "Fetching GPG key $GPG_KEYS from $server"; \ + gpg --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$GPG_KEYS" && found=yes && break; \ + done; \ + test -z "$found" && echo >&2 "error: failed to fetch GPG key $GPG_KEYS" && exit 1; \ + gpg --batch --verify /tmp/mosq.tar.gz.asc /tmp/mosq.tar.gz && \ + gpgconf --kill all && \ + rm -rf "$GNUPGHOME" /tmp/mosq.tar.gz.asc && \ + mkdir -p /build/mosq && \ + tar --strip=1 -xf /tmp/mosq.tar.gz -C /build/mosq && \ + rm /tmp/mosq.tar.gz && \ + make -C /build/mosq -j "$(nproc)" \ + CFLAGS="-Wall -O2 -I/build/lws/include" \ + LDFLAGS="-L/build/lws/lib" \ + WITH_ADNS=no \ + WITH_DOCS=no \ + WITH_SHARED_LIBRARIES=yes \ + WITH_SRV=no \ + WITH_STRIP=yes \ + WITH_WEBSOCKETS=yes \ + prefix=/usr \ + binary && \ + addgroup -S -g 1883 mosquitto 2>/dev/null && \ + adduser -S -u 1883 -D -H -h /var/empty -s /sbin/nologin -G mosquitto -g mosquitto mosquitto 2>/dev/null && \ + mkdir -p /mosquitto/config /mosquitto/data /mosquitto/log && \ + install -d /usr/sbin/ && \ + install -s -m755 /build/mosq/client/mosquitto_pub /usr/bin/mosquitto_pub && \ + install -s -m755 /build/mosq/client/mosquitto_rr /usr/bin/mosquitto_rr && \ + install -s -m755 /build/mosq/client/mosquitto_sub /usr/bin/mosquitto_sub && \ + install -s -m644 /build/mosq/lib/libmosquitto.so.1 /usr/lib/libmosquitto.so.1 && \ + install -s -m755 /build/mosq/src/mosquitto /usr/sbin/mosquitto && \ + install -s -m755 /build/mosq/src/mosquitto_passwd /usr/bin/mosquitto_passwd && \ + install -m644 /build/mosq/mosquitto.conf /mosquitto/config/mosquitto.conf && \ + chown -R mosquitto:mosquitto /mosquitto && \ + apk --no-cache add \ + ca-certificates && \ + apk del build-deps && \ + rm -rf /build + +VOLUME ["/mosquitto/data", "/mosquitto/log"] + +# Set up the entry point script and default command +COPY docker-entrypoint.sh / +EXPOSE 1883 +ENTRYPOINT ["/docker-entrypoint.sh"] +CMD ["/usr/sbin/mosquitto", "-c", "/mosquitto/config/mosquitto.conf"] diff --git a/docker/1.6-openssl/README.md b/docker/1.6-openssl/README.md new file mode 100644 index 00000000..8a54a86b --- /dev/null +++ b/docker/1.6-openssl/README.md @@ -0,0 +1,49 @@ +# Eclipse Mosquitto Docker Image +Containers built with this Dockerfile build as source from published tarballs. + +## Mount Points +A docker mount point has been created in the image to be used for configuration. +``` +/mosquitto/config +``` + +Two docker volumes have been created in the image to be used for persistent storage and logs. +``` +/mosquitto/data +/mosquitto/log +``` + +## User/Group + +The image runs mosquitto under the mosquitto user and group, which are created +with a uid and gid of 1883. + +## Configuration +When creating a container from the image, the default configuration values are used. +To use a custom configuration file, mount a **local** configuration file to `/mosquitto/config/mosquitto.conf` +``` +docker run -it -p 1883:1883 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: +``` + +:boom: if the mosquitto configuration (mosquitto.conf) was modified +to use non-default ports, the docker run command will need to be updated +to expose the ports that have been configured, for example: + +``` +docker run -it -p 1883:1883 -p 8080:8080 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: +``` + +Configuration can be changed to: + +* persist data to `/mosquitto/data` +* log to `/mosquitto/log/mosquitto.log` + +i.e. add the following to `mosquitto.conf`: +``` +persistence true +persistence_location /mosquitto/data/ + +log_dest file /mosquitto/log/mosquitto.log +``` + +**Note**: For any volume used, the data will be persistent between containers. diff --git a/docker/1.6-openssl/docker-entrypoint.sh b/docker/1.6-openssl/docker-entrypoint.sh new file mode 100755 index 00000000..b381ac57 --- /dev/null +++ b/docker/1.6-openssl/docker-entrypoint.sh @@ -0,0 +1,4 @@ +#!/bin/ash +set -e + +exec "$@" diff --git a/docker/1.6/Dockerfile b/docker/1.6/Dockerfile index 8cc94464..7f725437 100644 --- a/docker/1.6/Dockerfile +++ b/docker/1.6/Dockerfile @@ -13,7 +13,7 @@ RUN set -x && \ build-base \ cmake \ gnupg \ - openssl-dev \ + libressl-dev \ util-linux-dev && \ wget https://github.com/warmcat/libwebsockets/archive/v${LWS_VERSION}.tar.gz -O /tmp/lws.tar.gz && \ mkdir -p /build/lws && \ @@ -62,6 +62,7 @@ RUN set -x && \ WITH_SHARED_LIBRARIES=yes \ WITH_SRV=no \ WITH_STRIP=yes \ + WITH_TLS_PSK=no \ WITH_WEBSOCKETS=yes \ prefix=/usr \ binary && \ From 8f1f10743c852b21684a488d4a424c48edee815b Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 16 Jun 2020 16:00:51 +0100 Subject: [PATCH 044/113] New windows installer. --- www/pages/download.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/www/pages/download.md b/www/pages/download.md index 3dbec293..2cb19286 100644 --- a/www/pages/download.md +++ b/www/pages/download.md @@ -1,7 +1,7 @@ + +Ubuntu has just announced their new [Ubuntu Appliance] initiative, which provides self contained images for a number of different applications, for use on a Raspberry Pi or PC. These are full Ubuntu derivatives that use snap packages, so will keep up to date with the latest releases. + +There are five different applications in the first set of appliances, and Mosquitto is one of them. + +Read more at the [Ubuntu blog]. + +[Ubuntu Appliance]: http://ubuntu.com/appliance +[Ubuntu blog]: https://ubuntu.com/blog/the-ubuntu-appliance-portfolio From 09db90c41a22831a926523ce6494f56e0141fcf3 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 3 Mar 2020 21:26:29 +0000 Subject: [PATCH 046/113] Bump dockerfile for 1.6.9. --- docker/1.6/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/1.6/Dockerfile b/docker/1.6/Dockerfile index bd3bac23..5c7db1e8 100644 --- a/docker/1.6/Dockerfile +++ b/docker/1.6/Dockerfile @@ -3,8 +3,8 @@ FROM alpine:3.8 LABEL maintainer="Roger Light " \ description="Eclipse Mosquitto MQTT Broker" -ENV VERSION=1.6.8 \ - DOWNLOAD_SHA256=7df23c81ca37f0e070574fe74414403cf25183016433d07add6134366fb45df6 \ +ENV VERSION=1.6.9 \ + DOWNLOAD_SHA256=412979b2db0a0020bd02fa64f0a0de9e7000b84462586e32b67f29bb1f6c1685 \ GPG_KEYS=A0D6EEA1DCAE49A635A3B2F0779B22DFB3E717B7 \ LWS_VERSION=2.4.2 From 9313f09c9d09574ce5e61df483841f2ea730dc62 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 19 Mar 2020 15:45:18 +0000 Subject: [PATCH 047/113] Updated pull rqeuest text. --- .github/pull_request_template.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 7a283e07..9a93dc05 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,8 +1,18 @@ +Thank you for contributing your time to the Mosquitto project! + +Before you go any further, please note that we cannot accept contributions if +you haven't signed the [Eclipse Contributor Agreement](https://www.eclipse.org/legal/ECA.php). +If you aren't able to do that, or just don't want to, please describe your bug +fix/feature change in an issue. For simple bug fixes it is can be just as easy +for us to be told about the problem and then go fix it directly. + +Then please check the following list of things we ask for in your pull request: + +- [ ] Have you signed the [Eclipse Contributor Agreement](https://www.eclipse.org/legal/ECA.php), using the same email address as you used in your commits? +- [ ] Do each of your commits have a "Signed-off-by" line, with the correct email address? Use "git commit -s" to generate this line for you. - [ ] If you are contributing a new feature, is your work based off the develop branch? - [ ] If you are contributing a bugfix, is your work based off the fixes branch? - [ ] Have you added an explanation of what your changes do and why you'd like us to include them? - [ ] Have you successfully run `make test` with your changes locally? -- [ ] Have you signed the [Eclipse Contributor Agreement](https://www.eclipse.org/legal/ECA.php), using the same email address as you used in your commits? -- [ ] Do each of your commits have a "Signed-off-by" line, with the correct email address? Use "git commit -s" to generate this line for you. ----- From faf0530a76a5c08652e658271def5992edc2439d Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 23 Apr 2020 13:10:11 +0100 Subject: [PATCH 048/113] Update example Docker ports. Port 9001 is used by Intel drivers on Windows, so some users are suddenly seeing a problem. Issue #1580. --- docker/1.4.12/README.md | 4 ++-- docker/1.5/README.md | 2 +- docker/1.6/README.md | 2 +- docker/generic/README.md | 4 ++-- docker/local/README.md | 5 +++-- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/docker/1.4.12/README.md b/docker/1.4.12/README.md index 1ad42798..d5b68a45 100644 --- a/docker/1.4.12/README.md +++ b/docker/1.4.12/README.md @@ -15,7 +15,7 @@ Three mount points have been created in the image to be used for configuration, When running the image, the default configuration values are used. To use a custom configuration file, mount a **local** configuration file to `/mosquitto/config/mosquitto.conf` ``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto:1.4.12 +docker run -it -p 1883:1883 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto:1.4.12 ``` Configuration can be changed to: @@ -42,7 +42,7 @@ docker build -t eclipse-mosquitto:1.4.12 . ##Run Run a container using the new image: ``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log eclipse-mosquitto:1.4.12 +docker run -it -p 1883:1883 -v :/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log eclipse-mosquitto:1.4.12 ``` :boom: if the mosquitto configuration (mosquitto.conf) was modified to use non-default ports, the docker run command will need to be updated diff --git a/docker/1.5/README.md b/docker/1.5/README.md index ce91cd03..8a54a86b 100644 --- a/docker/1.5/README.md +++ b/docker/1.5/README.md @@ -30,7 +30,7 @@ to use non-default ports, the docker run command will need to be updated to expose the ports that have been configured, for example: ``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: +docker run -it -p 1883:1883 -p 8080:8080 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: ``` Configuration can be changed to: diff --git a/docker/1.6/README.md b/docker/1.6/README.md index ce91cd03..8a54a86b 100644 --- a/docker/1.6/README.md +++ b/docker/1.6/README.md @@ -30,7 +30,7 @@ to use non-default ports, the docker run command will need to be updated to expose the ports that have been configured, for example: ``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: +docker run -it -p 1883:1883 -p 8080:8080 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: ``` Configuration can be changed to: diff --git a/docker/generic/README.md b/docker/generic/README.md index 421cb91d..4e0279c7 100644 --- a/docker/generic/README.md +++ b/docker/generic/README.md @@ -13,7 +13,7 @@ Three docker volumes have been created in the image to be used for configuration When creating a container from the image, the default configuration values are used. To use a custom configuration file, mount a **local** configuration file to `/mosquitto/config/mosquitto.conf` ``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: +docker run -it -p 1883:1883 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: ``` Configuration can be changed to: @@ -40,7 +40,7 @@ docker build -t eclipse-mosquitto: --build-arg VERSION="" . ## Run Run a container using the new image: ``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log eclipse-mosquitto: +docker run -it -p 1883:1883 -v :/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log eclipse-mosquitto: ``` :boom: if the mosquitto configuration (mosquitto.conf) was modified to use non-default ports, the docker run command will need to be updated diff --git a/docker/local/README.md b/docker/local/README.md index f11086aa..210455f9 100644 --- a/docker/local/README.md +++ b/docker/local/README.md @@ -29,10 +29,11 @@ docker run -it -p 1883:1883 -v :/mosquitto/ :boom: if the mosquitto configuration (mosquitto.conf) was modified to use non-default ports, the docker run command will need to be updated -to expose the ports that have been configured, for example: +to expose the ports that have been configured, for example if you use port 8080 +for websockets as well as port 1883: ``` -docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: +docker run -it -p 1883:1883 -p 8080:8080 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto: ``` Configuration can be changed to: From 0946dc3a8d3883323cd673089f32944dc89d0346 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 25 May 2020 23:48:51 +0100 Subject: [PATCH 049/113] Release post. --- www/posts/2020/05/version-1-6-10-released.md | 55 ++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 www/posts/2020/05/version-1-6-10-released.md diff --git a/www/posts/2020/05/version-1-6-10-released.md b/www/posts/2020/05/version-1-6-10-released.md new file mode 100644 index 00000000..ff91b364 --- /dev/null +++ b/www/posts/2020/05/version-1-6-10-released.md @@ -0,0 +1,55 @@ + + +Mosquitto 1.6.10 has been released, this is a bugfix release. + +# Broker +- Report invalid bridge prefix+pattern combinations at config parsing time + rather than letting the bridge fail later. Issue [#1635]. +- Fix `mosquitto_passwd -b` not updating passwords for existing users + correctly. Creating a new user with `-b` worked without problem. + Closes [#1664]. +- Fix memory leak when connecting clients rejected. +- Don't disconnect clients that are already disconnected. This prevents the + session expiry being extended on SIGHUP. Closes [#1521]. +- Fix support for openssl 3.0. +- Fix check when loading persistence file of a different version than the + native version. Closes [#1684]. +- Fix possible assert crash associated with bridge reconnecting when compiled + without epoll support. Closes [#1700]. + +# Client library +- Don't treat an unexpected PUBACK, PUBREL, or PUBCOMP as a fatal error. + Issue [#1629]. +- Fix support for openssl 3.0. +- Fix memory leaks from multiple calls to + `mosquitto_lib_init()`/`mosquitto_lib_cleanup()`. Closes [#1691]. +- Fix documentation on return code of `mosquitto_lib_init()` for Windows. + Closes [#1690]. + +# Clients +- Fix mosquitto_sub `%j` or `%J` not working on Windows. Closes [#1674]. + +# Build +- Various fixes for building with below C99 support. Closes [#1622]. +- Fix use of sed on BSD. Closes [#1614]. + +[#1521]: https://github.com/eclipse/mosquitto/issues/1521 +[#1614]: https://github.com/eclipse/mosquitto/issues/1614 +[#1622]: https://github.com/eclipse/mosquitto/issues/1622 +[#1629]: https://github.com/eclipse/mosquitto/issues/1629 +[#1635]: https://github.com/eclipse/mosquitto/issues/1635 +[#1664]: https://github.com/eclipse/mosquitto/issues/1664 +[#1674]: https://github.com/eclipse/mosquitto/issues/1674 +[#1684]: https://github.com/eclipse/mosquitto/issues/1684 +[#1690]: https://github.com/eclipse/mosquitto/issues/1690 +[#1691]: https://github.com/eclipse/mosquitto/issues/1691 +[#1700]: https://github.com/eclipse/mosquitto/issues/1700 From 40a23981d381c7348e47e4d27c45a5daa18e85d2 Mon Sep 17 00:00:00 2001 From: HowJMay Date: Tue, 26 May 2020 15:19:51 +0800 Subject: [PATCH 050/113] fix typos in examples Fix typos Signed-off-by: HowJMay --- examples/temperature_conversion/readme.txt | 4 ++-- .../temperature_conversion/temperature_conversion.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/temperature_conversion/readme.txt b/examples/temperature_conversion/readme.txt index a706a7cc..de9d9a19 100644 --- a/examples/temperature_conversion/readme.txt +++ b/examples/temperature_conversion/readme.txt @@ -2,5 +2,5 @@ This is a simple example of the C++ library mosquittopp. It is a client that subscribes to the topic temperature/celsius which should have temperature data in text form being published to it. It reads this data as -a Celsius temperature, converts to Farenheit and republishes on -temperature/farenheit. +a Celsius temperature, converts to Fahrenheit and republishes on +temperature/fahrenheit. diff --git a/examples/temperature_conversion/temperature_conversion.cpp b/examples/temperature_conversion/temperature_conversion.cpp index 1fa6f55e..7ecf0d80 100644 --- a/examples/temperature_conversion/temperature_conversion.cpp +++ b/examples/temperature_conversion/temperature_conversion.cpp @@ -28,7 +28,7 @@ void mqtt_tempconv::on_connect(int rc) void mqtt_tempconv::on_message(const struct mosquitto_message *message) { - double temp_celsius, temp_farenheit; + double temp_celsius, temp_fahrenheit; char buf[51]; if(!strcmp(message->topic, "temperature/celsius")){ @@ -36,9 +36,9 @@ void mqtt_tempconv::on_message(const struct mosquitto_message *message) /* Copy N-1 bytes to ensure always 0 terminated. */ memcpy(buf, message->payload, 50*sizeof(char)); temp_celsius = atof(buf); - temp_farenheit = temp_celsius*9.0/5.0 + 32.0; - snprintf(buf, 50, "%f", temp_farenheit); - publish(NULL, "temperature/farenheit", strlen(buf), buf); + temp_fahrenheit = temp_celsius*9.0/5.0 + 32.0; + snprintf(buf, 50, "%f", temp_fahrenheit); + publish(NULL, "temperature/fahrenheit", strlen(buf), buf); } } From 27584018292f3df0a35f987b6adc5c39afbeeb44 Mon Sep 17 00:00:00 2001 From: Jasper Lievisse Adriaanse Date: Wed, 10 Jun 2020 09:33:57 +0200 Subject: [PATCH 051/113] only link with libm on OpenBSD fixes "ld: error: unable to find library -ldl" Signed-off-by: Jasper Lievisse Adriaanse --- src/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ee34673b..053ca1d9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -150,6 +150,8 @@ endif (HAVE_GETADDRINFO_A AND WITH_ADNS) if (UNIX) if (APPLE) set (MOSQ_LIBS ${MOSQ_LIBS} dl m) + elseif (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") + set (MOSQ_LIBS ${MOSQ_LIBS} m) elseif(QNX) set(MOSQ_LIBS ${MOSQ_LIBS} m socket) else(APPLE) From 4ef7ea6244ee1704720d0bd696c1c95d2697ede5 Mon Sep 17 00:00:00 2001 From: Jasper Lievisse Adriaanse Date: Wed, 10 Jun 2020 09:34:15 +0200 Subject: [PATCH 052/113] extend ifdef guard to fix compilation on OpenBSD otherwise in6_addr, AF_INET and AF_INET6 end up being undefined Signed-off-by: Jasper Lievisse Adriaanse --- lib/socks_mosq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/socks_mosq.c b/lib/socks_mosq.c index 51d8fb73..06b4116d 100644 --- a/lib/socks_mosq.c +++ b/lib/socks_mosq.c @@ -27,7 +27,7 @@ Contributors: #else # include #endif -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__OpenBSD__) # include # include #endif From c8964228e3aaef34a92b537b29a1af45c871a530 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 22 Jun 2020 21:45:50 +0100 Subject: [PATCH 053/113] Improved documentation around connect callback return codes. Close #1730. Thanks to John Laird. --- ChangeLog.txt | 3 +++ lib/mosquitto.h | 32 ++++++++++++-------------------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index e7c3b4ed..0fc175bb 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,6 +1,9 @@ Broker: - Fix usage message only mentioning v3.1.1. Closes #1713. +Client library: +- Improved documentation around connect callback return codes. Close #1730. + 1.6.10 - 2020-05-25 =================== diff --git a/lib/mosquitto.h b/lib/mosquitto.h index 7267b605..5e3591a5 100644 --- a/lib/mosquitto.h +++ b/lib/mosquitto.h @@ -1779,13 +1779,10 @@ libmosq_EXPORT int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk * Callback Parameters: * mosq - the mosquitto instance making the callback. * obj - the user data provided in - * rc - the return code of the connection response, one of: - * - * * 0 - success - * * 1 - connection refused (unacceptable protocol version) - * * 2 - connection refused (identifier rejected) - * * 3 - connection refused (broker unavailable) - * * 4-255 - reserved for future use + * rc - the return code of the connection response. The values are defined by + * the MQTT protocol version in use. + * For MQTT v5.0, look at section 3.2.2.2 Connect Reason code: https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html + * For MQTT v3.1.1, look at section 3.2.2.3 Connect Return code: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html */ libmosq_EXPORT void mosquitto_connect_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int)); @@ -1803,14 +1800,11 @@ libmosq_EXPORT void mosquitto_connect_callback_set(struct mosquitto *mosq, void * Callback Parameters: * mosq - the mosquitto instance making the callback. * obj - the user data provided in - * rc - the return code of the connection response, one of: + * rc - the return code of the connection response. The values are defined by + * the MQTT protocol version in use. + * For MQTT v5.0, look at section 3.2.2.2 Connect Reason code: https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html + * For MQTT v3.1.1, look at section 3.2.2.3 Connect Return code: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html * flags - the connect flags. - * - * * 0 - success - * * 1 - connection refused (unacceptable protocol version) - * * 2 - connection refused (identifier rejected) - * * 3 - connection refused (broker unavailable) - * * 4-255 - reserved for future use */ libmosq_EXPORT void mosquitto_connect_with_flags_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int)); @@ -1828,12 +1822,10 @@ libmosq_EXPORT void mosquitto_connect_with_flags_callback_set(struct mosquitto * * Callback Parameters: * mosq - the mosquitto instance making the callback. * obj - the user data provided in - * rc - the return code of the connection response, one of: - * * 0 - success - * * 1 - connection refused (unacceptable protocol version) - * * 2 - connection refused (identifier rejected) - * * 3 - connection refused (broker unavailable) - * * 4-255 - reserved for future use + * rc - the return code of the connection response. The values are defined by + * the MQTT protocol version in use. + * For MQTT v5.0, look at section 3.2.2.2 Connect Reason code: https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html + * For MQTT v3.1.1, look at section 3.2.2.3 Connect Return code: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html * flags - the connect flags. * props - list of MQTT 5 properties, or NULL * From 63f05643542cf198187a66c0e74aad6e17d9d419 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 6 Jul 2020 18:58:07 +0100 Subject: [PATCH 054/113] Add basic snap documentation. --- www/conf.py | 1 + www/pages/documentation.md | 6 +- www/pages/documentation/using-the-snap.md | 77 +++++++++++++++++++++++ 3 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 www/pages/documentation/using-the-snap.md diff --git a/www/conf.py b/www/conf.py index d7f1cbfe..8c41bec4 100644 --- a/www/conf.py +++ b/www/conf.py @@ -156,6 +156,7 @@ PAGES = ( ("pages/*.txt", "", "story.tmpl"), ("pages/*.html", "", "story.tmpl"), ("pages/*.md", "", "story.tmpl"), + ("pages/documentation/*.md", "", "story.tmpl"), ("man/*.xml", "man", "story.tmpl"), ) diff --git a/www/pages/documentation.md b/www/pages/documentation.md index 24064224..af4ed0f8 100644 --- a/www/pages/documentation.md +++ b/www/pages/documentation.md @@ -1,7 +1,7 @@ -Write your page here. +* [Using the snap package] - specific instructions on installing and configuring the Mosquitto snap package. + +[Using the snap package]:/documentation/using-the-snap/ diff --git a/www/pages/documentation/using-the-snap.md b/www/pages/documentation/using-the-snap.md new file mode 100644 index 00000000..d9926b20 --- /dev/null +++ b/www/pages/documentation/using-the-snap.md @@ -0,0 +1,77 @@ + + +On Linux systems that have snap support, Mosquitto can be installed from the +graphical software installer, or with `snap install mosquitto`. + +After installing the Mosquitto snap, the Mosquitto broker will be running with +the default configuration, which means it is listening for connections on port +1883. + +To test the broker, you can use the `mosquitto_pub` and `mosquitto_sub` command +line utilities, which are also provided in the snap. `mosquitto_pub` allows you +to publish messages to an MQTT broker, and `mosquitto_sub` allows you to +subscribe to messages from an MQTT broker. Both tools have a large number of +options to control how they are used and as such are useful for a wide variety +of tasks. In this case, we will just use them for some simple testing. + +To subscribe to all messages being published to the MQTT broker on the +`snap/example` topic, use the following command. If your MQTT broker is not +running on the same machine as `mosquitto_sub`, you will need to change the +`localhost` argument to match your MQTT broker host or IP address. + +``` +mosquitto_sub -h localhost -t 'snap/example' -v +``` + +The `-t snap/example` option sets the topic to subscribe to, and can be +provided multiple times. The `-v` option means to print both the topic of the +message as well as its payload. + +Now to publish a message to the same topic, use the very similar `mosquitto_pub` +command: + +``` +mosquitto_pub -h localhost -t 'snap/example' -m 'Hello from mosquitto_pub' +``` + +In this case the `-m` option provides the message payload to be published. If +everything works as planned, you should see `mosquitto_sub` print + +``` +snap/example Hello from mosquitto_pub +``` + +This is of course a very simple example, but it does allow testing of the +broker operation. Other things you may wish to try are subscribing to wildcard +topics that include `#` or `+`, or subscribing to the `$SYS/#` topic to see +information the broker is publishing about itself. Beware that the command line +treats `#` as a special character, and `$SYS` will be expanded as a environment +variable if you do not surround them with single quotes. + +Once you have finished your testing, you will want to configure your broker to +have encrypted connections and use authentication, possibly configuring +bridges, which allow different brokers to share topics, or many other options. + +To do this, you need to provide a new configuration file. The snap provides an +example configuration file at +`/var/snap/mosquitto/common/mosquitto_example.conf`. This file contains all of +the broker configuration, in a similar manner to the man page. To create your +own configuration, copy the example file to +`/var/snap/mosquitto/common/mosquitto.conf` and edit according to your needs. + +Any additional files required by the configuration, such as TLS certificates +and keys, must also be placed in `/var/snap/mosquitto/common/` - in new folders +if wanted. This directory is the only place accessible by Mosquitto when +running as a snap. + +All other aspects of running Mosquitto are the same as with any other +installation methods. From 20972a2819eb060fb12f980defc9b42e3a804c82 Mon Sep 17 00:00:00 2001 From: Sigmund Vik Date: Fri, 10 Jul 2020 16:36:17 +0200 Subject: [PATCH 055/113] Add broker ready message. Before this commit there was no good way to detect that the Mosquitto broker was done with its startup phase on systems without systemd. On such systems it was tricky to e.g. start the broker from a test where ports are dynamically assigned and one have to deal with potential port conflicts. Without a way to know that the broker is done with its startup phase, there was no way to know if the broker was able to acquire the port (for both IPv4 and IPv6) without waiting for some unknown period of time (when many tests are run in parallel a single process might be starved for resources). With this new broker ready message it is easy for the parent process to monitor the broker output and figure out when the port was successfully acquired. Signed-off-by: Sigmund Vik --- src/mosquitto.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mosquitto.c b/src/mosquitto.c index 43b0a203..98861248 100644 --- a/src/mosquitto.c +++ b/src/mosquitto.c @@ -364,6 +364,7 @@ int main(int argc, char *argv[]) } #endif + log__printf(NULL, MOSQ_LOG_INFO, "mosquitto version %s running", VERSION); #ifdef WITH_SYSTEMD sd_notify(0, "READY=1"); #endif From b7911f191b8bcacb054a5f1c2d1dea85ba925a22 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Sun, 12 Jul 2020 09:20:36 +0100 Subject: [PATCH 056/113] Add all docs to documentation page. --- www/conf.py | 1 + www/pages/documentation.md | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/www/conf.py b/www/conf.py index 8c41bec4..6018b89a 100644 --- a/www/conf.py +++ b/www/conf.py @@ -87,6 +87,7 @@ NAVIGATION_LINKS = { #("/sponsoring/", "Sponsoring"), ( ( + ("/documentation/", "All"), ("/roadmap/", "Roadmap"), ("/api/", "API"), ("/man/libmosquitto-3.html", "libmosquitto"), diff --git a/www/pages/documentation.md b/www/pages/documentation.md index af4ed0f8..b4b12468 100644 --- a/www/pages/documentation.md +++ b/www/pages/documentation.md @@ -9,6 +9,34 @@ .. type: text --> +# Man pages + +* [mosquitto] - running the Mosquitto broker +* [mosquitto.conf] - the Mosquitto broker configuration file +* [mosquitto_passwd] - command line utility for generating Mosquitto password files +* [mosquitto_pub] - command line utility for publishing messages to a broker +* [mosquitto_rr] - command line utility for simple request/response with a broker +* [mosquitto_sub] - command line utility for subscribing to topics on a broker +* [mosquitto-tls] - brief cheat sheet for creating x509 certificates +* [mqtt] - description of MQTT features + +# libmosquitto API + +* [libmosquitto API documentation] + +# Other + * [Using the snap package] - specific instructions on installing and configuring the Mosquitto snap package. +[mosquitto]:/man/mosquitto-8.html +[mosquitto.conf]:/man/mosquitto-conf-5.html +[mosquitto_passwd]:/man/mosquitto_passwd-1.html +[mosquitto_pub]:/man/mosquitto_pub-1.html +[mosquitto_rr]:/man/mosquitto_rr-1.html +[mosquitto_sub]:/man/mosquitto_sub-1.html +[mosquitto-tls]:/man/mosquitto-tls-7.html +[mqtt]:/man/mqtt-7.html + +[libmosquitto API documentation]:/api/ + [Using the snap package]:/documentation/using-the-snap/ From a75d574870c317442d70ed11617461d0d2401c45 Mon Sep 17 00:00:00 2001 From: Sigmund Vik Date: Fri, 3 Jul 2020 11:44:41 +0200 Subject: [PATCH 057/113] Fix sys_tree macro stubs with no arguments. This fixes Visual Studio compiler warnings like this one: "warning C4003: not enough arguments for function-like macro invocation 'G_MSGS_DROPPED_INC'" Signed-off-by: Sigmund Vik --- src/sys_tree.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sys_tree.h b/src/sys_tree.h index 275fb0a2..6b9804c4 100644 --- a/src/sys_tree.h +++ b/src/sys_tree.h @@ -54,10 +54,10 @@ extern unsigned int g_connection_count; #define G_MSGS_SENT_INC(A) #define G_PUB_MSGS_RECEIVED_INC(A) #define G_PUB_MSGS_SENT_INC(A) -#define G_MSGS_DROPPED_INC(A) -#define G_CLIENTS_EXPIRED_INC(A) -#define G_SOCKET_CONNECTIONS_INC(A) -#define G_CONNECTION_COUNT_INC(A) +#define G_MSGS_DROPPED_INC() +#define G_CLIENTS_EXPIRED_INC() +#define G_SOCKET_CONNECTIONS_INC() +#define G_CONNECTION_COUNT_INC() #endif From 5481575f8bff8521a86b9e0c9b24ff0bfe392404 Mon Sep 17 00:00:00 2001 From: Sigmund Vik Date: Fri, 10 Jul 2020 14:22:40 +0200 Subject: [PATCH 058/113] Fix FormatMessage warnings for Windows. From the FormatMessage() Win32 API documentation: "The lpBuffer parameter is a pointer to an LPTSTR; you must cast the pointer to an LPTSTR (for example, (LPTSTR)&lpBuffer)." https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessage#parameters This commit fixes warnings like these: warning C4047: 'function': 'LPSTR' differs in levels of indirection from 'char **' warning C4024: 'FormatMessageA': different types for formal and actual parameter 5 Signed-off-by: Sigmund Vik --- src/net.c | 2 +- src/security.c | 2 +- src/service.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/net.c b/src/net.c index 169c0a99..addc0a47 100644 --- a/src/net.c +++ b/src/net.c @@ -86,7 +86,7 @@ static void net__print_error(int log, const char *format_str) #ifdef WIN32 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, WSAGetLastError(), LANG_NEUTRAL, &buf, 0, NULL); + NULL, WSAGetLastError(), LANG_NEUTRAL, (LPTSTR)&buf, 0, NULL); log__printf(NULL, log, format_str, buf); LocalFree(buf); diff --git a/src/security.c b/src/security.c index 7779ca55..20b30627 100644 --- a/src/security.c +++ b/src/security.c @@ -33,7 +33,7 @@ void LIB_ERROR(void) #ifdef WIN32 char *buf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING, - NULL, GetLastError(), LANG_NEUTRAL, &buf, 0, NULL); + NULL, GetLastError(), LANG_NEUTRAL, (LPTSTR)&buf, 0, NULL); log__printf(NULL, MOSQ_LOG_ERR, "Load error: %s", buf); LocalFree(buf); #else diff --git a/src/service.c b/src/service.c index 05bee0c5..08099aa5 100644 --- a/src/service.c +++ b/src/service.c @@ -32,7 +32,7 @@ static void print_error(void) char *buf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, GetLastError(), LANG_NEUTRAL, &buf, 0, NULL); + NULL, GetLastError(), LANG_NEUTRAL, (LPTSTR)&buf, 0, NULL); fprintf(stderr, "Error: %s\n", buf); LocalFree(buf); From 873e580a004e5f9ebb74b79ca154d81c330f79bb Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 14 Jul 2020 16:44:33 +0100 Subject: [PATCH 059/113] Spelling/grammar fixes. --- man/mosquitto.conf.5.xml | 4 ++-- www/posts/2010/08/version-0-8-released.md | 2 +- www/posts/2011/07/version-0-12-released.md | 2 +- www/posts/2014/07/version-1-3-2-released.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/man/mosquitto.conf.5.xml b/man/mosquitto.conf.5.xml index 4b7843c0..bed00c6c 100644 --- a/man/mosquitto.conf.5.xml +++ b/man/mosquitto.conf.5.xml @@ -1182,7 +1182,7 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S Set to true to replace the clientid that a client - connected with with its username. This allows + connected with its username. This allows authentication to be tied to the clientid, which means that it is possible to prevent one client disconnecting another by using the same @@ -1926,7 +1926,7 @@ topic clients/total in 0 test/mosquitto/org/ $SYS/broker/ disable the hostname verification. Setting this option to true means that a - malicious third party could potentially inpersonate + malicious third party could potentially impersonate your server, so it should always be set to false in production environments. diff --git a/www/posts/2010/08/version-0-8-released.md b/www/posts/2010/08/version-0-8-released.md index e360d2bf..45179be0 100644 --- a/www/posts/2010/08/version-0-8-released.md +++ b/www/posts/2010/08/version-0-8-released.md @@ -26,7 +26,7 @@ The documentation of the library is currently ongoing... There is an overview of most of the function calls and an example in the [libmosquitto.3] man page, but complete coverage can be found in the mosquitto.h man page. This, combined with the class details in mosquittopp.h can be used to help use the C++ -library. The python module isn't documented due to it's extremely changeable +library. The python module isn't documented due to its extremely changeable state, but there is an example in the python directory. Other changes: diff --git a/www/posts/2011/07/version-0-12-released.md b/www/posts/2011/07/version-0-12-released.md index 343d9c78..5f3774c7 100644 --- a/www/posts/2011/07/version-0-12-released.md +++ b/www/posts/2011/07/version-0-12-released.md @@ -9,7 +9,7 @@ .. type: text --> -This is an update with some features and and bug fixes. The most significant +This is an update with some features and bug fixes. The most significant change is configuration reloading support. This will be improved to include bridge reloading in the future. diff --git a/www/posts/2014/07/version-1-3-2-released.md b/www/posts/2014/07/version-1-3-2-released.md index 13daa0e5..432abd45 100644 --- a/www/posts/2014/07/version-1-3-2-released.md +++ b/www/posts/2014/07/version-1-3-2-released.md @@ -34,7 +34,7 @@ authentication plugins in mosquitto. * When a durable client reconnects, its queued messages are now checked against ACLs in case of a change in username/ACL state since it last connected. - * Anonymous clients are no longer accidently disconnected from the broker + * Anonymous clients are no longer accidentally disconnected from the broker after a SIGHUP. * Fix bug [#1324411], which could have had unexpected consequences for delayed messages in rare circumstances. From abb31ffe8d5f970d81ef14c11004fc9d51c1e3a9 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 14 Jul 2020 17:27:57 +0100 Subject: [PATCH 060/113] Fix broker refusing to start if only websockets listeners were defined. Closes #1740. Thanks to OkenKhuman. --- ChangeLog.txt | 2 ++ src/mosquitto.c | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 0fc175bb..cf1ac6d2 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,5 +1,7 @@ Broker: - Fix usage message only mentioning v3.1.1. Closes #1713. +- Fix broker refusing to start if only websockets listeners were defined. + Closes #1740. Client library: - Improved documentation around connect callback return codes. Close #1730. diff --git a/src/mosquitto.c b/src/mosquitto.c index 98861248..fdde843b 100644 --- a/src/mosquitto.c +++ b/src/mosquitto.c @@ -333,10 +333,6 @@ int main(int argc, char *argv[]) #endif } } - if(listensock == NULL){ - log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to start any listening sockets, exiting."); - return 1; - } rc = drop_privileges(&config, false); if(rc != MOSQ_ERR_SUCCESS) return rc; From 5a56f066a873f68cf0d6b196b3794c85bb7c634d Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 14 Jul 2020 20:10:54 +0100 Subject: [PATCH 061/113] Change systemd unit files to create /var/log/mosquitto This happens before starting the broker. Also don't quit with an error if opening the log file isn't possible. Closes #821. --- ChangeLog.txt | 4 ++++ service/systemd/mosquitto.service.notify | 4 +++- service/systemd/mosquitto.service.simple | 4 +++- src/logging.c | 1 - 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index cf1ac6d2..8938ff7e 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -2,6 +2,10 @@ Broker: - Fix usage message only mentioning v3.1.1. Closes #1713. - Fix broker refusing to start if only websockets listeners were defined. Closes #1740. +- Change systemd unit files to create /var/log/mosquitto before starting. + Closes #821. +- Don't quit with an error if opening the log file isn't possible. + Closes #821. Client library: - Improved documentation around connect callback return codes. Close #1730. diff --git a/service/systemd/mosquitto.service.notify b/service/systemd/mosquitto.service.notify index 584a1101..84b08f84 100644 --- a/service/systemd/mosquitto.service.notify +++ b/service/systemd/mosquitto.service.notify @@ -1,5 +1,5 @@ [Unit] -Description=Mosquitto MQTT v3.1/v3.1.1 Broker +Description=Mosquitto MQTT Broker Documentation=man:mosquitto.conf(5) man:mosquitto(8) After=network.target Wants=network.target @@ -10,6 +10,8 @@ NotifyAccess=main ExecStart=/usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure +ExecStartPre=/bin/mkdir -m 740 -p /var/log/mosquitto +ExecStartPre=/bin/chown mosquitto: /var/log/mosquitto [Install] WantedBy=multi-user.target diff --git a/service/systemd/mosquitto.service.simple b/service/systemd/mosquitto.service.simple index 4346ea14..d0e657e6 100644 --- a/service/systemd/mosquitto.service.simple +++ b/service/systemd/mosquitto.service.simple @@ -1,5 +1,5 @@ [Unit] -Description=Mosquitto MQTT v3.1/v3.1.1 Broker +Description=Mosquitto MQTT Broker Documentation=man:mosquitto.conf(5) man:mosquitto(8) After=network.target Wants=network.target @@ -8,6 +8,8 @@ Wants=network.target ExecStart=/usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure +ExecStartPre=/bin/mkdir -m 740 -p /var/log/mosquitto +ExecStartPre=/bin/chown mosquitto: /var/log/mosquitto [Install] WantedBy=multi-user.target diff --git a/src/logging.c b/src/logging.c index a43ca22e..c1bc10b1 100644 --- a/src/logging.c +++ b/src/logging.c @@ -114,7 +114,6 @@ int log__init(struct mosquitto__config *config) log_destinations = MQTT3_LOG_STDERR; log_priorities = MOSQ_LOG_ERR; log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open log file %s for writing.", config->log_file); - return MOSQ_ERR_INVAL; } restore_privileges(); } From 1d66d3e443df99a308514d8143b0560fb11ef333 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 15 Jul 2020 00:19:44 +0100 Subject: [PATCH 062/113] Fix bridge topic remapping when using "" as the topic. Closes #1749. Thanks to cieslarchristian. --- ChangeLog.txt | 1 + src/conf.c | 166 ++++++++++++++++++++++++++------------------------ 2 files changed, 88 insertions(+), 79 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 8938ff7e..5bfb045c 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -6,6 +6,7 @@ Broker: Closes #821. - Don't quit with an error if opening the log file isn't possible. Closes #821. +- Fix bridge topic remapping when using "" as the topic. Closes #1749. Client library: - Improved documentation around connect callback return codes. Close #1730. diff --git a/src/conf.c b/src/conf.c index 42614956..6ec461ed 100644 --- a/src/conf.c +++ b/src/conf.c @@ -653,7 +653,7 @@ int config__read(struct mosquitto_db *db, struct mosquitto__config *config, bool } /* Check plugins loaded to see if they have username/password checks enabled */ - for(j=0; jlisteners[i].security_options.auth_plugin_config_count; j++){ + for(j=0; jlisteners[i].security_options.auth_plugin_config_count; j++){ plugin = &config->listeners[i].security_options.auth_plugin_configs[j].plugin; if(plugin->version == 3 || plugin->version == 2){ @@ -685,7 +685,7 @@ int config__read(struct mosquitto_db *db, struct mosquitto__config *config, bool } /* Check plugins loaded to see if they have username/password checks enabled */ - for(j=0; jsecurity_options.auth_plugin_config_count; j++){ + for(j=0; jsecurity_options.auth_plugin_config_count; j++){ plugin = &config->security_options.auth_plugin_configs[j].plugin; if(plugin->version == 3 || plugin->version == 2){ @@ -759,6 +759,76 @@ int config__read(struct mosquitto_db *db, struct mosquitto__config *config, bool return MOSQ_ERR_SUCCESS; } + +static int config__create_bridge_remap_topic(const char *prefix, const char *topic, char **remap_topic) +{ + int len; + + if(prefix){ + if(topic){ + len = strlen(topic) + strlen(prefix)+1; + *remap_topic = mosquitto__malloc(len+1); + if(!(*remap_topic)){ + log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); + return MOSQ_ERR_NOMEM; + } + snprintf(*remap_topic, len+1, "%s%s", prefix, topic); + (*remap_topic)[len] = '\0'; + }else{ + *remap_topic = mosquitto__strdup(prefix); + if(!(*remap_topic)){ + log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); + return MOSQ_ERR_NOMEM; + } + } + }else{ + *remap_topic = mosquitto__strdup(topic); + if(!(*remap_topic)){ + log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); + return MOSQ_ERR_NOMEM; + } + } + return MOSQ_ERR_SUCCESS; +} + + +static int config__create_bridge_prefix(char **prefix, const char *topic, const char *token, const char *direction) +{ + int len; + + if(topic){ + len = strlen(topic) + strlen(token) + 1; + }else{ + len = strlen(token) + 1; + } + *prefix = malloc(len); + if(*prefix == NULL){ + log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); + return MOSQ_ERR_NOMEM; + } + + if(topic){ + /* Print prefix+pattern to check for validity */ + snprintf(*prefix, len, "%s%s", token, topic); + }else{ + snprintf(*prefix, len, "%s", token); + } + + if(mosquitto_sub_topic_check(*prefix) != MOSQ_ERR_SUCCESS){ + log__printf(NULL, MOSQ_LOG_ERR, + "Error: Invalid bridge topic %s prefix and pattern combination '%s'.", + direction, *prefix); + + return MOSQ_ERR_INVAL; + } + + /* Print just the prefix for storage */ + snprintf(*prefix, len, "%s", token); + + return MOSQ_ERR_SUCCESS; +} + + int config__read_file_core(struct mosquitto__config *config, bool reload, struct config_recurse *cr, int level, int *lineno, FILE *fptr, char **buf, int *buflen) { int rc; @@ -769,7 +839,6 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct char *tmp_char; struct mosquitto__bridge *cur_bridge = NULL; struct mosquitto__bridge_topic *cur_topic; - int len; #endif struct mosquitto__auth_plugin_config *cur_auth_plugin_config = NULL; @@ -2021,22 +2090,12 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge topic local prefix '%s'.", token); return MOSQ_ERR_INVAL; } - cur_topic->local_prefix = malloc(strlen(cur_topic->topic) + strlen(token) + 1); - if(cur_topic->local_prefix == NULL){ - log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); - return MOSQ_ERR_NOMEM; - } - /* Print prefix+pattern to check for validity */ - snprintf(cur_topic->local_prefix, strlen(cur_topic->topic) + strlen(token)+1, - "%s%s", token, cur_topic->topic); - if(mosquitto_sub_topic_check(cur_topic->local_prefix) != MOSQ_ERR_SUCCESS){ - log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge topic local prefix and pattern combination '%s'.", cur_topic->local_prefix); + + if(config__create_bridge_prefix(&cur_topic->local_prefix, + cur_topic->topic, token, "local")){ + return MOSQ_ERR_INVAL; } - - /* Print just the prefix for storage */ - snprintf(cur_topic->local_prefix, strlen(cur_topic->topic) + strlen(token)+1, - "%s", token); } token = strtok_r(NULL, " ", &saveptr); @@ -2048,24 +2107,11 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge topic remote prefix '%s'.", token); return MOSQ_ERR_INVAL; } - cur_topic->remote_prefix = malloc(strlen(cur_topic->topic) + strlen(token) + 1); - if(cur_topic == NULL){ - log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); - return MOSQ_ERR_NOMEM; - } - /* Print prefix+pattern to check for validity */ - snprintf(cur_topic->remote_prefix, strlen(cur_topic->topic) + strlen(token)+1, - "%s%s", token, cur_topic->topic); - if(mosquitto_sub_topic_check(cur_topic->remote_prefix) != MOSQ_ERR_SUCCESS){ - log__printf(NULL, MOSQ_LOG_ERR, - "Error: Invalid bridge topic remote prefix and pattern combination '%s'.", - cur_topic->remote_prefix); + if(config__create_bridge_prefix(&cur_topic->remote_prefix, + cur_topic->topic, token, "remote")){ + return MOSQ_ERR_INVAL; } - - /* Print just the prefix for storage */ - snprintf(cur_topic->remote_prefix, strlen(cur_topic->topic) + strlen(token)+1, - "%s", token); } } } @@ -2077,54 +2123,16 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge remapping."); return MOSQ_ERR_INVAL; } - if(cur_topic->local_prefix){ - if(cur_topic->topic){ - len = strlen(cur_topic->topic) + strlen(cur_topic->local_prefix)+1; - cur_topic->local_topic = mosquitto__malloc(len+1); - if(!cur_topic->local_topic){ - log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); - return MOSQ_ERR_NOMEM; - } - snprintf(cur_topic->local_topic, len+1, "%s%s", cur_topic->local_prefix, cur_topic->topic); - cur_topic->local_topic[len] = '\0'; - }else{ - cur_topic->local_topic = mosquitto__strdup(cur_topic->local_prefix); - if(!cur_topic->local_topic){ - log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); - return MOSQ_ERR_NOMEM; - } - } - }else{ - cur_topic->local_topic = mosquitto__strdup(cur_topic->topic); - if(!cur_topic->local_topic){ - log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); - return MOSQ_ERR_NOMEM; - } + if(config__create_bridge_remap_topic(cur_topic->local_prefix, + cur_topic->topic, &cur_topic->local_topic)){ + + return MOSQ_ERR_INVAL; } - if(cur_topic->remote_prefix){ - if(cur_topic->topic){ - len = strlen(cur_topic->topic) + strlen(cur_topic->remote_prefix)+1; - cur_topic->remote_topic = mosquitto__malloc(len+1); - if(!cur_topic->remote_topic){ - log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); - return MOSQ_ERR_NOMEM; - } - snprintf(cur_topic->remote_topic, len, "%s%s", cur_topic->remote_prefix, cur_topic->topic); - cur_topic->remote_topic[len] = '\0'; - }else{ - cur_topic->remote_topic = mosquitto__strdup(cur_topic->remote_prefix); - if(!cur_topic->remote_topic){ - log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); - return MOSQ_ERR_NOMEM; - } - } - }else{ - cur_topic->remote_topic = mosquitto__strdup(cur_topic->topic); - if(!cur_topic->remote_topic){ - log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); - return MOSQ_ERR_NOMEM; - } + if(config__create_bridge_remap_topic(cur_topic->remote_prefix, + cur_topic->topic, &cur_topic->remote_topic)){ + + return MOSQ_ERR_INVAL; } #else log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Bridge support not available."); From 80bb31cf484d060bb5ec511c1afed1c5742b518c Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 15 Jul 2020 11:10:10 +0100 Subject: [PATCH 063/113] Github action for synchronising coverity scan branches --- .github/workflows/covsync.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/covsync.yml diff --git a/.github/workflows/covsync.yml b/.github/workflows/covsync.yml new file mode 100644 index 00000000..9119f6ae --- /dev/null +++ b/.github/workflows/covsync.yml @@ -0,0 +1,18 @@ +name: "Synchronise Coverity Scan branches on a weekly basis" + +on: + schedule: + - cron: "7 3 * * 0" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - run: | + git checkout -b coverity-fixes origin/fixes + git push origin coverity-fixes + git checkout -b coverity-develop origin/develop + git push origin coverity-develop From 3a83bafe4059a7cd5cb93697a6634776ef20722a Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 15 Jul 2020 11:26:23 +0100 Subject: [PATCH 064/113] Github actions: Add workflow_dispatch to allow a manual trigger. --- .github/workflows/covsync.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/covsync.yml b/.github/workflows/covsync.yml index 9119f6ae..2aec2ca9 100644 --- a/.github/workflows/covsync.yml +++ b/.github/workflows/covsync.yml @@ -1,6 +1,7 @@ name: "Synchronise Coverity Scan branches on a weekly basis" on: + workflow_dispatch: schedule: - cron: "7 3 * * 0" From cadcde52a46ddc310e8e3534fd348ef890df300c Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 15 Jul 2020 12:00:29 +0100 Subject: [PATCH 065/113] Remove duplicate code. Coverity Scan 1430458. --- client/pub_shared.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/client/pub_shared.c b/client/pub_shared.c index ae4cb277..bc9901db 100644 --- a/client/pub_shared.c +++ b/client/pub_shared.c @@ -71,7 +71,7 @@ int load_stdin(void) pos += rlen; } if(pos > MQTT_MAX_PAYLOAD){ - err_printf(&cfg, "Error: Message length must be less that %u bytes.\n\n", MQTT_MAX_PAYLOAD); + err_printf(&cfg, "Error: Message length must be less than %u bytes.\n\n", MQTT_MAX_PAYLOAD); free(cfg.message); return 1; } @@ -100,14 +100,9 @@ int load_file(const char *filename) fseek(fptr, 0, SEEK_END); flen = ftell(fptr); if(flen > MQTT_MAX_PAYLOAD){ - err_printf(&cfg, "Error: Message length must be less that %u bytes.\n\n", MQTT_MAX_PAYLOAD); + err_printf(&cfg, "Error: File must be less than %u bytes.\n\n", MQTT_MAX_PAYLOAD); free(cfg.message); return 1; - } - if(flen > 268435455){ - fclose(fptr); - err_printf(&cfg, "Error: File \"%s\" is too large (>268,435,455 bytes).\n", filename); - return 1; }else if(flen == 0){ fclose(fptr); err_printf(&cfg, "Error: File \"%s\" is empty.\n", filename); From e272f8fbca892301df0a754823ac556c3a1ca7bf Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 15 Jul 2020 12:04:20 +0100 Subject: [PATCH 066/113] mosquitto_pub: Close file on file too large. This wasn't a problem because this error caused the program to exit, so there was no real resource leak. Coverity Scan 1430457. --- client/pub_shared.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/pub_shared.c b/client/pub_shared.c index bc9901db..015c5eb1 100644 --- a/client/pub_shared.c +++ b/client/pub_shared.c @@ -100,6 +100,7 @@ int load_file(const char *filename) fseek(fptr, 0, SEEK_END); flen = ftell(fptr); if(flen > MQTT_MAX_PAYLOAD){ + fclose(fptr); err_printf(&cfg, "Error: File must be less than %u bytes.\n\n", MQTT_MAX_PAYLOAD); free(cfg.message); return 1; From d9003bb858e0b950f94e93a67ade968b962ee7e3 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 15 Jul 2020 12:12:51 +0100 Subject: [PATCH 067/113] Don't use mutex until it is initialised. Coverity Scan 1430456. --- lib/mosquitto.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/mosquitto.c b/lib/mosquitto.c index f1f200fd..25a4441b 100644 --- a/lib/mosquitto.c +++ b/lib/mosquitto.c @@ -151,10 +151,6 @@ int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_st } mosq->protocol = mosq_p_mqtt311; mosq->sock = INVALID_SOCKET; - if(net__socketpair(&mosq->sockpairR, &mosq->sockpairW)){ - log__printf(mosq, MOSQ_LOG_WARNING, - "Warning: Unable to open socket pair, outgoing publish commands may be delayed."); - } mosq->keepalive = 60; mosq->clean_start = clean_start; if(id){ @@ -213,6 +209,12 @@ int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_st pthread_mutex_init(&mosq->mid_mutex, NULL); mosq->thread_id = pthread_self(); #endif + /* This must be after pthread_mutex_init(), otherwise the log mutex may be + * used before being initialised. */ + if(net__socketpair(&mosq->sockpairR, &mosq->sockpairW)){ + log__printf(mosq, MOSQ_LOG_WARNING, + "Warning: Unable to open socket pair, outgoing publish commands may be delayed."); + } return MOSQ_ERR_SUCCESS; } From 4e0312c55f5cdf179ffca6f26e2087196f730db8 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 15 Jul 2020 17:08:00 +0100 Subject: [PATCH 068/113] Fix messages being queued for disconnected bridges This occurred incorrectly when clean start was set to true. Closes #1729. Thanks to Andreyooo. --- ChangeLog.txt | 2 ++ src/database.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index 5bfb045c..e818ce16 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,6 +7,8 @@ Broker: - Don't quit with an error if opening the log file isn't possible. Closes #821. - Fix bridge topic remapping when using "" as the topic. Closes #1749. +- Fix messages being queued for disconnected bridges when clean start was + set to true. Closes #1729. Client library: - Improved documentation around connect callback return codes. Close #1730. diff --git a/src/database.c b/src/database.c index 11980d7a..ef509db0 100644 --- a/src/database.c +++ b/src/database.c @@ -394,6 +394,10 @@ int db__message_insert(struct mosquitto_db *db, struct mosquitto *context, uint1 } } } + if(context->bridge && context->bridge->clean_start == true){ + mosquitto_property_free_all(&properties); + return 2; + } } if(context->sock != INVALID_SOCKET){ From b4e0dfa59819f9d94ed5d13a116b749516e3f2bb Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 15 Jul 2020 19:29:40 +0100 Subject: [PATCH 069/113] Fix `autosave_interval` not being triggered by messages being delivered. Closes #1726. Thanks to nduhme. --- ChangeLog.txt | 2 ++ src/database.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index e818ce16..e24719ee 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -9,6 +9,8 @@ Broker: - Fix bridge topic remapping when using "" as the topic. Closes #1749. - Fix messages being queued for disconnected bridges when clean start was set to true. Closes #1729. +- Fix `autosave_interval` not being triggered by messages being delivered. + Closes #1726. Client library: - Improved documentation around connect callback return codes. Close #1730. diff --git a/src/database.c b/src/database.c index ef509db0..124824cd 100644 --- a/src/database.c +++ b/src/database.c @@ -339,6 +339,9 @@ int db__message_delete_outgoing(struct mosquitto_db *db, struct mosquitto *conte } db__message_dequeue_first(context, &context->msgs_out); } +#ifdef WITH_PERSISTENCE + db->persistence_changes++; +#endif return MOSQ_ERR_SUCCESS; } From d371b3c58b67e1eb131623d9f71a2b621c347b7b Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 15 Jul 2020 20:25:36 +0100 Subject: [PATCH 070/113] Fix `mosquitto_publish*()` no longer returning `MOSQ_ERR_NO_CONN`. This was always returning success when the client was not connected. Closes #1725. Thanks to BOTorioN. --- ChangeLog.txt | 2 ++ lib/actions.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index e24719ee..18dbf201 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -14,6 +14,8 @@ Broker: Client library: - Improved documentation around connect callback return codes. Close #1730. +- Fix `mosquitto_publish*()` no longer returning `MOSQ_ERR_NO_CONN` when not + connected. Closes #1725. 1.6.10 - 2020-05-25 diff --git a/lib/actions.c b/lib/actions.c index 2b6dc596..d3914acf 100644 --- a/lib/actions.c +++ b/lib/actions.c @@ -151,9 +151,9 @@ int mosquitto_publish_v5(struct mosquitto *mosq, int *mid, const char *topic, in pthread_mutex_lock(&mosq->msgs_out.mutex); message->state = mosq_ms_invalid; - message__queue(mosq, message, mosq_md_out); + rc = message__queue(mosq, message, mosq_md_out); pthread_mutex_unlock(&mosq->msgs_out.mutex); - return MOSQ_ERR_SUCCESS; + return rc; } } From 8234d24b1b08e1f15353828649ca3290f67ea455 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 15 Jul 2020 22:06:29 +0100 Subject: [PATCH 071/113] Fix websockets clients sometimes not being disconnected promptly. Closes #1718. Thanks to Luca Casonato. --- ChangeLog.txt | 2 ++ src/websockets.c | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 18dbf201..28a04a47 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -11,6 +11,8 @@ Broker: set to true. Closes #1729. - Fix `autosave_interval` not being triggered by messages being delivered. Closes #1726. +- Fix websockets clients sometimes not being disconnected promptly. + Closes #1718. Client library: - Improved documentation around connect callback return codes. Close #1730. diff --git a/src/websockets.c b/src/websockets.c index fccece30..039b0d89 100644 --- a/src/websockets.c +++ b/src/websockets.c @@ -302,7 +302,10 @@ static int callback_mqtt(struct libwebsocket_context *context, } count = libwebsocket_write(wsi, &packet->payload[packet->pos], txlen, LWS_WRITE_BINARY); if(count < 0){ - if (mosq->state == mosq_cs_disconnect_ws || mosq->state == mosq_cs_disconnecting){ + if (mosq->state == mosq_cs_disconnect_ws + || mosq->state == mosq_cs_disconnecting + || mosq->state == mosq_cs_disused){ + return -1; } return 0; @@ -313,7 +316,10 @@ static int callback_mqtt(struct libwebsocket_context *context, packet->to_process -= count; packet->pos += count; if(packet->to_process > 0){ - if (mosq->state == mosq_cs_disconnect_ws || mosq->state == mosq_cs_disconnecting){ + if (mosq->state == mosq_cs_disconnect_ws + || mosq->state == mosq_cs_disconnecting + || mosq->state == mosq_cs_disused){ + return -1; } break; @@ -340,7 +346,10 @@ static int callback_mqtt(struct libwebsocket_context *context, mosq->next_msg_out = mosquitto_time() + mosq->keepalive; } - if (mosq->state == mosq_cs_disconnect_ws || mosq->state == mosq_cs_disconnecting){ + if (mosq->state == mosq_cs_disconnect_ws + || mosq->state == mosq_cs_disconnecting + || mosq->state == mosq_cs_disused){ + return -1; } if(mosq->current_out_packet){ From 54f3b686dc2a52d952ccf03945c19985440eb49c Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 15 Jul 2020 22:28:19 +0100 Subject: [PATCH 072/113] Fix "slow" file based logging by switching to line based buffering. Closes #1689. Closes #1741. Thanks to Brett M. Gordon and tt92. --- ChangeLog.txt | 2 ++ src/logging.c | 8 +------- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 28a04a47..0b458670 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -13,6 +13,8 @@ Broker: Closes #1726. - Fix websockets clients sometimes not being disconnected promptly. Closes #1718. +- Fix "slow" file based logging by switching to line based buffering. + Closes #1689. Closes #1741. Client library: - Improved documentation around connect callback return codes. Close #1730. diff --git a/src/logging.c b/src/logging.c index c1bc10b1..a72eb274 100644 --- a/src/logging.c +++ b/src/logging.c @@ -115,6 +115,7 @@ int log__init(struct mosquitto__config *config) log_priorities = MOSQ_LOG_ERR; log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open log file %s for writing.", config->log_file); } + setvbuf(config->log_fptr, NULL, _IOLBF, 0); restore_privileges(); } #ifdef WITH_DLT @@ -181,7 +182,6 @@ int log__vprintf(int priority, const char *fmt, va_list va) const char *topic; int syslog_priority; time_t now = time(NULL); - static time_t last_flush = 0; char time_buf[50]; bool log_timestamp = true; char *log_timestamp_format = NULL; @@ -293,7 +293,6 @@ int log__vprintf(int priority, const char *fmt, va_list va) }else{ fprintf(stdout, "%s\n", s); } - fflush(stdout); } if(log_destinations & MQTT3_LOG_STDERR){ if(log_timestamp){ @@ -305,7 +304,6 @@ int log__vprintf(int priority, const char *fmt, va_list va) }else{ fprintf(stderr, "%s\n", s); } - fflush(stderr); } if(log_destinations & MQTT3_LOG_FILE && log_fptr){ if(log_timestamp){ @@ -317,10 +315,6 @@ int log__vprintf(int priority, const char *fmt, va_list va) }else{ fprintf(log_fptr, "%s\n", s); } - if(now - last_flush > 1){ - fflush(log_fptr); - last_flush = now; - } } if(log_destinations & MQTT3_LOG_SYSLOG){ #ifndef WIN32 From 19d65ba200d3267f54a72bdb3cfe89d196ff2b41 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Fri, 17 Jul 2020 22:35:11 +0100 Subject: [PATCH 073/113] Set ownership of docker files on startup. --- docker/1.5/docker-entrypoint.sh | 11 +++++++++++ docker/1.6/docker-entrypoint.sh | 11 +++++++++++ docker/generic/docker-entrypoint.sh | 11 +++++++++++ docker/local/docker-entrypoint.sh | 11 +++++++++++ 4 files changed, 44 insertions(+) diff --git a/docker/1.5/docker-entrypoint.sh b/docker/1.5/docker-entrypoint.sh index b381ac57..85099f54 100755 --- a/docker/1.5/docker-entrypoint.sh +++ b/docker/1.5/docker-entrypoint.sh @@ -1,4 +1,15 @@ #!/bin/ash set -e +docker_set_permissions() { + local user; user="$(id -u)" + + if [ "$user" = '0' ]; then + chown -R mosquitto:mosquitto /mosquitto + fi +} + + +docker_set_permissions() + exec "$@" diff --git a/docker/1.6/docker-entrypoint.sh b/docker/1.6/docker-entrypoint.sh index b381ac57..85099f54 100755 --- a/docker/1.6/docker-entrypoint.sh +++ b/docker/1.6/docker-entrypoint.sh @@ -1,4 +1,15 @@ #!/bin/ash set -e +docker_set_permissions() { + local user; user="$(id -u)" + + if [ "$user" = '0' ]; then + chown -R mosquitto:mosquitto /mosquitto + fi +} + + +docker_set_permissions() + exec "$@" diff --git a/docker/generic/docker-entrypoint.sh b/docker/generic/docker-entrypoint.sh index b381ac57..85099f54 100755 --- a/docker/generic/docker-entrypoint.sh +++ b/docker/generic/docker-entrypoint.sh @@ -1,4 +1,15 @@ #!/bin/ash set -e +docker_set_permissions() { + local user; user="$(id -u)" + + if [ "$user" = '0' ]; then + chown -R mosquitto:mosquitto /mosquitto + fi +} + + +docker_set_permissions() + exec "$@" diff --git a/docker/local/docker-entrypoint.sh b/docker/local/docker-entrypoint.sh index b381ac57..85099f54 100755 --- a/docker/local/docker-entrypoint.sh +++ b/docker/local/docker-entrypoint.sh @@ -1,4 +1,15 @@ #!/bin/ash set -e +docker_set_permissions() { + local user; user="$(id -u)" + + if [ "$user" = '0' ]; then + chown -R mosquitto:mosquitto /mosquitto + fi +} + + +docker_set_permissions() + exec "$@" From 2b1a22776bd54bbdb54665f33f2b55e0fac7b3c0 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Sun, 19 Jul 2020 21:59:28 +0100 Subject: [PATCH 074/113] Only call setvbuf on open files. --- src/logging.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/logging.c b/src/logging.c index a72eb274..e9f92df9 100644 --- a/src/logging.c +++ b/src/logging.c @@ -110,12 +110,13 @@ int log__init(struct mosquitto__config *config) return 1; } config->log_fptr = mosquitto__fopen(config->log_file, "at", true); - if(!config->log_fptr){ + if(config->log_fptr){ + setvbuf(config->log_fptr, NULL, _IOLBF, 0); + }else{ log_destinations = MQTT3_LOG_STDERR; log_priorities = MOSQ_LOG_ERR; log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open log file %s for writing.", config->log_file); } - setvbuf(config->log_fptr, NULL, _IOLBF, 0); restore_privileges(); } #ifdef WITH_DLT From 42ab1fe2d30f1dc210c75500e03123da5d02f2cf Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 22 Jul 2020 15:13:40 +0100 Subject: [PATCH 075/113] Upgrade snap to core18. --- snap/snapcraft.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 5cabb807..263ddc0d 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,7 +1,7 @@ name: mosquitto version: 1.6.10 summary: Eclipse Mosquitto MQTT broker -description: This is a message broker that supports version 3.1 and 3.1.1 of the MQTT +description: This is a message broker that supports version 5.0, 3.1.1, and 3.1 of the MQTT protocol. MQTT provides a method of carrying out messaging using a publish/subscribe model. It is lightweight, both in terms of bandwidth usage and ease of @@ -10,6 +10,7 @@ description: This is a message broker that supports version 3.1 and 3.1.1 of the example. confinement: strict grade: stable +base: core18 apps: mosquitto: @@ -64,7 +65,7 @@ parts: - gcc - g++ stage-packages: - - libssl1.0.0 + - libssl1.1 - ca-certificates prime: - usr/sbin/mosquitto From 0ac46c2d2aadfc98c3d75843195122d5172e6d10 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 22 Jul 2020 20:36:29 +0100 Subject: [PATCH 076/113] core18 doesn't have libssl1.1 --- snap/snapcraft.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 263ddc0d..4de5f916 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -65,7 +65,7 @@ parts: - gcc - g++ stage-packages: - - libssl1.1 + - libssl1.0.0 - ca-certificates prime: - usr/sbin/mosquitto From 1f717873d682b0137ebc202166e004958354f18b Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Fri, 31 Jul 2020 23:01:15 +0100 Subject: [PATCH 077/113] Log protocol error message where appropriate from a bad UNSUBSCRIBE Rather than the generic "socket error". Related to #1765. --- ChangeLog.txt | 2 ++ src/handle_unsubscribe.c | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 0b458670..81fd892e 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -15,6 +15,8 @@ Broker: Closes #1718. - Fix "slow" file based logging by switching to line based buffering. Closes #1689. Closes #1741. +- Log protocol error message where appropriate from a bad UNSUBSCRIBE, rather + than the generic "socket error". Client library: - Improved documentation around connect callback return codes. Close #1730. diff --git a/src/handle_unsubscribe.c b/src/handle_unsubscribe.c index 9869b32a..df27911d 100644 --- a/src/handle_unsubscribe.c +++ b/src/handle_unsubscribe.c @@ -49,7 +49,7 @@ int handle__unsubscribe(struct mosquitto_db *db, struct mosquitto *context) return MOSQ_ERR_PROTOCOL; } } - if(packet__read_uint16(&context->in_packet, &mid)) return 1; + if(packet__read_uint16(&context->in_packet, &mid)) return MOSQ_ERR_PROTOCOL; if(mid == 0) return MOSQ_ERR_PROTOCOL; if(context->protocol == mosq_p_mqtt5){ @@ -76,7 +76,7 @@ int handle__unsubscribe(struct mosquitto_db *db, struct mosquitto *context) sub = NULL; if(packet__read_string(&context->in_packet, &sub, &slen)){ mosquitto__free(reason_codes); - return 1; + return MOSQ_ERR_PROTOCOL; } if(!slen){ @@ -85,7 +85,7 @@ int handle__unsubscribe(struct mosquitto_db *db, struct mosquitto *context) context->id); mosquitto__free(sub); mosquitto__free(reason_codes); - return 1; + return MOSQ_ERR_PROTOCOL; } if(mosquitto_sub_topic_check(sub)){ log__printf(NULL, MOSQ_LOG_INFO, @@ -93,7 +93,7 @@ int handle__unsubscribe(struct mosquitto_db *db, struct mosquitto *context) context->id); mosquitto__free(sub); mosquitto__free(reason_codes); - return 1; + return MOSQ_ERR_PROTOCOL; } log__printf(NULL, MOSQ_LOG_DEBUG, "\t%s", sub); From 618cd7006bda49abbb3f3e00baa7328026845882 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 4 Aug 2020 11:17:04 +0100 Subject: [PATCH 078/113] Don't try to start DLT logging if DLT unavailable. This is to avoid a long delay when shutting down the broker. Closes #1735. Thanks to Colin Law. --- ChangeLog.txt | 2 ++ src/logging.c | 37 +++++++++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 81fd892e..6dc20f76 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -17,6 +17,8 @@ Broker: Closes #1689. Closes #1741. - Log protocol error message where appropriate from a bad UNSUBSCRIBE, rather than the generic "socket error". +- Don't try to start DLT logging if DLT unavailable, to avoid a long delay + when shutting down the broker. Closes #1735. Client library: - Improved documentation around connect callback return codes. Close #1730. diff --git a/src/logging.c b/src/logging.c index e9f92df9..ac079a85 100644 --- a/src/logging.c +++ b/src/logging.c @@ -24,6 +24,7 @@ Contributors: #include #ifdef WITH_DLT +#include #include #endif @@ -55,6 +56,29 @@ static int log_priorities = MOSQ_LOG_ERR | MOSQ_LOG_WARNING | MOSQ_LOG_NOTICE | #ifdef WITH_DLT static DltContext dltContext; +static bool dlt_allowed = false; + +void dlt_fifo_check(void) +{ + struct stat statbuf; + int fd; + + /* If we start DLT but the /tmp/dlt fifo doesn't exist, or isn't available + * for writing then there is a big delay when we try and close the log + * later, so check for it first. This has the side effect of not letting + * people using DLT create the fifo after Mosquitto has started, but at the + * benefit of not having a massive delay for everybody else. */ + memset(&statbuf, 0, sizeof(statbuf)); + if(stat("/tmp/dlt", &statbuf) == 0){ + if(S_ISFIFO(statbuf.st_mode)){ + fd = open("/tmp/dlt", O_NONBLOCK | O_WRONLY); + if(fd != -1){ + dlt_allowed = true; + close(fd); + } + } + } +} #endif static int get_time(struct tm **ti) @@ -120,8 +144,11 @@ int log__init(struct mosquitto__config *config) restore_privileges(); } #ifdef WITH_DLT - DLT_REGISTER_APP("MQTT","mosquitto log"); - dlt_register_context(&dltContext, "MQTT", "mosquitto DLT context"); + dlt_fifo_check(); + if(dlt_allowed){ + DLT_REGISTER_APP("MQTT","mosquitto log"); + dlt_register_context(&dltContext, "MQTT", "mosquitto DLT context"); + } #endif return rc; } @@ -143,8 +170,10 @@ int log__close(struct mosquitto__config *config) } #ifdef WITH_DLT - dlt_unregister_context(&dltContext); - DLT_UNREGISTER_APP(); + if(dlt_allowed){ + dlt_unregister_context(&dltContext); + DLT_UNREGISTER_APP(); + } #endif /* FIXME - do something for all destinations! */ return MOSQ_ERR_SUCCESS; From a38cb3bf51e8eef600bcc453eff631ec3a2f6d03 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 4 Aug 2020 12:25:49 +0100 Subject: [PATCH 079/113] Branch sync - only sync when there is a difference to avoid errors. --- .github/workflows/covsync.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/covsync.yml b/.github/workflows/covsync.yml index 2aec2ca9..6a4eb28a 100644 --- a/.github/workflows/covsync.yml +++ b/.github/workflows/covsync.yml @@ -13,7 +13,13 @@ jobs: with: fetch-depth: 0 - run: | - git checkout -b coverity-fixes origin/fixes - git push origin coverity-fixes - git checkout -b coverity-develop origin/develop - git push origin coverity-develop + git diff --exit-code -s origin/coverity-fixes origin/fixes + if [ "$?" = "1" ]; then + git checkout -b coverity-fixes origin/fixes + git push origin coverity-fixes + fi + git diff --exit-code -s origin/coverity-develop origin/develop + if [ "$?" = "1" ]; then + git checkout -b coverity-develop origin/develop + git push origin coverity-develop + fi From 5f565fe4ea126c8191e52ec1c5a817071aac4794 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 6 Aug 2020 12:17:41 +0100 Subject: [PATCH 080/113] Previous change to only update on difference causes errors :( --- .github/workflows/covsync.yml | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/.github/workflows/covsync.yml b/.github/workflows/covsync.yml index 6a4eb28a..2aec2ca9 100644 --- a/.github/workflows/covsync.yml +++ b/.github/workflows/covsync.yml @@ -13,13 +13,7 @@ jobs: with: fetch-depth: 0 - run: | - git diff --exit-code -s origin/coverity-fixes origin/fixes - if [ "$?" = "1" ]; then - git checkout -b coverity-fixes origin/fixes - git push origin coverity-fixes - fi - git diff --exit-code -s origin/coverity-develop origin/develop - if [ "$?" = "1" ]; then - git checkout -b coverity-develop origin/develop - git push origin coverity-develop - fi + git checkout -b coverity-fixes origin/fixes + git push origin coverity-fixes + git checkout -b coverity-develop origin/develop + git push origin coverity-develop From 94d04136f8beedbd34ca16158b5be3111a9cb7b4 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 6 Aug 2020 21:28:09 +0100 Subject: [PATCH 081/113] Fix potential memory leaks. Closes #1773. Closes #1774. Thanks to Yingpei Zeng. --- ChangeLog.txt | 1 + src/handle_publish.c | 5 ++++- src/handle_subscribe.c | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 6dc20f76..35336aca 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -19,6 +19,7 @@ Broker: than the generic "socket error". - Don't try to start DLT logging if DLT unavailable, to avoid a long delay when shutting down the broker. Closes #1735. +- Fix potential memory leaks. Closes #1773. Closes #1774. Client library: - Improved documentation around connect callback return codes. Close #1730. diff --git a/src/handle_publish.c b/src/handle_publish.c index 2504860d..acbbec93 100644 --- a/src/handle_publish.c +++ b/src/handle_publish.c @@ -109,7 +109,10 @@ int handle__publish(struct mosquitto_db *db, struct mosquitto *context) /* Handle properties */ if(context->protocol == mosq_p_mqtt5){ rc = property__read_all(CMD_PUBLISH, &context->in_packet, &properties); - if(rc) return rc; + if(rc){ + mosquitto__free(topic); + return rc; + } p = properties; p_prev = NULL; diff --git a/src/handle_subscribe.c b/src/handle_subscribe.c index 2ebf8ae4..c42604ba 100644 --- a/src/handle_subscribe.c +++ b/src/handle_subscribe.c @@ -119,6 +119,8 @@ int handle__subscribe(struct mosquitto_db *db, struct mosquitto *context) retain_handling = (subscription_options & 0x30); if(retain_handling == 0x30 || (subscription_options & 0xC0) != 0){ + mosquitto__free(sub); + mosquitto__free(payload); return MOSQ_ERR_PROTOCOL; } } From 212fd8635f5e31fcf866d64f5e2ee87243735e03 Mon Sep 17 00:00:00 2001 From: david-beinder Date: Fri, 7 Aug 2020 08:32:14 +0200 Subject: [PATCH 082/113] Store username and listener of persistent clients Signed-off-by: david-beinder --- src/db_dump/db_dump.c | 24 +++++++++---------- src/db_dump/print.c | 6 +++++ src/mosquitto.c | 12 ++++++++++ src/persist.h | 43 ++++++++++++++++++++++------------ src/persist_read.c | 52 ++++++++++++++++++++++++++++-------------- src/persist_read_v5.c | 38 ++++++++++++++++++++++-------- src/persist_write.c | 19 ++++++++++----- src/persist_write_v5.c | 20 ++++++++++------ 8 files changed, 147 insertions(+), 67 deletions(-) diff --git a/src/db_dump/db_dump.c b/src/db_dump/db_dump.c index 1488f2ef..c453ed99 100644 --- a/src/db_dump/db_dump.c +++ b/src/db_dump/db_dump.c @@ -110,8 +110,8 @@ static int dump__cfg_chunk_process(struct mosquitto_db *db, FILE *db_fd, uint32_ memset(&chunk, 0, sizeof(struct PF_cfg)); - if(db_version == 5){ - rc = persist__chunk_cfg_read_v5(db_fd, &chunk); + if(db_version == 6 || db_version == 5){ + rc = persist__chunk_cfg_read_v56(db_fd, &chunk); }else{ rc = persist__chunk_cfg_read_v234(db_fd, &chunk); } @@ -147,8 +147,8 @@ static int dump__client_chunk_process(struct mosquitto_db *db, FILE *db_fd, uint memset(&chunk, 0, sizeof(struct P_client)); - if(db_version == 5){ - rc = persist__chunk_client_read_v5(db_fd, &chunk); + if(db_version == 6 || db_version == 5){ + rc = persist__chunk_client_read_v56(db_fd, &chunk, db_version); }else{ rc = persist__chunk_client_read_v234(db_fd, &chunk, db_version); } @@ -189,8 +189,8 @@ static int dump__client_msg_chunk_process(struct mosquitto_db *db, FILE *db_fd, client_msg_count++; memset(&chunk, 0, sizeof(struct P_client_msg)); - if(db_version == 5){ - rc = persist__chunk_client_msg_read_v5(db_fd, &chunk, length); + if(db_version == 6 || db_version == 5){ + rc = persist__chunk_client_msg_read_v56(db_fd, &chunk, length); }else{ rc = persist__chunk_client_msg_read_v234(db_fd, &chunk); } @@ -234,8 +234,8 @@ static int dump__msg_store_chunk_process(struct mosquitto_db *db, FILE *db_fptr, msg_store_count++; memset(&chunk, 0, sizeof(struct P_msg_store)); - if(db_version == 5){ - rc = persist__chunk_msg_store_read_v5(db_fptr, &chunk, length); + if(db_version == 6 || db_version == 5){ + rc = persist__chunk_msg_store_read_v56(db_fptr, &chunk, length); }else{ rc = persist__chunk_msg_store_read_v234(db_fptr, &chunk, db_version); } @@ -321,8 +321,8 @@ static int dump__retain_chunk_process(struct mosquitto_db *db, FILE *db_fd, uint if(do_print) printf("DB_CHUNK_RETAIN:\n"); if(do_print) printf("\tLength: %d\n", length); - if(db_version == 5){ - rc = persist__chunk_retain_read_v5(db_fd, &chunk); + if(db_version == 6 || db_version == 5){ + rc = persist__chunk_retain_read_v56(db_fd, &chunk); }else{ rc = persist__chunk_retain_read_v234(db_fd, &chunk); } @@ -345,8 +345,8 @@ static int dump__sub_chunk_process(struct mosquitto_db *db, FILE *db_fd, uint32_ sub_count++; memset(&chunk, 0, sizeof(struct P_sub)); - if(db_version == 5){ - rc = persist__chunk_sub_read_v5(db_fd, &chunk); + if(db_version == 6 || db_version == 5){ + rc = persist__chunk_sub_read_v56(db_fd, &chunk); }else{ rc = persist__chunk_sub_read_v234(db_fd, &chunk); } diff --git a/src/db_dump/print.c b/src/db_dump/print.c index 8effd317..414f931d 100644 --- a/src/db_dump/print.c +++ b/src/db_dump/print.c @@ -145,6 +145,12 @@ void print__client(struct P_client *chunk, int length) printf("DB_CHUNK_CLIENT:\n"); printf("\tLength: %d\n", length); printf("\tClient ID: %s\n", chunk->client_id); + if(chunk->username){ + printf("\tUsername: %s\n", chunk->username); + } + if(chunk->F.listener_port > 0){ + printf("\tListener port: %u\n", chunk->F.listener_port); + } printf("\tLast MID: %d\n", chunk->F.last_mid); printf("\tSession expiry time: %" PRIu64 "\n", chunk->F.session_expiry_time); printf("\tSession expiry interval: %u\n", chunk->F.session_expiry_interval); diff --git a/src/mosquitto.c b/src/mosquitto.c index fdde843b..985c31d6 100644 --- a/src/mosquitto.c +++ b/src/mosquitto.c @@ -289,6 +289,18 @@ int main(int argc, char *argv[]) rc = mosquitto_security_init(&int_db, false); if(rc) return rc; + /* After loading persisted clients and ACLs, try to associate them, + * so persisted subscriptions can start storing messages */ + HASH_ITER(hh_id, int_db.contexts_by_id, ctxt, ctxt_tmp){ + if(ctxt && !ctxt->clean_start && ctxt->username){ + rc = acl__find_acls(&int_db, ctxt); + if(rc){ + log__printf(NULL, MOSQ_LOG_WARNING, "Failed to associate persisted user %s with ACLs, " + "likely due to changed ports while using a per_listener_settings configuration.", ctxt->username); + } + } + } + #ifdef WITH_SYS_TREE sys_tree__init(&int_db); #endif diff --git a/src/persist.h b/src/persist.h index b9bc3708..816ec400 100644 --- a/src/persist.h +++ b/src/persist.h @@ -17,7 +17,7 @@ Contributors: #ifndef PERSIST_H #define PERSIST_H -#define MOSQ_DB_VERSION 5 +#define MOSQ_DB_VERSION 6 /* DB read/write */ extern const unsigned char magic[15]; @@ -57,15 +57,28 @@ struct PF_cfg{ uint8_t dbid_size; }; +struct PF_client_v5{ + int64_t session_expiry_time; + uint32_t session_expiry_interval; + uint16_t last_mid; + uint16_t id_len; +}; struct PF_client{ + /* struct PF_client_v5; */ int64_t session_expiry_time; uint32_t session_expiry_interval; uint16_t last_mid; uint16_t id_len; + + uint16_t listener_port; + uint16_t username_len; + /* tail: 4 byte padding, because 64bit member + * forces multiple of 8 for struct size */ }; struct P_client{ struct PF_client F; char *client_id; + char *username; }; @@ -141,19 +154,19 @@ int persist__chunk_msg_store_read_v234(FILE *db_fptr, struct P_msg_store *chunk, int persist__chunk_retain_read_v234(FILE *db_fptr, struct P_retain *chunk); int persist__chunk_sub_read_v234(FILE *db_fptr, struct P_sub *chunk); -int persist__chunk_header_read_v5(FILE *db_fptr, int *chunk, int *length); -int persist__chunk_cfg_read_v5(FILE *db_fptr, struct PF_cfg *chunk); -int persist__chunk_client_read_v5(FILE *db_fptr, struct P_client *chunk); -int persist__chunk_client_msg_read_v5(FILE *db_fptr, struct P_client_msg *chunk, uint32_t length); -int persist__chunk_msg_store_read_v5(FILE *db_fptr, struct P_msg_store *chunk, uint32_t length); -int persist__chunk_retain_read_v5(FILE *db_fptr, struct P_retain *chunk); -int persist__chunk_sub_read_v5(FILE *db_fptr, struct P_sub *chunk); - -int persist__chunk_cfg_write_v5(FILE *db_fptr, struct PF_cfg *chunk); -int persist__chunk_client_write_v5(FILE *db_fptr, struct P_client *chunk); -int persist__chunk_client_msg_write_v5(FILE *db_fptr, struct P_client_msg *chunk); -int persist__chunk_message_store_write_v5(FILE *db_fptr, struct P_msg_store *chunk); -int persist__chunk_retain_write_v5(FILE *db_fptr, struct P_retain *chunk); -int persist__chunk_sub_write_v5(FILE *db_fptr, struct P_sub *chunk); +int persist__chunk_header_read_v56(FILE *db_fptr, int *chunk, int *length); +int persist__chunk_cfg_read_v56(FILE *db_fptr, struct PF_cfg *chunk); +int persist__chunk_client_read_v56(FILE *db_fptr, struct P_client *chunk, int db_version); +int persist__chunk_client_msg_read_v56(FILE *db_fptr, struct P_client_msg *chunk, uint32_t length); +int persist__chunk_msg_store_read_v56(FILE *db_fptr, struct P_msg_store *chunk, uint32_t length); +int persist__chunk_retain_read_v56(FILE *db_fptr, struct P_retain *chunk); +int persist__chunk_sub_read_v56(FILE *db_fptr, struct P_sub *chunk); + +int persist__chunk_cfg_write_v6(FILE *db_fptr, struct PF_cfg *chunk); +int persist__chunk_client_write_v6(FILE *db_fptr, struct P_client *chunk); +int persist__chunk_client_msg_write_v6(FILE *db_fptr, struct P_client_msg *chunk); +int persist__chunk_message_store_write_v6(FILE *db_fptr, struct P_msg_store *chunk); +int persist__chunk_retain_write_v6(FILE *db_fptr, struct P_retain *chunk); +int persist__chunk_sub_write_v6(FILE *db_fptr, struct P_sub *chunk); #endif diff --git a/src/persist_read.c b/src/persist_read.c index ad0c78e3..df643020 100644 --- a/src/persist_read.c +++ b/src/persist_read.c @@ -175,14 +175,14 @@ static int persist__client_msg_restore(struct mosquitto_db *db, struct P_client_ static int persist__client_chunk_restore(struct mosquitto_db *db, FILE *db_fptr) { - int rc = 0; + int i, rc = 0; struct mosquitto *context; struct P_client chunk; memset(&chunk, 0, sizeof(struct P_client)); - if(db_version == 5){ - rc = persist__chunk_client_read_v5(db_fptr, &chunk); + if(db_version == 6 || db_version == 5){ + rc = persist__chunk_client_read_v56(db_fptr, &chunk, db_version); }else{ rc = persist__chunk_client_read_v234(db_fptr, &chunk, db_version); } @@ -195,13 +195,29 @@ static int persist__client_chunk_restore(struct mosquitto_db *db, FILE *db_fptr) if(context){ context->session_expiry_time = chunk.F.session_expiry_time; context->session_expiry_interval = chunk.F.session_expiry_interval; + if(chunk.username && !context->username){ + /* username is not freed here, it is now owned by context */ + context->username = chunk.username; + chunk.username = NULL; + /* in per_listener_settings mode, try to find the listener by persisted port */ + if(db->config->per_listener_settings && !context->listener && chunk.F.listener_port > 0){ + for(i=0; i < db->config->listener_count; i++){ + if(db->config->listeners[i].port == chunk.F.listener_port){ + context->listener = &db->config->listeners[i]; + break; + } + } + } + } /* FIXME - we should expire clients here if they have exceeded their time */ }else{ rc = 1; } mosquitto__free(chunk.client_id); - + if(chunk.username){ + mosquitto__free(chunk.username); + } return rc; } @@ -213,8 +229,8 @@ static int persist__client_msg_chunk_restore(struct mosquitto_db *db, FILE *db_f memset(&chunk, 0, sizeof(struct P_client_msg)); - if(db_version == 5){ - rc = persist__chunk_client_msg_read_v5(db_fptr, &chunk, length); + if(db_version == 6 || db_version == 5){ + rc = persist__chunk_client_msg_read_v56(db_fptr, &chunk, length); }else{ rc = persist__chunk_client_msg_read_v234(db_fptr, &chunk); } @@ -242,8 +258,8 @@ static int persist__msg_store_chunk_restore(struct mosquitto_db *db, FILE *db_fp memset(&chunk, 0, sizeof(struct P_msg_store)); - if(db_version == 5){ - rc = persist__chunk_msg_store_read_v5(db_fptr, &chunk, length); + if(db_version == 6 || db_version == 5){ + rc = persist__chunk_msg_store_read_v56(db_fptr, &chunk, length); }else{ rc = persist__chunk_msg_store_read_v234(db_fptr, &chunk, db_version); } @@ -320,8 +336,8 @@ static int persist__retain_chunk_restore(struct mosquitto_db *db, FILE *db_fptr) memset(&chunk, 0, sizeof(struct P_retain)); - if(db_version == 5){ - rc = persist__chunk_retain_read_v5(db_fptr, &chunk); + if(db_version == 6 || db_version == 5){ + rc = persist__chunk_retain_read_v56(db_fptr, &chunk); }else{ rc = persist__chunk_retain_read_v234(db_fptr, &chunk); } @@ -346,8 +362,8 @@ static int persist__sub_chunk_restore(struct mosquitto_db *db, FILE *db_fptr) memset(&chunk, 0, sizeof(struct P_sub)); - if(db_version == 5){ - rc = persist__chunk_sub_read_v5(db_fptr, &chunk); + if(db_version == 6 || db_version == 5){ + rc = persist__chunk_sub_read_v56(db_fptr, &chunk); }else{ rc = persist__chunk_sub_read_v234(db_fptr, &chunk); } @@ -367,8 +383,8 @@ static int persist__sub_chunk_restore(struct mosquitto_db *db, FILE *db_fptr) int persist__chunk_header_read(FILE *db_fptr, int *chunk, int *length) { - if(db_version == 5){ - return persist__chunk_header_read_v5(db_fptr, chunk, length); + if(db_version == 6 || db_version == 5){ + return persist__chunk_header_read_v56(db_fptr, chunk, length); }else{ return persist__chunk_header_read_v234(db_fptr, chunk, length); } @@ -416,7 +432,9 @@ int persist__restore(struct mosquitto_db *db) * Is your DB change still compatible with previous versions? */ if(db_version != MOSQ_DB_VERSION){ - if(db_version == 4){ + if(db_version == 5){ + /* Addition of username and listener_port to client chunk in v6 */ + }else if(db_version == 4){ }else if(db_version == 3){ /* Addition of source_username and source_port to msg_store chunk in v4, v1.5.6 */ }else if(db_version == 2){ @@ -431,8 +449,8 @@ int persist__restore(struct mosquitto_db *db) while(persist__chunk_header_read(fptr, &chunk, &length) == MOSQ_ERR_SUCCESS){ switch(chunk){ case DB_CHUNK_CFG: - if(db_version == 5){ - if(persist__chunk_cfg_read_v5(fptr, &cfg_chunk)){ + if(db_version == 6 || db_version == 5){ + if(persist__chunk_cfg_read_v56(fptr, &cfg_chunk)){ fclose(fptr); return 1; } diff --git a/src/persist_read_v5.c b/src/persist_read_v5.c index e8bb5aed..0d0605b1 100644 --- a/src/persist_read_v5.c +++ b/src/persist_read_v5.c @@ -38,7 +38,7 @@ Contributors: #include "util_mosq.h" -int persist__chunk_header_read_v5(FILE *db_fptr, int *chunk, int *length) +int persist__chunk_header_read_v56(FILE *db_fptr, int *chunk, int *length) { size_t rlen; struct PF_header header; @@ -53,7 +53,7 @@ int persist__chunk_header_read_v5(FILE *db_fptr, int *chunk, int *length) } -int persist__chunk_cfg_read_v5(FILE *db_fptr, struct PF_cfg *chunk) +int persist__chunk_cfg_read_v56(FILE *db_fptr, struct PF_cfg *chunk) { if(fread(chunk, sizeof(struct PF_cfg), 1, db_fptr) != 1){ log__printf(NULL, MOSQ_LOG_ERR, "Error: %s.", strerror(errno)); @@ -64,28 +64,46 @@ int persist__chunk_cfg_read_v5(FILE *db_fptr, struct PF_cfg *chunk) } -int persist__chunk_client_read_v5(FILE *db_fptr, struct P_client *chunk) +int persist__chunk_client_read_v56(FILE *db_fptr, struct P_client *chunk, int db_version) { int rc; - read_e(db_fptr, &chunk->F, sizeof(struct PF_client)); + if(db_version == 6){ + read_e(db_fptr, &chunk->F, sizeof(struct PF_client)); + chunk->F.username_len = ntohs(chunk->F.username_len); + chunk->F.listener_port = ntohs(chunk->F.listener_port); + }else if(db_version == 5){ + read_e(db_fptr, &chunk->F, sizeof(struct PF_client_v5)); + }else{ + return 1; + } + chunk->F.session_expiry_interval = ntohl(chunk->F.session_expiry_interval); chunk->F.last_mid = ntohs(chunk->F.last_mid); chunk->F.id_len = ntohs(chunk->F.id_len); + rc = persist__read_string_len(db_fptr, &chunk->client_id, chunk->F.id_len); if(rc || !chunk->client_id){ return 1; - }else{ - return MOSQ_ERR_SUCCESS; } + + if(chunk->F.username_len > 0){ + rc = persist__read_string_len(db_fptr, &chunk->username, chunk->F.username_len); + if(rc || !chunk->username){ + mosquitto__free(chunk->client_id); + return 1; + } + } + + return MOSQ_ERR_SUCCESS; error: log__printf(NULL, MOSQ_LOG_ERR, "Error: %s.", strerror(errno)); return 1; } -int persist__chunk_client_msg_read_v5(FILE *db_fptr, struct P_client_msg *chunk, uint32_t length) +int persist__chunk_client_msg_read_v56(FILE *db_fptr, struct P_client_msg *chunk, uint32_t length) { mosquitto_property *properties = NULL; struct mosquitto__packet prop_packet; @@ -125,7 +143,7 @@ error: } -int persist__chunk_msg_store_read_v5(FILE *db_fptr, struct P_msg_store *chunk, uint32_t length) +int persist__chunk_msg_store_read_v56(FILE *db_fptr, struct P_msg_store *chunk, uint32_t length) { int rc = 0; mosquitto_property *properties = NULL; @@ -215,7 +233,7 @@ error: } -int persist__chunk_retain_read_v5(FILE *db_fptr, struct P_retain *chunk) +int persist__chunk_retain_read_v56(FILE *db_fptr, struct P_retain *chunk) { if(fread(&chunk->F, sizeof(struct P_retain), 1, db_fptr) != 1){ log__printf(NULL, MOSQ_LOG_ERR, "Error: %s.", strerror(errno)); @@ -225,7 +243,7 @@ int persist__chunk_retain_read_v5(FILE *db_fptr, struct P_retain *chunk) } -int persist__chunk_sub_read_v5(FILE *db_fptr, struct P_sub *chunk) +int persist__chunk_sub_read_v56(FILE *db_fptr, struct P_sub *chunk) { int rc; diff --git a/src/persist_write.c b/src/persist_write.c index 61f4a73d..e6d25121 100644 --- a/src/persist_write.c +++ b/src/persist_write.c @@ -70,7 +70,7 @@ static int persist__client_messages_save(struct mosquitto_db *db, FILE *db_fptr, chunk.client_id = context->id; chunk.properties = cmsg->properties; - rc = persist__chunk_client_msg_write_v5(db_fptr, &chunk); + rc = persist__chunk_client_msg_write_v6(db_fptr, &chunk); if(rc){ return rc; } @@ -146,7 +146,7 @@ static int persist__message_store_save(struct mosquitto_db *db, FILE *db_fptr) chunk.payload = stored->payload; chunk.properties = stored->properties; - rc = persist__chunk_message_store_write_v5(db_fptr, &chunk); + rc = persist__chunk_message_store_write_v6(db_fptr, &chunk); if(rc){ return rc; } @@ -174,8 +174,15 @@ static int persist__client_save(struct mosquitto_db *db, FILE *db_fptr) chunk.F.last_mid = context->last_mid; chunk.F.id_len = strlen(context->id); chunk.client_id = context->id; + if(context->username){ + chunk.F.username_len = strlen(context->username); + chunk.username = context->username; + if(context->listener){ + chunk.F.listener_port = context->listener->port; + } + } - rc = persist__chunk_client_write_v5(db_fptr, &chunk); + rc = persist__chunk_client_write_v6(db_fptr, &chunk); if(rc){ return rc; } @@ -224,7 +231,7 @@ static int persist__subs_retain_save(struct mosquitto_db *db, FILE *db_fptr, str sub_chunk.client_id = sub->context->id; sub_chunk.topic = thistopic; - rc = persist__chunk_sub_write_v5(db_fptr, &sub_chunk); + rc = persist__chunk_sub_write_v6(db_fptr, &sub_chunk); if(rc){ mosquitto__free(thistopic); return rc; @@ -236,7 +243,7 @@ static int persist__subs_retain_save(struct mosquitto_db *db, FILE *db_fptr, str if(strncmp(node->retained->topic, "$SYS", 4)){ /* Don't save $SYS messages. */ retain_chunk.F.store_id = node->retained->db_id; - rc = persist__chunk_retain_write_v5(db_fptr, &retain_chunk); + rc = persist__chunk_retain_write_v6(db_fptr, &retain_chunk); if(rc){ mosquitto__free(thistopic); return rc; @@ -334,7 +341,7 @@ int persist__backup(struct mosquitto_db *db, bool shutdown) cfg_chunk.last_db_id = db->last_db_id; cfg_chunk.shutdown = shutdown; cfg_chunk.dbid_size = sizeof(dbid_t); - if(persist__chunk_cfg_write_v5(db_fptr, &cfg_chunk)){ + if(persist__chunk_cfg_write_v6(db_fptr, &cfg_chunk)){ goto error; } diff --git a/src/persist_write_v5.c b/src/persist_write_v5.c index ba960f09..48ca9c93 100644 --- a/src/persist_write_v5.c +++ b/src/persist_write_v5.c @@ -37,7 +37,7 @@ Contributors: #include "time_mosq.h" #include "util_mosq.h" -int persist__chunk_cfg_write_v5(FILE *db_fptr, struct PF_cfg *chunk) +int persist__chunk_cfg_write_v6(FILE *db_fptr, struct PF_cfg *chunk) { struct PF_header header; @@ -53,22 +53,28 @@ error: } -int persist__chunk_client_write_v5(FILE *db_fptr, struct P_client *chunk) +int persist__chunk_client_write_v6(FILE *db_fptr, struct P_client *chunk) { struct PF_header header; uint16_t id_len = chunk->F.id_len; + uint16_t username_len = chunk->F.username_len; chunk->F.session_expiry_interval = htonl(chunk->F.session_expiry_interval); chunk->F.last_mid = htons(chunk->F.last_mid); chunk->F.id_len = htons(chunk->F.id_len); + chunk->F.username_len = htons(chunk->F.username_len); + chunk->F.listener_port = htons(chunk->F.listener_port); header.chunk = htonl(DB_CHUNK_CLIENT); - header.length = htonl(sizeof(struct PF_client)+id_len); + header.length = htonl(sizeof(struct PF_client)+id_len+username_len); write_e(db_fptr, &header, sizeof(struct PF_header)); write_e(db_fptr, &chunk->F, sizeof(struct PF_client)); write_e(db_fptr, chunk->client_id, id_len); + if(username_len > 0){ + write_e(db_fptr, chunk->username, username_len); + } return MOSQ_ERR_SUCCESS; error: @@ -77,7 +83,7 @@ error: } -int persist__chunk_client_msg_write_v5(FILE *db_fptr, struct P_client_msg *chunk) +int persist__chunk_client_msg_write_v6(FILE *db_fptr, struct P_client_msg *chunk) { struct PF_header header; struct mosquitto__packet prop_packet; @@ -123,7 +129,7 @@ error: } -int persist__chunk_message_store_write_v5(FILE *db_fptr, struct P_msg_store *chunk) +int persist__chunk_message_store_write_v6(FILE *db_fptr, struct P_msg_store *chunk) { struct PF_header header; uint32_t payloadlen = chunk->F.payloadlen; @@ -188,7 +194,7 @@ error: } -int persist__chunk_retain_write_v5(FILE *db_fptr, struct P_retain *chunk) +int persist__chunk_retain_write_v6(FILE *db_fptr, struct P_retain *chunk) { struct PF_header header; @@ -205,7 +211,7 @@ error: } -int persist__chunk_sub_write_v5(FILE *db_fptr, struct P_sub *chunk) +int persist__chunk_sub_write_v6(FILE *db_fptr, struct P_sub *chunk) { struct PF_header header; uint16_t id_len = chunk->F.id_len; From c11d20f82ce013fb7136eb4bcd7280133829590d Mon Sep 17 00:00:00 2001 From: david-beinder Date: Fri, 7 Aug 2020 08:56:52 +0200 Subject: [PATCH 083/113] Database v6 tests keep v5 client read test to test for backwards compatability adds username="usrname" and listener_port=1883 for v6 tests Signed-off-by: david-beinder --- test/unit/files/persist_read/v5-cfg.test-db | Bin 47 -> 0 bytes .../v5-client-message-props.test-db | Bin 185 -> 0 bytes .../persist_read/v5-client-message.test-db | Bin 182 -> 0 bytes .../v5-message-store-props.test-db | Bin 185 -> 0 bytes .../persist_read/v5-message-store.test-db | Bin 116 -> 0 bytes .../unit/files/persist_read/v5-retain.test-db | Bin 132 -> 0 bytes test/unit/files/persist_read/v5-sub.test-db | Bin 121 -> 0 bytes test/unit/files/persist_read/v6-cfg.test-db | Bin 0 -> 47 bytes .../v6-client-message-props.test-db | Bin 0 -> 200 bytes .../persist_read/v6-client-message.test-db | Bin 0 -> 197 bytes .../unit/files/persist_read/v6-client.test-db | Bin 0 -> 95 bytes .../v6-message-store-props.test-db | Bin 0 -> 200 bytes .../persist_read/v6-message-store.test-db | Bin 0 -> 116 bytes .../unit/files/persist_read/v6-retain.test-db | Bin 0 -> 132 bytes test/unit/files/persist_read/v6-sub.test-db | Bin 0 -> 136 bytes test/unit/files/persist_write/empty.test-db | Bin 47 -> 47 bytes .../v5-message-store-no-ref.test-db | Bin 47 -> 0 bytes .../v6-message-store-no-ref.test-db | Bin 0 -> 47 bytes test/unit/persist_read_test.c | 81 +++++++++++---- test/unit/persist_write_test.c | 94 ++++++++++-------- 20 files changed, 111 insertions(+), 64 deletions(-) delete mode 100644 test/unit/files/persist_read/v5-cfg.test-db delete mode 100644 test/unit/files/persist_read/v5-client-message-props.test-db delete mode 100644 test/unit/files/persist_read/v5-client-message.test-db delete mode 100644 test/unit/files/persist_read/v5-message-store-props.test-db delete mode 100644 test/unit/files/persist_read/v5-message-store.test-db delete mode 100644 test/unit/files/persist_read/v5-retain.test-db delete mode 100644 test/unit/files/persist_read/v5-sub.test-db create mode 100644 test/unit/files/persist_read/v6-cfg.test-db create mode 100644 test/unit/files/persist_read/v6-client-message-props.test-db create mode 100644 test/unit/files/persist_read/v6-client-message.test-db create mode 100644 test/unit/files/persist_read/v6-client.test-db create mode 100644 test/unit/files/persist_read/v6-message-store-props.test-db create mode 100644 test/unit/files/persist_read/v6-message-store.test-db create mode 100644 test/unit/files/persist_read/v6-retain.test-db create mode 100644 test/unit/files/persist_read/v6-sub.test-db delete mode 100644 test/unit/files/persist_write/v5-message-store-no-ref.test-db create mode 100644 test/unit/files/persist_write/v6-message-store-no-ref.test-db diff --git a/test/unit/files/persist_read/v5-cfg.test-db b/test/unit/files/persist_read/v5-cfg.test-db deleted file mode 100644 index 2449222e8c8357abcb9e3ab4b865cc0f64d5efad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 qcmZSB%8;91Tv(b}Qj)KblEeT3tU!tphy_4gA(OBQMh*~*fdK&Nzy`zs diff --git a/test/unit/files/persist_read/v5-client-message-props.test-db b/test/unit/files/persist_read/v5-client-message-props.test-db deleted file mode 100644 index b34f6db8dd02e26ef52404fd5833b19476ba7690..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 185 zcmZSB%8;91Tv(b}Qj)KblEeT3tU!tphy_4gA(OBQMh*}Q448nVZ3vWuM6ok4F>o?) zFtD;mGcgwDmlh?b#%HFK7N-{FCFZ7<o?) zFtD;mGcgwDmlh?b#%HFK7N-{FCFZ7<~XQq@ErxxWU=BAe97i1~XQq@ErxxWU=BAe97i1o?) vFtD;mGcgwDmlh?b#%HFK7N-{FCFZ7<uMBP diff --git a/test/unit/files/persist_read/v5-sub.test-db b/test/unit/files/persist_read/v5-sub.test-db deleted file mode 100644 index acd1437910e788cd3a55e743106b90205409df9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 121 zcmZSB%8;91Tv(b}Qj)KblEeT3tU!tphy_4gA(OBQMh*}Q4A_9Aq%xHA9|(fl890-3 qGE?(PbTdo?) zFtD;mGcgwDmlh?b#%HFK7N-{FCFZ7<o?) zFtD;mGcgwDmlh?b#%HFK7N-{FCFZ7<~XQq@ErxxWU=BAe97i1~XQq@ErxxWU=BAe97i1o?) vFtD;mGcgwDmlh?b#%HFK7N-{FCFZ7<(~@p literal 0 HcmV?d00001 diff --git a/test/unit/files/persist_read/v6-sub.test-db b/test/unit/files/persist_read/v6-sub.test-db new file mode 100644 index 0000000000000000000000000000000000000000..f1f6663a07f77cb435e78bcd6c750a8322ff47bd GIT binary patch literal 136 zcmZSB%8;91Tv(b}Qj)KblEeT3Y(R<;hy_4gA(OBQMh*}Q3_x-k%23XKAP8z_;AD?x zUt>badJ^+K}lwQ9sr2O B98drN literal 0 HcmV?d00001 diff --git a/test/unit/files/persist_write/empty.test-db b/test/unit/files/persist_write/empty.test-db index 26169f329a72040f870b505b64d9003adb737ab8..eba5ad858da318e8532941dfa65d8ec5fecbdcaf 100644 GIT binary patch delta 30 ZcmdPbpCBg5#=yY92*d(F3;`Sv3IHL30X+Z! delta 30 ZcmdPbpCBg5%D}+D2*d(F3;`Sv3IHK#0XzTz diff --git a/test/unit/files/persist_write/v5-message-store-no-ref.test-db b/test/unit/files/persist_write/v5-message-store-no-ref.test-db deleted file mode 100644 index 2449222e8c8357abcb9e3ab4b865cc0f64d5efad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 qcmZSB%8;91Tv(b}Qj)KblEeT3tU!tphy_4gA(OBQMh*~*fdK&Nzy`zs diff --git a/test/unit/files/persist_write/v6-message-store-no-ref.test-db b/test/unit/files/persist_write/v6-message-store-no-ref.test-db new file mode 100644 index 0000000000000000000000000000000000000000..bf8151fd8f8c444216a0b681b2e2e028bbc91159 GIT binary patch literal 47 qcmZSB%8;91Tv(b}Qj)KblEeT3Y(R<;hy_4gA(OBQMh*~*fdK&N*#^Y` literal 0 HcmV?d00001 diff --git a/test/unit/persist_read_test.c b/test/unit/persist_read_test.c index d1c7e786..84c36c03 100644 --- a/test/unit/persist_read_test.c +++ b/test/unit/persist_read_test.c @@ -409,7 +409,7 @@ static void TEST_v4_message_store(void) } } -static void TEST_v5_config_ok(void) +static void TEST_v6_config_ok(void) { struct mosquitto_db db; struct mosquitto__config config; @@ -420,7 +420,7 @@ static void TEST_v5_config_ok(void) db.config = &config; config.persistence = true; - config.persistence_filepath = "files/persist_read/v5-cfg.test-db"; + config.persistence_filepath = "files/persist_read/v6-cfg.test-db"; rc = persist__restore(&db); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); @@ -466,7 +466,7 @@ static void TEST_v5_bad_chunk(void) } -static void TEST_v5_message_store(void) +static void TEST_v6_message_store(void) { struct mosquitto_db db; struct mosquitto__config config; @@ -477,7 +477,7 @@ static void TEST_v5_message_store(void) db.config = &config; config.persistence = true; - config.persistence_filepath = "files/persist_read/v5-message-store.test-db"; + config.persistence_filepath = "files/persist_read/v6-message-store.test-db"; rc = persist__restore(&db); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); @@ -501,7 +501,7 @@ static void TEST_v5_message_store(void) } -static void TEST_v5_message_store_props(void) +static void TEST_v6_message_store_props(void) { struct mosquitto_db db; struct mosquitto__config config; @@ -518,7 +518,7 @@ static void TEST_v5_message_store_props(void) config.listener_count = 1; config.persistence = true; - config.persistence_filepath = "files/persist_read/v5-message-store-props.test-db"; + config.persistence_filepath = "files/persist_read/v6-message-store-props.test-db"; rc = persist__restore(&db); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); @@ -573,7 +573,43 @@ static void TEST_v5_client(void) } } -static void TEST_v5_client_message(void) +static void TEST_v6_client(void) +{ + struct mosquitto_db db; + struct mosquitto__config config; + struct mosquitto *context; + struct mosquitto__listener listener; + int rc; + + memset(&db, 0, sizeof(struct mosquitto_db)); + memset(&config, 0, sizeof(struct mosquitto__config)); + memset(&listener, 0, sizeof(struct mosquitto__listener)); + db.config = &config; + + listener.port = 1883; + config.per_listener_settings = true; + config.listeners = &listener; + config.listener_count = 1; + config.persistence = true; + config.persistence_filepath = "files/persist_read/v6-client.test-db"; + + rc = persist__restore(&db); + CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); + + CU_ASSERT_PTR_NOT_NULL(db.contexts_by_id); + HASH_FIND(hh_id, db.contexts_by_id, "client-id", strlen("client-id"), context); + CU_ASSERT_PTR_NOT_NULL(context); + if(context){ + CU_ASSERT_PTR_NULL(context->msgs_in.inflight); + CU_ASSERT_PTR_NULL(context->msgs_out.inflight); + CU_ASSERT_EQUAL(context->last_mid, 0x5287); + CU_ASSERT_EQUAL(context->listener, &listener); + CU_ASSERT_PTR_NOT_NULL(context->username); + CU_ASSERT_STRING_EQUAL(context->username, "usrname"); + } +} + +static void TEST_v6_client_message(void) { struct mosquitto_db db; struct mosquitto__config config; @@ -585,7 +621,7 @@ static void TEST_v5_client_message(void) db.config = &config; config.persistence = true; - config.persistence_filepath = "files/persist_read/v5-client-message.test-db"; + config.persistence_filepath = "files/persist_read/v6-client-message.test-db"; rc = persist__restore(&db); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); @@ -622,7 +658,7 @@ static void TEST_v5_client_message(void) } } -static void TEST_v5_client_message_props(void) +static void TEST_v6_client_message_props(void) { struct mosquitto_db db; struct mosquitto__config config; @@ -634,7 +670,7 @@ static void TEST_v5_client_message_props(void) db.config = &config; config.persistence = true; - config.persistence_filepath = "files/persist_read/v5-client-message-props.test-db"; + config.persistence_filepath = "files/persist_read/v6-client-message-props.test-db"; rc = persist__restore(&db); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); @@ -675,7 +711,7 @@ static void TEST_v5_client_message_props(void) } } -static void TEST_v5_retain(void) +static void TEST_v6_retain(void) { struct mosquitto_db db; struct mosquitto__config config; @@ -688,7 +724,7 @@ static void TEST_v5_retain(void) db.config = &config; config.persistence = true; - config.persistence_filepath = "files/persist_read/v5-retain.test-db"; + config.persistence_filepath = "files/persist_read/v6-retain.test-db"; rc = persist__restore(&db); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); @@ -711,7 +747,7 @@ static void TEST_v5_retain(void) CU_ASSERT_EQUAL(last_retained, 0x54); } -static void TEST_v5_sub(void) +static void TEST_v6_sub(void) { struct mosquitto_db db; struct mosquitto__config config; @@ -726,7 +762,7 @@ static void TEST_v5_sub(void) db.config = &config; config.persistence = true; - config.persistence_filepath = "files/persist_read/v5-sub.test-db"; + config.persistence_filepath = "files/persist_read/v6-sub.test-db"; rc = persist__restore(&db); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); @@ -775,16 +811,17 @@ int init_persist_read_tests(void) || !CU_add_test(test_suite, "v3 sub", TEST_v3_sub) || !CU_add_test(test_suite, "v4 config ok", TEST_v4_config_ok) || !CU_add_test(test_suite, "v4 message store", TEST_v4_message_store) - || !CU_add_test(test_suite, "v5 config ok", TEST_v5_config_ok) + || !CU_add_test(test_suite, "v5 client", TEST_v5_client) || !CU_add_test(test_suite, "v5 config bad truncated", TEST_v5_config_truncated) || !CU_add_test(test_suite, "v5 bad chunk", TEST_v5_bad_chunk) - || !CU_add_test(test_suite, "v5 message store", TEST_v5_message_store) - || !CU_add_test(test_suite, "v5 message store+props", TEST_v5_message_store_props) - || !CU_add_test(test_suite, "v5 client", TEST_v5_client) - || !CU_add_test(test_suite, "v5 client message", TEST_v5_client_message) - || !CU_add_test(test_suite, "v5 client message+props", TEST_v5_client_message_props) - || !CU_add_test(test_suite, "v5 retain", TEST_v5_retain) - || !CU_add_test(test_suite, "v5 sub", TEST_v5_sub) + || !CU_add_test(test_suite, "v6 config ok", TEST_v6_config_ok) + || !CU_add_test(test_suite, "v6 message store", TEST_v6_message_store) + || !CU_add_test(test_suite, "v6 message store+props", TEST_v6_message_store_props) + || !CU_add_test(test_suite, "v6 client", TEST_v6_client) + || !CU_add_test(test_suite, "v6 client message", TEST_v6_client_message) + || !CU_add_test(test_suite, "v6 client message+props", TEST_v6_client_message_props) + || !CU_add_test(test_suite, "v6 retain", TEST_v6_retain) + || !CU_add_test(test_suite, "v6 sub", TEST_v6_sub) ){ printf("Error adding persist CUnit tests.\n"); diff --git a/test/unit/persist_write_test.c b/test/unit/persist_write_test.c index b6043761..16e422de 100644 --- a/test/unit/persist_write_test.c +++ b/test/unit/persist_write_test.c @@ -110,7 +110,7 @@ static void TEST_empty_file(void) } -static void TEST_v5_config_ok(void) +static void TEST_v6_config_ok(void) { struct mosquitto_db db; struct mosquitto__config config; @@ -121,20 +121,20 @@ static void TEST_v5_config_ok(void) db.config = &config; config.persistence = true; - config.persistence_filepath = "files/persist_read/v5-cfg.test-db"; + config.persistence_filepath = "files/persist_read/v6-cfg.test-db"; rc = persist__restore(&db); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); - config.persistence_filepath = "v5-cfg.db"; + config.persistence_filepath = "v6-cfg.db"; rc = persist__backup(&db, true); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); - CU_ASSERT_EQUAL(0, file_diff("files/persist_read/v5-cfg.test-db", "v5-cfg.db")); - unlink("v5-cfg.db"); + CU_ASSERT_EQUAL(0, file_diff("files/persist_read/v6-cfg.test-db", "v6-cfg.db")); + unlink("v6-cfg.db"); } -static void TEST_v5_message_store_no_ref(void) +static void TEST_v6_message_store_no_ref(void) { struct mosquitto_db db; struct mosquitto__config config; @@ -145,20 +145,20 @@ static void TEST_v5_message_store_no_ref(void) db.config = &config; config.persistence = true; - config.persistence_filepath = "files/persist_read/v5-message-store.test-db"; + config.persistence_filepath = "files/persist_read/v6-message-store.test-db"; rc = persist__restore(&db); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); - config.persistence_filepath = "v5-message-store-no-ref.db"; + config.persistence_filepath = "v6-message-store-no-ref.db"; rc = persist__backup(&db, true); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); - CU_ASSERT_EQUAL(0, file_diff("files/persist_write/v5-message-store-no-ref.test-db", "v5-message-store-no-ref.db")); - unlink("v5-message-store-no-ref.db"); + CU_ASSERT_EQUAL(0, file_diff("files/persist_write/v6-message-store-no-ref.test-db", "v6-message-store-no-ref.db")); + unlink("v6-message-store-no-ref.db"); } -static void TEST_v5_message_store_props(void) +static void TEST_v6_message_store_props(void) { struct mosquitto_db db; struct mosquitto__config config; @@ -170,48 +170,55 @@ static void TEST_v5_message_store_props(void) memset(&listener, 0, sizeof(struct mosquitto__listener)); db.config = &config; listener.port = 1883; + config.per_listener_settings = true; config.listeners = &listener; config.listener_count = 1; config.persistence = true; - config.persistence_filepath = "files/persist_read/v5-message-store-props.test-db"; + config.persistence_filepath = "files/persist_read/v6-message-store-props.test-db"; rc = persist__restore(&db); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); - config.persistence_filepath = "v5-message-store-props.db"; + config.persistence_filepath = "v6-message-store-props.db"; rc = persist__backup(&db, true); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); - CU_ASSERT_EQUAL(0, file_diff("files/persist_read/v5-message-store-props.test-db", "v5-message-store-props.db")); - unlink("v5-message-store-props.db"); + CU_ASSERT_EQUAL(0, file_diff("files/persist_read/v6-message-store-props.test-db", "v6-message-store-props.db")); + unlink("v6-message-store-props.db"); } -static void TEST_v5_client(void) +static void TEST_v6_client(void) { struct mosquitto_db db; struct mosquitto__config config; + struct mosquitto__listener listener; int rc; memset(&db, 0, sizeof(struct mosquitto_db)); memset(&config, 0, sizeof(struct mosquitto__config)); + memset(&listener, 0, sizeof(struct mosquitto__listener)); db.config = &config; + listener.port = 1883; + config.per_listener_settings = true; + config.listeners = &listener; + config.listener_count = 1; config.persistence = true; - config.persistence_filepath = "files/persist_read/v5-client.test-db"; + config.persistence_filepath = "files/persist_read/v6-client.test-db"; rc = persist__restore(&db); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); - config.persistence_filepath = "v5-client.db"; + config.persistence_filepath = "v6-client.db"; rc = persist__backup(&db, true); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); - CU_ASSERT_EQUAL(0, file_diff("files/persist_read/v5-client.test-db", "v5-client.db")); - unlink("v5-client.db"); + CU_ASSERT_EQUAL(0, file_diff("files/persist_read/v6-client.test-db", "v6-client.db")); + unlink("v6-client.db"); } -static void TEST_v5_client_message(void) +static void TEST_v6_client_message(void) { struct mosquitto_db db; struct mosquitto__config config; @@ -223,24 +230,25 @@ static void TEST_v5_client_message(void) memset(&listener, 0, sizeof(struct mosquitto__listener)); db.config = &config; listener.port = 1883; + config.per_listener_settings = true; config.listeners = &listener; config.listener_count = 1; config.persistence = true; - config.persistence_filepath = "files/persist_read/v5-client-message.test-db"; + config.persistence_filepath = "files/persist_read/v6-client-message.test-db"; rc = persist__restore(&db); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); - config.persistence_filepath = "v5-client-message.db"; + config.persistence_filepath = "v6-client-message.db"; rc = persist__backup(&db, true); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); - CU_ASSERT_EQUAL(0, file_diff("files/persist_read/v5-client-message.test-db", "v5-client-message.db")); - unlink("v5-client-message.db"); + CU_ASSERT_EQUAL(0, file_diff("files/persist_read/v6-client-message.test-db", "v6-client-message.db")); + unlink("v6-client-message.db"); } -static void TEST_v5_client_message_props(void) +static void TEST_v6_client_message_props(void) { struct mosquitto_db db; struct mosquitto__config config; @@ -252,11 +260,12 @@ static void TEST_v5_client_message_props(void) memset(&listener, 0, sizeof(struct mosquitto__listener)); db.config = &config; listener.port = 1883; + config.per_listener_settings = true; config.listeners = &listener; config.listener_count = 1; config.persistence = true; - config.persistence_filepath = "files/persist_read/v5-client-message-props.test-db"; + config.persistence_filepath = "files/persist_read/v6-client-message-props.test-db"; rc = persist__restore(&db); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); @@ -268,16 +277,16 @@ static void TEST_v5_client_message_props(void) } } - config.persistence_filepath = "v5-client-message-props.db"; + config.persistence_filepath = "v6-client-message-props.db"; rc = persist__backup(&db, true); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); - CU_ASSERT_EQUAL(0, file_diff("files/persist_read/v5-client-message-props.test-db", "v5-client-message-props.db")); - unlink("v5-client-message-props.db"); + CU_ASSERT_EQUAL(0, file_diff("files/persist_read/v6-client-message-props.test-db", "v6-client-message-props.db")); + unlink("v6-client-message-props.db"); } -static void TEST_v5_sub(void) +static void TEST_v6_sub(void) { struct mosquitto_db db; struct mosquitto__config config; @@ -289,22 +298,23 @@ static void TEST_v5_sub(void) memset(&listener, 0, sizeof(struct mosquitto__listener)); db.config = &config; listener.port = 1883; + config.per_listener_settings = true; config.listeners = &listener; config.listener_count = 1; db__open(&config, &db); config.persistence = true; - config.persistence_filepath = "files/persist_read/v5-sub.test-db"; + config.persistence_filepath = "files/persist_read/v6-sub.test-db"; rc = persist__restore(&db); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); - config.persistence_filepath = "v5-sub.db"; + config.persistence_filepath = "v6-sub.db"; rc = persist__backup(&db, true); CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS); - CU_ASSERT_EQUAL(0, file_diff("files/persist_read/v5-sub.test-db", "v5-sub.db")); - unlink("v5-sub.db"); + CU_ASSERT_EQUAL(0, file_diff("files/persist_read/v6-sub.test-db", "v6-sub.db")); + unlink("v6-sub.db"); } @@ -362,13 +372,13 @@ int main(int argc, char *argv[]) if(0 || !CU_add_test(test_suite, "Persistence disabled", TEST_persistence_disabled) || !CU_add_test(test_suite, "Empty file", TEST_empty_file) - || !CU_add_test(test_suite, "v5 config ok", TEST_v5_config_ok) - || !CU_add_test(test_suite, "v5 message store (message has no refs)", TEST_v5_message_store_no_ref) - || !CU_add_test(test_suite, "v5 message store + props", TEST_v5_message_store_props) - || !CU_add_test(test_suite, "v5 client", TEST_v5_client) - || !CU_add_test(test_suite, "v5 client message", TEST_v5_client_message) - || !CU_add_test(test_suite, "v5 client message+props", TEST_v5_client_message_props) - || !CU_add_test(test_suite, "v5 sub", TEST_v5_sub) + || !CU_add_test(test_suite, "v6 config ok", TEST_v6_config_ok) + || !CU_add_test(test_suite, "v6 message store (message has no refs)", TEST_v6_message_store_no_ref) + || !CU_add_test(test_suite, "v6 message store + props", TEST_v6_message_store_props) + || !CU_add_test(test_suite, "v6 client", TEST_v6_client) + || !CU_add_test(test_suite, "v6 client message", TEST_v6_client_message) + || !CU_add_test(test_suite, "v6 client message+props", TEST_v6_client_message_props) + || !CU_add_test(test_suite, "v6 sub", TEST_v6_sub) //|| !CU_add_test(test_suite, "v5 full", TEST_v5_full) ){ From bd27935ff63613301e485c0ce9e7e9b4e67e6d07 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 10 Aug 2020 22:51:17 +0100 Subject: [PATCH 084/113] `mosquitto_loop_start()` now sets a thread name. This applies on Linux, FreeBSD, NetBSD, and OpenBSD. Closes #1777. Thanks to ABuch19. --- ChangeLog.txt | 2 ++ lib/thread_mosq.c | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index 35336aca..e2da59c5 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -25,6 +25,8 @@ Client library: - Improved documentation around connect callback return codes. Close #1730. - Fix `mosquitto_publish*()` no longer returning `MOSQ_ERR_NO_CONN` when not connected. Closes #1725. +- `mosquitto_loop_start()` now sets a thread name on Linux, FreeBSD, NetBSD, + and OpenBSD. Closes #1777. 1.6.10 - 2020-05-25 diff --git a/lib/thread_mosq.c b/lib/thread_mosq.c index d32e26fa..a8cfa725 100644 --- a/lib/thread_mosq.c +++ b/lib/thread_mosq.c @@ -20,6 +20,12 @@ Contributors: #include #endif +#if defined(__linux__) || defined(__NetBSD__) +# include +#elif defined(__FreeBSD__) || defined(__OpenBSD__) +# include +#endif + #include "mosquitto_internal.h" #include "net_mosq.h" #include "util_mosq.h" @@ -33,6 +39,13 @@ int mosquitto_loop_start(struct mosquitto *mosq) mosq->threaded = mosq_ts_self; if(!pthread_create(&mosq->thread_id, NULL, mosquitto__thread_main, mosq)){ +#if defined(__linux__) + pthread_setname_np(mosq->thread_id, "mosquitto loop"); +#elif defined(__NetBSD__) + pthread_setname_np(mosq->thread_id, "%s", "mosquitto loop"); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) + pthread_set_name_np(mosq->thread_id, "mosquitto loop"); +#endif return MOSQ_ERR_SUCCESS; }else{ return MOSQ_ERR_ERRNO; From 3eb60e2e6a9e02d5e1984c1aee5954f94f74b064 Mon Sep 17 00:00:00 2001 From: Roger Light Date: Tue, 11 Aug 2020 08:43:24 +0100 Subject: [PATCH 085/113] Fix some winsock argument types. --- src/net.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/net.c b/src/net.c index addc0a47..3833b947 100644 --- a/src/net.c +++ b/src/net.c @@ -165,7 +165,11 @@ int net__socket_accept(struct mosquitto_db *db, mosq_sock_t listensock) if(db->config->set_tcp_nodelay){ int flag = 1; +#ifdef WIN32 + if (setsockopt(new_sock, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)) != 0) { +#else if(setsockopt(new_sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int)) != 0){ +#endif log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Unable to set TCP_NODELAY."); } } @@ -588,11 +592,7 @@ int net__socket_listen(struct mosquitto__listener *listener) struct addrinfo *ainfo, *rp; char service[10]; int rc; -#ifndef WIN32 int ss_opt = 1; -#else - char ss_opt = 1; -#endif #ifdef SO_BINDTODEVICE struct ifreq ifr; #endif From 4ef48269f5dd98ef20aee209813222c13c5a5072 Mon Sep 17 00:00:00 2001 From: Roger Light Date: Tue, 11 Aug 2020 08:55:05 +0100 Subject: [PATCH 086/113] Fix mosquitto_loop_stop() not stopping on Windows Closes #1748. Closes #117. Thanks to Sigmund Vik. --- ChangeLog.txt | 1 + lib/dummypthread.h | 1 + lib/loop.c | 2 ++ 3 files changed, 4 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index e2da59c5..ee68e729 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -27,6 +27,7 @@ Client library: connected. Closes #1725. - `mosquitto_loop_start()` now sets a thread name on Linux, FreeBSD, NetBSD, and OpenBSD. Closes #1777. +- Fix `mosquitto_loop_stop()` not stopping on Windows. Closes #1748. Closes #117. 1.6.10 - 2020-05-25 diff --git a/lib/dummypthread.h b/lib/dummypthread.h index 4207f3d6..611a1574 100644 --- a/lib/dummypthread.h +++ b/lib/dummypthread.h @@ -4,6 +4,7 @@ #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) diff --git a/lib/loop.c b/lib/loop.c index 048b8211..f7b26a0f 100644 --- a/lib/loop.c +++ b/lib/loop.c @@ -256,6 +256,7 @@ int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets) while(run){ do{ + pthread_testcancel(); rc = mosquitto_loop(mosq, timeout, max_packets); }while(run && rc == MOSQ_ERR_SUCCESS); /* Quit after fatal errors. */ @@ -280,6 +281,7 @@ int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets) return rc; } do{ + pthread_testcancel(); rc = MOSQ_ERR_SUCCESS; state = mosquitto__get_state(mosq); if(state == mosq_cs_disconnecting || state == mosq_cs_disconnected){ From 60dc8f5e4c19dd4282bd4e7eefbd91038488aeee Mon Sep 17 00:00:00 2001 From: Roger Light Date: Tue, 11 Aug 2020 09:09:31 +0100 Subject: [PATCH 087/113] Fix service path quoting on Windows. https://bugs.eclipse.org/bugs/show_bug.cgi?id=565671 --- ChangeLog.txt | 4 ++++ src/service.c | 13 +++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index ee68e729..21f56a22 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,7 @@ +Security: +- On Windows the Mosquitto service was being installed without appropriate + path quoting, this has been fixed. + Broker: - Fix usage message only mentioning v3.1.1. Closes #1713. - Fix broker refusing to start if only websockets listeners were defined. diff --git a/src/service.c b/src/service.c index 08099aa5..199afe32 100644 --- a/src/service.c +++ b/src/service.c @@ -70,7 +70,7 @@ void __stdcall service_main(DWORD dwArgc, LPTSTR *lpszArgv) service_handle = RegisterServiceCtrlHandler("mosquitto", service_handler); if(service_handle){ - memset(conf_path, 0, MAX_PATH + 20); + memset(conf_path, 0, sizeof(conf_path)); rc = GetEnvironmentVariable("MOSQUITTO_DIR", conf_path, MAX_PATH); if(!rc || rc == MAX_PATH){ service_status.dwCurrentState = SERVICE_STOPPED; @@ -103,25 +103,26 @@ void __stdcall service_main(DWORD dwArgc, LPTSTR *lpszArgv) void service_install(void) { SC_HANDLE sc_manager, svc_handle; - char exe_path[MAX_PATH + 5]; + char service_string[MAX_PATH + 20]; + char exe_path[MAX_PATH + 1]; SERVICE_DESCRIPTION svc_desc; - memset(exe_path, 0, MAX_PATH+5); + memset(exe_path, 0, sizeof(exe_path)); if(GetModuleFileName(NULL, exe_path, MAX_PATH) == MAX_PATH){ fprintf(stderr, "Error: Path too long.\n"); return; } - strcat(exe_path, " run"); + snprintf(service_string, sizeof(service_string), "\"%s\" run", exe_path); sc_manager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); if(sc_manager){ svc_handle = CreateService(sc_manager, "mosquitto", "Mosquitto Broker", SERVICE_START | SERVICE_STOP | SERVICE_CHANGE_CONFIG, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, - exe_path, NULL, NULL, NULL, NULL, NULL); + service_string, NULL, NULL, NULL, NULL, NULL); if(svc_handle){ - svc_desc.lpDescription = "MQTT v3.1.1 broker"; + svc_desc.lpDescription = "Eclipse Mosquitto MQTT v5/v3.1.1 broker"; ChangeServiceConfig2(svc_handle, SERVICE_CONFIG_DESCRIPTION, &svc_desc); CloseServiceHandle(svc_handle); }else{ From 4b100df5b13f071954b93974bbef868c7afcf1ec Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 11 Aug 2020 10:56:35 +0100 Subject: [PATCH 088/113] Fix reconnect+will delay interval issue causing missing messages. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix clients not receiving messages after a previous client with the same client ID and positive will delay interval quit. Closes #1752. Thanks to Jiří Zuzaňák. --- ChangeLog.txt | 2 ++ lib/will_mosq.c | 1 + 2 files changed, 3 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index 21f56a22..06f9b974 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -24,6 +24,8 @@ Broker: - Don't try to start DLT logging if DLT unavailable, to avoid a long delay when shutting down the broker. Closes #1735. - Fix potential memory leaks. Closes #1773. Closes #1774. +- Fix clients not receiving messages after a previous client with the same + client ID and positive will delay interval quit. Closes #1752. Client library: - Improved documentation around connect callback return codes. Close #1730. diff --git a/lib/will_mosq.c b/lib/will_mosq.c index 97fa67d0..59639f4a 100644 --- a/lib/will_mosq.c +++ b/lib/will_mosq.c @@ -120,6 +120,7 @@ int will__clear(struct mosquitto *mosq) mosquitto__free(mosq->will); mosq->will = NULL; + mosq->will_delay_interval = 0; return MOSQ_ERR_SUCCESS; } From b3c2ac20dc5fdaac75baa046134d716e0f5ae846 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 11 Aug 2020 11:02:38 +0100 Subject: [PATCH 089/113] Fix overly broad HAVE_PTHREAD_CANCEL compile guard. Closes #1547. Thanks to Markus Gothe. --- ChangeLog.txt | 1 + lib/loop.c | 4 ++++ lib/thread_mosq.c | 6 ++++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 06f9b974..9b64ffe9 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -26,6 +26,7 @@ Broker: - Fix potential memory leaks. Closes #1773. Closes #1774. - Fix clients not receiving messages after a previous client with the same client ID and positive will delay interval quit. Closes #1752. +- Fix overly broad HAVE_PTHREAD_CANCEL compile guard. Closes #1547. Client library: - Improved documentation around connect callback return codes. Close #1730. diff --git a/lib/loop.c b/lib/loop.c index f7b26a0f..a3773b0a 100644 --- a/lib/loop.c +++ b/lib/loop.c @@ -256,7 +256,9 @@ int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets) while(run){ do{ +#ifdef HAVE_PTHREAD_CANCEL pthread_testcancel(); +#endif rc = mosquitto_loop(mosq, timeout, max_packets); }while(run && rc == MOSQ_ERR_SUCCESS); /* Quit after fatal errors. */ @@ -281,7 +283,9 @@ int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets) return rc; } do{ +#ifdef HAVE_PTHREAD_CANCEL pthread_testcancel(); +#endif rc = MOSQ_ERR_SUCCESS; state = mosquitto__get_state(mosq); if(state == mosq_cs_disconnecting || state == mosq_cs_disconnected){ diff --git a/lib/thread_mosq.c b/lib/thread_mosq.c index a8cfa725..b05c1d2a 100644 --- a/lib/thread_mosq.c +++ b/lib/thread_mosq.c @@ -34,7 +34,7 @@ void *mosquitto__thread_main(void *obj); int mosquitto_loop_start(struct mosquitto *mosq) { -#if defined(WITH_THREADING) && defined(HAVE_PTHREAD_CANCEL) +#if defined(WITH_THREADING) if(!mosq || mosq->threaded != mosq_ts_none) return MOSQ_ERR_INVAL; mosq->threaded = mosq_ts_self; @@ -57,7 +57,7 @@ int mosquitto_loop_start(struct mosquitto *mosq) int mosquitto_loop_stop(struct mosquitto *mosq, bool force) { -#if defined(WITH_THREADING) && defined(HAVE_PTHREAD_CANCEL) +#if defined(WITH_THREADING) # ifndef WITH_BROKER char sockpair_data = 0; # endif @@ -76,9 +76,11 @@ int mosquitto_loop_stop(struct mosquitto *mosq, bool force) #endif } +#ifdef HAVE_PTHREAD_CANCEL if(force){ pthread_cancel(mosq->thread_id); } +#endif pthread_join(mosq->thread_id, NULL); mosq->thread_id = pthread_self(); mosq->threaded = mosq_ts_none; From c9218fd48c7bee2dcefb2a296f294f42c010f024 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 11 Aug 2020 12:05:32 +0100 Subject: [PATCH 090/113] Bump version. --- CMakeLists.txt | 2 +- ChangeLog.txt | 3 +++ config.mk | 2 +- installer/mosquitto.nsi | 2 +- installer/mosquitto64.nsi | 2 +- lib/mosquitto.h | 2 +- set-version.sh | 2 +- snap/snapcraft.yaml | 2 +- 8 files changed, 10 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d326ea2b..92604490 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ project(mosquitto) cmake_minimum_required(VERSION 2.8) # Only for version 3 and up. cmake_policy(SET CMP0042 NEW) -set (VERSION 1.6.10) +set (VERSION 1.6.11) add_definitions (-DCMAKE -DVERSION=\"${VERSION}\") diff --git a/ChangeLog.txt b/ChangeLog.txt index 9b64ffe9..1630e251 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,6 @@ +1.6.11 - 2020-08-11 +=================== + Security: - On Windows the Mosquitto service was being installed without appropriate path quoting, this has been fixed. diff --git a/config.mk b/config.mk index 89e0c319..75c8b35f 100644 --- a/config.mk +++ b/config.mk @@ -109,7 +109,7 @@ WITH_COVERAGE:=no # Also bump lib/mosquitto.h, CMakeLists.txt, # installer/mosquitto.nsi, installer/mosquitto64.nsi -VERSION=1.6.10 +VERSION=1.6.11 # Client library SO version. Bump if incompatible API/ABI changes are made. SOVERSION=1 diff --git a/installer/mosquitto.nsi b/installer/mosquitto.nsi index 4df8ac3d..6cd04601 100644 --- a/installer/mosquitto.nsi +++ b/installer/mosquitto.nsi @@ -9,7 +9,7 @@ !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' Name "Eclipse Mosquitto" -!define VERSION 1.6.10 +!define VERSION 1.6.11 OutFile "mosquitto-${VERSION}-install-windows-x86.exe" InstallDir "$PROGRAMFILES\mosquitto" diff --git a/installer/mosquitto64.nsi b/installer/mosquitto64.nsi index cd4ddc8f..dc54654b 100644 --- a/installer/mosquitto64.nsi +++ b/installer/mosquitto64.nsi @@ -9,7 +9,7 @@ !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' Name "Eclipse Mosquitto" -!define VERSION 1.6.10 +!define VERSION 1.6.11 OutFile "mosquitto-${VERSION}-install-windows-x64.exe" !include "x64.nsh" diff --git a/lib/mosquitto.h b/lib/mosquitto.h index 5e3591a5..9d3557d6 100644 --- a/lib/mosquitto.h +++ b/lib/mosquitto.h @@ -48,7 +48,7 @@ extern "C" { #define LIBMOSQUITTO_MAJOR 1 #define LIBMOSQUITTO_MINOR 6 -#define LIBMOSQUITTO_REVISION 10 +#define LIBMOSQUITTO_REVISION 11 /* LIBMOSQUITTO_VERSION_NUMBER looks like 1002001 for e.g. version 1.2.1. */ #define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION) diff --git a/set-version.sh b/set-version.sh index 2d081eeb..c98f34bd 100755 --- a/set-version.sh +++ b/set-version.sh @@ -2,7 +2,7 @@ MAJOR=1 MINOR=6 -REVISION=10 +REVISION=11 sed -i "s/^VERSION=.*/VERSION=${MAJOR}.${MINOR}.${REVISION}/" config.mk diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 5cabb807..7730aca4 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,5 +1,5 @@ name: mosquitto -version: 1.6.10 +version: 1.6.11 summary: Eclipse Mosquitto MQTT broker description: This is a message broker that supports version 3.1 and 3.1.1 of the MQTT protocol. From f89cea2bc53ad08dc1340b1d19e8fb20913d08a0 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 11 Aug 2020 12:13:38 +0100 Subject: [PATCH 091/113] Update webpage. --- www/pages/download.md | 8 +-- www/posts/2020/08/version-1-6-11-released.md | 72 ++++++++++++++++++++ 2 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 www/posts/2020/08/version-1-6-11-released.md diff --git a/www/pages/download.md b/www/pages/download.md index 2cb19286..2e805643 100644 --- a/www/pages/download.md +++ b/www/pages/download.md @@ -1,7 +1,7 @@ + +Mosquitto 1.6.11 has been released, this is a bugfix release. + +# Security +- On Windows the Mosquitto service was being installed without appropriate + path quoting, this has been fixed. Closes [#565671]. + +# Broker +- Fix usage message only mentioning v3.1.1. Closes [#1713]. +- Fix broker refusing to start if only websockets listeners were defined. + Closes [#1740]. +- Change systemd unit files to create /var/log/mosquitto before starting. + Closes [#821]. +- Don't quit with an error if opening the log file isn't possible. + Closes [#821]. +- Fix bridge topic remapping when using "" as the topic. Closes [#1749]. +- Fix messages being queued for disconnected bridges when clean start was + set to true. Closes [#1729]. +- Fix `autosave_interval` not being triggered by messages being delivered. + Closes [#1726]. +- Fix websockets clients sometimes not being disconnected promptly. + Closes [#1718]. +- Fix "slow" file based logging by switching to line based buffering. + Closes [#1689]. Closes [#1741]. +- Log protocol error message where appropriate from a bad UNSUBSCRIBE, rather + than the generic "socket error". +- Don't try to start DLT logging if DLT unavailable, to avoid a long delay + when shutting down the broker. Closes [#1735]. +- Fix potential memory leaks. Closes [#1773]. Closes [#1774]. +- Fix clients not receiving messages after a previous client with the same + client ID and positive will delay interval quit. Closes [#1752]. +- Fix overly broad `HAVE_PTHREAD_CANCEL` compile guard. Closes [#1547]. + +# Client library +- Improved documentation around connect callback return codes. Close [#1730]. +- Fix `mosquitto_publish*()` no longer returning `MOSQ_ERR_NO_CONN` when not + connected. Closes [#1725]. +- `mosquitto_loop_start()` now sets a thread name on Linux, FreeBSD, NetBSD, + and OpenBSD. Closes [#1777]. +- Fix `mosquitto_loop_stop()` not stopping on Windows. Closes [#1748]. Closes [#117]. + + +[#117]: https://github.com/eclipse/mosquitto/issues/117 +[#821]: https://github.com/eclipse/mosquitto/issues/821 +[#1547]: https://github.com/eclipse/mosquitto/issues/1547 +[#1689]: https://github.com/eclipse/mosquitto/issues/1689 +[#1713]: https://github.com/eclipse/mosquitto/issues/1713 +[#1718]: https://github.com/eclipse/mosquitto/issues/1718 +[#1725]: https://github.com/eclipse/mosquitto/issues/1725 +[#1726]: https://github.com/eclipse/mosquitto/issues/1726 +[#1729]: https://github.com/eclipse/mosquitto/issues/1729 +[#1730]: https://github.com/eclipse/mosquitto/issues/1730 +[#1735]: https://github.com/eclipse/mosquitto/issues/1735 +[#1740]: https://github.com/eclipse/mosquitto/issues/1740 +[#1741]: https://github.com/eclipse/mosquitto/issues/1741 +[#1748]: https://github.com/eclipse/mosquitto/issues/1748 +[#1749]: https://github.com/eclipse/mosquitto/issues/1749 +[#1752]: https://github.com/eclipse/mosquitto/issues/1752 +[#1773]: https://github.com/eclipse/mosquitto/issues/1773 +[#1774]: https://github.com/eclipse/mosquitto/issues/1774 +[#1777]: https://github.com/eclipse/mosquitto/issues/1777 +[#565671]: https://bugs.eclipse.org/bugs/show_bug.cgi?id=565671 From 32ed4809ed1e013f4214e3646d6e1dedaed89a8f Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 11 Aug 2020 16:12:18 +0100 Subject: [PATCH 092/113] Build fix for NetBSD. Thanks to Greg Troxel. --- src/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 053ca1d9..92ff0ca2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -152,6 +152,8 @@ if (UNIX) set (MOSQ_LIBS ${MOSQ_LIBS} dl m) elseif (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") set (MOSQ_LIBS ${MOSQ_LIBS} m) + elseif (${CMAKE_SYSTEM_NAME} MATCHES "NetBSD") + set (MOSQ_LIBS ${MOSQ_LIBS} m) elseif(QNX) set(MOSQ_LIBS ${MOSQ_LIBS} m socket) else(APPLE) From 9929ce0a26e3b66349286d778587dbb7239f2d91 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 12 Aug 2020 09:44:42 +0100 Subject: [PATCH 093/113] All clients exit with an error exit code on CONNACK failure. Closes #1778. Thanks to jflambert. --- ChangeLog.txt | 4 +++ client/pub_client.c | 9 +++++- client/rr_client.c | 8 +++++- client/sub_client.c | 8 +++++- man/mosquitto_passwd.1.xml | 58 ++++++++++++++++++++++++++++++++++++++ man/mosquitto_pub.1.xml | 58 ++++++++++++++++++++++++++++++++++++++ man/mosquitto_sub.1.xml | 58 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 200 insertions(+), 3 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 1630e251..f67fc472 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,7 @@ +Clients: +- All clients exit with an error exit code on CONNACK failure. Closes #1778. + + 1.6.11 - 2020-08-11 =================== diff --git a/client/pub_client.c b/client/pub_client.c index ef0bf16e..3b0078a8 100644 --- a/client/pub_client.c +++ b/client/pub_client.c @@ -46,6 +46,7 @@ static bool disconnect_sent = false; static int publish_count = 0; static bool ready_for_repeat = false; static volatile int status = STATUS_CONNECTING; +static int connack_result = 0; #ifdef WIN32 static uint64_t next_publish_tv; @@ -129,6 +130,8 @@ void my_connect_callback(struct mosquitto *mosq, void *obj, int result, int flag UNUSED(flags); UNUSED(properties); + connack_result = result; + if(!result){ switch(cfg.pub_mode){ case MSGMODE_CMD: @@ -555,7 +558,11 @@ int main(int argc, char *argv[]) if(rc){ err_printf(&cfg, "Error: %s\n", mosquitto_strerror(rc)); } - return rc; + if(connack_result){ + return connack_result; + }else{ + return rc; + } cleanup: mosquitto_lib_cleanup(); diff --git a/client/rr_client.c b/client/rr_client.c index 4e22fa3b..dec94686 100644 --- a/client/rr_client.c +++ b/client/rr_client.c @@ -52,6 +52,7 @@ extern struct mosq_config cfg; bool process_messages = true; int msg_count = 0; struct mosquitto *mosq = NULL; +static int connack_result = 0; #ifndef WIN32 void my_signal_handler(int signum) @@ -117,6 +118,7 @@ void my_message_callback(struct mosquitto *mosq, void *obj, const struct mosquit void my_connect_callback(struct mosquitto *mosq, void *obj, int result, int flags, const mosquitto_property *properties) { + connack_result = result; if(!result){ client_state = rr_s_connected; mosquitto_subscribe_v5(mosq, NULL, cfg.response_topic, cfg.qos, 0, cfg.subscribe_props); @@ -363,7 +365,11 @@ int main(int argc, char *argv[]) if(rc){ err_printf(&cfg, "Error: %s\n", mosquitto_strerror(rc)); } - return rc; + if(connack_result){ + return connack_result; + }else{ + return rc; + } cleanup: mosquitto_lib_cleanup(); diff --git a/client/sub_client.c b/client/sub_client.c index 7eeaae59..fb26638f 100644 --- a/client/sub_client.c +++ b/client/sub_client.c @@ -40,6 +40,7 @@ bool process_messages = true; int msg_count = 0; struct mosquitto *mosq = NULL; int last_mid = 0; +static int connack_result = 0; #ifndef WIN32 void my_signal_handler(int signum) @@ -117,6 +118,7 @@ void my_connect_callback(struct mosquitto *mosq, void *obj, int result, int flag UNUSED(flags); UNUSED(properties); + connack_result = result; if(!result){ mosquitto_subscribe_multiple(mosq, NULL, cfg.topic_count, cfg.topics, cfg.qos, cfg.sub_opts, cfg.subscribe_props); @@ -371,7 +373,11 @@ int main(int argc, char *argv[]) if(rc){ err_printf(&cfg, "Error: %s\n", mosquitto_strerror(rc)); } - return rc; + if(connack_result){ + return connack_result; + }else{ + return rc; + } cleanup: mosquitto_destroy(mosq); diff --git a/man/mosquitto_passwd.1.xml b/man/mosquitto_passwd.1.xml index 5f144bf9..3c0abd3f 100644 --- a/man/mosquitto_passwd.1.xml +++ b/man/mosquitto_passwd.1.xml @@ -109,6 +109,64 @@ + + Exit Status + + mosquitto_sub returns zero on success, or non-zero on error. If + the connection is refused by the broker at the MQTT level, then + the exit code is the CONNACK reason code. If another error + occurs, the exit code is a libmosquitto return value. + + + MQTT v3.1.1 CONNACK codes: + + Success + Connection refused: Bad protocol version + Connection refused: Identifier rejected + Connection refused: Server unavailable + Connection refused: Bad username/password + Connection refused: Not authorized + + + MQTT v5 CONNACK codes: + + Success + Unspecified error + Malformed packet + Protocol error + Implementation specific error + Unsupported protocol version + Client ID not valid + Bad username or password + Not authorized + Server unavailable + Server busy + Banned + Server shutting down + Bad authentication method + Keep alive timeout + Session taken over + Topic filter invalid + Topic name invalid + Receive maximum exceeded + Topic alias invalid + Packet too large + Message rate too high + Quota exceeded + Administrative action + Payload format invalid + Retain not supported + QoS not supported + Use another server + Server moved + Shared subscriptions not supported + Connection rate exceeded + Maximum connect time + Subscription IDs not supported + Wildcard subscriptions not supported + + + Examples Add a user to a new password file: diff --git a/man/mosquitto_pub.1.xml b/man/mosquitto_pub.1.xml index a05a938f..58991749 100644 --- a/man/mosquitto_pub.1.xml +++ b/man/mosquitto_pub.1.xml @@ -654,6 +654,64 @@ + + Exit Status + + mosquitto_sub returns zero on success, or non-zero on error. If + the connection is refused by the broker at the MQTT level, then + the exit code is the CONNACK reason code. If another error + occurs, the exit code is a libmosquitto return value. + + + MQTT v3.1.1 CONNACK codes: + + Success + Connection refused: Bad protocol version + Connection refused: Identifier rejected + Connection refused: Server unavailable + Connection refused: Bad username/password + Connection refused: Not authorized + + + MQTT v5 CONNACK codes: + + Success + Unspecified error + Malformed packet + Protocol error + Implementation specific error + Unsupported protocol version + Client ID not valid + Bad username or password + Not authorized + Server unavailable + Server busy + Banned + Server shutting down + Bad authentication method + Keep alive timeout + Session taken over + Topic filter invalid + Topic name invalid + Receive maximum exceeded + Topic alias invalid + Packet too large + Message rate too high + Quota exceeded + Administrative action + Payload format invalid + Retain not supported + QoS not supported + Use another server + Server moved + Shared subscriptions not supported + Connection rate exceeded + Maximum connect time + Subscription IDs not supported + Wildcard subscriptions not supported + + + Examples Publish temperature information to localhost with QoS 1: diff --git a/man/mosquitto_sub.1.xml b/man/mosquitto_sub.1.xml index 55867c7e..2e7e4bd6 100644 --- a/man/mosquitto_sub.1.xml +++ b/man/mosquitto_sub.1.xml @@ -893,6 +893,64 @@ mosquitto_sub -t 'bbc/#' -T bbc/bbc1 --remove-retained + + Exit Status + + mosquitto_sub returns zero on success, or non-zero on error. If + the connection is refused by the broker at the MQTT level, then + the exit code is the CONNACK reason code. If another error + occurs, the exit code is a libmosquitto return value. + + + MQTT v3.1.1 CONNACK codes: + + Success + Connection refused: Bad protocol version + Connection refused: Identifier rejected + Connection refused: Server unavailable + Connection refused: Bad username/password + Connection refused: Not authorized + + + MQTT v5 CONNACK codes: + + Success + Unspecified error + Malformed packet + Protocol error + Implementation specific error + Unsupported protocol version + Client ID not valid + Bad username or password + Not authorized + Server unavailable + Server busy + Banned + Server shutting down + Bad authentication method + Keep alive timeout + Session taken over + Topic filter invalid + Topic name invalid + Receive maximum exceeded + Topic alias invalid + Packet too large + Message rate too high + Quota exceeded + Administrative action + Payload format invalid + Retain not supported + QoS not supported + Use another server + Server moved + Shared subscriptions not supported + Connection rate exceeded + Maximum connect time + Subscription IDs not supported + Wildcard subscriptions not supported + + + Examples Note that these really are examples - the subscriptions will work From 124225d02b587bd7d13595dcb50ed991ac620c3a Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 12 Aug 2020 16:00:42 +0100 Subject: [PATCH 094/113] Update docker. --- docker/1.6-openssl/Dockerfile | 4 ++-- docker/1.6-openssl/docker-entrypoint.sh | 11 +++++++++++ docker/1.6/Dockerfile | 4 ++-- docker/README.md | 10 ++++++++-- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/docker/1.6-openssl/Dockerfile b/docker/1.6-openssl/Dockerfile index 8cc94464..3c6287bc 100644 --- a/docker/1.6-openssl/Dockerfile +++ b/docker/1.6-openssl/Dockerfile @@ -3,8 +3,8 @@ FROM alpine:3.12 LABEL maintainer="Roger Light " \ description="Eclipse Mosquitto MQTT Broker" -ENV VERSION=1.6.10 \ - DOWNLOAD_SHA256=92d1807717f0f6d57d1ac1207ffdb952e8377e916c7b0bb4718f745239774232 \ +ENV VERSION=1.6.11 \ + DOWNLOAD_SHA256=b02d8f1368c40d5779ee125c37daf9003608eb47d7fbb04c5b938c76c1230a1f \ GPG_KEYS=A0D6EEA1DCAE49A635A3B2F0779B22DFB3E717B7 \ LWS_VERSION=2.4.2 diff --git a/docker/1.6-openssl/docker-entrypoint.sh b/docker/1.6-openssl/docker-entrypoint.sh index b381ac57..85099f54 100755 --- a/docker/1.6-openssl/docker-entrypoint.sh +++ b/docker/1.6-openssl/docker-entrypoint.sh @@ -1,4 +1,15 @@ #!/bin/ash set -e +docker_set_permissions() { + local user; user="$(id -u)" + + if [ "$user" = '0' ]; then + chown -R mosquitto:mosquitto /mosquitto + fi +} + + +docker_set_permissions() + exec "$@" diff --git a/docker/1.6/Dockerfile b/docker/1.6/Dockerfile index 7f725437..4fb7a5e8 100644 --- a/docker/1.6/Dockerfile +++ b/docker/1.6/Dockerfile @@ -3,8 +3,8 @@ FROM alpine:3.12 LABEL maintainer="Roger Light " \ description="Eclipse Mosquitto MQTT Broker" -ENV VERSION=1.6.10 \ - DOWNLOAD_SHA256=92d1807717f0f6d57d1ac1207ffdb952e8377e916c7b0bb4718f745239774232 \ +ENV VERSION=1.6.11 \ + DOWNLOAD_SHA256=b02d8f1368c40d5779ee125c37daf9003608eb47d7fbb04c5b938c76c1230a1f \ GPG_KEYS=A0D6EEA1DCAE49A635A3B2F0779B22DFB3E717B7 \ LWS_VERSION=2.4.2 diff --git a/docker/README.md b/docker/README.md index ff53a2b4..0314c244 100644 --- a/docker/README.md +++ b/docker/README.md @@ -2,8 +2,14 @@ This directory contains Docker files for Mosquitto. -The `1.5` directory contains the latest version of Mosquitto for -that series, and provide the basis of the official image. +The `1.6` directory contains the latest version of Mosquitto for +that series, and provide the basis of the official image. It uses libressl. The +`1.6-openssl` directory is identical except that it uses openssl instead of +libressl, and enables TLS-PSK support. + +The `1.5` directory contains the version of Mosquitto based on the 1.5 branch. +It uses libressl. The `1.5-openssl` directory is identical except that it uses +openssl instead of libressl, and enables TLS-PSK support. The `generic` directory contains a generic Dockerfile that can be used to build arbitrary versions of Mosquitto based on the released tarballs as follows: From ac3b30ca4f692fc9935766d210d5de501f17e403 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 12 Aug 2020 17:00:53 +0100 Subject: [PATCH 095/113] Fix docker command override. --- docker/1.5-openssl/docker-entrypoint.sh | 6 ++++++ docker/1.5/docker-entrypoint.sh | 15 +++++---------- docker/1.6-openssl/docker-entrypoint.sh | 15 +++++---------- docker/1.6/docker-entrypoint.sh | 15 +++++---------- 4 files changed, 21 insertions(+), 30 deletions(-) diff --git a/docker/1.5-openssl/docker-entrypoint.sh b/docker/1.5-openssl/docker-entrypoint.sh index b381ac57..378d91ec 100755 --- a/docker/1.5-openssl/docker-entrypoint.sh +++ b/docker/1.5-openssl/docker-entrypoint.sh @@ -1,4 +1,10 @@ #!/bin/ash set -e +# Set permissions +user="$(id -u)" +if [ "$user" = '0' ]; then + [ -d "/mosquitto" ] && chown -R mosquitto:mosquitto /mosquitto +fi + exec "$@" diff --git a/docker/1.5/docker-entrypoint.sh b/docker/1.5/docker-entrypoint.sh index 85099f54..378d91ec 100755 --- a/docker/1.5/docker-entrypoint.sh +++ b/docker/1.5/docker-entrypoint.sh @@ -1,15 +1,10 @@ #!/bin/ash set -e -docker_set_permissions() { - local user; user="$(id -u)" - - if [ "$user" = '0' ]; then - chown -R mosquitto:mosquitto /mosquitto - fi -} - - -docker_set_permissions() +# Set permissions +user="$(id -u)" +if [ "$user" = '0' ]; then + [ -d "/mosquitto" ] && chown -R mosquitto:mosquitto /mosquitto +fi exec "$@" diff --git a/docker/1.6-openssl/docker-entrypoint.sh b/docker/1.6-openssl/docker-entrypoint.sh index 85099f54..378d91ec 100755 --- a/docker/1.6-openssl/docker-entrypoint.sh +++ b/docker/1.6-openssl/docker-entrypoint.sh @@ -1,15 +1,10 @@ #!/bin/ash set -e -docker_set_permissions() { - local user; user="$(id -u)" - - if [ "$user" = '0' ]; then - chown -R mosquitto:mosquitto /mosquitto - fi -} - - -docker_set_permissions() +# Set permissions +user="$(id -u)" +if [ "$user" = '0' ]; then + [ -d "/mosquitto" ] && chown -R mosquitto:mosquitto /mosquitto +fi exec "$@" diff --git a/docker/1.6/docker-entrypoint.sh b/docker/1.6/docker-entrypoint.sh index 85099f54..378d91ec 100755 --- a/docker/1.6/docker-entrypoint.sh +++ b/docker/1.6/docker-entrypoint.sh @@ -1,15 +1,10 @@ #!/bin/ash set -e -docker_set_permissions() { - local user; user="$(id -u)" - - if [ "$user" = '0' ]; then - chown -R mosquitto:mosquitto /mosquitto - fi -} - - -docker_set_permissions() +# Set permissions +user="$(id -u)" +if [ "$user" = '0' ]; then + [ -d "/mosquitto" ] && chown -R mosquitto:mosquitto /mosquitto +fi exec "$@" From 6407abf717bcffb60e832fa3c2bcc3e5d1cc22ac Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 12 Aug 2020 22:08:05 +0100 Subject: [PATCH 096/113] Docker: Fix missing libressl library. --- docker/1.5/Dockerfile | 4 +++- docker/1.6/Dockerfile | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docker/1.5/Dockerfile b/docker/1.5/Dockerfile index 7a0a10a3..b698aa52 100644 --- a/docker/1.5/Dockerfile +++ b/docker/1.5/Dockerfile @@ -78,7 +78,9 @@ RUN set -x && \ install -m644 /build/mosq/mosquitto.conf /mosquitto/config/mosquitto.conf && \ chown -R mosquitto:mosquitto /mosquitto && \ apk --no-cache add \ - ca-certificates libuuid && \ + ca-certificates \ + libressl \ + libuuid && \ apk del build-deps && \ rm -rf /build diff --git a/docker/1.6/Dockerfile b/docker/1.6/Dockerfile index 4fb7a5e8..c7fd02d8 100644 --- a/docker/1.6/Dockerfile +++ b/docker/1.6/Dockerfile @@ -79,7 +79,8 @@ RUN set -x && \ install -m644 /build/mosq/mosquitto.conf /mosquitto/config/mosquitto.conf && \ chown -R mosquitto:mosquitto /mosquitto && \ apk --no-cache add \ - ca-certificates && \ + ca-certificates \ + libressl && \ apk del build-deps && \ rm -rf /build From a224a8f217a0428e1ad85f9a92760af5f0a06258 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 13 Aug 2020 14:32:47 +0100 Subject: [PATCH 097/113] Don't busy loop with `mosquitto_pub -l` on a slow connection. --- ChangeLog.txt | 1 + client/pub_client.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index f67fc472..a762ff9e 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,5 +1,6 @@ Clients: - All clients exit with an error exit code on CONNACK failure. Closes #1778. +- Don't busy loop with `mosquitto_pub -l` on a slow connection. 1.6.11 - 2020-08-11 diff --git a/client/pub_client.c b/client/pub_client.c index 3b0078a8..b39c700a 100644 --- a/client/pub_client.c +++ b/client/pub_client.c @@ -235,6 +235,17 @@ int pub_stdin_line_loop(struct mosquitto *mosq) mosquitto_loop_start(mosq); stdin_finished = false; do{ + if(status == STATUS_CONNECTING){ +#ifdef WIN32 + Sleep(100); +#else + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 100000000; + nanosleep(&ts, NULL); +#endif + } + if(status == STATUS_CONNACK_RECVD){ pos = 0; read_len = line_buf_len; From 367a282c61460a1f021df086887ad195e26fc968 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 13 Aug 2020 20:08:30 +0100 Subject: [PATCH 098/113] Don't quit on chmod error, it can be ignored. --- docker/1.5-openssl/docker-entrypoint.sh | 2 +- docker/1.5/docker-entrypoint.sh | 2 +- docker/1.6-openssl/docker-entrypoint.sh | 2 +- docker/1.6/docker-entrypoint.sh | 2 +- docker/generic/docker-entrypoint.sh | 15 +++++---------- docker/local/docker-entrypoint.sh | 15 +++++---------- 6 files changed, 14 insertions(+), 24 deletions(-) diff --git a/docker/1.5-openssl/docker-entrypoint.sh b/docker/1.5-openssl/docker-entrypoint.sh index 378d91ec..583f67c9 100755 --- a/docker/1.5-openssl/docker-entrypoint.sh +++ b/docker/1.5-openssl/docker-entrypoint.sh @@ -4,7 +4,7 @@ set -e # Set permissions user="$(id -u)" if [ "$user" = '0' ]; then - [ -d "/mosquitto" ] && chown -R mosquitto:mosquitto /mosquitto + [ -d "/mosquitto" ] && chown -R mosquitto:mosquitto /mosquitto || true fi exec "$@" diff --git a/docker/1.5/docker-entrypoint.sh b/docker/1.5/docker-entrypoint.sh index 378d91ec..583f67c9 100755 --- a/docker/1.5/docker-entrypoint.sh +++ b/docker/1.5/docker-entrypoint.sh @@ -4,7 +4,7 @@ set -e # Set permissions user="$(id -u)" if [ "$user" = '0' ]; then - [ -d "/mosquitto" ] && chown -R mosquitto:mosquitto /mosquitto + [ -d "/mosquitto" ] && chown -R mosquitto:mosquitto /mosquitto || true fi exec "$@" diff --git a/docker/1.6-openssl/docker-entrypoint.sh b/docker/1.6-openssl/docker-entrypoint.sh index 378d91ec..583f67c9 100755 --- a/docker/1.6-openssl/docker-entrypoint.sh +++ b/docker/1.6-openssl/docker-entrypoint.sh @@ -4,7 +4,7 @@ set -e # Set permissions user="$(id -u)" if [ "$user" = '0' ]; then - [ -d "/mosquitto" ] && chown -R mosquitto:mosquitto /mosquitto + [ -d "/mosquitto" ] && chown -R mosquitto:mosquitto /mosquitto || true fi exec "$@" diff --git a/docker/1.6/docker-entrypoint.sh b/docker/1.6/docker-entrypoint.sh index 378d91ec..583f67c9 100755 --- a/docker/1.6/docker-entrypoint.sh +++ b/docker/1.6/docker-entrypoint.sh @@ -4,7 +4,7 @@ set -e # Set permissions user="$(id -u)" if [ "$user" = '0' ]; then - [ -d "/mosquitto" ] && chown -R mosquitto:mosquitto /mosquitto + [ -d "/mosquitto" ] && chown -R mosquitto:mosquitto /mosquitto || true fi exec "$@" diff --git a/docker/generic/docker-entrypoint.sh b/docker/generic/docker-entrypoint.sh index 85099f54..583f67c9 100755 --- a/docker/generic/docker-entrypoint.sh +++ b/docker/generic/docker-entrypoint.sh @@ -1,15 +1,10 @@ #!/bin/ash set -e -docker_set_permissions() { - local user; user="$(id -u)" - - if [ "$user" = '0' ]; then - chown -R mosquitto:mosquitto /mosquitto - fi -} - - -docker_set_permissions() +# Set permissions +user="$(id -u)" +if [ "$user" = '0' ]; then + [ -d "/mosquitto" ] && chown -R mosquitto:mosquitto /mosquitto || true +fi exec "$@" diff --git a/docker/local/docker-entrypoint.sh b/docker/local/docker-entrypoint.sh index 85099f54..583f67c9 100755 --- a/docker/local/docker-entrypoint.sh +++ b/docker/local/docker-entrypoint.sh @@ -1,15 +1,10 @@ #!/bin/ash set -e -docker_set_permissions() { - local user; user="$(id -u)" - - if [ "$user" = '0' ]; then - chown -R mosquitto:mosquitto /mosquitto - fi -} - - -docker_set_permissions() +# Set permissions +user="$(id -u)" +if [ "$user" = '0' ]; then + [ -d "/mosquitto" ] && chown -R mosquitto:mosquitto /mosquitto || true +fi exec "$@" From d254ea70dfe5c3fd7df1bab4c0a0457e2ab7b74d Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 18 Aug 2020 21:06:14 +0000 Subject: [PATCH 099/113] docs: remove duplicate mosquitto_reconnect_delay_set Was listed in both client options, and under the callbacks. Signed-off-by: Karl Palsson --- lib/mosquitto.h | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/lib/mosquitto.h b/lib/mosquitto.h index 9d3557d6..262c523e 100644 --- a/lib/mosquitto.h +++ b/lib/mosquitto.h @@ -2097,43 +2097,6 @@ libmosq_EXPORT void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on libmosq_EXPORT int mosquitto_string_option(struct mosquitto *mosq, enum mosq_opt_t option, const char *value); -/* - * Function: mosquitto_reconnect_delay_set - * - * Control the behaviour of the client when it has unexpectedly disconnected in - * or after . The default - * behaviour if this function is not used is to repeatedly attempt to reconnect - * with a delay of 1 second until the connection succeeds. - * - * Use reconnect_delay parameter to change the delay between successive - * reconnection attempts. You may also enable exponential backoff of the time - * between reconnections by setting reconnect_exponential_backoff to true and - * set an upper bound on the delay with reconnect_delay_max. - * - * Example 1: - * delay=2, delay_max=10, exponential_backoff=False - * Delays would be: 2, 4, 6, 8, 10, 10, ... - * - * Example 2: - * delay=3, delay_max=30, exponential_backoff=True - * Delays would be: 3, 6, 12, 24, 30, 30, ... - * - * Parameters: - * mosq - a valid mosquitto instance. - * reconnect_delay - the number of seconds to wait between - * reconnects. - * reconnect_delay_max - the maximum number of seconds to wait - * between reconnects. - * reconnect_exponential_backoff - use exponential backoff between - * reconnect attempts. Set to true to enable - * exponential backoff. - * - * Returns: - * MOSQ_ERR_SUCCESS - on success. - * MOSQ_ERR_INVAL - if the input parameters were invalid. - */ -libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); - /* ============================================================================= * From 2fdb5a01715834d714f1be7307e4eda4772173f9 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 18 Aug 2020 21:07:03 +0000 Subject: [PATCH 100/113] docs: move _string_option with rest of client options It was grouped with the callbacks, where it didn't make a lot of sense. Signed-off-by: Karl Palsson --- lib/mosquitto.h | 67 ++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/lib/mosquitto.h b/lib/mosquitto.h index 262c523e..93793fa5 100644 --- a/lib/mosquitto.h +++ b/lib/mosquitto.h @@ -1511,6 +1511,39 @@ libmosq_EXPORT int mosquitto_int_option(struct mosquitto *mosq, enum mosq_opt_t */ libmosq_EXPORT int mosquitto_void_option(struct mosquitto *mosq, enum mosq_opt_t option, void *value); +/* + * Function: mosquitto_string_option + * + * Used to set const char* options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_TLS_ENGINE + * Configure the client for TLS Engine support. Pass a TLS Engine ID + * to be used when creating TLS connections. + * Must be set before . + * MOSQ_OPT_TLS_KEYFORM + * Configure the client to treat the keyfile differently depending + * on its type. Must be set before . + * Set as either "pem" or "engine", to determine from where the + * private key for a TLS connection will be obtained. Defaults to + * "pem", a normal private key file. + * MOSQ_OPT_TLS_KPASS_SHA1 + * Where the TLS Engine requires the use of a password to be + * accessed, this option allows a hex encoded SHA1 hash of the + * private key password to be passed to the engine directly. + * Must be set before . + * MOSQ_OPT_TLS_ALPN + * If the broker being connected to has multiple services available + * on a single TLS port, such as both MQTT and WebSockets, use this + * option to configure the ALPN option for the connection. + */ +libmosq_EXPORT int mosquitto_string_option(struct mosquitto *mosq, enum mosq_opt_t option, const char *value); + /* * Function: mosquitto_reconnect_delay_set @@ -2063,40 +2096,6 @@ libmosq_EXPORT void mosquitto_unsubscribe_v5_callback_set(struct mosquitto *mosq */ libmosq_EXPORT void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mosquitto *, void *, int, const char *)); -/* - * Function: mosquitto_string_option - * - * Used to set const char* options for the client. - * - * Parameters: - * mosq - a valid mosquitto instance. - * option - the option to set. - * value - the option specific value. - * - * Options: - * MOSQ_OPT_TLS_ENGINE - * Configure the client for TLS Engine support. Pass a TLS Engine ID - * to be used when creating TLS connections. - * Must be set before . - * MOSQ_OPT_TLS_KEYFORM - * Configure the client to treat the keyfile differently depending - * on its type. Must be set before . - * Set as either "pem" or "engine", to determine from where the - * private key for a TLS connection will be obtained. Defaults to - * "pem", a normal private key file. - * MOSQ_OPT_TLS_KPASS_SHA1 - * Where the TLS Engine requires the use of a password to be - * accessed, this option allows a hex encoded SHA1 hash of the - * private key password to be passed to the engine directly. - * Must be set before . - * MOSQ_OPT_TLS_ALPN - * If the broker being connected to has multiple services available - * on a single TLS port, such as both MQTT and WebSockets, use this - * option to configure the ALPN option for the connection. - */ -libmosq_EXPORT int mosquitto_string_option(struct mosquitto *mosq, enum mosq_opt_t option, const char *value); - - /* ============================================================================= * From 79051fbdca3a137d5ef000bec3edfe93eaa4c224 Mon Sep 17 00:00:00 2001 From: Titouan Christophe Date: Tue, 18 Aug 2020 01:26:58 +0200 Subject: [PATCH 101/113] do not include pthread when compiling without threading support This fixes the following error, when compiling for systems without pthread support, and when passing WITH_THREADING=no to make: thread_mosq.c:24:12: fatal error: pthread.h: No such file or directory # include ^~~~~~~~~~~ compilation terminated. Signed-off-by: Titouan Christophe --- lib/thread_mosq.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/thread_mosq.c b/lib/thread_mosq.c index b05c1d2a..46e19807 100644 --- a/lib/thread_mosq.c +++ b/lib/thread_mosq.c @@ -20,11 +20,13 @@ Contributors: #include #endif +#if defined(WITH_THREADING) #if defined(__linux__) || defined(__NetBSD__) # include #elif defined(__FreeBSD__) || defined(__OpenBSD__) # include #endif +#endif #include "mosquitto_internal.h" #include "net_mosq.h" From 4dc835b73d352a4a67ee1a57f70d7a1b8a88003a Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 19 Aug 2020 11:12:05 +0100 Subject: [PATCH 102/113] Fix possible memory leaks on errors during persistence write. --- src/persist_write_v5.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/persist_write_v5.c b/src/persist_write_v5.c index 48ca9c93..10d51456 100644 --- a/src/persist_write_v5.c +++ b/src/persist_write_v5.c @@ -115,7 +115,10 @@ int persist__chunk_client_msg_write_v6(FILE *db_fptr, struct P_client_msg *chunk return MOSQ_ERR_NOMEM; } rc = property__write_all(&prop_packet, chunk->properties, true); - if(rc) return rc; + if(rc){ + mosquitto__free(prop_packet.payload); + return rc; + } write_e(db_fptr, prop_packet.payload, proplen); mosquitto__free(prop_packet.payload); @@ -179,7 +182,10 @@ int persist__chunk_message_store_write_v6(FILE *db_fptr, struct P_msg_store *chu return MOSQ_ERR_NOMEM; } rc = property__write_all(&prop_packet, chunk->properties, true); - if(rc) return rc; + if(rc){ + mosquitto__free(prop_packet.payload); + return rc; + } write_e(db_fptr, prop_packet.payload, proplen); mosquitto__free(prop_packet.payload); From b3b58cc6357336eb23da73922d3ef971998689ab Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 19 Aug 2020 14:04:02 +0100 Subject: [PATCH 103/113] Build warning fixes. --- ChangeLog.txt | 3 +++ src/conf.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index a762ff9e..33646461 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,6 @@ +Broker: +- Build warning fixes when building with WITH_BRIDGE=no and WITH_TLS=no. + Clients: - All clients exit with an error exit code on CONNACK failure. Closes #1778. - Don't busy loop with `mosquitto_pub -l` on a slow connection. diff --git a/src/conf.c b/src/conf.c index 6ec461ed..9d31ad9b 100644 --- a/src/conf.c +++ b/src/conf.c @@ -760,6 +760,7 @@ int config__read(struct mosquitto_db *db, struct mosquitto__config *config, bool } +#ifdef WITH_BRIDGE static int config__create_bridge_remap_topic(const char *prefix, const char *topic, char **remap_topic) { int len; @@ -827,6 +828,7 @@ static int config__create_bridge_prefix(char **prefix, const char *topic, const return MOSQ_ERR_SUCCESS; } +#endif int config__read_file_core(struct mosquitto__config *config, bool reload, struct config_recurse *cr, int level, int *lineno, FILE *fptr, char **buf, int *buflen) @@ -849,8 +851,10 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct int lineno_ext = 0; char **files; int file_count; +#ifdef WITH_TLS char *kpass_sha = NULL, *kpass_sha_bin = NULL; char *keyform ; +#endif *lineno = 0; From c1b009e4dfa0644282037e432400bf537948f868 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 19 Aug 2020 14:05:27 +0100 Subject: [PATCH 104/113] Fix memory leak on handling QoS 2 PUBLISH. In some circumstances, Mosquitto could leak memory when handling PUBLISH messages. This is limited to incoming QoS 2 messages, and is related to the combination of the broker having persistence enabled, a clean session=false client, which was connected prior to the broker restarting, then has reconnected and has now sent messages at a sufficiently high rate that the incoming queue at the broker has filled up and hence messages are being dropped. This is more likely to have an effect where max_queued_messages is a small value. This has now been fixed. Closes #1793. Thanks to mbates14. --- ChangeLog.txt | 13 +++++++++++++ src/database.c | 4 ++-- src/handle_publish.c | 20 +++++++++++++++----- src/mosquitto_broker_internal.h | 2 ++ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 33646461..c7dcb03f 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,16 @@ +1.6.12 - 2020-08-19 +=================== + +Security: +- In some circumstances, Mosquitto could leak memory when handling PUBLISH + messages. This is limited to incoming QoS 2 messages, and is related + to the combination of the broker having persistence enabled, a clean + session=false client, which was connected prior to the broker restarting, + then has reconnected and has now sent messages at a sufficiently high rate + that the incoming queue at the broker has filled up and hence messages are + being dropped. This is more likely to have an effect where + max_queued_messages is a small value. This has now been fixed. Closes #1793. + Broker: - Build warning fixes when building with WITH_BRIDGE=no and WITH_TLS=no. diff --git a/src/database.c b/src/database.c index 124824cd..1e58f05d 100644 --- a/src/database.c +++ b/src/database.c @@ -37,7 +37,7 @@ static unsigned long max_queued_bytes = 0; * @param qos qos for the packet of interest * @return true if more in flight are allowed. */ -static bool db__ready_for_flight(struct mosquitto_msg_data *msgs, int qos) +bool db__ready_for_flight(struct mosquitto_msg_data *msgs, int qos) { bool valid_bytes; bool valid_count; @@ -68,7 +68,7 @@ static bool db__ready_for_flight(struct mosquitto_msg_data *msgs, int qos) * @param qos destination qos for the packet of interest * @return true if queuing is allowed, false if should be dropped */ -static bool db__ready_for_queue(struct mosquitto *context, int qos, struct mosquitto_msg_data *msg_data) +bool db__ready_for_queue(struct mosquitto *context, int qos, struct mosquitto_msg_data *msg_data) { int source_count; int adjust_count; diff --git a/src/handle_publish.c b/src/handle_publish.c index acbbec93..610a7ad8 100644 --- a/src/handle_publish.c +++ b/src/handle_publish.c @@ -302,12 +302,21 @@ int handle__publish(struct mosquitto_db *db, struct mosquitto *context) db__message_store_find(context, mid, &stored); } if(!stored){ - dup = 0; - if(db__message_store(db, context, mid, topic, qos, payloadlen, &payload, retain, &stored, message_expiry_interval, msg_properties, 0, mosq_mo_client)){ - mosquitto_property_free_all(&msg_properties); - return 1; + if(qos == 0 + || db__ready_for_flight(&context->msgs_in, qos) + || db__ready_for_queue(context, qos, &context->msgs_in)){ + + dup = 0; + if(db__message_store(db, context, mid, topic, qos, payloadlen, &payload, retain, &stored, message_expiry_interval, msg_properties, 0, mosq_mo_client)){ + mosquitto_property_free_all(&msg_properties); + return 1; + } + msg_properties = NULL; /* Now belongs to db__message_store() */ + }else{ + /* Client isn't allowed any more incoming messages, so fail early */ + reason_code = MQTT_RC_QUOTA_EXCEEDED; + goto process_bad_message; } - msg_properties = NULL; /* Now belongs to db__message_store() */ }else{ mosquitto__free(topic); topic = stored->topic; @@ -340,6 +349,7 @@ int handle__publish(struct mosquitto_db *db, struct mosquitto *context) } /* db__message_insert() returns 2 to indicate dropped message * due to queue. This isn't an error so don't disconnect them. */ + /* FIXME - this is no longer necessary due to failing early above */ if(!res){ if(send__pubrec(context, mid, 0)) rc = 1; }else if(res == 1){ diff --git a/src/mosquitto_broker_internal.h b/src/mosquitto_broker_internal.h index 1e0c42c6..ba42bafa 100644 --- a/src/mosquitto_broker_internal.h +++ b/src/mosquitto_broker_internal.h @@ -629,6 +629,8 @@ void db__msg_store_ref_dec(struct mosquitto_db *db, struct mosquitto_msg_store * void db__msg_store_clean(struct mosquitto_db *db); void db__msg_store_compact(struct mosquitto_db *db); int db__message_reconnect_reset(struct mosquitto_db *db, struct mosquitto *context); +bool db__ready_for_flight(struct mosquitto_msg_data *msgs, int qos); +bool db__ready_for_queue(struct mosquitto *context, int qos, struct mosquitto_msg_data *msg_data); void sys_tree__init(struct mosquitto_db *db); void sys_tree__update(struct mosquitto_db *db, int interval, time_t start_time); From 39ff7226eb675f66edf56c32a9249aa582278e01 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 19 Aug 2020 14:46:44 +0100 Subject: [PATCH 105/113] Bump version, add new www posts. --- CMakeLists.txt | 2 +- config.mk | 2 +- installer/mosquitto.nsi | 2 +- installer/mosquitto64.nsi | 2 +- lib/mosquitto.h | 2 +- set-version.sh | 2 +- snap/snapcraft.yaml | 2 +- www/pages/download.md | 8 ++--- www/posts/2020/08/version-1-6-12-released.md | 32 ++++++++++++++++++++ 9 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 www/posts/2020/08/version-1-6-12-released.md diff --git a/CMakeLists.txt b/CMakeLists.txt index 92604490..27c08c58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ project(mosquitto) cmake_minimum_required(VERSION 2.8) # Only for version 3 and up. cmake_policy(SET CMP0042 NEW) -set (VERSION 1.6.11) +set (VERSION 1.6.12) add_definitions (-DCMAKE -DVERSION=\"${VERSION}\") diff --git a/config.mk b/config.mk index 75c8b35f..80e02f96 100644 --- a/config.mk +++ b/config.mk @@ -109,7 +109,7 @@ WITH_COVERAGE:=no # Also bump lib/mosquitto.h, CMakeLists.txt, # installer/mosquitto.nsi, installer/mosquitto64.nsi -VERSION=1.6.11 +VERSION=1.6.12 # Client library SO version. Bump if incompatible API/ABI changes are made. SOVERSION=1 diff --git a/installer/mosquitto.nsi b/installer/mosquitto.nsi index 6cd04601..60ac9a26 100644 --- a/installer/mosquitto.nsi +++ b/installer/mosquitto.nsi @@ -9,7 +9,7 @@ !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' Name "Eclipse Mosquitto" -!define VERSION 1.6.11 +!define VERSION 1.6.12 OutFile "mosquitto-${VERSION}-install-windows-x86.exe" InstallDir "$PROGRAMFILES\mosquitto" diff --git a/installer/mosquitto64.nsi b/installer/mosquitto64.nsi index dc54654b..c303f7a4 100644 --- a/installer/mosquitto64.nsi +++ b/installer/mosquitto64.nsi @@ -9,7 +9,7 @@ !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' Name "Eclipse Mosquitto" -!define VERSION 1.6.11 +!define VERSION 1.6.12 OutFile "mosquitto-${VERSION}-install-windows-x64.exe" !include "x64.nsh" diff --git a/lib/mosquitto.h b/lib/mosquitto.h index 93793fa5..88abaead 100644 --- a/lib/mosquitto.h +++ b/lib/mosquitto.h @@ -48,7 +48,7 @@ extern "C" { #define LIBMOSQUITTO_MAJOR 1 #define LIBMOSQUITTO_MINOR 6 -#define LIBMOSQUITTO_REVISION 11 +#define LIBMOSQUITTO_REVISION 12 /* LIBMOSQUITTO_VERSION_NUMBER looks like 1002001 for e.g. version 1.2.1. */ #define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION) diff --git a/set-version.sh b/set-version.sh index c98f34bd..c27c55bb 100755 --- a/set-version.sh +++ b/set-version.sh @@ -2,7 +2,7 @@ MAJOR=1 MINOR=6 -REVISION=11 +REVISION=12 sed -i "s/^VERSION=.*/VERSION=${MAJOR}.${MINOR}.${REVISION}/" config.mk diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index a8ba134a..694a6c26 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,5 +1,5 @@ name: mosquitto -version: 1.6.11 +version: 1.6.12 summary: Eclipse Mosquitto MQTT broker description: This is a message broker that supports version 5.0, 3.1.1, and 3.1 of the MQTT protocol. diff --git a/www/pages/download.md b/www/pages/download.md index 2e805643..4619a7b4 100644 --- a/www/pages/download.md +++ b/www/pages/download.md @@ -1,7 +1,7 @@ + +Mosquitto 1.6.12 has been released, this is a bugfix release. + +# Security +- In some circumstances, Mosquitto could leak memory when handling PUBLISH + messages. This is limited to incoming QoS 2 messages, and is related + to the combination of the broker having persistence enabled, a clean + session=false client, which was connected prior to the broker restarting, + then has reconnected and has now sent messages at a sufficiently high rate + that the incoming queue at the broker has filled up and hence messages are + being dropped. This is more likely to have an effect where + `max_queued_messages` is a small value. This has now been fixed. Closes [#1793]. + +# Broker +- Build warning fixes when building with `WITH_BRIDGE=no` and `WITH_TLS=no`. + +# Clients +- All clients exit with an error exit code on CONNACK failure. Closes [#1778]. +- Don't busy loop with `mosquitto_pub -l` on a slow connection. + +[#1778]: https://github.com/eclipse/mosquitto/issues/1778 +[#1793]: https://github.com/eclipse/mosquitto/issues/1793 From 938e17a3d0cf9dc3f6eac24d9e0b07b92a51784d Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 24 Aug 2020 09:59:36 +0100 Subject: [PATCH 106/113] Fix incorrect authentication-method property type in mosquitto_sub man. Closes #1801. Thanks to roebotron. --- man/mosquitto_sub.1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/mosquitto_sub.1.xml b/man/mosquitto_sub.1.xml index 2e7e4bd6..0685a22a 100644 --- a/man/mosquitto_sub.1.xml +++ b/man/mosquitto_sub.1.xml @@ -846,7 +846,7 @@ mosquitto_sub -t 'bbc/#' -T bbc/bbc1 --remove-retained Connect (binary data - note treated as a string in mosquitto_sub) - (UTF-8 string pair) + (UTF-8 string) (32-bit unsigned integer) (16-bit unsigned integer) (8-bit unsigned integer) From 7804c3f0afbd93d91b5ffc8efd08f708ae723572 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 24 Aug 2020 17:05:35 +0100 Subject: [PATCH 107/113] Note that 1024 "limit" is from operating systems, not Mosquitto. --- mosquitto.conf | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mosquitto.conf b/mosquitto.conf index c12193fe..841d1da9 100644 --- a/mosquitto.conf +++ b/mosquitto.conf @@ -228,8 +228,10 @@ # a per listener setting. # Default is -1, which means unlimited connections. # Note that other process limits mean that unlimited connections -# are not really possible. Typically the default maximum number of -# connections possible is around 1024. +# are not really possible. Typically operating systems such as Linux set a +# default maximum number of connections possible at around 1024. If you require +# more connections than this, the operating system limit must be increased with +# something like `ulimit`. #max_connections -1 # Choose the protocol to use when listening. From 3806296c15e93f32bb2c558d32f6885ad863f000 Mon Sep 17 00:00:00 2001 From: "ignacy.ruksza" Date: Wed, 2 Sep 2020 16:26:50 +0200 Subject: [PATCH 108/113] Ld symbol of the mosquitto_property_copy_all has global bind now. Signed-off-by: ignacy.ruksza --- lib/linker.version | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/linker.version b/lib/linker.version index 017d5a5e..7ab3459e 100644 --- a/lib/linker.version +++ b/lib/linker.version @@ -109,6 +109,7 @@ MOSQ_1.6 { mosquitto_property_add_varint; mosquitto_property_check_all; mosquitto_property_check_command; + mosquitto_property_copy_all; mosquitto_property_free_all; mosquitto_property_read_binary; mosquitto_property_read_byte; From 298d84941ed673ea386c886bb9dda9b0ed18cc61 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Fri, 11 Sep 2020 13:34:03 +0100 Subject: [PATCH 109/113] Fix send quota being incorrecly reset on reconnect. Closes #1822. Thanks to Sarek. --- ChangeLog.txt | 3 +++ lib/handle_connack.c | 1 + 2 files changed, 4 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index c7dcb03f..839ae0c2 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,6 @@ +Client library: +- Fix send quota being incorrecly reset on reconnect. Closes #1822. + 1.6.12 - 2020-08-19 =================== diff --git a/lib/handle_connack.c b/lib/handle_connack.c index 81c74668..a4282722 100644 --- a/lib/handle_connack.c +++ b/lib/handle_connack.c @@ -103,6 +103,7 @@ int handle__connack(struct mosquitto *mosq) mosquitto_property_read_int32(properties, MQTT_PROP_MAXIMUM_PACKET_SIZE, &mosq->maximum_packet_size, false); mosq->msgs_out.inflight_quota = mosq->msgs_out.inflight_maximum; + message__reconnect_reset(mosq); connack_callback(mosq, reason_code, connect_flags, properties); mosquitto_property_free_all(&properties); From a53712a14d94167b39310e910291ae53e706f55b Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Fri, 11 Sep 2020 17:02:15 +0100 Subject: [PATCH 110/113] Don't use logging until log mutex is initialised. Closes #1819. Thanks to santoshks68. --- ChangeLog.txt | 1 + lib/mosquitto.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 839ae0c2..21bcd1d4 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,5 +1,6 @@ Client library: - Fix send quota being incorrecly reset on reconnect. Closes #1822. +- Don't use logging until log mutex is initialised. Closes #1819. 1.6.12 - 2020-08-19 =================== diff --git a/lib/mosquitto.c b/lib/mosquitto.c index 25a4441b..8d8b4b78 100644 --- a/lib/mosquitto.c +++ b/lib/mosquitto.c @@ -110,10 +110,6 @@ struct mosquitto *mosquitto_new(const char *id, bool clean_start, void *userdata mosq = (struct mosquitto *)mosquitto__calloc(1, sizeof(struct mosquitto)); if(mosq){ mosq->sock = INVALID_SOCKET; - if(net__socketpair(&mosq->sockpairR, &mosq->sockpairW)){ - log__printf(mosq, MOSQ_LOG_WARNING, - "Warning: Unable to open socket pair, outgoing publish commands may be delayed."); - } #ifdef WITH_THREADING mosq->thread_id = pthread_self(); #endif @@ -127,6 +123,10 @@ struct mosquitto *mosquitto_new(const char *id, bool clean_start, void *userdata } return NULL; } + if(net__socketpair(&mosq->sockpairR, &mosq->sockpairW)){ + log__printf(mosq, MOSQ_LOG_WARNING, + "Warning: Unable to open socket pair, outgoing publish commands may be delayed."); + } }else{ errno = ENOMEM; } From acf4ff37386871300503c9d70d2d8c6cb2b68c7d Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 14 Sep 2020 19:35:22 +0100 Subject: [PATCH 111/113] Fix stdin being closed by mistake This was closing the sockpair* sockets before they were initialised to INVALID_SOCKET. Close #1823. Thanks to ostkamp. --- lib/mosquitto.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/mosquitto.c b/lib/mosquitto.c index 8d8b4b78..80e3a765 100644 --- a/lib/mosquitto.c +++ b/lib/mosquitto.c @@ -113,6 +113,8 @@ struct mosquitto *mosquitto_new(const char *id, bool clean_start, void *userdata #ifdef WITH_THREADING mosq->thread_id = pthread_self(); #endif + mosq->sockpairR = INVALID_SOCKET; + mosq->sockpairW = INVALID_SOCKET; rc = mosquitto_reinitialise(mosq, id, clean_start, userdata); if(rc){ mosquitto_destroy(mosq); @@ -123,10 +125,6 @@ struct mosquitto *mosquitto_new(const char *id, bool clean_start, void *userdata } return NULL; } - if(net__socketpair(&mosq->sockpairR, &mosq->sockpairW)){ - log__printf(mosq, MOSQ_LOG_WARNING, - "Warning: Unable to open socket pair, outgoing publish commands may be delayed."); - } }else{ errno = ENOMEM; } From cec24116d8ddc71b0d1739128b471fd03210b649 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 15 Sep 2020 13:18:14 +0100 Subject: [PATCH 112/113] Add very basic client tests. --- test/Makefile | 2 ++ test/client/test.sh | 46 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100755 test/client/test.sh diff --git a/test/Makefile b/test/Makefile index 119d61e1..54b15eee 100644 --- a/test/Makefile +++ b/test/Makefile @@ -9,10 +9,12 @@ check : test test : utest $(MAKE) -C broker test $(MAKE) -C lib test + $(MAKE) -C client test ptest : utest $(MAKE) -C broker ptest $(MAKE) -C lib ptest + $(MAKE) -C client test utest : $(MAKE) -C unit test diff --git a/test/client/test.sh b/test/client/test.sh new file mode 100755 index 00000000..a5229455 --- /dev/null +++ b/test/client/test.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# Very basic client testing. + + +set -e + +export LD_LIBRARY_PATH=../lib +export PORT=1888 +export SUB_TIMEOUT=1 + +# Start broker +../src/mosquitto -p ${PORT} 2>/dev/null & +export MOSQ_PID=$! +sleep 0.5 + +# Kill broker on exit +trap "kill $MOSQ_PID" EXIT + + +# Simple subscribe test - single message from $SYS +./mosquitto_sub -p ${PORT} -W ${SUB_TIMEOUT} -C 1 -t '$SYS/broker/uptime' >/dev/null +echo "Simple subscribe ok" + +# Simple publish/subscribe test - single message from mosquitto_pub +./mosquitto_sub -p ${PORT} -W ${SUB_TIMEOUT} -C 1 -t 'single/test' >/dev/null & +export SUB_PID=$! +./mosquitto_pub -p ${PORT} -t 'single/test' -m 'single-test' +kill ${SUB_PID} 2>/dev/null || true +echo "Simple publish/subscribe ok" + +# Publish a file and subscribe, do we get at least that many lines? +export TEST_LINES=$(wc -l test.sh | cut -d' ' -f1) +./mosquitto_sub -p ${PORT} -W ${SUB_TIMEOUT} -C ${TEST_LINES} -t 'file-publish' >/dev/null & +export SUB_PID=$! +./mosquitto_pub -p ${PORT} -t 'file-publish' -f ./test.sh +kill ${SUB_PID} 2>/dev/null || true +echo "File publish ok" + +# Publish a file from stdin and subscribe, do we get at least that many lines? +export TEST_LINES=$(wc -l test.sh | cut -d' ' -f1) +./mosquitto_sub -p ${PORT} -W ${SUB_TIMEOUT} -C ${TEST_LINES} -t 'file-publish' >/dev/null & +export SUB_PID=$! +./mosquitto_pub -p ${PORT} -t 'file-publish' -l < ./test.sh +kill ${SUB_PID} 2>/dev/null || true +echo "stdin publish ok" From 27745154567bbf16c4e10a89413f298407f9ea6f Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 22 Sep 2020 15:08:48 +0100 Subject: [PATCH 113/113] Fix missing mach/mach_time.h header on OS X. Closes #1831. Thanks to P-Hagen. --- ChangeLog.txt | 1 + lib/mosquitto.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/ChangeLog.txt b/ChangeLog.txt index 21bcd1d4..ded3a8e2 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,6 +1,7 @@ Client library: - Fix send quota being incorrecly reset on reconnect. Closes #1822. - Don't use logging until log mutex is initialised. Closes #1819. +- Fix missing mach/mach_time.h header on OS X. Closes #1831. 1.6.12 - 2020-08-19 =================== diff --git a/lib/mosquitto.c b/lib/mosquitto.c index 80e3a765..6cd13f31 100644 --- a/lib/mosquitto.c +++ b/lib/mosquitto.c @@ -24,6 +24,10 @@ Contributors: #include #endif +#if defined(__APPLE__) +# include +#endif + #include "logging_mosq.h" #include "mosquitto.h" #include "mosquitto_internal.h"