diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b4b2bf5b..c3b76c99 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,6 +47,10 @@ There are further details at - +If your contribution is a fix for a bug, please use the 'fixes' branch as the +base for your work. If you are proposing new behaviour/features please use the +'develop' branch. + Once the patch is pushed back to Gerrit, the project committers will be informed and they will undertake a review of the code. The patch may need modifying for some reason. In order to make amending commits more diff --git a/ChangeLog.txt b/ChangeLog.txt index 2f995431..a3cf20b2 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -36,6 +36,41 @@ Client: - Add -U to mosquitto_sub for unsubscribing from topics. +1.4.7 - 20151221 +================ + +Broker: +- Fix support for libwebsockets 1.22. + + +1.4.6 - 20151220 +================ + +Broker: +- Add support for libwebsockets 1.6. + +Client library: +- Fix _mosquitto_socketpair() on Windows, reducing the chance of delays when + publishing. Closes #483979. + +Clients: +- Fix "mosquitto_pub -l" stripping the final character on a line. Closes + #483981. + + +1.4.5 - 20151108 +================ + +Broker: +- Fix possible memory leak if bridge using SSL attempts to connect to a + host that is not up. +- Free unused topic tree elements (fix in 1.4.3 was incomplete). Closes + #468987. + +Clients: +- "mosquitto_pub -l" now no longer limited to 1024 byte lines. Closes #478917. + + 1.4.4 - 20150916 ================ diff --git a/client/pub_client.c b/client/pub_client.c index b2a2e8dd..c8ca981a 100644 --- a/client/pub_client.c +++ b/client/pub_client.c @@ -290,10 +290,20 @@ void print_usage(void) int main(int argc, char *argv[]) { struct mosq_config cfg; - char buf[1024]; struct mosquitto *mosq = NULL; int rc; int rc2; + char *buf; + int buf_len = 1024; + int buf_len_actual; + int read_len; + int pos; + + buf = malloc(buf_len); + if(!buf){ + fprintf(stderr, "Error: Out of memory.\n"); + return 1; + } memset(&cfg, 0, sizeof(struct mosq_config)); rc = client_config_load(&cfg, CLIENT_PUB, argc, argv); @@ -376,14 +386,30 @@ int main(int argc, char *argv[]) do{ if(mode == MSGMODE_STDIN_LINE){ if(status == STATUS_CONNACK_RECVD){ - if(fgets(buf, 1024, stdin)){ - buf[strlen(buf)-1] = '\0'; - rc2 = mosquitto_publish(mosq, &mid_sent, topic, strlen(buf), buf, qos, retain); - if(rc2){ - if(!quiet) fprintf(stderr, "Error: Publish returned %d, disconnecting.\n", rc2); - mosquitto_disconnect(mosq); + pos = 0; + read_len = buf_len; + while(fgets(&buf[pos], read_len, stdin)){ + buf_len_actual = strlen(buf); + if(buf[buf_len_actual-1] == '\n'){ + buf[buf_len_actual-1] = '\0'; + rc2 = mosquitto_publish(mosq, &mid_sent, topic, buf_len_actual-1, buf, qos, retain); + if(rc2){ + if(!quiet) fprintf(stderr, "Error: Publish returned %d, disconnecting.\n", rc2); + mosquitto_disconnect(mosq); + } + break; + }else{ + buf_len += 1024; + pos += 1023; + read_len = 1024; + buf = realloc(buf, buf_len); + if(!buf){ + fprintf(stderr, "Error: Out of memory.\n"); + return 1; + } } - }else if(feof(stdin)){ + } + if(feof(stdin)){ last_mid = mid_sent; status = STATUS_WAITING; } diff --git a/lib/mosquitto.c b/lib/mosquitto.c index b8c7e3d2..fc5d736a 100644 --- a/lib/mosquitto.c +++ b/lib/mosquitto.c @@ -394,6 +394,15 @@ static int mosquitto__connect_init(struct mosquitto *mosq, const char *host, int mosq->keepalive = keepalive; + if(mosq->sockpairR != INVALID_SOCKET){ + COMPAT_CLOSE(mosq->sockpairR); + mosq->sockpairR = INVALID_SOCKET; + } + if(mosq->sockpairW != INVALID_SOCKET){ + COMPAT_CLOSE(mosq->sockpairW); + mosq->sockpairW = INVALID_SOCKET; + } + if(net__socketpair(&mosq->sockpairR, &mosq->sockpairW)){ log__printf(mosq, MOSQ_LOG_WARNING, "Warning: Unable to open socket pair, outgoing publish commands may be delayed."); diff --git a/lib/mosquitto.h b/lib/mosquitto.h index 09353a97..4be9d5f5 100644 --- a/lib/mosquitto.h +++ b/lib/mosquitto.h @@ -577,6 +577,7 @@ libmosq_EXPORT int mosquitto_disconnect(struct mosquitto *mosq); * Note that although the MQTT protocol doesn't use message ids * for messages with QoS=0, libmosquitto assigns them message ids * so they can be tracked with this parameter. + * topic - null terminated string of the topic to publish to. * payloadlen - the size of the payload (bytes). Valid values are between 0 and * 268,435,455. * payload - pointer to the data to send. If payloadlen > 0 this must be a diff --git a/lib/mosquitto_internal.h b/lib/mosquitto_internal.h index 2677f2f7..91de1333 100644 --- a/lib/mosquitto_internal.h +++ b/lib/mosquitto_internal.h @@ -207,8 +207,12 @@ struct mosquitto { int sub_count; int pollfd_index; # ifdef WITH_WEBSOCKETS +# if defined(LWS_LIBRARY_VERSION_NUMBER) + struct lws *wsi; +# else struct libwebsocket_context *ws_context; struct libwebsocket *wsi; +# endif # endif #else # ifdef WITH_SOCKS diff --git a/lib/net_mosq.c b/lib/net_mosq.c index e36b8cb1..b2f356d8 100644 --- a/lib/net_mosq.c +++ b/lib/net_mosq.c @@ -669,10 +669,6 @@ int net__socketpair(mosq_sock_t *pairR, mosq_sock_t *pairW) continue; } - if(net__socket_nonblock(listensock)){ - continue; - } - if(family[i] == AF_INET){ sa->sin_family = family[i]; sa->sin_addr.s_addr = htonl(INADDR_LOOPBACK); @@ -689,6 +685,7 @@ int net__socketpair(mosq_sock_t *pairR, mosq_sock_t *pairW) continue; } if(net__socket_nonblock(spR)){ + COMPAT_CLOSE(spR); COMPAT_CLOSE(listensock); continue; } @@ -716,6 +713,7 @@ int net__socketpair(mosq_sock_t *pairR, mosq_sock_t *pairW) if(net__socket_nonblock(spW)){ COMPAT_CLOSE(spR); + COMPAT_CLOSE(spW); COMPAT_CLOSE(listensock); continue; } diff --git a/man/Makefile b/man/Makefile index daacab99..a0496869 100644 --- a/man/Makefile +++ b/man/Makefile @@ -64,7 +64,7 @@ html : *.xml set -e; for m in *.xml; \ do \ hfile=$$(echo $${m} | sed -e 's#\(.*\)\.xml#\1#' | sed -e 's/\./-/g'); \ - $(XSLTPROC) html.xsl $${m} > $${hfile}.php; \ + $(XSLTPROC) html.xsl $${m} > $${hfile}.html; \ done potgen : diff --git a/man/html.xsl b/man/html.xsl index d7f9001f..44f00187 100644 --- a/man/html.xsl +++ b/man/html.xsl @@ -9,26 +9,4 @@ - - - - - - - - - ]]> - - - - - - - - - ]]> - - - - diff --git a/man/libmosquitto.3.xml b/man/libmosquitto.3.xml index b34683c5..ed122283 100644 --- a/man/libmosquitto.3.xml +++ b/man/libmosquitto.3.xml @@ -439,8 +439,8 @@ int main(int argc, char *argv[]) return 1; } - while(!mosquitto_loop(mosq, -1, 1)){ - } + mosquitto_loop_forever(mosq, -1, 1); + mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return 0; @@ -452,11 +452,11 @@ int main(int argc, char *argv[]) - mosquitto + mosquitto 8 - mqtt + mqtt 7 diff --git a/man/mosquitto-tls.7.xml b/man/mosquitto-tls.7.xml index ddb02aa8..1fa40f7f 100644 --- a/man/mosquitto-tls.7.xml +++ b/man/mosquitto-tls.7.xml @@ -80,13 +80,13 @@ - mosquitto + mosquitto 8 - mosquitto-conf + mosquitto-conf 5 diff --git a/man/mosquitto.8.xml b/man/mosquitto.8.xml index 3cb72a04..4b6fd651 100644 --- a/man/mosquitto.8.xml +++ b/man/mosquitto.8.xml @@ -481,49 +481,49 @@ - mqtt + mqtt 7 - mosquitto-tls + mosquitto-tls 7 - mosquitto.conf + mosquitto.conf 5 - hosts_access + hosts_access 5 - mosquitto_passwd + mosquitto_passwd 1 - mosquitto_pub + mosquitto_pub 1 - mosquitto_sub + mosquitto_sub 1 - libmosquitto + libmosquitto 3 diff --git a/man/mosquitto.conf.5.xml b/man/mosquitto.conf.5.xml index d3a8d54b..aa6ace00 100644 --- a/man/mosquitto.conf.5.xml +++ b/man/mosquitto.conf.5.xml @@ -1421,25 +1421,25 @@ topic clients/total in 0 test/mosquitto/org $SYS/broker/ - mosquitto + mosquitto 8 - mosquitto_passwd + mosquitto_passwd 1 - mosquitto-tls + mosquitto-tls 7 - mqtt + mqtt 7 diff --git a/man/mosquitto_passwd.1.xml b/man/mosquitto_passwd.1.xml index 88324e75..6a75b8d4 100644 --- a/man/mosquitto_passwd.1.xml +++ b/man/mosquitto_passwd.1.xml @@ -132,19 +132,19 @@ - mosquitto + mosquitto 8 - mosquitto.conf + mosquitto.conf 5 - mqtt + mqtt 7 diff --git a/man/mosquitto_pub.1.xml b/man/mosquitto_pub.1.xml index 5b5795fc..c896dc33 100644 --- a/man/mosquitto_pub.1.xml +++ b/man/mosquitto_pub.1.xml @@ -485,31 +485,31 @@ - mqtt + mqtt 7 - mosquitto_sub + mosquitto_sub 1 - mosquitto + mosquitto 8 - libmosquitto + libmosquitto 3 - mosquitto-tls + mosquitto-tls 7 diff --git a/man/mosquitto_sub.1.xml b/man/mosquitto_sub.1.xml index aff023d9..d31d1046 100644 --- a/man/mosquitto_sub.1.xml +++ b/man/mosquitto_sub.1.xml @@ -568,31 +568,31 @@ - mqtt + mqtt 7 - mosquitto_pub + mosquitto_pub 1 - mosquitto + mosquitto 8 - libmosquitto + libmosquitto 3 - mosquitto-tls + mosquitto-tls 7 diff --git a/man/mqtt.7.xml b/man/mqtt.7.xml index b6473471..dc06582a 100644 --- a/man/mqtt.7.xml +++ b/man/mqtt.7.xml @@ -161,19 +161,19 @@ - mosquitto + mosquitto 8 - mosquitto_pub + mosquitto_pub 1 - mosquitto_sub + mosquitto_sub 1 diff --git a/src/bridge.c b/src/bridge.c index 0f1ad03c..c3787e6e 100644 --- a/src/bridge.c +++ b/src/bridge.c @@ -180,6 +180,7 @@ int bridge__connect(struct mosquitto_db *db, struct mosquitto *context) rc = net__socket_connect(context, context->bridge->addresses[context->bridge->cur_address].address, context->bridge->addresses[context->bridge->cur_address].port, NULL, false); if(rc > 0 ){ if(rc == MOSQ_ERR_TLS){ + _mosquitto_socket_close(db, context); return rc; /* Error already printed */ }else if(rc == MOSQ_ERR_ERRNO){ log__printf(NULL, MOSQ_LOG_ERR, "Error creating bridge: %s.", strerror(errno)); diff --git a/src/mosquitto_broker.h b/src/mosquitto_broker.h index 2431bca4..7dbeecea 100644 --- a/src/mosquitto_broker.h +++ b/src/mosquitto_broker.h @@ -20,6 +20,25 @@ Contributors: #include "config.h" #include +#ifdef WITH_WEBSOCKETS +# include + +# if defined(LWS_LIBRARY_VERSION_NUMBER) +# define libwebsocket_callback_on_writable(A, B) lws_callback_on_writable((B)) +# define libwebsocket_service(A, B) lws_service((A), (B)) +# define libwebsocket_create_context(A) lws_create_context((A)) +# define libwebsocket_context_destroy(A) lws_context_destroy((A)) +# define libwebsocket_write(A, B, C, D) lws_write((A), (B), (C), (D)) +# define libwebsocket_get_socket_fd(A) lws_get_socket_fd((A)) +# define libwebsockets_return_http_status(A, B, C, D) lws_return_http_status((B), (C), (D)) + +# define libwebsocket_context lws_context +# define libwebsocket_protocols lws_protocols +# define libwebsocket_callback_reasons lws_callback_reasons +# define libwebsocket lws +# endif +#endif + #include "mosquitto_internal.h" #include "mosquitto_plugin.h" #include "mosquitto.h" @@ -560,7 +579,11 @@ void service_run(void); * Websockets related functions * ============================================================ */ #ifdef WITH_WEBSOCKETS -struct libwebsocket_context *mosq_websockets_init(struct mosquitto__listener *listener, int log_level); +# if defined(LWS_LIBRARY_VERSION_NUMBER) +struct lws_context *mosq_websockets_init(struct _mqtt3_listener *listener, int log_level); +# else +struct libwebsocket_context *mosq_websockets_init(struct _mqtt3_listener *listener, int log_level); +# endif #endif void do_disconnect(struct mosquitto_db *db, struct mosquitto *context); diff --git a/src/read_handle_server.c b/src/read_handle_server.c index 7da5f24d..d137f2aa 100644 --- a/src/read_handle_server.c +++ b/src/read_handle_server.c @@ -34,7 +34,7 @@ Contributors: #endif #ifdef WITH_WEBSOCKETS -#include +# include #endif static char *client_id_gen(struct mosquitto_db *db) diff --git a/src/subs.c b/src/subs.c index 9c77094e..37192d96 100644 --- a/src/subs.c +++ b/src/subs.c @@ -559,18 +559,20 @@ static struct mosquitto__subhier *tmp_remove_subs(struct mosquitto__subhier *sub if(!sub || !sub->parent){ return NULL; } - if(sub->children || sub->subs || sub->next){ + + if(sub->children || sub->subs){ return NULL; } parent = sub->parent; hier = sub->parent->children; + while(hier){ if(hier == sub){ if(last){ - last->next = sub->next; + last->next = hier->next; }else{ - parent->children = NULL; + parent->children = hier->next; } UHPA_FREE_TOPIC(sub); mosquitto__free(sub); diff --git a/src/websockets.c b/src/websockets.c index c3e47e41..f812f0fe 100644 --- a/src/websockets.c +++ b/src/websockets.c @@ -43,13 +43,22 @@ POSSIBILITY OF SUCH DAMAGE. extern struct mosquitto_db int_db; +#if defined(LWS_LIBRARY_VERSION_NUMBER) +static int callback_mqtt( +#else static int callback_mqtt(struct libwebsocket_context *context, +#endif struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len); + +#if defined(LWS_LIBRARY_VERSION_NUMBER) +static int callback_http( +#else static int callback_http(struct libwebsocket_context *context, +#endif struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, @@ -77,7 +86,9 @@ static struct libwebsocket_protocols protocols[] = { 0, #endif NULL, +#if !defined(LWS_LIBRARY_VERSION_NUMBER) 0 +#endif }, { "mqtt", @@ -88,7 +99,9 @@ static struct libwebsocket_protocols protocols[] = { 1, #endif NULL, +#if !defined(LWS_LIBRARY_VERSION_NUMBER) 0 +#endif }, { "mqttv3.1", @@ -99,10 +112,16 @@ static struct libwebsocket_protocols protocols[] = { 1, #endif NULL, +#if !defined(LWS_LIBRARY_VERSION_NUMBER) 0 +#endif }, #ifdef LWS_FEATURE_PROTOCOLS_HAS_ID_FIELD +# if defined(LWS_LIBRARY_VERSION_NUMBER) + { NULL, NULL, 0, 0, 0, NULL} +# else { NULL, NULL, 0, 0, 0, NULL, 0} +# endif #else { NULL, NULL, 0, 0, NULL, 0} #endif @@ -117,7 +136,11 @@ static void easy_address(int sock, struct mosquitto *mosq) } } +#if defined(LWS_LIBRARY_VERSION_NUMBER) +static int callback_mqtt( +#else static int callback_mqtt(struct libwebsocket_context *context, +#endif struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, @@ -140,7 +163,9 @@ static int callback_mqtt(struct libwebsocket_context *context, case LWS_CALLBACK_ESTABLISHED: mosq = context__init(db, WEBSOCKET_CLIENT); if(mosq){ +#if !defined(LWS_LIBRARY_VERSION_NUMBER) mosq->ws_context = context; +#endif mosq->wsi = wsi; u->mosq = mosq; }else{ @@ -319,7 +344,11 @@ static int callback_mqtt(struct libwebsocket_context *context, } +#if defined(LWS_LIBRARY_VERSION_NUMBER) +static int callback_http( +#else static int callback_http(struct libwebsocket_context *context, +#endif struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, @@ -343,7 +372,11 @@ static int callback_http(struct libwebsocket_context *context, return -1; } +#if defined(LWS_LIBRARY_VERSION_NUMBER) + hack = (struct libws_mqtt_hack *)lws_context_user(lws_get_context(wsi)); +#else hack = (struct libws_mqtt_hack *)libwebsocket_context_user(context); +#endif if(!hack){ return -1; }