diff --git a/CMakeLists.txt b/CMakeLists.txt
index d9a86362bd..265c106d9c 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.5.3)
+set (VERSION 1.5.5)
add_definitions (-DCMAKE -DVERSION=\"${VERSION}\")
@@ -73,6 +73,30 @@ endif (${WITH_SOCKS} STREQUAL ON)
option(WITH_SRV "Include SRV lookup support?" OFF)
+option(WITH_THREADING "Include client library threading support?" ON)
+if (${WITH_THREADING} STREQUAL ON)
+ add_definitions("-DWITH_THREADING")
+ if (WIN32)
+ if (CMAKE_CL_64)
+ set (PTHREAD_LIBRARIES C:\\pthreads\\Pre-built.2\\lib\\x64\\pthreadVC2.lib)
+ else (CMAKE_CL_64)
+ set (PTHREAD_LIBRARIES C:\\pthreads\\Pre-built.2\\lib\\x86\\pthreadVC2.lib)
+ endif (CMAKE_CL_64)
+ set (PTHREAD_INCLUDE_DIR C:\\pthreads\\Pre-built.2\\include)
+ else (WIN32)
+ find_library(LIBPTHREAD pthread)
+ if (LIBPTHREAD)
+ set (PTHREAD_LIBRARIES pthread)
+ else (LIBPTHREAD)
+ set (PTHREAD_LIBRARIES "")
+ endif()
+ set (PTHREAD_INCLUDE_DIR "")
+ endif (WIN32)
+else (${WITH_THREADING} STREQUAL ON)
+ set (PTHREAD_LIBRARIES "")
+ set (PTHREAD_INCLUDE_DIR "")
+endif (${WITH_THREADING} STREQUAL ON)
+
option(DOCUMENTATION "Build documentation?" ON)
# ========================================
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 27be9d4632..7b83dd4953 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -18,6 +18,78 @@ Client features:
session without requiring a message to be received.
+1.5.5 - 20181211
+================
+
+Security:
+- If `per_listener_settings` is set to true, then the `acl_file` setting was
+ ignored for the "default listener" only. This has been fixed. This does not
+ affect any listeners defined with the `listener` option. Closes #1073.
+
+Broker:
+- Add `socket_domain` option to allow listeners to disable IPv6 support.
+ This is required to work around a problem in libwebsockets that means
+ sockets only listen on IPv6 by default if IPv6 support is compiled in.
+ Closes #1004.
+- When using ADNS, don't ask for all network protocols when connecting,
+ because this can lead to confusing "Protocol not supported" errors if the
+ network is down. Closes #1062.
+- Fix outgoing retained messages not being sent by bridges on initial
+ connection. Closes #1040.
+- Don't reload auth_opt_ options on reload, to match the behaviour of the
+ other plugin options. Closes #1068.
+- Print message on error when installing/uninstalling as a Windows service.
+- All non-error connect/disconnect messages are controlled by the
+ `connection_messages` option. Closes #772. Closes #613. Closes #537.
+
+Library:
+- Fix reconnect delay backoff behaviour. Closes #1027.
+- Don't call on_disconnect() twice if keepalive tests fail. Closes #1067.
+
+Client:
+- Always print leading zeros in mosquitto_sub when output format is hex.
+ Closes #1066.
+
+Build:
+- Fix building where TLS-PSK is not available. Closes #68.
+
+
+1.5.4 - 20181108
+================
+
+Security:
+- When using a TLS enabled websockets listener with "require_certificate"
+ enabled, the mosquitto broker does not correctly verify client certificates.
+ This is now fixed. All other security measures operate as expected, and in
+ particular non-websockets listeners are not affected by this. Closes #996.
+
+Broker:
+- Process all pending messages even when a client has disconnected. This means
+ a client that send a PUBLISH then DISCONNECT quickly, then disconnects will
+ have its DISCONNECT message processed properly and so no Will will be sent.
+ Closes #7.
+- $SYS/broker/clients/disconnected should never be negative. Closes #287.
+- Give better error message if a client sends a password without a username.
+ Closes #1015.
+- Fix bridge not honoring restart_timeout. Closes #1019.
+- Don't disconnect a client if an auth plugin denies access to SUBSCRIBE.
+ Closes #1016.
+
+Library:
+- Fix memory leak that occurred if mosquitto_reconnect() was used when TLS
+ errors were present. Closes #592.
+- Fix TLS connections when using an external event loop with
+ mosquitto_loop_read() and mosquitto_write(). Closes #990.
+
+Build:
+- Fix clients not being compiled with threading support when using CMake.
+ Closes #983.
+- Header fixes for FreeBSD. Closes #977.
+- Use _GNU_SOURCE to fix build errors in websockets and getaddrinfo usage.
+ Closes #862 and #933.
+- Fix builds on QNX 7.0.0. Closes #1018.
+
+
1.5.3 - 20180925
================
@@ -36,6 +108,8 @@ Broker:
removed. Closes #645.
- Fix Windows version not starting if include_dir did not contain any files.
Closes #566.
+- When an authentication plugin denied access to a SUBSCRIBE, the client would
+ be disconnected incorrectly. This has been fixed. Closes #1016.
Build:
- Various fixes to ease building.
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index d53772ed71..85b0eb631a 100644
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -1,5 +1,5 @@
include_directories(${mosquitto_SOURCE_DIR} ${mosquitto_SOURCE_DIR}/lib
- ${STDBOOL_H_PATH} ${STDINT_H_PATH})
+ ${STDBOOL_H_PATH} ${STDINT_H_PATH} ${PTHREAD_INCLUDE_DIR})
link_directories(${mosquitto_BINARY_DIR}/lib)
set(shared_src client_shared.c client_shared.h client_props.c)
@@ -11,8 +11,14 @@ endif (${WITH_SRV} STREQUAL ON)
add_executable(mosquitto_pub pub_client.c pub_shared.c ${shared_src})
add_executable(mosquitto_sub sub_client.c sub_client_output.c ${shared_src})
+
target_link_libraries(mosquitto_pub libmosquitto)
target_link_libraries(mosquitto_sub libmosquitto)
+if (QNX)
+ target_link_libraries(mosquitto_pub socket)
+ target_link_libraries(mosquitto_sub socket)
+endif()
+
install(TARGETS mosquitto_pub RUNTIME DESTINATION "${BINDIR}" LIBRARY DESTINATION "${LIBDIR}")
install(TARGETS mosquitto_sub RUNTIME DESTINATION "${BINDIR}" LIBRARY DESTINATION "${LIBDIR}")
diff --git a/client/Makefile b/client/Makefile
index 39310b973f..7bc7cc8a5e 100644
--- a/client/Makefile
+++ b/client/Makefile
@@ -2,7 +2,19 @@ include ../config.mk
.PHONY: all install uninstall reallyclean clean static static_pub static_sub
-all : mosquitto_pub mosquitto_sub
+ifeq ($(WITH_SHARED_LIBRARIES),yes)
+SHARED_DEP:=../lib/libmosquitto.so.${SOVERSION}
+endif
+
+ifeq ($(WITH_SHARED_LIBRARIES),yes)
+ALL_DEPS:= mosquitto_pub mosquitto_sub
+else
+ifeq ($(WITH_STATIC_LIBRARIES),yes)
+ALL_DEPS:= static_pub static_sub
+endif
+endif
+
+all : ${ALL_DEPS}
static : static_pub static_sub
# This makes mosquitto_pub/sub versions that are statically linked with
@@ -20,16 +32,16 @@ mosquitto_pub : pub_client.o pub_shared.o client_shared.o client_props.o
mosquitto_sub : sub_client.o sub_client_output.o client_shared.o client_props.o
${CROSS_COMPILE}${CC} $^ -o $@ ${CLIENT_LDFLAGS}
-pub_client.o : pub_client.c ../lib/libmosquitto.so.${SOVERSION}
+pub_client.o : pub_client.c ${SHARED_DEP}
${CROSS_COMPILE}${CC} -c $< -o $@ ${CLIENT_CFLAGS}
-pub_shared.o : pub_shared.c ../lib/libmosquitto.so.${SOVERSION}
+pub_shared.o : pub_shared.c ${SHARED_DEP}
${CROSS_COMPILE}${CC} -c $< -o $@ ${CLIENT_CFLAGS}
-sub_client.o : sub_client.c ../lib/libmosquitto.so.${SOVERSION}
+sub_client.o : sub_client.c ${SHARED_DEP}
${CROSS_COMPILE}${CC} -c $< -o $@ ${CLIENT_CFLAGS}
-sub_client_output.o : sub_client_output.c ../lib/libmosquitto.so.${SOVERSION}
+sub_client_output.o : sub_client_output.c ${SHARED_DEP}
${CROSS_COMPILE}${CC} -c $< -o $@ ${CLIENT_CFLAGS}
client_shared.o : client_shared.c client_shared.h
diff --git a/client/client_shared.c b/client/client_shared.c
index b37d3067d4..517a6a6f78 100644
--- a/client/client_shared.c
+++ b/client/client_shared.c
@@ -152,7 +152,7 @@ void client_config_cleanup(struct mosq_config *cfg)
free(cfg->keyfile);
free(cfg->ciphers);
free(cfg->tls_version);
-# ifdef WITH_TLS_PSK
+# ifdef FINAL_WITH_TLS_PSK
free(cfg->psk);
free(cfg->psk_identity);
# endif
@@ -316,7 +316,7 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char *
return 1;
}
#endif
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
if((cfg->cafile || cfg->capath) && cfg->psk){
if(!cfg->quiet) fprintf(stderr, "Error: Only one of --psk or --cafile/--capath may be used at once.\n");
return 1;
@@ -734,7 +734,7 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c
i++;
}
#endif
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
}else if(!strcmp(argv[i], "--psk")){
if(i==argc-1){
fprintf(stderr, "Error: --psk argument given but no key specified.\n\n");
@@ -977,7 +977,7 @@ int client_opts_set(struct mosquitto *mosq, struct mosq_config *cfg)
mosquitto_lib_cleanup();
return 1;
}
-# ifdef WITH_TLS_PSK
+# ifdef FINAL_WITH_TLS_PSK
if(cfg->psk && mosquitto_tls_psk_set(mosq, cfg->psk, cfg->psk_identity, NULL)){
if(!cfg->quiet) fprintf(stderr, "Error: Problem setting TLS-PSK options.\n");
mosquitto_lib_cleanup();
@@ -1038,14 +1038,18 @@ int client_id_generate(struct mosq_config *cfg, const char *id_base)
int client_connect(struct mosquitto *mosq, struct mosq_config *cfg)
{
+#ifndef WIN32
+ char *err;
+#else
char err[1024];
+#endif
int rc;
int port;
if(cfg->port < 0){
#ifdef WITH_TLS
if(cfg->cafile || cfg->capath
-# ifdef WITH_TLS_PSK
+# ifdef FINAL_WITH_TLS_PSK
|| cfg->psk
# endif
){
@@ -1072,7 +1076,7 @@ int client_connect(struct mosquitto *mosq, struct mosq_config *cfg)
if(!cfg->quiet){
if(rc == MOSQ_ERR_ERRNO){
#ifndef WIN32
- strerror_r(errno, err, 1024);
+ err = strerror(errno);
#else
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errno, 0, (LPTSTR)&err, 1024, NULL);
#endif
diff --git a/client/client_shared.h b/client/client_shared.h
index 1a8ad2800e..554f19e227 100644
--- a/client/client_shared.h
+++ b/client/client_shared.h
@@ -66,7 +66,7 @@ struct mosq_config {
char *ciphers;
bool insecure;
char *tls_version;
-# ifdef WITH_TLS_PSK
+# ifdef FINAL_WITH_TLS_PSK
char *psk;
char *psk_identity;
# endif
diff --git a/client/pub_client.c b/client/pub_client.c
index bede0032fc..4c9c75d558 100644
--- a/client/pub_client.c
+++ b/client/pub_client.c
@@ -123,7 +123,7 @@ void print_usage(void)
#ifdef WITH_TLS
printf(" [{--cafile file | --capath dir} [--cert file] [--key file]\n");
printf(" [--ciphers ciphers] [--insecure]]\n");
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
#endif
#endif
@@ -183,7 +183,7 @@ void print_usage(void)
printf(" hostname. Using this option means that you cannot be sure that the\n");
printf(" remote host is the server you wish to connect to and so is insecure.\n");
printf(" Do not use this option in a production environment.\n");
-# ifdef WITH_TLS_PSK
+# ifdef FINAL_WITH_TLS_PSK
printf(" --psk : pre-shared-key in hexadecimal (no leading 0x) to enable TLS-PSK mode.\n");
printf(" --psk-identity : client identity string for TLS-PSK mode.\n");
# endif
diff --git a/client/sub_client.c b/client/sub_client.c
index 62d91ca757..6cbf76f903 100644
--- a/client/sub_client.c
+++ b/client/sub_client.c
@@ -152,7 +152,7 @@ void print_usage(void)
#ifdef WITH_TLS
printf(" [{--cafile file | --capath dir} [--cert file] [--key file]\n");
printf(" [--ciphers ciphers] [--insecure]]\n");
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
#endif
#endif
@@ -218,7 +218,7 @@ void print_usage(void)
printf(" hostname. Using this option means that you cannot be sure that the\n");
printf(" remote host is the server you wish to connect to and so is insecure.\n");
printf(" Do not use this option in a production environment.\n");
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
printf(" --psk : pre-shared-key in hexadecimal (no leading 0x) to enable TLS-PSK mode.\n");
printf(" --psk-identity : client identity string for TLS-PSK mode.\n");
#endif
diff --git a/client/sub_client_output.c b/client/sub_client_output.c
index ab3f5e963a..4aeb8c3966 100644
--- a/client/sub_client_output.c
+++ b/client/sub_client_output.c
@@ -85,11 +85,11 @@ static void write_payload(const unsigned char *payload, int payloadlen, int hex)
(void)fwrite(payload, 1, payloadlen, stdout);
}else if(hex == 1){
for(i=0; i
+# if defined(WITH_TLS_PSK) && !defined(OPENSSL_NO_PSK)
+# define FINAL_WITH_TLS_PSK
+# endif
+#endif
+
#endif
diff --git a/config.mk b/config.mk
index f7a030dbc4..74844c114d 100644
--- a/config.mk
+++ b/config.mk
@@ -82,6 +82,9 @@ WITH_STRIP:=no
# Build static libraries
WITH_STATIC_LIBRARIES:=no
+# Build shared libraries
+WITH_SHARED_LIBRARIES:=yes
+
# Build with async dns lookup support for bridges (temporary). Requires glibc.
#WITH_ADNS:=yes
@@ -101,7 +104,7 @@ WITH_COVERAGE:=no
# Also bump lib/mosquitto.h, CMakeLists.txt,
# installer/mosquitto.nsi, installer/mosquitto64.nsi
-VERSION=1.5.3
+VERSION=1.5.5
# Client library SO version. Bump if incompatible API/ABI changes are made.
SOVERSION=1
@@ -146,7 +149,10 @@ ifeq ($(UNAME),Linux)
LIB_LIBS:=$(LIB_LIBS) -lrt
endif
-CLIENT_LDFLAGS:=$(LDFLAGS) -L../lib ../lib/libmosquitto.so.${SOVERSION}
+CLIENT_LDFLAGS:=$(LDFLAGS) -L../lib
+ifeq ($(WITH_SHARED_LIBRARIES),yes)
+ CLIENT_LDFLAGS:=${CLIENT_LDFLAGS} ../lib/libmosquitto.so.${SOVERSION}
+endif
ifeq ($(UNAME),SunOS)
ifeq ($(CC),cc)
diff --git a/docker/1.4.10/Dockerfile b/docker/1.4.10/Dockerfile
deleted file mode 100644
index 3101650b9f..0000000000
--- a/docker/1.4.10/Dockerfile
+++ /dev/null
@@ -1,13 +0,0 @@
-FROM alpine:3.5
-MAINTAINER David Audet
-
-LABEL Description="Eclipse Mosquitto MQTT Broker"
-
-RUN apk --no-cache add mosquitto=1.4.10-r2 && \
- mkdir -p /mosquitto/config /mosquitto/data /mosquitto/log && \
- cp /etc/mosquitto/mosquitto.conf /mosquitto/config && \
- chown -R mosquitto:mosquitto /mosquitto
-
-COPY docker-entrypoint.sh /
-ENTRYPOINT ["/docker-entrypoint.sh"]
-CMD ["/usr/sbin/mosquitto", "-c", "/mosquitto/config/mosquitto.conf"]
diff --git a/docker/1.4.10/README.md b/docker/1.4.10/README.md
deleted file mode 100644
index 98bb150dfe..0000000000
--- a/docker/1.4.10/README.md
+++ /dev/null
@@ -1,49 +0,0 @@
-#Eclipse Mosquitto v1.4.10 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 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto:1.4.10
-```
-
-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.10 .
-```
-
-##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.10
-```
-: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.10/docker-entrypoint.sh b/docker/1.4.10/docker-entrypoint.sh
deleted file mode 100755
index 1a9fc8d05f..0000000000
--- a/docker/1.4.10/docker-entrypoint.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/ash
-
-set -e
-exec "$@"
-
diff --git a/docker/1.4.14/Dockerfile b/docker/1.4.14/Dockerfile
deleted file mode 100644
index 359cde1b48..0000000000
--- a/docker/1.4.14/Dockerfile
+++ /dev/null
@@ -1,13 +0,0 @@
-FROM alpine:edge
-MAINTAINER David Audet
-
-LABEL Description="Eclipse Mosquitto MQTT Broker"
-
-RUN apk --no-cache add mosquitto=1.4.14-r0 && \
- mkdir -p /mosquitto/config /mosquitto/data /mosquitto/log && \
- cp /etc/mosquitto/mosquitto.conf /mosquitto/config && \
- chown -R mosquitto:mosquitto /mosquitto
-
-COPY docker-entrypoint.sh /
-ENTRYPOINT ["/docker-entrypoint.sh"]
-CMD ["/usr/sbin/mosquitto", "-c", "/mosquitto/config/mosquitto.conf"]
diff --git a/docker/1.4.4/Dockerfile b/docker/1.4.4/Dockerfile
deleted file mode 100644
index bd757e3b4a..0000000000
--- a/docker/1.4.4/Dockerfile
+++ /dev/null
@@ -1,13 +0,0 @@
-FROM alpine:3.3
-MAINTAINER David Audet
-
-LABEL Description="Eclipse Mosquitto MQTT Broker"
-
-RUN apk --no-cache add mosquitto=1.4.4-r0 && \
- mkdir -p /mosquitto/config /mosquitto/data /mosquitto/log && \
- cp /etc/mosquitto/mosquitto.conf /mosquitto/config && \
- chown -R mosquitto:mosquitto /mosquitto
-
-COPY docker-entrypoint.sh /
-ENTRYPOINT ["/docker-entrypoint.sh"]
-CMD ["/usr/sbin/mosquitto", "-c", "/mosquitto/config/mosquitto.conf"]
diff --git a/docker/1.4.4/README.md b/docker/1.4.4/README.md
deleted file mode 100644
index 4f01fee9ed..0000000000
--- a/docker/1.4.4/README.md
+++ /dev/null
@@ -1,49 +0,0 @@
-#Eclipse Mosquitto v1.4.4 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 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto:1.4.4
-```
-
-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.4 .
-```
-
-##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.4
-```
-: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.
\ No newline at end of file
diff --git a/docker/1.4.8/Dockerfile b/docker/1.4.8/Dockerfile
deleted file mode 100644
index a9027a7895..0000000000
--- a/docker/1.4.8/Dockerfile
+++ /dev/null
@@ -1,13 +0,0 @@
-FROM alpine:3.4
-MAINTAINER David Audet
-
-LABEL Description="Eclipse Mosquitto MQTT Broker"
-
-RUN apk --no-cache add mosquitto=1.4.8-r2 && \
- mkdir -p /mosquitto/config /mosquitto/data /mosquitto/log && \
- cp /etc/mosquitto/mosquitto.conf /mosquitto/config && \
- chown -R mosquitto:mosquitto /mosquitto
-
-COPY docker-entrypoint.sh /
-ENTRYPOINT ["/docker-entrypoint.sh"]
-CMD ["/usr/sbin/mosquitto", "-c", "/mosquitto/config/mosquitto.conf"]
diff --git a/docker/1.4.8/README.md b/docker/1.4.8/README.md
deleted file mode 100644
index d78f517fb2..0000000000
--- a/docker/1.4.8/README.md
+++ /dev/null
@@ -1,49 +0,0 @@
-#Eclipse Mosquitto v1.4.8 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 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto:1.4.8
-```
-
-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.8 .
-```
-
-##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.8
-```
-: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.8/docker-entrypoint.sh b/docker/1.4.8/docker-entrypoint.sh
deleted file mode 100755
index 1a9fc8d05f..0000000000
--- a/docker/1.4.8/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
new file mode 100644
index 0000000000..2c9b15c67f
--- /dev/null
+++ b/docker/1.5/Dockerfile
@@ -0,0 +1,88 @@
+FROM alpine:3.8
+
+LABEL maintainer="Roger Light " \
+ description="Eclipse Mosquitto MQTT Broker"
+
+ENV VERSION=1.5.5 \
+ DOWNLOAD_SHA256=fcdb47e340864c545146681af7253399cc292e41775afd76400fda5b0d23d668 \
+ GPG_KEYS=A0D6EEA1DCAE49A635A3B2F0779B22DFB3E717B7 \
+ LWS_VERSION=2.4.2
+
+RUN set -x && \
+ apk --no-cache add --virtual build-deps \
+ build-base \
+ cmake \
+ gnupg \
+ 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 && \
+ 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_MEMORY_TRACKING=no \
+ WITH_SHARED_LIBRARIES=no \
+ WITH_SRV=no \
+ WITH_STRIP=yes \
+ WITH_TLS_PSK=no \
+ 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/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 \
+ 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 /
+ENTRYPOINT ["/docker-entrypoint.sh"]
+CMD ["/usr/sbin/mosquitto", "-c", "/mosquitto/config/mosquitto.conf"]
diff --git a/docker/1.5/README.md b/docker/1.5/README.md
new file mode 100644
index 0000000000..27b05904c9
--- /dev/null
+++ b/docker/1.5/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 mosqutto 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 9001:9001 -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.4.14/docker-entrypoint.sh b/docker/1.5/docker-entrypoint.sh
similarity index 96%
rename from docker/1.4.14/docker-entrypoint.sh
rename to docker/1.5/docker-entrypoint.sh
index 1a9fc8d05f..b381ac5775 100755
--- a/docker/1.4.14/docker-entrypoint.sh
+++ b/docker/1.5/docker-entrypoint.sh
@@ -1,5 +1,4 @@
#!/bin/ash
-
set -e
-exec "$@"
+exec "$@"
diff --git a/docker/README.md b/docker/README.md
index 6fe5506c99..06db82b1f1 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -1,4 +1,19 @@
# Docker Images
-This directory contains the required files to build Mosquitto Docker images.
+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:
+
+```
+cd generic
+docker build -t eclipse-mosquitto:1.5.1 --build-arg VERSION="1.5.1" .
+docker run --rm -it eclipse-mosquitto:1.5.1
+```
diff --git a/docker/generic/Dockerfile b/docker/generic/Dockerfile
new file mode 100644
index 0000000000..51c1d18154
--- /dev/null
+++ b/docker/generic/Dockerfile
@@ -0,0 +1,70 @@
+FROM alpine:latest AS build
+
+# A released dist version, like "1.2.3"
+ARG VERSION
+RUN test -n "${VERSION}"
+
+RUN apk --no-cache add \
+ build-base \
+ libressl-dev \
+ c-ares-dev \
+ curl \
+ util-linux-dev \
+ libwebsockets-dev \
+ libxslt \
+ python2
+
+# This build procedure is based on:
+# https://github.com/alpinelinux/aports/blob/master/main/mosquitto/APKBUILD
+#
+# If this step fails, double check the version build-arg and make sure its
+# a valid published tarball at https://mosquitto.org/files/source/
+RUN mkdir -p /build /install && \
+ curl -SL https://mosquitto.org/files/source/mosquitto-${VERSION}.tar.gz \
+ | tar --strip=1 -xzC /build && \
+ make -C /build \
+ WITH_MEMORY_TRACKING=no \
+ WITH_WEBSOCKETS=yes \
+ WITH_SRV=yes \
+ WITH_TLS_PSK=no \
+ WITH_ADNS=no \
+ prefix=/usr \
+ binary && \
+ make -C /build \
+ prefix=/usr \
+ DESTDIR="/install" \
+ install && \
+ mv /install/etc/mosquitto/mosquitto.conf.example /install/etc/mosquitto/mosquitto.conf && \
+ sed -i -e 's/#log_dest stderr/log_dest syslog/' /install/etc/mosquitto/mosquitto.conf
+
+
+# Single-layer image for the mosquitto distribution
+FROM alpine:latest
+LABEL maintainer="Jonathan Hanson " \
+ description="Eclipse Mosquitto MQTT Broker"
+
+# Install the run-time dependencies
+RUN apk --no-cache add \
+ busybox \
+ libcrypto1.0 \
+ libssl1.0 \
+ libuuid \
+ libwebsockets \
+ musl
+
+# Copy over the built install from the earlier image layer
+COPY --from=build /install /
+
+# Set up the mosquitto directories and the mosquitto user
+RUN addgroup -S mosquitto 2>/dev/null && \
+ adduser -S -D -H -h /var/empty -s /sbin/nologin -G mosquitto -g mosquitto mosquitto 2>/dev/null && \
+ mkdir -p /mosquitto/config /mosquitto/data /mosquitto/log && \
+ cp /etc/mosquitto/mosquitto.conf /mosquitto/config && \
+ chown -R mosquitto:mosquitto /mosquitto
+
+VOLUME ["/mosquitto/config", "/mosquitto/data", "/mosquitto/log"]
+
+# Set up the entry point script and default command
+COPY docker-entrypoint.sh /
+ENTRYPOINT ["/docker-entrypoint.sh"]
+CMD ["/usr/sbin/mosquitto", "-c", "/mosquitto/config/mosquitto.conf"]
diff --git a/docker/1.4.14/README.md b/docker/generic/README.md
similarity index 51%
rename from docker/1.4.14/README.md
rename to docker/generic/README.md
index 206f8d3139..421cb91d90 100644
--- a/docker/1.4.14/README.md
+++ b/docker/generic/README.md
@@ -1,21 +1,19 @@
-#Eclipse Mosquitto v1.4.14 Docker Image
+# Eclipse Mosquitto Docker Image
+Containers built with this Dockerfile build as source from published tarballs.
-##Mount Points
-
-Three mount points have been created in the image to be used for configuration, persistent storage and logs.
+## Mount Points
+Three docker volumes 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.
+## 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:1.4.14
+docker run -it -p 1883:1883 -p 9001:9001 -v :/mosquitto/config/mosquitto.conf eclipse-mosquitto:
```
Configuration can be changed to:
@@ -31,18 +29,18 @@ persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
```
-**Note**: If a volume is used, the data will persist between containers.
+**Note**: For any volume used, the data will be persistent between containers.
-##Build
-Build the image:
+## Build
+Build and tag the docker image for a specific version:
```
-docker build -t eclipse-mosquitto:1.4.14 .
+docker build -t eclipse-mosquitto: --build-arg VERSION="" .
```
-##Run
+## 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.14
+docker run -it -p 1883:1883 -p 9001:9001 -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/1.4.4/docker-entrypoint.sh b/docker/generic/docker-entrypoint.sh
similarity index 96%
rename from docker/1.4.4/docker-entrypoint.sh
rename to docker/generic/docker-entrypoint.sh
index 1a9fc8d05f..b381ac5775 100755
--- a/docker/1.4.4/docker-entrypoint.sh
+++ b/docker/generic/docker-entrypoint.sh
@@ -1,5 +1,4 @@
#!/bin/ash
-
set -e
-exec "$@"
+exec "$@"
diff --git a/installer/mosquitto.nsi b/installer/mosquitto.nsi
index b97f6f3a33..0574e0b10e 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.5.3
+!define VERSION 1.5.5
OutFile "mosquitto-${VERSION}-install-windows-x86.exe"
InstallDir "$PROGRAMFILES\mosquitto"
@@ -18,8 +18,7 @@ InstallDir "$PROGRAMFILES\mosquitto"
; Installer pages
!insertmacro MUI_PAGE_WELCOME
-Page custom DependencyPage
-!insertmacro MUI_PAGE_COMPONENTS
+;!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
@@ -55,8 +54,8 @@ Section "Files" SecInstall
File "..\readme.md"
File "..\readme-windows.txt"
;File "C:\pthreads\Pre-built.2\dll\x86\pthreadVC2.dll"
- ;File "C:\OpenSSL-Win32\bin\libssl_1-1.dll"
- ;File "C:\OpenSSL-Win32\bin\libcrypto_1-1.dll"
+ File "C:\OpenSSL-Win32\bin\libssl-1_1.dll"
+ File "C:\OpenSSL-Win32\bin\libcrypto-1_1.dll"
File "..\edl-v10"
File "..\epl-v10"
@@ -96,8 +95,8 @@ Section "Uninstall"
Delete "$INSTDIR\readme.txt"
Delete "$INSTDIR\readme-windows.txt"
;Delete "$INSTDIR\pthreadVC2.dll"
- ;Delete "$INSTDIR\libssl_1-1.dll"
- ;Delete "$INSTDIR\libcrypto_1-1.dll"
+ Delete "$INSTDIR\libssl-1_1.dll"
+ Delete "$INSTDIR\libcrypto-1_1.dll"
Delete "$INSTDIR\edl-v10"
Delete "$INSTDIR\epl-v10"
@@ -120,28 +119,3 @@ LangString DESC_SecInstall ${LANG_ENGLISH} "The main installation."
!insertmacro MUI_DESCRIPTION_TEXT ${SecInstall} $(DESC_SecInstall)
!insertmacro MUI_FUNCTION_DESCRIPTION_END
-Var Dialog
-Var OSSLLink
-Var PTHLink
-
-Function DependencyPage
- nsDialogs::Create 1018
- Pop $Dialog
-
- ${If} $Dialog == error
- Abort
- ${EndIf}
-
- ${NSD_CreateLabel} 0 0 100% 12u "OpenSSL - install 'Win32 OpenSSL v1.1.0* Light' then copy libssl_1-1.dll and libcrypto_1-1.dll to the mosquitto directory"
- ${NSD_CreateLink} 13u 13u 100% 12u "http://slproweb.com/products/Win32OpenSSL.html"
- Pop $OSSLLink
- ${NSD_OnClick} $OSSLLink OnClick_OSSL
-
- !insertmacro MUI_HEADER_TEXT_PAGE "Dependencies" "This page lists packages that must be installed if not already present"
- nsDialogs::Show
-FunctionEnd
-
-Function OnClick_OSSL
- Pop $0
- ExecShell "open" "http://slproweb.com/products/Win32OpenSSL.html"
-FunctionEnd
diff --git a/installer/mosquitto64.nsi b/installer/mosquitto64.nsi
index 59acea1a10..5e9706c4b5 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.5.3
+!define VERSION 1.5.5
OutFile "mosquitto-${VERSION}-install-windows-x64.exe"
!include "x64.nsh"
@@ -19,8 +19,7 @@ InstallDir "$PROGRAMFILES64\mosquitto"
; Installer pages
!insertmacro MUI_PAGE_WELCOME
-Page custom DependencyPage
-!insertmacro MUI_PAGE_COMPONENTS
+;!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
@@ -56,8 +55,8 @@ Section "Files" SecInstall
File "..\readme.md"
File "..\readme-windows.txt"
;File "C:\pthreads\Pre-built.2\dll\x64\pthreadVC2.dll"
- ;File "C:\OpenSSL-Win64\bin\libssl_1-1-x64.dll"
- ;File "C:\OpenSSL-Win64\bin\libcrypto_1-1-x64.dll"
+ File "C:\OpenSSL-Win64\bin\libssl-1_1-x64.dll"
+ File "C:\OpenSSL-Win64\bin\libcrypto-1_1-x64.dll"
File "..\edl-v10"
File "..\epl-v10"
@@ -97,8 +96,8 @@ Section "Uninstall"
Delete "$INSTDIR\readme.txt"
Delete "$INSTDIR\readme-windows.txt"
;Delete "$INSTDIR\pthreadVC2.dll"
- ;Delete "$INSTDIR\libssl_1-1-x64.dll"
- ;Delete "$INSTDIR\libcrypto_1-1-x64.dll"
+ Delete "$INSTDIR\libssl-1_1-x64.dll"
+ Delete "$INSTDIR\libcrypto-1_1-x64.dll"
Delete "$INSTDIR\edl-v10"
Delete "$INSTDIR\epl-v10"
@@ -121,28 +120,3 @@ LangString DESC_SecInstall ${LANG_ENGLISH} "The main installation."
!insertmacro MUI_DESCRIPTION_TEXT ${SecInstall} $(DESC_SecInstall)
!insertmacro MUI_FUNCTION_DESCRIPTION_END
-Var Dialog
-Var OSSLLink
-Var PTHLink
-
-Function DependencyPage
- nsDialogs::Create 1018
- Pop $Dialog
-
- ${If} $Dialog == error
- Abort
- ${EndIf}
-
- ${NSD_CreateLabel} 0 0 100% 12u "OpenSSL - install 'Win64 OpenSSL v1.1.0* Light' then copy libssl_1-1-x64.dll and libcrypto_1-1-x64.dll to the mosquitto directory"
- ${NSD_CreateLink} 13u 13u 100% 12u "http://slproweb.com/products/Win32OpenSSL.html"
- Pop $OSSLLink
- ${NSD_OnClick} $OSSLLink OnClick_OSSL
-
- !insertmacro MUI_HEADER_TEXT_PAGE "Dependencies" "This page lists packages that must be installed if not already present"
- nsDialogs::Show
-FunctionEnd
-
-Function OnClick_OSSL
- Pop $0
- ExecShell "open" "http://slproweb.com/products/Win32OpenSSL.html"
-FunctionEnd
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index da5164800a..7b22c44d1b 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -2,30 +2,6 @@ option(WITH_STATIC_LIBRARIES "Build static versions of the libmosquitto/pp libra
option(WITH_PIC "Build the static library with PIC (Position Independent Code) enabled archives?" OFF)
add_subdirectory(cpp)
-option(WITH_THREADING "Include client library threading support?" ON)
-if (${WITH_THREADING} STREQUAL ON)
- add_definitions("-DWITH_THREADING")
- if (WIN32)
- if (CMAKE_CL_64)
- set (PTHREAD_LIBRARIES C:\\pthreads\\Pre-built.2\\lib\\x64\\pthreadVC2.lib)
- else (CMAKE_CL_64)
- set (PTHREAD_LIBRARIES C:\\pthreads\\Pre-built.2\\lib\\x86\\pthreadVC2.lib)
- endif (CMAKE_CL_64)
- set (PTHREAD_INCLUDE_DIR C:\\pthreads\\Pre-built.2\\include)
- else (WIN32)
- find_library(LIBPTHREAD pthread)
- if (LIBPTHREAD)
- set (PTHREAD_LIBRARIES pthread)
- else (LIBPTHREAD)
- set (PTHREAD_LIBRARIES "")
- endif()
- set (PTHREAD_INCLUDE_DIR "")
- endif (WIN32)
-else (${WITH_THREADING} STREQUAL ON)
- set (PTHREAD_LIBRARIES "")
- set (PTHREAD_INCLUDE_DIR "")
-endif (${WITH_THREADING} STREQUAL ON)
-
include_directories(${mosquitto_SOURCE_DIR} ${mosquitto_SOURCE_DIR}/lib
${STDBOOL_H_PATH} ${STDINT_H_PATH}
${OPENSSL_INCLUDE_DIR} ${PTHREAD_INCLUDE_DIR})
diff --git a/lib/Makefile b/lib/Makefile
index 8e310e6119..efce2c9843 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -43,19 +43,27 @@ MOSQ_OBJS=mosquitto.o \
util_topic.o \
will_mosq.o
-ALL_DEPS=libmosquitto.so.${SOVERSION}
+ALL_DEPS:=
+
+ifeq ($(WITH_SHARED_LIBRARIES),yes)
+ ALL_DEPS+=libmosquitto.so.${SOVERSION}
+endif
ifeq ($(WITH_STATIC_LIBRARIES),yes)
ALL_DEPS+=libmosquitto.a
endif
all : ${ALL_DEPS}
+ifeq ($(WITH_SHARED_LIBRARIES),yes)
$(MAKE) -C cpp
+endif
install : all
$(INSTALL) -d "${DESTDIR}${libdir}/"
+ifeq ($(WITH_SHARED_LIBRARIES),yes)
$(INSTALL) ${STRIP_OPTS} libmosquitto.so.${SOVERSION} "${DESTDIR}${libdir}/libmosquitto.so.${SOVERSION}"
ln -sf libmosquitto.so.${SOVERSION} "${DESTDIR}${libdir}/libmosquitto.so"
+endif
ifeq ($(WITH_STATIC_LIBRARIES),yes)
$(INSTALL) ${STRIP_OPTS} libmosquitto.a "${DESTDIR}${libdir}/libmosquitto.a"
endif
@@ -64,7 +72,9 @@ endif
$(INSTALL) -d "${DESTDIR}${libdir}/pkgconfig"
$(INSTALL) -m644 ../libmosquitto.pc.in "${DESTDIR}${libdir}/pkgconfig/libmosquitto.pc"
sed -i -e "s#@CMAKE_INSTALL_PREFIX@#${prefix}#" -e "s#@VERSION@#${VERSION}#" "${DESTDIR}${libdir}/pkgconfig/libmosquitto.pc"
+ifeq ($(WITH_SHARED_LIBRARIES),yes)
$(MAKE) -C cpp install
+endif
uninstall :
-rm -f "${DESTDIR}${libdir}/libmosquitto.so.${SOVERSION}"
diff --git a/lib/loop.c b/lib/loop.c
index 628d7d12dd..d3ee0c5262 100644
--- a/lib/loop.c
+++ b/lib/loop.c
@@ -147,19 +147,9 @@ int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets)
}else{
if(mosq->sock != INVALID_SOCKET){
if(FD_ISSET(mosq->sock, &readfds)){
-#ifdef WITH_TLS
- if(mosq->want_connect){
- rc = net__socket_connect_tls(mosq);
- if(rc) return rc;
- }else
-#endif
- {
- do{
- rc = mosquitto_loop_read(mosq, max_packets);
- if(rc || mosq->sock == INVALID_SOCKET){
- return rc;
- }
- }while(SSL_DATA_PENDING(mosq));
+ rc = mosquitto_loop_read(mosq, max_packets);
+ if(rc || mosq->sock == INVALID_SOCKET){
+ return rc;
}
}
if(mosq->sockpairR != INVALID_SOCKET && FD_ISSET(mosq->sockpairR, &readfds)){
@@ -253,8 +243,12 @@ int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets)
}else{
pthread_mutex_unlock(&mosq->state_mutex);
- if(mosq->reconnect_delay > 0 && mosq->reconnect_exponential_backoff){
- reconnect_delay = mosq->reconnect_delay*reconnects*reconnects;
+ if(mosq->reconnect_delay_max > mosq->reconnect_delay){
+ if(mosq->reconnect_exponential_backoff){
+ reconnect_delay = mosq->reconnect_delay*(reconnects+1)*(reconnects+1);
+ }else{
+ reconnect_delay = mosq->reconnect_delay*(reconnects+1);
+ }
}else{
reconnect_delay = mosq->reconnect_delay;
}
@@ -292,42 +286,10 @@ int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets)
int mosquitto_loop_misc(struct mosquitto *mosq)
{
- time_t now;
- int rc;
-
if(!mosq) return MOSQ_ERR_INVAL;
if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
- mosquitto__check_keepalive(mosq);
- now = mosquitto_time();
-
- if(mosq->ping_t && now - mosq->ping_t >= mosq->keepalive){
- /* mosq->ping_t != 0 means we are waiting for a pingresp.
- * This hasn't happened in the keepalive time so we should disconnect.
- */
- net__socket_close(mosq);
- pthread_mutex_lock(&mosq->state_mutex);
- if(mosq->state == mosq_cs_disconnecting){
- rc = MOSQ_ERR_SUCCESS;
- }else{
- rc = MOSQ_ERR_KEEPALIVE;
- }
- pthread_mutex_unlock(&mosq->state_mutex);
- pthread_mutex_lock(&mosq->callback_mutex);
- if(mosq->on_disconnect){
- mosq->in_callback = true;
- mosq->on_disconnect(mosq, mosq->userdata, rc);
- mosq->in_callback = false;
- }
- if(mosq->on_disconnect_v5){
- mosq->in_callback = true;
- mosq->on_disconnect_v5(mosq, mosq->userdata, rc, NULL);
- mosq->in_callback = false;
- }
- pthread_mutex_unlock(&mosq->callback_mutex);
- return MOSQ_ERR_CONN_LOST;
- }
- return MOSQ_ERR_SUCCESS;
+ return mosquitto__check_keepalive(mosq);
}
@@ -364,6 +326,12 @@ int mosquitto_loop_read(struct mosquitto *mosq, int max_packets)
int i;
if(max_packets < 1) return MOSQ_ERR_INVAL;
+#ifdef WITH_TLS
+ if(mosq->want_connect){
+ return net__socket_connect_tls(mosq);
+ }
+#endif
+
pthread_mutex_lock(&mosq->out_message_mutex);
max_packets = mosq->out_queue_len;
pthread_mutex_unlock(&mosq->out_message_mutex);
@@ -376,7 +344,7 @@ int mosquitto_loop_read(struct mosquitto *mosq, int max_packets)
/* Queue len here tells us how many messages are awaiting processing and
* have QoS > 0. We should try to deal with that many in this loop in order
* to keep up. */
- for(i=0; isocks5_host){
rc = socks5__read(mosq);
diff --git a/lib/mosquitto.h b/lib/mosquitto.h
index bb1524bd0d..1c91d7fb80 100644
--- a/lib/mosquitto.h
+++ b/lib/mosquitto.h
@@ -48,7 +48,7 @@ extern "C" {
#define LIBMOSQUITTO_MAJOR 1
#define LIBMOSQUITTO_MINOR 5
-#define LIBMOSQUITTO_REVISION 3
+#define LIBMOSQUITTO_REVISION 5
/* 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/lib/net_mosq.c b/lib/net_mosq.c
index e7dc8aeb98..2fb6b16792 100644
--- a/lib/net_mosq.c
+++ b/lib/net_mosq.c
@@ -183,7 +183,7 @@ int net__socket_close(struct mosquitto *mosq)
}
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
static unsigned int psk_client_callback(SSL *ssl, const char *hint,
char *identity, unsigned int max_identity_len,
unsigned char *psk, unsigned int max_psk_len)
@@ -208,21 +208,39 @@ int net__try_connect_step1(struct mosquitto *mosq, const char *host)
{
int s;
void *sevp = NULL;
+ struct addrinfo *hints;
if(mosq->adns){
+ gai_cancel(mosq->adns);
+ mosquitto__free((struct addrinfo *)mosq->adns->ar_request);
mosquitto__free(mosq->adns);
}
mosq->adns = mosquitto__calloc(1, sizeof(struct gaicb));
if(!mosq->adns){
return MOSQ_ERR_NOMEM;
}
+
+ hints = mosquitto__calloc(1, sizeof(struct addrinfo));
+ if(!hints){
+ mosquitto__free(mosq->adns);
+ mosq->adns = NULL;
+ return MOSQ_ERR_NOMEM;
+ }
+
+ hints->ai_family = AF_UNSPEC;
+ hints->ai_socktype = SOCK_STREAM;
+
mosq->adns->ar_name = host;
+ mosq->adns->ar_request = hints;
s = getaddrinfo_a(GAI_NOWAIT, &mosq->adns, 1, sevp);
if(s){
errno = s;
- mosquitto__free(mosq->adns);
- mosq->adns = NULL;
+ if(mosq->adns){
+ mosquitto__free((struct addrinfo *)mosq->adns->ar_request);
+ mosquitto__free(mosq->adns);
+ mosq->adns = NULL;
+ }
return MOSQ_ERR_EAI;
}
@@ -278,6 +296,7 @@ int net__try_connect_step2(struct mosquitto *mosq, uint16_t port, mosq_sock_t *s
freeaddrinfo(mosq->adns->ar_result);
mosq->adns->ar_result = NULL;
+ mosquitto__free((struct addrinfo *)mosq->adns->ar_request);
mosquitto__free(mosq->adns);
mosq->adns = NULL;
@@ -575,7 +594,7 @@ static int net__init_ssl_ctx(struct mosquitto *mosq)
return MOSQ_ERR_TLS;
}
}
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
}else if(mosq->tls_psk){
SSL_CTX_set_psk_client_callback(mosq->ssl_ctx, psk_client_callback);
#endif
@@ -596,6 +615,9 @@ int net__socket_connect_step3(struct mosquitto *mosq, const char *host, uint16_t
if(rc) return rc;
if(mosq->ssl_ctx){
+ if(mosq->ssl){
+ SSL_free(mosq->ssl);
+ }
mosq->ssl = SSL_new(mosq->ssl_ctx);
if(!mosq->ssl){
COMPAT_CLOSE(mosq->sock);
diff --git a/lib/options.c b/lib/options.c
index 7f18993e6b..85a9cba1a2 100644
--- a/lib/options.c
+++ b/lib/options.c
@@ -91,6 +91,8 @@ int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect
{
if(!mosq) return MOSQ_ERR_INVAL;
+ if(reconnect_delay == 0) reconnect_delay = 1;
+
mosq->reconnect_delay = reconnect_delay;
mosq->reconnect_delay_max = reconnect_delay_max;
mosq->reconnect_exponential_backoff = reconnect_exponential_backoff;
@@ -236,7 +238,7 @@ int mosquitto_tls_insecure_set(struct mosquitto *mosq, bool value)
int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers)
{
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
if(!mosq || !psk || !identity) return MOSQ_ERR_INVAL;
/* Check for hex only digits */
diff --git a/lib/socks_mosq.c b/lib/socks_mosq.c
index 5f43d16aa7..f0e4c8d219 100644
--- a/lib/socks_mosq.c
+++ b/lib/socks_mosq.c
@@ -21,9 +21,16 @@ and the Eclipse Distribution License is available at
#include
#ifdef WIN32
# include
+#elif __QNX__
+# include
+# include
#else
# include
#endif
+#ifdef __FreeBSD__
+# include
+# include
+#endif
#include "mosquitto_internal.h"
#include "memory_mosq.h"
diff --git a/lib/util_mosq.c b/lib/util_mosq.c
index e67eaa1533..07ba6afb9b 100644
--- a/lib/util_mosq.c
+++ b/lib/util_mosq.c
@@ -46,9 +46,9 @@ and the Eclipse Distribution License is available at
#endif
#ifdef WITH_BROKER
-void mosquitto__check_keepalive(struct mosquitto_db *db, struct mosquitto *mosq)
+int mosquitto__check_keepalive(struct mosquitto_db *db, struct mosquitto *mosq)
#else
-void mosquitto__check_keepalive(struct mosquitto *mosq)
+int mosquitto__check_keepalive(struct mosquitto *mosq)
#endif
{
time_t next_msg_out;
@@ -67,7 +67,7 @@ void mosquitto__check_keepalive(struct mosquitto *mosq)
log__printf(NULL, MOSQ_LOG_NOTICE, "Bridge connection %s has exceeded idle timeout, disconnecting.", mosq->id);
net__socket_close(db, mosq);
- return;
+ return MOSQ_ERR_SUCCESS;
}
#endif
pthread_mutex_lock(&mosq->msgtime_mutex);
@@ -113,9 +113,12 @@ void mosquitto__check_keepalive(struct mosquitto *mosq)
mosq->in_callback = false;
}
pthread_mutex_unlock(&mosq->callback_mutex);
+
+ return rc;
#endif
}
}
+ return MOSQ_ERR_SUCCESS;
}
uint16_t mosquitto__mid_generate(struct mosquitto *mosq)
@@ -140,7 +143,7 @@ uint16_t mosquitto__mid_generate(struct mosquitto *mosq)
}
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
int mosquitto__hex2bin(const char *hex, unsigned char *bin, int bin_max_len)
{
BIGNUM *bn = NULL;
diff --git a/lib/util_mosq.h b/lib/util_mosq.h
index 0e65dd9889..d94661e7aa 100644
--- a/lib/util_mosq.h
+++ b/lib/util_mosq.h
@@ -26,14 +26,14 @@ and the Eclipse Distribution License is available at
#endif
#ifdef WITH_BROKER
-void mosquitto__check_keepalive(struct mosquitto_db *db, struct mosquitto *mosq);
+int mosquitto__check_keepalive(struct mosquitto_db *db, struct mosquitto *mosq);
#else
-void mosquitto__check_keepalive(struct mosquitto *mosq);
+int mosquitto__check_keepalive(struct mosquitto *mosq);
#endif
uint16_t mosquitto__mid_generate(struct mosquitto *mosq);
FILE *mosquitto__fopen(const char *path, const char *mode, bool restrict_read);
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
int mosquitto__hex2bin(const char *hex, unsigned char *bin, int bin_max_len);
#endif
diff --git a/man/mosquitto.conf.5.xml b/man/mosquitto.conf.5.xml
index dbfce513a2..97509b0544 100644
--- a/man/mosquitto.conf.5.xml
+++ b/man/mosquitto.conf.5.xml
@@ -842,6 +842,27 @@
Not reloaded on reload signal.
+
+ socket_domain [ ipv4 | ipv6 ]
+
+ By default, a listener will attempt to listen on
+ all supported IP protocol versions. If you do not
+ have an IPv4 or IPv6 interface you may wish to
+ disable support for either of those protocol
+ versions. In particular, note that due to the
+ limitations of the websockets library, it will only
+ ever attempt to open IPv6 sockets if IPv6 support
+ is compiled in, and so will fail if IPv6 is not
+ available.
+ Set to ipv4 to force the
+ listener to only use IPv4, or set to
+ ipv6 to force the listener to only
+ use IPv6. If you want support for both IPv4 and
+ IPv6, then do not use the
+ socket_domain option.
+ Not reloaded on reload signal.
+
+
use_username_as_clientid [ true | false ]
diff --git a/set-version.sh b/set-version.sh
index 522dfa1d39..ec105f6bdb 100755
--- a/set-version.sh
+++ b/set-version.sh
@@ -2,7 +2,7 @@
MAJOR=1
MINOR=5
-REVISION=3
+REVISION=5
sed -i "s/^VERSION=.*/VERSION=${MAJOR}.${MINOR}.${REVISION}/" config.mk
diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
index 7ce01902b3..b6ede932e0 100644
--- a/snap/snapcraft.yaml
+++ b/snap/snapcraft.yaml
@@ -1,5 +1,5 @@
name: mosquitto
-version: 1.5.3
+version: 1.5.5
summary: Eclipse Mosquitto MQTT broker
description: This is a message broker that supports version 3.1 and 3.1.1 of the MQTT
protocol.
@@ -26,6 +26,9 @@ apps:
command: usr/bin/mosquitto_sub
plugs: [network]
+ passwd:
+ command: usr/bin/mosquitto_passwd
+
parts:
script:
@@ -61,9 +64,13 @@ parts:
- usr/sbin/mosquitto
- usr/bin/mosquitto_pub
- usr/bin/mosquitto_sub
+ - usr/bin/mosquitto_passwd
- usr/lib/libmosquitto.so*
- lib/*-linux-gnu/libcrypto.so*
- lib/*-linux-gnu/libssl.so*
+ - usr/include/mosquitto.h
+ - usr/include/mosquitto_broker.h
+ - usr/include/mosquitto_plugin.h
lws:
plugin: cmake
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 960b263a2f..274f102e81 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -131,17 +131,18 @@ if (HAVE_GETADDRINFO_A)
endif (HAVE_GETADDRINFO_A)
-
if (UNIX)
if (APPLE)
set (MOSQ_LIBS ${MOSQ_LIBS} dl m)
- else (APPLE)
- set (MOSQ_LIBS ${MOSQ_LIBS} dl m)
- find_library(LIBRT rt)
- if (LIBRT)
- set (MOSQ_LIBS ${MOSQ_LIBS} rt)
- endif (LIBRT)
- endif (APPLE)
+ elseif(QNX)
+ set(MOSQ_LIBS ${MOSQ_LIBS} m socket)
+ else(APPLE)
+ set (MOSQ_LIBS ${MOSQ_LIBS} dl m)
+ find_library(LIBRT rt)
+ if (LIBRT)
+ set (MOSQ_LIBS ${MOSQ_LIBS} rt)
+ endif (LIBRT)
+ endif (APPLE)
endif (UNIX)
if (WIN32)
diff --git a/src/bridge.c b/src/bridge.c
index 8006c2d938..365658e602 100644
--- a/src/bridge.c
+++ b/src/bridge.c
@@ -83,7 +83,7 @@ int bridge__new(struct mosquitto_db *db, struct mosquitto__bridge *bridge)
new_context->tls_cert_reqs = SSL_VERIFY_PEER;
new_context->tls_version = new_context->bridge->tls_version;
new_context->tls_insecure = new_context->bridge->tls_insecure;
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
new_context->tls_psk_identity = new_context->bridge->tls_psk_identity;
new_context->tls_psk = new_context->bridge->tls_psk;
#endif
diff --git a/src/conf.c b/src/conf.c
index 9053f22888..b18af7b176 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -343,7 +343,7 @@ void config__cleanup(struct mosquitto__config *config)
#ifdef WITH_TLS
mosquitto__free(config->bridges[i].tls_version);
mosquitto__free(config->bridges[i].tls_cafile);
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
mosquitto__free(config->bridges[i].tls_psk_identity);
mosquitto__free(config->bridges[i].tls_psk);
#endif
@@ -448,6 +448,7 @@ int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config
|| config->default_listener.max_connections != -1
|| config->default_listener.mount_point
|| config->default_listener.protocol != mp_mqtt
+ || config->default_listener.socket_domain
|| config->default_listener.security_options.password_file
|| config->default_listener.security_options.psk_file
|| config->default_listener.security_options.auth_plugin_config_count
@@ -478,6 +479,7 @@ int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config
}
config->listeners[config->listener_count-1].max_connections = config->default_listener.max_connections;
config->listeners[config->listener_count-1].protocol = config->default_listener.protocol;
+ config->listeners[config->listener_count-1].socket_domain = config->default_listener.socket_domain;
config->listeners[config->listener_count-1].client_count = 0;
config->listeners[config->listener_count-1].socks = NULL;
config->listeners[config->listener_count-1].sock_count = 0;
@@ -497,6 +499,7 @@ int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config
config->listeners[config->listener_count-1].use_identity_as_username = config->default_listener.use_identity_as_username;
config->listeners[config->listener_count-1].use_subject_as_username = config->default_listener.use_subject_as_username;
#endif
+ config->listeners[config->listener_count-1].security_options.acl_file = config->default_listener.security_options.acl_file;
config->listeners[config->listener_count-1].security_options.password_file = config->default_listener.security_options.password_file;
config->listeners[config->listener_count-1].security_options.psk_file = config->default_listener.security_options.psk_file;
config->listeners[config->listener_count-1].security_options.auth_plugin_configs = config->default_listener.security_options.auth_plugin_configs;
@@ -686,7 +689,7 @@ int config__read(struct mosquitto_db *db, struct mosquitto__config *config, bool
log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration.");
return MOSQ_ERR_INVAL;
}
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
if(config->bridges[i].tls_psk && !config->bridges[i].tls_psk_identity){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration: missing bridge_identity.\n");
return MOSQ_ERR_INVAL;
@@ -818,6 +821,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(!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;
@@ -919,7 +923,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration.");
return MOSQ_ERR_INVAL;
}
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
if(cur_bridge->tls_psk_identity || cur_bridge->tls_psk){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Cannot use both certificate and psk encryption in a single bridge.");
return MOSQ_ERR_INVAL;
@@ -936,7 +940,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration.");
return MOSQ_ERR_INVAL;
}
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
if(cur_bridge->tls_psk_identity || cur_bridge->tls_psk){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Cannot use both certificate and psk encryption in a single bridge.");
return MOSQ_ERR_INVAL;
@@ -953,7 +957,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration.");
return MOSQ_ERR_INVAL;
}
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
if(cur_bridge->tls_psk_identity || cur_bridge->tls_psk){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Cannot use both certificate and psk encryption in a single bridge.");
return MOSQ_ERR_INVAL;
@@ -964,7 +968,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Bridge and/or TLS support not available.");
#endif
}else if(!strcmp(token, "bridge_identity")){
-#if defined(WITH_BRIDGE) && defined(WITH_TLS_PSK)
+#if defined(WITH_BRIDGE) && defined(FINAL_WITH_TLS_PSK)
if(reload) continue; // FIXME
if(!cur_bridge){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration.");
@@ -999,7 +1003,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration.");
return MOSQ_ERR_INVAL;
}
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
if(cur_bridge->tls_psk_identity || cur_bridge->tls_psk){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Cannot use both certificate and psk encryption in a single bridge.");
return MOSQ_ERR_INVAL;
@@ -1034,7 +1038,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, "bridge_psk")){
-#if defined(WITH_BRIDGE) && defined(WITH_TLS_PSK)
+#if defined(WITH_BRIDGE) && defined(FINAL_WITH_TLS_PSK)
if(reload) continue; // FIXME
if(!cur_bridge){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration.");
@@ -1697,7 +1701,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
log__printf(NULL, MOSQ_LOG_ERR, "Error: Empty protocol value in configuration.");
}
}else if(!strcmp(token, "psk_file")){
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
conf__set_cur_security_options(config, cur_listener, &cur_security_options);
if(reload){
mosquitto__free(cur_security_options->psk_file);
@@ -1708,7 +1712,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: TLS/TLS-PSK support not available.");
#endif
}else if(!strcmp(token, "psk_hint")){
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
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
@@ -1784,6 +1788,22 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
#else
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.
+ token = strtok_r(NULL, " ", &saveptr);
+ if(token){
+ if(!strcmp(token, "ipv4")){
+ cur_listener->socket_domain = AF_INET;
+ }else if(!strcmp(token, "ipv6")){
+ cur_listener->socket_domain = AF_INET6;
+ }else{
+ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid socket_domain value \"%s\" in configuration.", token);
+ return MOSQ_ERR_INVAL;
+ }
+ }else{
+ log__printf(NULL, MOSQ_LOG_ERR, "Error: Empty socket_domain value in configuration.");
+ return MOSQ_ERR_INVAL;
+ }
}else if(!strcmp(token, "store_clean_interval")){
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: store_clean_interval is no longer needed.");
}else if(!strcmp(token, "sys_interval")){
@@ -2161,6 +2181,7 @@ static int conf__parse_bool(char **token, const char *name, bool *value, char *s
*value = true;
}else{
log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid %s value (%s).", name, *token);
+ return MOSQ_ERR_INVAL;
}
}else{
log__printf(NULL, MOSQ_LOG_ERR, "Error: Empty %s value in configuration.", name);
diff --git a/src/conf_includedir.c b/src/conf_includedir.c
index 4fc04a282d..11e60ccdc5 100644
--- a/src/conf_includedir.c
+++ b/src/conf_includedir.c
@@ -36,7 +36,7 @@ and the Eclipse Distribution License is available at
# include
#endif
-#if !defined(WIN32) && !defined(__CYGWIN__)
+#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__QNX__)
# include
#endif
diff --git a/src/context.c b/src/context.c
index 164969dbef..c7fa9da39d 100644
--- a/src/context.c
+++ b/src/context.c
@@ -198,6 +198,13 @@ void context__cleanup(struct mosquitto_db *db, struct mosquitto *context, bool d
context->queued_msgs = NULL;
context->last_queued_msg = NULL;
}
+#if defined(WITH_BROKER) && defined(__GLIBC__) && defined(WITH_ADNS)
+ if(context->adns){
+ gai_cancel(context->adns);
+ mosquitto__free((struct addrinfo *)context->adns->ar_request);
+ mosquitto__free(context->adns);
+ }
+#endif
if(do_free){
mosquitto__free(context);
}
diff --git a/src/handle_connack.c b/src/handle_connack.c
index 20ac526a9c..bc6e37a879 100644
--- a/src/handle_connack.c
+++ b/src/handle_connack.c
@@ -100,6 +100,20 @@ int handle__connack(struct mosquitto_db *db, struct mosquitto *context)
}
}
}
+ for(i=0; ibridge->topic_count; i++){
+ if(context->bridge->topics[i].direction == bd_out || context->bridge->topics[i].direction == bd_both){
+ log__printf(NULL, MOSQ_LOG_DEBUG, "Bridge %s doing local SUBSCRIBE on topic %s", context->id, context->bridge->topics[i].local_topic);
+ if(sub__add(db,
+ context,
+ context->bridge->topics[i].local_topic,
+ context->bridge->topics[i].qos,
+ MQTT_SUB_OPT_NO_LOCAL | MQTT_SUB_OPT_RETAIN_AS_PUBLISHED,
+ &db->subs)) return 1;
+ sub__retain_queue(db, context,
+ context->bridge->topics[i].local_topic,
+ context->bridge->topics[i].qos);
+ }
+ }
}
context->state = mosq_cs_connected;
return MOSQ_ERR_SUCCESS;
diff --git a/src/handle_connect.c b/src/handle_connect.c
index c1634eb74e..342cac566b 100644
--- a/src/handle_connect.c
+++ b/src/handle_connect.c
@@ -466,6 +466,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context)
if(context->protocol == mosq_p_mqtt311 || context->protocol == mosq_p_mqtt5){
if(password_flag){
/* username_flag == 0 && password_flag == 1 is forbidden */
+ log__printf(NULL, MOSQ_LOG_ERR, "Protocol error from %s: password without username, closing connection.", client_id);
rc = MOSQ_ERR_PROTOCOL;
goto handle_connect_error;
}
@@ -490,7 +491,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context)
rc = 1;
goto handle_connect_error;
}
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
if(context->listener->psk_hint){
/* Client should have provided an identity to get this far. */
if(!context->username){
@@ -499,7 +500,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context)
goto handle_connect_error;
}
}else{
-#endif /* WITH_TLS_PSK */
+#endif /* FINAL_WITH_TLS_PSK */
client_cert = SSL_get_peer_certificate(context->ssl);
if(!client_cert){
send__connack(db, context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL);
@@ -527,7 +528,11 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context)
rc = 1;
goto handle_connect_error;
}
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
context->username = mosquitto__strdup((char *) ASN1_STRING_data(name_asn1));
+#else
+ context->username = mosquitto__strdup((char *) ASN1_STRING_get0_data(name_asn1));
+#endif
if(!context->username){
send__connack(db, context, 0, CONNACK_REFUSED_SERVER_UNAVAILABLE, NULL);
rc = MOSQ_ERR_NOMEM;
@@ -562,9 +567,9 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context)
}
X509_free(client_cert);
client_cert = NULL;
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
}
-#endif /* WITH_TLS_PSK */
+#endif /* FINAL_WITH_TLS_PSK */
}else{
#endif /* WITH_TLS */
if(username_flag){
diff --git a/src/loop.c b/src/loop.c
index dd6b21394c..cd0df9d26b 100644
--- a/src/loop.c
+++ b/src/loop.c
@@ -87,7 +87,9 @@ static void temp__expire_websockets_clients(struct mosquitto_db *db)
}else{
id = "";
}
- log__printf(NULL, MOSQ_LOG_NOTICE, "Client %s has exceeded timeout, disconnecting.", id);
+ if(db->config->connection_messages == true){
+ log__printf(NULL, MOSQ_LOG_NOTICE, "Client %s has exceeded timeout, disconnecting.", id);
+ }
}
/* Client has exceeded keepalive*1.5 */
do_disconnect(db, context);
@@ -408,6 +410,10 @@ int mosquitto_main_loop(struct mosquitto_db *db, mosq_sock_t *listensock, int li
context->bridge->restart_t = 0;
}
}else{
+#ifdef WITH_EPOLL
+ /* clean any events triggered in previous connection */
+ context->events = 0;
+#endif
rc = bridge__connect_step1(db, context);
if(rc){
context->bridge->cur_address++;
@@ -422,8 +428,8 @@ int mosquitto_main_loop(struct mosquitto_db *db, mosq_sock_t *listensock, int li
#else
{
rc = bridge__connect(db, context);
+ context->bridge->restart_t = 0;
if(rc == MOSQ_ERR_SUCCESS){
- context->bridge->restart_t = 0;
if(context->bridge->round_robin == false && context->bridge->cur_address != 0){
context->bridge->primary_retry = now + 5;
}
@@ -638,9 +644,11 @@ void do_disconnect(struct mosquitto_db *db, struct mosquitto *context)
context->sock = INVALID_SOCKET;
context->pollfd_index = -1;
}
- HASH_DELETE(hh_id, db->contexts_by_id, context);
- context->old_id = context->id;
- context->id = NULL;
+ if(context->id){
+ HASH_DELETE(hh_id, db->contexts_by_id, context);
+ context->old_id = context->id;
+ context->id = NULL;
+ }
}else
#endif
{
@@ -660,7 +668,9 @@ void do_disconnect(struct mosquitto_db *db, struct mosquitto *context)
}
#ifdef WITH_EPOLL
if (context->sock != INVALID_SOCKET && epoll_ctl(db->epollfd, EPOLL_CTL_DEL, context->sock, &ev) == -1) {
- log__printf(NULL, MOSQ_LOG_DEBUG, "Error in epoll disconnecting: %s", strerror(errno));
+ if(db->config->connection_messages == true){
+ log__printf(NULL, MOSQ_LOG_DEBUG, "Error in epoll disconnecting: %s", strerror(errno));
+ }
}
#endif
context__disconnect(db, context);
@@ -811,14 +821,15 @@ static void loop_handle_reads_writes(struct mosquitto_db *db, struct pollfd *pol
continue;
}
}while(SSL_DATA_PENDING(context));
- }
+ }else{
#ifdef WITH_EPOLL
- if(events & (EPOLLERR | EPOLLHUP)){
+ if(events & (EPOLLERR | EPOLLHUP)){
#else
- if(context->pollfd_index >= 0 && pollfds[context->pollfd_index].revents & (POLLERR | POLLNVAL | POLLHUP)){
+ if(context->pollfd_index >= 0 && pollfds[context->pollfd_index].revents & (POLLERR | POLLNVAL | POLLHUP)){
#endif
- do_disconnect(db, context);
- continue;
+ do_disconnect(db, context);
+ continue;
+ }
}
}
}
diff --git a/src/mosquitto.c b/src/mosquitto.c
index eb90260ca7..768d5c102e 100644
--- a/src/mosquitto.c
+++ b/src/mosquitto.c
@@ -91,7 +91,7 @@ int drop_privileges(struct mosquitto__config *config, bool temporary)
{
#if !defined(__CYGWIN__) && !defined(WIN32)
struct passwd *pwd;
- char err[256];
+ char *err;
int rc;
const char *snap = getenv("SNAP_NAME");
@@ -108,7 +108,7 @@ int drop_privileges(struct mosquitto__config *config, bool temporary)
return 1;
}
if(initgroups(config->user, pwd->pw_gid) == -1){
- strerror_r(errno, err, 256);
+ err = strerror(errno);
log__printf(NULL, MOSQ_LOG_ERR, "Error setting groups whilst dropping privileges: %s.", err);
return 1;
}
@@ -118,7 +118,7 @@ int drop_privileges(struct mosquitto__config *config, bool temporary)
rc = setgid(pwd->pw_gid);
}
if(rc == -1){
- strerror_r(errno, err, 256);
+ err = strerror(errno);
log__printf(NULL, MOSQ_LOG_ERR, "Error setting gid whilst dropping privileges: %s.", err);
return 1;
}
@@ -128,7 +128,7 @@ int drop_privileges(struct mosquitto__config *config, bool temporary)
rc = setuid(pwd->pw_uid);
}
if(rc == -1){
- strerror_r(errno, err, 256);
+ err = strerror(errno);
log__printf(NULL, MOSQ_LOG_ERR, "Error setting uid whilst dropping privileges: %s.", err);
return 1;
}
@@ -144,19 +144,19 @@ int drop_privileges(struct mosquitto__config *config, bool temporary)
int restore_privileges(void)
{
#if !defined(__CYGWIN__) && !defined(WIN32)
- char err[256];
+ char *err;
int rc;
if(getuid() == 0){
rc = setegid(0);
if(rc == -1){
- strerror_r(errno, err, 256);
+ err = strerror(errno);
log__printf(NULL, MOSQ_LOG_ERR, "Error setting gid whilst restoring privileges: %s.", err);
return 1;
}
rc = seteuid(0);
if(rc == -1){
- strerror_r(errno, err, 256);
+ err = strerror(errno);
log__printf(NULL, MOSQ_LOG_ERR, "Error setting uid whilst restoring privileges: %s.", err);
return 1;
}
@@ -169,12 +169,12 @@ int restore_privileges(void)
void mosquitto__daemonise(void)
{
#ifndef WIN32
- char err[256];
+ char *err;
pid_t pid;
pid = fork();
if(pid < 0){
- strerror_r(errno, err, 256);
+ err = strerror(errno);
log__printf(NULL, MOSQ_LOG_ERR, "Error in fork: %s", err);
exit(1);
}
@@ -182,7 +182,7 @@ void mosquitto__daemonise(void)
exit(0);
}
if(setsid() < 0){
- strerror_r(errno, err, 256);
+ err = strerror(errno);
log__printf(NULL, MOSQ_LOG_ERR, "Error in setsid: %s", err);
exit(1);
}
diff --git a/src/mosquitto_broker_internal.h b/src/mosquitto_broker_internal.h
index d80accceeb..9cf0246e6d 100644
--- a/src/mosquitto_broker_internal.h
+++ b/src/mosquitto_broker_internal.h
@@ -218,6 +218,7 @@ struct mosquitto__listener {
int sock_count;
int client_count;
enum mosquitto_protocol protocol;
+ int socket_domain;
bool use_username_as_clientid;
#ifdef WITH_TLS
char *cafile;
@@ -468,7 +469,7 @@ struct mosquitto__bridge{
char *tls_certfile;
char *tls_keyfile;
char *tls_version;
-# ifdef WITH_TLS_PSK
+# ifdef FINAL_WITH_TLS_PSK
char *tls_psk_identity;
char *tls_psk;
# endif
diff --git a/src/net.c b/src/net.c
index 12e80e9e49..35ad123ba2 100644
--- a/src/net.c
+++ b/src/net.c
@@ -81,18 +81,16 @@ void net__broker_cleanup(void)
static void net__print_error(int log, const char *format_str)
{
-#ifdef WIN32
char *buf;
+#ifdef WIN32
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, WSAGetLastError(), LANG_NEUTRAL, &buf, 0, NULL);
log__printf(NULL, log, format_str, buf);
LocalFree(buf);
#else
- char buf[256];
-
- strerror_r(errno, buf, 256);
+ buf = strerror(errno);
log__printf(NULL, log, format_str, buf);
#endif
}
@@ -154,8 +152,10 @@ int net__socket_accept(struct mosquitto_db *db, mosq_sock_t listensock)
fromhost(&wrap_req);
if(!hosts_access(&wrap_req)){
/* Access is denied */
- if(!net__socket_get_address(new_sock, address, 1024)){
- log__printf(NULL, MOSQ_LOG_NOTICE, "Client connection from %s denied access by tcpd.", address);
+ if(db->config->connection_messages == true){
+ if(!net__socket_get_address(new_sock, address, 1024)){
+ log__printf(NULL, MOSQ_LOG_NOTICE, "Client connection from %s denied access by tcpd.", address);
+ }
}
COMPAT_CLOSE(new_sock);
return -1;
@@ -189,7 +189,9 @@ int net__socket_accept(struct mosquitto_db *db, mosq_sock_t listensock)
}
if(new_context->listener->max_connections > 0 && new_context->listener->client_count > new_context->listener->max_connections){
- log__printf(NULL, MOSQ_LOG_NOTICE, "Client connection from %s denied: max_connections exceeded.", new_context->address);
+ if(db->config->connection_messages == true){
+ log__printf(NULL, MOSQ_LOG_NOTICE, "Client connection from %s denied: max_connections exceeded.", new_context->address);
+ }
context__cleanup(db, new_context, true);
return -1;
}
@@ -219,12 +221,14 @@ int net__socket_accept(struct mosquitto_db *db, mosq_sock_t listensock)
}else if(rc == SSL_ERROR_WANT_WRITE){
new_context->want_write = true;
}else{
- 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));
+ 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;
@@ -236,7 +240,9 @@ int net__socket_accept(struct mosquitto_db *db, mosq_sock_t listensock)
}
#endif
- log__printf(NULL, MOSQ_LOG_NOTICE, "New connection from %s on port %d.", new_context->address, new_context->listener->port);
+ if(db->config->connection_messages == true){
+ log__printf(NULL, MOSQ_LOG_NOTICE, "New connection from %s on port %d.", new_context->address, new_context->listener->port);
+ }
return new_sock;
}
@@ -249,7 +255,7 @@ static int client_certificate_verify(int preverify_ok, X509_STORE_CTX *ctx)
}
#endif
-#ifdef WITH_TLS_PSK
+#ifdef FINAL_WITH_TLS_PSK
static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned char *psk, unsigned int max_psk_len)
{
struct mosquitto_db *db;
@@ -393,7 +399,11 @@ int net__socket_listen(struct mosquitto__listener *listener)
snprintf(service, 10, "%d", listener->port);
memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family = AF_UNSPEC;
+ if(listener->socket_domain){
+ hints.ai_family = listener->socket_domain;
+ }else{
+ hints.ai_family = AF_UNSPEC;
+ }
hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_STREAM;
@@ -518,7 +528,7 @@ int net__socket_listen(struct mosquitto__listener *listener)
X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK);
}
-# ifdef WITH_TLS_PSK
+# ifdef FINAL_WITH_TLS_PSK
}else if(listener->psk_hint){
if(tls_ex_index_context == -1){
tls_ex_index_context = SSL_get_ex_new_index(0, "client context", NULL, NULL, NULL);
@@ -541,7 +551,7 @@ int net__socket_listen(struct mosquitto__listener *listener)
return 1;
}
}
-# endif /* WITH_TLS_PSK */
+# endif /* FINAL_WITH_TLS_PSK */
}
#endif /* WITH_TLS */
return 0;
diff --git a/src/persist.c b/src/persist.c
index 8cc2de5fff..b8b3e4b86b 100644
--- a/src/persist.c
+++ b/src/persist.c
@@ -287,7 +287,7 @@ static int persist__subs_retain_write(struct mosquitto_db *db, FILE *db_fptr, st
sub = node->subs;
while(sub){
- if(sub->context->clean_start == false){
+ if(sub->context->clean_start == false && sub->context->id){
length = htonl(2+strlen(sub->context->id) + 2+strlen(thistopic) + sizeof(uint8_t));
i16temp = htons(DB_CHUNK_SUB);
@@ -356,7 +356,7 @@ int persist__backup(struct mosquitto_db *db, bool shutdown)
uint32_t i32temp;
uint16_t i16temp;
uint8_t i8temp;
- char err[256];
+ char *err;
char *outfile = NULL;
int len;
@@ -477,7 +477,7 @@ int persist__backup(struct mosquitto_db *db, bool shutdown)
return rc;
error:
mosquitto__free(outfile);
- strerror_r(errno, err, 256);
+ err = strerror(errno);
log__printf(NULL, MOSQ_LOG_ERR, "Error: %s.", err);
if(db_fptr) fclose(db_fptr);
return 1;
@@ -596,7 +596,7 @@ static int persist__client_msg_chunk_restore(struct mosquitto_db *db, FILE *db_f
uint8_t qos, retain, direction, state, dup;
char *client_id = NULL;
int rc;
- char err[256];
+ char *err;
read_e(db_fptr, &i16temp, sizeof(uint16_t));
slen = ntohs(i16temp);
@@ -631,7 +631,7 @@ static int persist__client_msg_chunk_restore(struct mosquitto_db *db, FILE *db_f
return rc;
error:
- strerror_r(errno, err, 256);
+ err = strerror(errno);
log__printf(NULL, MOSQ_LOG_ERR, "Error: %s.", err);
fclose(db_fptr);
mosquitto__free(client_id);
@@ -650,7 +650,7 @@ static int persist__msg_store_chunk_restore(struct mosquitto_db *db, FILE *db_fp
int rc = 0;
struct mosquitto_msg_store *stored = NULL;
struct mosquitto_msg_store_load *load;
- char err[256];
+ char *err;
payload.ptr = NULL;
@@ -734,7 +734,7 @@ static int persist__msg_store_chunk_restore(struct mosquitto_db *db, FILE *db_fp
return rc;
}
error:
- strerror_r(errno, err, 256);
+ err = strerror(errno);
log__printf(NULL, MOSQ_LOG_ERR, "Error: %s.", err);
fclose(db_fptr);
mosquitto__free(source_id);
@@ -747,10 +747,10 @@ static int persist__retain_chunk_restore(struct mosquitto_db *db, FILE *db_fptr)
{
dbid_t i64temp, store_id;
struct mosquitto_msg_store_load *load;
- char err[256];
+ char *err;
if(fread(&i64temp, sizeof(dbid_t), 1, db_fptr) != 1){
- strerror_r(errno, err, 256);
+ err = strerror(errno);
log__printf(NULL, MOSQ_LOG_ERR, "Error: %s.", err);
fclose(db_fptr);
return 1;
@@ -773,7 +773,7 @@ static int persist__sub_chunk_restore(struct mosquitto_db *db, FILE *db_fptr)
char *client_id;
char *topic;
int rc = 0;
- char err[256];
+ char *err;
read_e(db_fptr, &i16temp, sizeof(uint16_t));
slen = ntohs(i16temp);
@@ -807,7 +807,7 @@ static int persist__sub_chunk_restore(struct mosquitto_db *db, FILE *db_fptr)
return rc;
error:
- strerror_r(errno, err, 256);
+ err = strerror(errno);
log__printf(NULL, MOSQ_LOG_ERR, "Error: %s.", err);
fclose(db_fptr);
return 1;
@@ -824,7 +824,7 @@ int persist__restore(struct mosquitto_db *db)
uint16_t i16temp, chunk;
uint8_t i8temp;
ssize_t rlen;
- char err[256];
+ char *err;
struct mosquitto_msg_store_load *load, *load_tmp;
assert(db);
@@ -919,7 +919,7 @@ int persist__restore(struct mosquitto_db *db)
}
return rc;
error:
- strerror_r(errno, err, 256);
+ err = strerror(errno);
log__printf(NULL, MOSQ_LOG_ERR, "Error: %s.", err);
if(fptr) fclose(fptr);
return 1;
diff --git a/src/service.c b/src/service.c
index 11b4b018a8..c0fdc68a2c 100644
--- a/src/service.c
+++ b/src/service.c
@@ -27,6 +27,18 @@ SERVICE_STATUS_HANDLE service_handle = 0;
static SERVICE_STATUS service_status;
int main(int argc, char *argv[]);
+static void print_error(void)
+{
+ char *buf;
+
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, GetLastError(), LANG_NEUTRAL, &buf, 0, NULL);
+
+ fprintf(stderr, "Error: %s\n", buf);
+ LocalFree(buf);
+}
+
+
/* Service control callback */
void __stdcall service_handler(DWORD fdwControl)
{
@@ -112,8 +124,12 @@ void service_install(void)
svc_desc.lpDescription = "MQTT v3.1.1 broker";
ChangeServiceConfig2(svc_handle, SERVICE_CONFIG_DESCRIPTION, &svc_desc);
CloseServiceHandle(svc_handle);
+ }else{
+ print_error();
}
CloseServiceHandle(sc_manager);
+ } else {
+ print_error();
}
}
@@ -132,8 +148,12 @@ void service_uninstall(void)
}
}
CloseServiceHandle(svc_handle);
+ }else{
+ print_error();
}
CloseServiceHandle(sc_manager);
+ }else{
+ print_error();
}
}
diff --git a/src/sys_tree.c b/src/sys_tree.c
index 582e8f540f..0baf82a53b 100644
--- a/src/sys_tree.c
+++ b/src/sys_tree.c
@@ -60,8 +60,8 @@ static void sys_tree__update_clients(struct mosquitto_db *db, char *buf)
static unsigned int client_count = -1;
static int clients_expired = -1;
static unsigned int client_max = 0;
- static unsigned int disconnected_count = -1;
- static unsigned int connected_count = -1;
+ static int disconnected_count = -1;
+ static int connected_count = -1;
unsigned int count_total, count_by_sock;
@@ -82,6 +82,13 @@ static void sys_tree__update_clients(struct mosquitto_db *db, char *buf)
if(disconnected_count != count_total-count_by_sock){
disconnected_count = count_total-count_by_sock;
+ if(disconnected_count < 0){
+ /* If a client has connected but not sent a CONNECT at this point,
+ * then it is possible that count_by_sock will be bigger than
+ * count_total, causing a negative number. This situation should
+ * not last for long, so just cap at zero and ignore. */
+ disconnected_count = 0;
+ }
snprintf(buf, BUFLEN, "%d", disconnected_count);
db__messages_easy_queue(db, NULL, "$SYS/broker/clients/inactive", SYS_TREE_QOS, strlen(buf), buf, 1, NULL);
db__messages_easy_queue(db, NULL, "$SYS/broker/clients/disconnected", SYS_TREE_QOS, strlen(buf), buf, 1, NULL);
diff --git a/src/websockets.c b/src/websockets.c
index 4815fbd5ac..d1218ebe1c 100644
--- a/src/websockets.c
+++ b/src/websockets.c
@@ -229,7 +229,9 @@ static int callback_mqtt(struct libwebsocket_context *context,
return -1;
}
if(mosq->listener->max_connections > 0 && mosq->listener->client_count > mosq->listener->max_connections){
- log__printf(NULL, MOSQ_LOG_NOTICE, "Client connection from %s denied: max_connections exceeded.", mosq->address);
+ if(db->config->connection_messages == true){
+ log__printf(NULL, MOSQ_LOG_NOTICE, "Client connection from %s denied: max_connections exceeded.", mosq->address);
+ }
mosquitto__free(mosq);
u->mosq = NULL;
return -1;
@@ -665,6 +667,14 @@ static int callback_http(struct libwebsocket_context *context,
}
break;
+#ifdef WITH_TLS
+ case LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION:
+ if(!len || (SSL_get_verify_result((SSL*)in) != X509_V_OK)){
+ return 1;
+ }
+ break;
+#endif
+
default:
return 0;
}
@@ -721,6 +731,9 @@ struct libwebsocket_context *mosq_websockets_init(struct mosquitto__listener *li
#if LWS_LIBRARY_VERSION_MAJOR>1
info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
#endif
+ if(listener->socket_domain == AF_INET){
+ info.options |= LWS_SERVER_OPTION_DISABLE_IPV6;
+ }
user = mosquitto__calloc(1, sizeof(struct libws_mqtt_hack));
if(!user){
diff --git a/test/broker/09-plugin-auth-acl-sub-denied.py b/test/broker/09-plugin-auth-acl-sub-denied.py
new file mode 100755
index 0000000000..83726653a3
--- /dev/null
+++ b/test/broker/09-plugin-auth-acl-sub-denied.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+
+# Test topic subscription. All SUBSCRIBE requests are denied. Check this
+# produces the correct response, and check the client isn't disconnected (ref:
+# issue #1016).
+
+import inspect, os, sys
+# From http://stackoverflow.com/questions/279237/python-import-a-module-from-a-folder
+cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"..")))
+if cmd_subfolder not in sys.path:
+ sys.path.insert(0, cmd_subfolder)
+
+import mosq_test
+
+def write_config(filename, port):
+ with open(filename, 'w') as f:
+ f.write("port %d\n" % (port))
+ f.write("auth_plugin c/auth_plugin_acl_sub_denied.so\n")
+ f.write("allow_anonymous false\n")
+
+port = mosq_test.get_port()
+conf_file = os.path.basename(__file__).replace('.py', '.conf')
+write_config(conf_file, port)
+
+rc = 1
+keepalive = 10
+connect_packet = mosq_test.gen_connect("sub-denied-test", keepalive=keepalive, username="denied")
+connack_packet = mosq_test.gen_connack(rc=0)
+
+mid = 53
+subscribe_packet = mosq_test.gen_subscribe(mid, "qos0/test", 0)
+suback_packet = mosq_test.gen_suback(mid, 128)
+
+mid_pub = 54
+publish_packet = mosq_test.gen_publish("topic", qos=1, payload="test", mid=mid_pub)
+puback_packet = mosq_test.gen_puback(mid_pub)
+
+broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port)
+
+try:
+ sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=20, port=port)
+ mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback")
+
+ mosq_test.do_send_receive(sock, publish_packet, puback_packet, "puback")
+
+ rc = 0
+
+ sock.close()
+finally:
+ os.remove(conf_file)
+ broker.terminate()
+ broker.wait()
+ (stdo, stde) = broker.communicate()
+ if rc:
+ print(stde)
+
+
+exit(rc)
diff --git a/test/broker/Makefile b/test/broker/Makefile
index 1d80d79d9a..681387e6af 100644
--- a/test/broker/Makefile
+++ b/test/broker/Makefile
@@ -125,6 +125,7 @@ endif
./09-plugin-auth-unpwd-success.py
./09-plugin-auth-unpwd-fail.py
./09-plugin-auth-acl-sub.py
+ ./09-plugin-auth-acl-sub-denied.py
./09-plugin-auth-v2-unpwd-success.py
./09-plugin-auth-v2-unpwd-fail.py
./09-plugin-auth-defer-unpwd-success.py
diff --git a/test/broker/c/Makefile b/test/broker/c/Makefile
index 2005270df3..326318998c 100644
--- a/test/broker/c/Makefile
+++ b/test/broker/c/Makefile
@@ -6,6 +6,7 @@ PLUGIN_SRC = \
auth_plugin.c \
auth_plugin_pwd.c \
auth_plugin_acl.c \
+ auth_plugin_acl_sub_denied.c \
auth_plugin_v2.c \
auth_plugin_context_params.c \
auth_plugin_msg_params.c
diff --git a/test/broker/c/auth_plugin_acl_sub_denied.c b/test/broker/c/auth_plugin_acl_sub_denied.c
new file mode 100644
index 0000000000..4c5a26fab5
--- /dev/null
+++ b/test/broker/c/auth_plugin_acl_sub_denied.c
@@ -0,0 +1,49 @@
+#include
+#include
+#include
+#include
+#include
+
+int mosquitto_auth_plugin_version(void)
+{
+ return MOSQ_AUTH_PLUGIN_VERSION;
+}
+
+int mosquitto_auth_plugin_init(void **user_data, struct mosquitto_opt *auth_opts, int auth_opt_count)
+{
+ return MOSQ_ERR_SUCCESS;
+}
+
+int mosquitto_auth_plugin_cleanup(void *user_data, struct mosquitto_opt *auth_opts, int auth_opt_count)
+{
+ return MOSQ_ERR_SUCCESS;
+}
+
+int mosquitto_auth_security_init(void *user_data, struct mosquitto_opt *auth_opts, int auth_opt_count, bool reload)
+{
+ return MOSQ_ERR_SUCCESS;
+}
+
+int mosquitto_auth_security_cleanup(void *user_data, struct mosquitto_opt *auth_opts, int auth_opt_count, bool reload)
+{
+ return MOSQ_ERR_SUCCESS;
+}
+
+int mosquitto_auth_acl_check(void *user_data, int access, const struct mosquitto *client, const struct mosquitto_acl_msg *msg)
+{
+ if(access == MOSQ_ACL_SUBSCRIBE){
+ return MOSQ_ERR_ACL_DENIED;
+ }else{
+ return MOSQ_ERR_SUCCESS;
+ }
+}
+
+int mosquitto_auth_unpwd_check(void *user_data, const struct mosquitto *client, const char *username, const char *password)
+{
+ return MOSQ_ERR_SUCCESS;
+}
+
+int mosquitto_auth_psk_key_get(void *user_data, const struct mosquitto *client, const char *hint, const char *identity, char *key, int max_key_len)
+{
+ return MOSQ_ERR_AUTH;
+}
diff --git a/test/broker/ptest.py b/test/broker/ptest.py
index 68f1ed25f6..42ca336f65 100755
--- a/test/broker/ptest.py
+++ b/test/broker/ptest.py
@@ -97,6 +97,7 @@
(1, './09-plugin-auth-unpwd-success.py'),
(1, './09-plugin-auth-unpwd-fail.py'),
(1, './09-plugin-auth-acl-sub.py'),
+ (1, './09-plugin-auth-acl-sub-denied.py'),
(1, './09-plugin-auth-v2-unpwd-success.py'),
(1, './09-plugin-auth-v2-unpwd-fail.py'),
(1, './09-plugin-auth-defer-unpwd-success.py'),
diff --git a/test/ssl/gen.sh b/test/ssl/gen.sh
index 7a49631caa..a52159c1e4 100755
--- a/test/ssl/gen.sh
+++ b/test/ssl/gen.sh
@@ -31,42 +31,42 @@ openssl req -new -x509 -days 3650 -key test-fake-root-ca.key -out test-fake-root
# An intermediate CA, signed by the root CA, used to sign server/client csrs.
openssl genrsa -out test-signing-ca.key 1024
openssl req -out test-signing-ca.csr -key test-signing-ca.key -new -config openssl.cnf -subj "${BASESUBJ}/CN=Signing CA/"
-openssl ca -config openssl.cnf -name CA_root -extensions v3_ca -out test-signing-ca.crt -infiles test-signing-ca.csr
+openssl ca -batch -config openssl.cnf -name CA_root -extensions v3_ca -out test-signing-ca.crt -infiles test-signing-ca.csr
# An alternative intermediate CA, signed by the root CA, not used to sign anything.
openssl genrsa -out test-alt-ca.key 1024
openssl req -out test-alt-ca.csr -key test-alt-ca.key -new -config openssl.cnf -subj "${BASESUBJ}/CN=Alternative Signing CA/"
-openssl ca -config openssl.cnf -name CA_root -extensions v3_ca -out test-alt-ca.crt -infiles test-alt-ca.csr
+openssl ca -batch -config openssl.cnf -name CA_root -extensions v3_ca -out test-alt-ca.crt -infiles test-alt-ca.csr
# Valid server key and certificate.
openssl genrsa -out server.key 1024
openssl req -new -key server.key -out server.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=localhost/"
-openssl ca -config openssl.cnf -name CA_signing -out server.crt -infiles server.csr
+openssl ca -batch -config openssl.cnf -name CA_signing -out server.crt -infiles server.csr
# Expired server certificate, based on the above server key.
openssl req -new -days 1 -key server.key -out server-expired.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=localhost/"
-openssl ca -config openssl.cnf -name CA_signing -days 1 -startdate 120820000000Z -enddate 120821000000Z -out server-expired.crt -infiles server-expired.csr
+openssl ca -batch -config openssl.cnf -name CA_signing -days 1 -startdate 120820000000Z -enddate 120821000000Z -out server-expired.crt -infiles server-expired.csr
# Valid client key and certificate.
openssl genrsa -out client.key 1024
openssl req -new -key client.key -out client.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=test client/"
-openssl ca -config openssl.cnf -name CA_signing -out client.crt -infiles client.csr
+openssl ca -batch -config openssl.cnf -name CA_signing -out client.crt -infiles client.csr
# Expired client certificate, based on the above client key.
openssl req -new -days 1 -key client.key -out client-expired.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=test client expired/"
-openssl ca -config openssl.cnf -name CA_signing -days 1 -startdate 120820000000Z -enddate 120821000000Z -out client-expired.crt -infiles client-expired.csr
+openssl ca -batch -config openssl.cnf -name CA_signing -days 1 -startdate 120820000000Z -enddate 120821000000Z -out client-expired.crt -infiles client-expired.csr
# Revoked client certificate, based on a new client key.
openssl genrsa -out client-revoked.key 1024
openssl req -new -days 1 -key client-revoked.key -out client-revoked.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=test client revoked/"
-openssl ca -config openssl.cnf -name CA_signing -out client-revoked.crt -infiles client-revoked.csr
-openssl ca -config openssl.cnf -name CA_signing -revoke client-revoked.crt
-openssl ca -config openssl.cnf -name CA_signing -gencrl -out crl.pem
+openssl ca -batch -config openssl.cnf -name CA_signing -out client-revoked.crt -infiles client-revoked.csr
+openssl ca -batch -config openssl.cnf -name CA_signing -revoke client-revoked.crt
+openssl ca -batch -config openssl.cnf -name CA_signing -gencrl -out crl.pem
# Valid client key and certificate, encrypted (use "password" as password)
-openssl genrsa -des3 -out client-encrypted.key 1024
-openssl req -new -key client-encrypted.key -out client-encrypted.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=test client encrypted/"
-openssl ca -config openssl.cnf -name CA_signing -out client-encrypted.crt -infiles client-encrypted.csr
+openssl genrsa -des3 -out client-encrypted.key -passout pass:password 1024
+openssl req -new -key client-encrypted.key -out client-encrypted.csr -config openssl.cnf -subj "${SBASESUBJ}/CN=test client encrypted/" -passin pass:password
+openssl ca -batch -config openssl.cnf -name CA_signing -out client-encrypted.crt -infiles client-encrypted.csr
cat test-signing-ca.crt test-root-ca.crt > all-ca.crt
#mkdir certs
diff --git a/www/README.md b/www/README.md
new file mode 100644
index 0000000000..923f54bfec
--- /dev/null
+++ b/www/README.md
@@ -0,0 +1,3 @@
+This is the mosquitto website, it can be built with `nikola`:
+
+`nikola build`
\ No newline at end of file
diff --git a/www/conf.py b/www/conf.py
index b41452372a..7b5f4ded55 100644
--- a/www/conf.py
+++ b/www/conf.py
@@ -87,6 +87,7 @@
#("/sponsoring/", "Sponsoring"),
(
(
+ ("/roadmap/", "Roadmap"),
("/api/", "API"),
("/man/libmosquitto-3.html", "libmosquitto"),
("/man/mosquitto-8.html", "mosquitto"),
diff --git a/www/pages/download.md b/www/pages/download.md
index 51c1b90c42..2aceb0a53a 100644
--- a/www/pages/download.md
+++ b/www/pages/download.md
@@ -11,11 +11,11 @@
# Source
-* [mosquitto-1.5.3.tar.gz](http://mosquitto.org/files/source/mosquitto-1.5.3.tar.gz) (319kB) ([GPG signature](http://mosquitto.org/files/source/mosquitto-1.5.3.tar.gz.asc))
-* [mosquitto-1.5.3.tar.gz](http://www.eclipse.org/downloads/download.php?file=/mosquitto/source/mosquitto-1.5.3.tar.gz) (via Eclipse)
+* [mosquitto-1.5.5.tar.gz](https://mosquitto.org/files/source/mosquitto-1.5.5.tar.gz) (319kB) ([GPG signature](https://mosquitto.org/files/source/mosquitto-1.5.5.tar.gz.asc))
+* [mosquitto-1.5.4.tar.gz](https://www.eclipse.org/downloads/download.php?file=/mosquitto/source/mosquitto-1.5.4.tar.gz) (via Eclipse)
* [Git source code repository](https://github.com/eclipse/mosquitto) (github.com)
-Older downloads are available at [http://mosquitto.org/files/](../files/)
+Older downloads are available at [https://mosquitto.org/files/](../files/)
# Binary Installation
@@ -25,14 +25,14 @@ distributions.
## Windows
-* [mosquitto-1.5.3-install-windows-x64.exe](http://www.eclipse.org/downloads/download.php?file=/mosquitto/binary/win64/mosquitto-1.5.3-install-windows-x64.exe) (~360 kB) (64-bit build, Windows Vista and up, built with Visual Studio Community 2017)
-* [mosquitto-1.5.3-install-windows-x32.exe](http://www.eclipse.org/downloads/download.php?file=/mosquitto/binary/win32/mosquitto-1.5.3-install-windows-x86.exe) (~360 kB) (32-bit build, Windows Vista and up, built with Visual Studio Community 2017)
+* [mosquitto-1.5.4-install-windows-x64.exe](https://www.eclipse.org/downloads/download.php?file=/mosquitto/binary/win64/mosquitto-1.5.4-install-windows-x64.exe) (~360 kB) (64-bit build, Windows Vista and up, built with Visual Studio Community 2017)
+* [mosquitto-1.5.4-install-windows-x32.exe](https://www.eclipse.org/downloads/download.php?file=/mosquitto/binary/win32/mosquitto-1.5.4-install-windows-x86.exe) (~360 kB) (32-bit build, Windows Vista and up, built with Visual Studio Community 2017)
See also readme-windows.txt after installing.
## Mac
Mosquitto can be installed from the homebrew project. See
-[brew.sh](http://brew.sh/) and then use `brew install mosquitto`
+[brew.sh](https://brew.sh/) and then use `brew install mosquitto`
## Linux distributions with snap support
@@ -42,30 +42,20 @@ Mosquitto can be installed from the homebrew project. See
Download the repository config file for your CentOS version from below and copy it to /etc/yum.repos.d/ You'll now be able to install and keep mosquitto up to date using the normal package management tools.
The available packages are: mosquitto, mosquitto-clients, libmosquitto1, libmosquitto-devel, libmosquittopp1, libmosquittopp-devel, python-mosquitto.
-* [CentOS 7](http://download.opensuse.org/repositories/home:/oojah:/mqtt/CentOS_CentOS-7/home:oojah:mqtt.repo)
-* [CentOS 6](http://download.opensuse.org/repositories/home:/oojah:/mqtt/CentOS_CentOS-6/home:oojah:mqtt.repo)
+* [CentOS 7](https://download.opensuse.org/repositories/home:/oojah:/mqtt/CentOS_CentOS-7/home:oojah:mqtt.repo)
+* [CentOS 6](https://download.opensuse.org/repositories/home:/oojah:/mqtt/CentOS_CentOS-6/home:oojah:mqtt.repo)
## Debian
* Mosquitto is now in Debian proper. There will be a short delay between a new
release and it appearing in Debian as part of the normal Debian procedures.
* There are also Debian repositories provided by the mosquitto project, as
- described at
-
-## openSUSE
-Download the repository config file for your openSUSE version from below and
-copy it to /etc/zypp/repos.d/ You'll now be able to install and keep mosquitto
-up to date using the normal package management tools.
-
-The available packages are: mosquitto, mosquitto-clients, libmosquitto1, libmosquitto-devel, libmosquittopp1, libmosquittopp-devel, python-mosquitto.
-
-* [openSUSE 13.2]http://download.opensuse.org/repositories/home:/oojah:/mqtt/openSUSE_13.2/home:oojah:mqtt.repo)
-* [openSUSE 13.1]http://download.opensuse.org/repositories/home:/oojah:/mqtt/openSUSE_13.1/home:oojah:mqtt.repo)
+ described at
## Raspberry Pi
Mosquitto is available through the main repository.
There are also Debian repositories provided by the mosquitto project, as
-described at
+described at
## Redhat Enterprise Linux
Download the repository config file for your RHEL version from below and copy
@@ -73,23 +63,14 @@ it to /etc/yum.repos.d/ You'll now be able to install and keep mosquitto up to
date using the normal package management tools.
The available packages are: mosquitto, mosquitto-clients, libmosquitto1, libmosquitto-devel, libmosquittopp1, libmosquittopp-devel, python-mosquitto.
-* [RHEL 7](http://download.opensuse.org/repositories/home:/oojah:/mqtt/RedHat_RHEL-7/home:oojah:mqtt.repo)
-* [RHEL 6](http://download.opensuse.org/repositories/home:/oojah:/mqtt/RedHat_RHEL-6/home:oojah:mqtt.repo)
-
-## SUSE Linux Enterprise Server
-Add the appropriate repository to your package config from the list below, then install mosquitto from your normal package management tools.
-
-* [SLE 15](http://download.opensuse.org/repositories/home:/oojah:/mqtt/SLE_15/)
-* [SLE 12 SP3](http://download.opensuse.org/repositories/home:/oojah:/mqtt/SLE_12_SP3/)
-* [SLE 12 SP2](http://download.opensuse.org/repositories/home:/oojah:/mqtt/SLE_12_SP2/)
-* [SLE 12 SP1](http://download.opensuse.org/repositories/home:/oojah:/mqtt/SLE_12_SP1/)
-* [SLE 12](http://download.opensuse.org/repositories/home:/oojah:/mqtt/SLE_123/)
+* [RHEL 7](https://download.opensuse.org/repositories/home:/oojah:/mqtt/RedHat_RHEL-7/home:oojah:mqtt.repo)
+* [RHEL 6](https://download.opensuse.org/repositories/home:/oojah:/mqtt/RedHat_RHEL-6/home:oojah:mqtt.repo)
## Ubuntu
Mosquitto is available in the Ubuntu repositories so you can install as with
any other package. If you are on an earlier version of Ubuntu or want a more
recent version of mosquitto, add the [mosquitto-dev
-PPA](http://launchpad.net/%7Emosquitto-dev/+archive/mosquitto-ppa/) to your
+PPA](https://launchpad.net/%7Emosquitto-dev/+archive/mosquitto-ppa/) to your
repositories list - see the link for details. mosquitto can then be installed
from your package manager.
@@ -98,24 +79,9 @@ from your package manager.
# Other packages known to exist
-## Arch Linux
-* Mosquitto can be found in the community repository.
-
-## Fedora
-Mosquitto is now available from Fedora directly. Use `yum install mosquitto`,
-or search for "mosquitto" to find the related packages.
-
-## FreeBSD
-Mosquitto is available for FreeBSD: http://www.freshports.org/net/mosquitto/
-
-## Gentoo
-Use `emerge mosquitto`
-
-## OpenWrt
-If you're using a trunk snapshot use `opkg update; opkg install mosquitto`
-
-Karl Palsson maintains a set of feeds that may be more up to date than the
-current OpenWrt version:
-
-* https://github.com/remakeelectric/owrt_pub_feeds
-
+* Arch Linux
+* Fedora
+* FreeBSD
+* Gentoo
+* OpenWrt
+* OpenSUSE
diff --git a/www/pages/index.html b/www/pages/index.html
index d31fb9a29f..e269d72c67 100644
--- a/www/pages/index.html
+++ b/www/pages/index.html
@@ -26,9 +26,9 @@
implementing MQTT clients, and the very popular mosquitto_pub
and mosquitto_sub command line MQTT clients.
- Mosquitto is part of the Eclipse
+ Mosquitto is part of the Eclipse
Foundation and is an iot.eclipse.org project.
+ href="https://iot.eclipse.org/">iot.eclipse.org project.
@@ -52,10 +52,10 @@ Test
You can have your own instance of Mosquitto running in
minutes, but to make testing even easier, the Mosquitto Project
runs a test server at test.mosquitto.org where
+ href="https://test.mosquitto.org/">test.mosquitto.org where
you can test your clients in a variety of ways: plain MQTT,
MQTT over TLS, MQTT over TLS (with client certificate ,
+ href="https://test.mosquitto.org/ssl/">client certificate,
MQTT over WebSockets and MQTT over WebSockets with TLS.
platforms.
diff --git a/www/pages/roadmap.md b/www/pages/roadmap.md
new file mode 100644
index 0000000000..7e607cf7f0
--- /dev/null
+++ b/www/pages/roadmap.md
@@ -0,0 +1,81 @@
+
+
+# Roadmap
+
+## Version 1.6
+
+The next minor release. The focus of this release is on providing support for
+version 5 of the MQTT protocol.
+
+This release will provide a feature complete implementation, but does not
+represent the final interface for all features. In particular, functions are
+being added to libmosquitto to provide support for MQTT 5 features, but these
+will be consolidated with the API changes planned for version 2.0.
+
+### Deprecation notices
+
+#### libmosquittopp
+
+libmosquittopp, the C++ wrapper around libmosquitto is now deprecated and will
+be removed in the next major release (2.0). The wrapper came about by an
+external request and at the time it was created there were no other C++
+solutions for MQTT. This has changed in the past years and this wrapper
+provides no benefit over true C++ libraries or using the pure C libmosquitto.
+
+#### libmosquitto API changes
+
+The Mosquitto project has maintained API and ABI compatibility in libmosquitto
+since version 1.0, and has dealt with the introduction of new specification
+features by adding new functions which duplicate the behaviour of existing
+functions, but with additional arguments to support the new features.
+Particularly with regards to adding support for MQTT version 5, this has lead
+to a proliferation of functions which offer small variations on a theme.
+
+The libmosquitto functions listed below (which includes some new functions
+included in 1.6) are going to be updated for version 2.0. Functions not listed
+here should still be considered at risk of being updated.
+
+* mosquitto\_will\_set
+* mosquitto\_connect\*
+* mosquitto\_reconnect\*
+* mosquitto\_disconnect
+* mosquitto\_publish\*
+* mosquitto\_subscribe\*
+* mosquitto\_unsubscribe\*
+* mosquitto\_loop\*
+* mosquitto\_\*\_callback\_set
+* All callbacks
+* mosquitto\_\*\_topic\_check\*
+
+
+## Version 2.0
+
+This is the next major release and includes breaking changes. Other features
+planned include:
+
+## Disk persistence improvements
+
+A new disk persistence interface will be created to allow persistence to occur
+immediately, rather than periodically. This will allow queued messages for
+disconnected clients to be removed from memory, and reduce the periodic pause
+caused when writing the persistence file.
+
+## Breaking changes
+
+### libmosquitto
+
+The libmosquitto API is being consolidated to better support the new MQTT 5
+features whilst reducing the number of function variants.
+
+### libmosquittopp
+
+The C++ wrapper around libmosquitto will be removed in this release.
diff --git a/www/pages/security.md b/www/pages/security.md
index c31eb3006f..43618a25a3 100644
--- a/www/pages/security.md
+++ b/www/pages/security.md
@@ -19,6 +19,10 @@ follow the steps on [Eclipse Security] page to report it.
Listed with most recent first. Further information on security related issues
can be found in the [security category].
+* December 2018: No CVE assigned. Affecting versions **1.5** to **1.5.4**
+ inclusive, fixed in **1.5.5.**. More details at [version-155-released].
+* November 2018: No CVE assigned. Affecting versions **1.4** to **1.5.3**
+ inclusive, fixed in **1.5.4**. More details at [version-154-released].
* September 2018: [CVE-2018-12543] affecting versions **1.5** to **1.5.2**
inclusive, fixed in **1.5.3**.
* April 2018: [CVE-2017-7655] affecting versions **1.0** to **1.4.15**
@@ -41,7 +45,8 @@ can be found in the [security category].
inclusive, fixed in **1.4.12**. More details at
[security-advisory-cve-2017-7650].
-
+[version-155-released]: /2018/11/version-155-released/
+[version-154-released]: /2018/11/version-154-released/
[security-advisory-cve-2018-12543]: /2018/09/security-advisory-cve-2018-12543/
[security-advisory-cve-2017-7651-cve-2017-7652]: /2018/02/security-advisory-cve-2017-7651-cve-2017-7652/
[security-advisory-cve-2017-7650]: /2017/05/security-advisory-cve-2017-7650/
diff --git a/www/posts/2018/11/mqtt5-progress.md b/www/posts/2018/11/mqtt5-progress.md
new file mode 100644
index 0000000000..2b27e82172
--- /dev/null
+++ b/www/posts/2018/11/mqtt5-progress.md
@@ -0,0 +1,59 @@
+
+
+Development of support for MQTT 5 is ongoing and making good progress, but has
+been substantially delayed due to other non-Mosquitto work having to take
+priority.
+
+It is possible to test the current state of MQTT 5 support by using the `mqtt5`
+branch of the [repository]. Please note that this is very much a work in
+progress, so parts are incomplete and interfaces may yet change. The client
+library in particular has had to have an increase in functions available in
+order to provide the features needed whilst providing backwards compatibility.
+Part of the plan for the 2.0 release, which will follow after 1.6, is to
+consolidate the libmosquitto API with breaking changes. There are more details
+on the [roadmap].
+
+Current features include:
+
+* Support for all incoming and outgoing packets, although not everything is
+ processed.
+* Support for sending and receiving all properties, with not all properties
+ processed.
+* Client support for setting properties
+* Request/response support (client cannot process incoming correlation data)
+* Retain availability
+* Message expiry interval support
+* Server support for assigned client identifiers
+* Payload format indicator support
+* Content-type support
+* Basic topic alias support from client to broker
+* Lots of new tests
+
+Both `mosquitto_pub` and `mosquitto_sub` support setting properties on the
+command line, for example:
+
+```
+mosquitto_sub -t topic -v -D connect session-expiry-interval 60 -D connect user-property key value -D subscribe user-property sub-key sub-value
+```
+
+```
+mosquitto_pub -t topic -m '{"key":"value"}' -D publish content-type "application/json"
+```
+
+```
+./sensor_read.sh | mosquitto_pub -t topic -l -D publish topic-alias 1
+```
+
+Further updates will be posted when more features are available.
+
+[repository]: https://github.com/eclipse/mosquitto/tree/mqtt5
+[roadmap]: https://mosquitto.org/roadmap/
\ No newline at end of file
diff --git a/www/posts/2018/11/version-154-released.md b/www/posts/2018/11/version-154-released.md
new file mode 100644
index 0000000000..7d0c9dd544
--- /dev/null
+++ b/www/posts/2018/11/version-154-released.md
@@ -0,0 +1,59 @@
+
+
+This is a bugfix and security release.
+
+# Version 1.5.4 changes
+
+## Security
+- When using a TLS enabled websockets listener with `require_certificate`
+ enabled, the mosquitto broker does not correctly verify client certificates.
+ This is now fixed. All other security measures operate as expected, and in
+ particular non-websockets listeners are not affected by this. Closes [#996].
+
+## Broker
+- Process all pending messages even when a client has disconnected. This means
+ a client that send a PUBLISH then DISCONNECT quickly, then disconnects will
+ have its DISCONNECT message processed properly and so no Will will be sent.
+ Closes [#7].
+- $SYS/broker/clients/disconnected should never be negative. Closes [#287].
+- Give better error message if a client sends a password without a username.
+ Closes [#1015].
+- Fix bridge not honoring `restart_timeout`. Closes [#1019].
+- Don't disconnect a client if an auth plugin denies access to SUBSCRIBE.
+ Closes [#1016].
+
+## Library
+- Fix memory leak that occurred if `mosquitto_reconnect()` was used when TLS
+ errors were present. Closes [#592].
+- Fix TLS connections when using an external event loop with
+ `mosquitto_loop_read()` and `mosquitto_write()`. Closes [#990].
+
+## Build
+- Fix clients not being compiled with threading support when using CMake.
+ Closes [#983].
+- Header fixes for FreeBSD. Closes [#977].
+- Use `_GNU_SOURCE` to fix build errors in websockets and getaddrinfo usage.
+ Closes [#862] and [#933].
+- Fix builds on QNX 7.0.0. Closes [#1018].
+
+[#7]: https://github.com/eclipse/mosquitto/issues/7
+[#287]: https://github.com/eclipse/mosquitto/issues/287
+[#592]: https://github.com/eclipse/mosquitto/issues/592
+[#933]: https://github.com/eclipse/mosquitto/issues/933
+[#977]: https://github.com/eclipse/mosquitto/issues/977
+[#983]: https://github.com/eclipse/mosquitto/issues/983
+[#990]: https://github.com/eclipse/mosquitto/issues/990
+[#996]: https://github.com/eclipse/mosquitto/issues/996
+[#1015]: https://github.com/eclipse/mosquitto/issues/1015
+[#1016]: https://github.com/eclipse/mosquitto/issues/1016
+[#1018]: https://github.com/eclipse/mosquitto/issues/1018
+[#1019]: https://github.com/eclipse/mosquitto/issues/1019
diff --git a/www/posts/2018/12/version-155-released.md b/www/posts/2018/12/version-155-released.md
new file mode 100644
index 0000000000..ca01171581
--- /dev/null
+++ b/www/posts/2018/12/version-155-released.md
@@ -0,0 +1,60 @@
+
+
+This is a bugfix and security release.
+
+# Version 1.5.5 changes
+
+## Security
+- If `per_listener_settings` is set to true, then the `acl_file` setting was
+ ignored for the "default listener" only. This has been fixed. This does not
+ affect any listeners defined with the `listener` option. Closes [#1073].
+
+## Broker
+- Add `socket_domain` option to allow listeners to disable IPv6 support.
+ This is required to work around a problem in libwebsockets that means
+ sockets only listen on IPv6 by default if IPv6 support is compiled in.
+ Closes [#1004].
+- When using ADNS, don't ask for all network protocols when connecting,
+ because this can lead to confusing "Protocol not supported" errors if the
+ network is down. Closes [#1062].
+- Fix outgoing retained messages not being sent by bridges on initial
+ connection. Closes [#1040].
+- Don't reload `auth_opt_` options on reload, to match the behaviour of the
+ other plugin options. Closes [#1068].
+- Print message on error when installing/uninstalling as a Windows service.
+- All non-error connect/disconnect messages are controlled by the
+ `connection_messages` option. Closes [#772]. Closes [#613]. Closes [#537].
+
+## Library
+- Fix reconnect delay backoff behaviour. Closes [#1027].
+- Don't call `on_disconnect()` twice if keepalive tests fail. Closes [#1067].
+
+## Client
+- Always print leading zeros in `mosquitto_sub` when output format is hex.
+ Closes [#1066].
+
+## Build
+- Fix building where TLS-PSK is not available. Closes [#68].
+
+
+[#68]: https://github.com/eclipse/mosquitto/issues/68
+[#537]: https://github.com/eclipse/mosquitto/issues/537
+[#613]: https://github.com/eclipse/mosquitto/issues/613
+[#772]: https://github.com/eclipse/mosquitto/issues/772
+[#1004]: https://github.com/eclipse/mosquitto/issues/1004
+[#1027]: https://github.com/eclipse/mosquitto/issues/1027
+[#1040]: https://github.com/eclipse/mosquitto/issues/1040
+[#1062]: https://github.com/eclipse/mosquitto/issues/1062
+[#1066]: https://github.com/eclipse/mosquitto/issues/1066
+[#1067]: https://github.com/eclipse/mosquitto/issues/1067
+[#1068]: https://github.com/eclipse/mosquitto/issues/1068
+[#1073]: https://github.com/eclipse/mosquitto/issues/1073