Don't treact unexpected PUBACK/COMP as fatal.

This commit is contained in:
Roger A. Light 2020-03-28 23:33:01 +00:00
parent de25ff694e
commit 21f203b91a
9 changed files with 237 additions and 26 deletions

View File

@ -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 <C99 support. Closes #1622.

View File

@ -92,9 +92,7 @@ int handle__pubackcomp(struct mosquitto *mosq, const char *type)
log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received %s (Mid: %d, RC:%d)", mosq->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);

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -0,0 +1,40 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mosquitto.h>
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;
}

View File

@ -0,0 +1,40 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mosquitto.h>
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;
}

View File

@ -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 \
03-publish-c2b-qos1-disconnect.c \
03-publish-c2b-qos1-len.c \
03-publish-c2b-qos2.c \
03-publish-c2b-qos2-disconnect.c \
03-publish-c2b-qos2-len.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-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-disconnect.c \
03-publish-c2b-qos2-len.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 \

View File

@ -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']),