diff --git a/ChangeLog.txt b/ChangeLog.txt index 5dc3fc23..31076c58 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -3,7 +3,8 @@ Broker: rather than letting the bridge fail later. Issue #1635. Client library: -- Don't treat an unexpected PUBREL as a fatal error. Issue #1629. +- Don't treat an unexpected PUBACK, PUBREL, or PUBCOMP as a fatal error. + Issue #1629. Build: - Various fixes for building with id, type, mid, reason_code); rc = message__delete(mosq, mid, mosq_md_out, qos); - if(rc){ - return rc; - }else{ + if(rc == MOSQ_ERR_SUCCESS){ /* Only inform the client the message has been sent once. */ pthread_mutex_lock(&mosq->callback_mutex); if(mosq->on_publish){ @@ -109,6 +107,8 @@ int handle__pubackcomp(struct mosquitto *mosq, const char *type) } pthread_mutex_unlock(&mosq->callback_mutex); mosquitto_property_free_all(&properties); + }else if(rc != MOSQ_ERR_NOT_FOUND){ + return rc; } pthread_mutex_lock(&mosq->msgs_out.mutex); message__release_to_inflight(mosq, mosq_md_out); diff --git a/test/lib/03-publish-b2c-qos1-unexpected-puback.py b/test/lib/03-publish-b2c-qos1-unexpected-puback.py new file mode 100755 index 00000000..58921e98 --- /dev/null +++ b/test/lib/03-publish-b2c-qos1-unexpected-puback.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 + +from mosq_test_helper import * + +port = mosq_test.get_lib_port() + +rc = 1 +keepalive = 5 +connect_packet = mosq_test.gen_connect("publish-qos1-test", keepalive=keepalive) +connack_packet = mosq_test.gen_connack(rc=0) + +disconnect_packet = mosq_test.gen_disconnect() + +mid = 13423 +puback_packet = mosq_test.gen_puback(mid) +pingreq_packet = mosq_test.gen_pingreq() + +sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +sock.settimeout(10) +sock.bind(('', port)) +sock.listen(5) + +client_args = sys.argv[1:] +env = dict(os.environ) +env['LD_LIBRARY_PATH'] = '../../lib:../../lib/cpp' +try: + pp = env['PYTHONPATH'] +except KeyError: + pp = '' +env['PYTHONPATH'] = '../../lib/python:'+pp +client = mosq_test.start_client(filename=sys.argv[1].replace('/', '-'), cmd=client_args, env=env, port=port) + +try: + (conn, address) = sock.accept() + conn.settimeout(10) + + if mosq_test.expect_packet(conn, "connect", connect_packet): + conn.send(connack_packet) + conn.send(puback_packet) + + if mosq_test.expect_packet(conn, "pingreq", pingreq_packet): + rc = 0 + + conn.close() +finally: + for i in range(0, 5): + if client.returncode != None: + break + time.sleep(0.1) + + try: + client.terminate() + except OSError: + pass + + client.wait() + sock.close() + if rc != 0 or client.returncode != 0: + exit(1) + +exit(rc) diff --git a/test/lib/03-publish-b2c-qos2-unexpected-pubcomp.py b/test/lib/03-publish-b2c-qos2-unexpected-pubcomp.py new file mode 100755 index 00000000..8e73c7cd --- /dev/null +++ b/test/lib/03-publish-b2c-qos2-unexpected-pubcomp.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 + +from mosq_test_helper import * + +port = mosq_test.get_lib_port() + +rc = 1 +keepalive = 5 +connect_packet = mosq_test.gen_connect("publish-qos2-test", keepalive=keepalive) +connack_packet = mosq_test.gen_connack(rc=0) + +disconnect_packet = mosq_test.gen_disconnect() + +mid = 13423 +pubcomp_packet = mosq_test.gen_pubcomp(mid) +pingreq_packet = mosq_test.gen_pingreq() + +sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +sock.settimeout(10) +sock.bind(('', port)) +sock.listen(5) + +client_args = sys.argv[1:] +env = dict(os.environ) +env['LD_LIBRARY_PATH'] = '../../lib:../../lib/cpp' +try: + pp = env['PYTHONPATH'] +except KeyError: + pp = '' +env['PYTHONPATH'] = '../../lib/python:'+pp +client = mosq_test.start_client(filename=sys.argv[1].replace('/', '-'), cmd=client_args, env=env, port=port) + +try: + (conn, address) = sock.accept() + conn.settimeout(10) + + if mosq_test.expect_packet(conn, "connect", connect_packet): + conn.send(connack_packet) + conn.send(pubcomp_packet) + + if mosq_test.expect_packet(conn, "pingreq", pingreq_packet): + rc = 0 + + conn.close() +finally: + for i in range(0, 5): + if client.returncode != None: + break + time.sleep(0.1) + + try: + client.terminate() + except OSError: + pass + + client.wait() + sock.close() + if rc != 0 or client.returncode != 0: + exit(1) + +exit(rc) diff --git a/test/lib/Makefile b/test/lib/Makefile index 941bf02d..93603f5b 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -39,9 +39,11 @@ c : test-compile ./02-unsubscribe-v5.py $@/02-unsubscribe-v5.test ./02-unsubscribe.py $@/02-unsubscribe.test ./03-publish-b2c-qos1.py $@/03-publish-b2c-qos1.test + ./03-publish-b2c-qos1-unexpected-puback.py $@/03-publish-b2c-qos1-unexpected-puback.test ./03-publish-b2c-qos2-len.py $@/03-publish-b2c-qos2-len.test ./03-publish-b2c-qos2.py $@/03-publish-b2c-qos2.test ./03-publish-b2c-qos2-unexpected-pubrel.py $@/03-publish-b2c-qos2-unexpected-pubrel.test + ./03-publish-b2c-qos2-unexpected-pubcomp.py $@/03-publish-b2c-qos2-unexpected-pubcomp.test ./03-publish-c2b-qos1-disconnect.py $@/03-publish-c2b-qos1-disconnect.test ./03-publish-c2b-qos1-len.py $@/03-publish-c2b-qos1-len.test ./03-publish-c2b-qos1-receive-maximum.py $@/03-publish-c2b-qos1-receive-maximum.test diff --git a/test/lib/c/03-publish-b2c-qos1-unexpected-puback.c b/test/lib/c/03-publish-b2c-qos1-unexpected-puback.c new file mode 100644 index 00000000..688b0907 --- /dev/null +++ b/test/lib/c/03-publish-b2c-qos1-unexpected-puback.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include + +static int run = -1; + +void on_connect(struct mosquitto *mosq, void *obj, int rc) +{ + if(rc){ + printf("Connect error: %d\n", rc); + exit(1); + } +} + +int main(int argc, char *argv[]) +{ + int rc; + struct mosquitto *mosq; + + int port = atoi(argv[1]); + + mosquitto_lib_init(); + + mosq = mosquitto_new("publish-qos1-test", true, &run); + mosquitto_connect_callback_set(mosq, on_connect); + + rc = mosquitto_connect(mosq, "localhost", port, 5); + + while(run == -1){ + rc = mosquitto_loop(mosq, 300, 1); + if(rc){ + exit(0); + } + } + + mosquitto_lib_cleanup(); + return 0; +} diff --git a/test/lib/c/03-publish-b2c-qos2-unexpected-pubcomp.c b/test/lib/c/03-publish-b2c-qos2-unexpected-pubcomp.c new file mode 100644 index 00000000..414c181c --- /dev/null +++ b/test/lib/c/03-publish-b2c-qos2-unexpected-pubcomp.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include + +static int run = -1; + +void on_connect(struct mosquitto *mosq, void *obj, int rc) +{ + if(rc){ + printf("Connect error: %d\n", rc); + exit(1); + } +} + +int main(int argc, char *argv[]) +{ + int rc; + struct mosquitto *mosq; + + int port = atoi(argv[1]); + + mosquitto_lib_init(); + + mosq = mosquitto_new("publish-qos2-test", true, &run); + mosquitto_connect_callback_set(mosq, on_connect); + + rc = mosquitto_connect(mosq, "localhost", port, 5); + + while(run == -1){ + rc = mosquitto_loop(mosq, 300, 1); + if(rc){ + exit(0); + } + } + + mosquitto_lib_cleanup(); + return 0; +} diff --git a/test/lib/c/Makefile b/test/lib/c/Makefile index 91d5a95c..7cae716d 100644 --- a/test/lib/c/Makefile +++ b/test/lib/c/Makefile @@ -5,45 +5,47 @@ LIBS=../../../lib/libmosquitto.so.1 SRC = \ 01-con-discon-success.c \ - 01-will-set.c \ - 01-unpwd-set.c \ - 01-will-unpwd-set.c \ - 01-no-clean-session.c \ 01-keepalive-pingreq.c \ + 01-no-clean-session.c \ 01-server-keepalive-pingreq.c \ + 01-unpwd-set.c \ + 01-will-set.c \ + 01-will-unpwd-set.c \ 02-subscribe-qos0.c \ - 02-subscribe-qos1.c \ 02-subscribe-qos1-async1.c \ 02-subscribe-qos1-async2.c \ + 02-subscribe-qos1.c \ 02-subscribe-qos2.c \ - 02-unsubscribe.c \ - 02-unsubscribe-v5.c \ 02-unsubscribe-multiple-v5.c \ - 03-publish-qos0.c \ - 03-publish-qos0-no-payload.c \ + 02-unsubscribe-v5.c \ + 02-unsubscribe.c \ + 03-publish-b2c-qos1-unexpected-puback.c \ + 03-publish-b2c-qos1.c \ + 03-publish-b2c-qos2-len.c \ + 03-publish-b2c-qos2-unexpected-pubrel.c \ + 03-publish-b2c-qos2-unexpected-pubcomp.c \ + 03-publish-b2c-qos2.c \ 03-publish-c2b-qos1-disconnect.c \ 03-publish-c2b-qos1-len.c \ - 03-publish-c2b-qos2.c \ + 03-publish-c2b-qos1-receive-maximum.c \ 03-publish-c2b-qos2-disconnect.c \ 03-publish-c2b-qos2-len.c \ - 03-publish-b2c-qos2-len.c \ - 03-publish-b2c-qos2-unexpected-pubrel.c \ - 03-publish-c2b-qos1-receive-maximum.c \ - 03-publish-c2b-qos2-receive-maximum-1.c \ - 03-publish-c2b-qos2-receive-maximum-2.c \ - 03-publish-c2b-qos2-pubrec-error.c \ 03-publish-c2b-qos2-maximum-qos-0.c \ 03-publish-c2b-qos2-maximum-qos-1.c \ - 03-publish-b2c-qos1.c \ - 03-publish-b2c-qos2.c \ + 03-publish-c2b-qos2-pubrec-error.c \ + 03-publish-c2b-qos2-receive-maximum-1.c \ + 03-publish-c2b-qos2-receive-maximum-2.c \ + 03-publish-c2b-qos2.c \ + 03-publish-qos0-no-payload.c \ + 03-publish-qos0.c \ 03-request-response-1.c \ 03-request-response-2.c \ 03-request-response-correlation-1.c \ 04-retain-qos0.c \ - 08-ssl-connect-no-auth.c \ - 08-ssl-connect-cert-auth.c \ - 08-ssl-connect-cert-auth-enc.c \ 08-ssl-bad-cacert.c \ + 08-ssl-connect-cert-auth-enc.c \ + 08-ssl-connect-cert-auth.c \ + 08-ssl-connect-no-auth.c \ 08-ssl-fake-cacert.c \ 09-util-topic-tokenise.c \ 11-prop-oversize-packet.c \ diff --git a/test/lib/test.py b/test/lib/test.py index 885055a7..eb56e718 100755 --- a/test/lib/test.py +++ b/test/lib/test.py @@ -22,8 +22,10 @@ tests = [ (1, ['./02-unsubscribe.py', 'c/02-unsubscribe.test']), (1, ['./03-publish-b2c-qos1.py', 'c/03-publish-b2c-qos1.test']), + (1, ['./03-publish-b2c-qos1-unexpected-puback.py', 'c/03-publish-b2c-qos1-unexpected-puback.test']), (1, ['./03-publish-b2c-qos2-len.py', 'c/03-publish-b2c-qos2-len.test']), (1, ['./03-publish-b2c-qos2-unexpected-pubrel.py', 'c/03-publish-b2c-qos2-unexpected-pubrel.test']), + (1, ['./03-publish-b2c-qos2-unexpected-pubcomp.py', 'c/03-publish-b2c-qos2-unexpected-pubcomp.test']), (1, ['./03-publish-b2c-qos2.py', 'c/03-publish-b2c-qos2.test']), (1, ['./03-publish-c2b-qos1-disconnect.py', 'c/03-publish-c2b-qos1-disconnect.test']), (1, ['./03-publish-c2b-qos1-len.py', 'c/03-publish-c2b-qos1-len.test']),