mirror of
https://github.com/eclipse-mosquitto/mosquitto.git
synced 2026-03-23 16:33:35 +08:00
Fix will messages being incorrectly delayed.
This occured if a client set session-expiry-interval=0 when using will-delay-interval>0. Closes #3505. Thanks to Julian Graf.
This commit is contained in:
committed by
Roger Light
parent
3a0f46aa20
commit
d0152406e3
@@ -7,6 +7,8 @@
|
|||||||
- Fix password length not being passed to MOSQ_EVT_BASIC_AUTH events.
|
- Fix password length not being passed to MOSQ_EVT_BASIC_AUTH events.
|
||||||
Closes #3490.
|
Closes #3490.
|
||||||
- Fix incorrect maximum-packet-size restriction. Closes #3503.
|
- Fix incorrect maximum-packet-size restriction. Closes #3503.
|
||||||
|
- Fix will messages being incorrectly delayed if a client set
|
||||||
|
session-expiry-interval=0 when using will-delay-interval>0. Closes #3505.
|
||||||
|
|
||||||
# Common lib:
|
# Common lib:
|
||||||
- Fix potential crash if reading a file in restricted mode and the group id
|
- Fix potential crash if reading a file in restricted mode and the group id
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ void context__cleanup(struct mosquitto *context, bool force_free)
|
|||||||
void context__send_will(struct mosquitto *ctxt)
|
void context__send_will(struct mosquitto *ctxt)
|
||||||
{
|
{
|
||||||
if(ctxt->state != mosq_cs_disconnecting && ctxt->will){
|
if(ctxt->state != mosq_cs_disconnecting && ctxt->will){
|
||||||
if(ctxt->will_delay_interval > 0){
|
if(ctxt->session_expiry_interval > 0 && ctxt->will_delay_interval > 0){
|
||||||
will_delay__add(ctxt);
|
will_delay__add(ctxt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,12 +14,13 @@ def do_test(start_broker):
|
|||||||
connect1_packet = mosq_test.gen_connect("will-delay-reconnect-test", proto_ver=5)
|
connect1_packet = mosq_test.gen_connect("will-delay-reconnect-test", proto_ver=5)
|
||||||
connack1_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
|
connack1_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
|
||||||
|
|
||||||
props = mqtt5_props.gen_uint32_prop(mqtt5_props.WILL_DELAY_INTERVAL, 3)
|
props = mqtt5_props.gen_uint32_prop(mqtt5_props.SESSION_EXPIRY_INTERVAL, 60)
|
||||||
connect2a_packet = mosq_test.gen_connect("will-delay-reconnect-helper", proto_ver=5, will_topic="will/delay/reconnect/test", will_payload=b"will delay", will_properties=props, clean_session=False)
|
will_props = mqtt5_props.gen_uint32_prop(mqtt5_props.WILL_DELAY_INTERVAL, 3)
|
||||||
|
connect2a_packet = mosq_test.gen_connect("will-delay-reconnect-helper", proto_ver=5, will_topic="will/delay/reconnect/test", will_payload=b"will delay", will_properties=will_props, clean_session=False, properties=props)
|
||||||
connack2a_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
|
connack2a_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
|
||||||
|
|
||||||
connect2b_packet = mosq_test.gen_connect("will-delay-reconnect-helper", proto_ver=5, clean_session=True)
|
connect2b_packet = mosq_test.gen_connect("will-delay-reconnect-helper", proto_ver=5, clean_session=False)
|
||||||
connack2b_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
|
connack2b_packet = mosq_test.gen_connack(rc=0, flags=1, proto_ver=5)
|
||||||
|
|
||||||
subscribe_packet = mosq_test.gen_subscribe(mid, "will/delay/reconnect/test", 0, proto_ver=5)
|
subscribe_packet = mosq_test.gen_subscribe(mid, "will/delay/reconnect/test", 0, proto_ver=5)
|
||||||
suback_packet = mosq_test.gen_suback(mid, 0, proto_ver=5)
|
suback_packet = mosq_test.gen_suback(mid, 0, proto_ver=5)
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ def do_test(start_broker, clean_session):
|
|||||||
|
|
||||||
connect2_packet_clear = mosq_test.gen_connect("will-delay-recovery-helper", proto_ver=5)
|
connect2_packet_clear = mosq_test.gen_connect("will-delay-recovery-helper", proto_ver=5)
|
||||||
|
|
||||||
|
will_packet = mosq_test.gen_publish(topic="will/delay/recovery/test", payload="will delay", qos=0, proto_ver=5)
|
||||||
|
|
||||||
port = mosq_test.get_port()
|
port = mosq_test.get_port()
|
||||||
if start_broker:
|
if start_broker:
|
||||||
broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
|
broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
|
||||||
@@ -43,8 +45,13 @@ def do_test(start_broker, clean_session):
|
|||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
|
|
||||||
# The client2 has reconnected within the will delay interval, which has now
|
# The client2 has reconnected within the will delay interval, which has now
|
||||||
# passed. We should not have received the will at this point.
|
# passed.
|
||||||
mosq_test.do_ping(sock1)
|
if clean_session:
|
||||||
|
# The old session has ended, so we should receive the will
|
||||||
|
mosq_test.expect_packet(sock1, "will", will_packet)
|
||||||
|
else:
|
||||||
|
# We should not have received the will at this point.
|
||||||
|
mosq_test.do_ping(sock1)
|
||||||
rc = 0
|
rc = 0
|
||||||
|
|
||||||
sock1.close()
|
sock1.close()
|
||||||
|
|||||||
65
test/broker/07-will-delay-session-expiry-0.py
Executable file
65
test/broker/07-will-delay-session-expiry-0.py
Executable file
@@ -0,0 +1,65 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Test whether a client that connects with a will delay that is longer than
|
||||||
|
# their session expiry interval has their will published.
|
||||||
|
# MQTT 5
|
||||||
|
# https://github.com/eclipse/mosquitto/issues/1401
|
||||||
|
|
||||||
|
from mosq_test_helper import *
|
||||||
|
|
||||||
|
def do_test(start_broker):
|
||||||
|
rc = 1
|
||||||
|
|
||||||
|
mid = 1
|
||||||
|
connect1_packet = mosq_test.gen_connect("will-session-exp", proto_ver=5)
|
||||||
|
connack1_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
|
||||||
|
|
||||||
|
will_props = mqtt5_props.gen_uint32_prop(mqtt5_props.WILL_DELAY_INTERVAL, 60)
|
||||||
|
connect_props = mqtt5_props.gen_uint32_prop(mqtt5_props.SESSION_EXPIRY_INTERVAL, 0)
|
||||||
|
|
||||||
|
connect2_packet = mosq_test.gen_connect("will-session-exp-helper", proto_ver=5, properties=connect_props, will_topic="will/session-expiry/test", will_payload=b"will delay", will_qos=2, will_properties=will_props)
|
||||||
|
connack2_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
|
||||||
|
|
||||||
|
subscribe_packet = mosq_test.gen_subscribe(mid, "will/session-expiry/test", 0, proto_ver=5)
|
||||||
|
suback_packet = mosq_test.gen_suback(mid, 0, proto_ver=5)
|
||||||
|
|
||||||
|
publish_packet = mosq_test.gen_publish("will/session-expiry/test", qos=0, payload="will delay", proto_ver=5)
|
||||||
|
|
||||||
|
port = mosq_test.get_port()
|
||||||
|
if start_broker:
|
||||||
|
broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
|
||||||
|
|
||||||
|
try:
|
||||||
|
sock1 = mosq_test.do_client_connect(connect1_packet, connack1_packet, timeout=5, port=port, connack_error="connack1")
|
||||||
|
mosq_test.do_send_receive(sock1, subscribe_packet, suback_packet, "suback")
|
||||||
|
|
||||||
|
sock2 = mosq_test.do_client_connect(connect2_packet, connack2_packet, timeout=5, port=port, connack_error="connack2")
|
||||||
|
time.sleep(1)
|
||||||
|
sock2.close()
|
||||||
|
|
||||||
|
# Will should be sent immediately due to session-expiry-interval=0. If not, the read will timeout
|
||||||
|
mosq_test.expect_packet(sock1, "publish", publish_packet)
|
||||||
|
rc = 0
|
||||||
|
|
||||||
|
sock1.close()
|
||||||
|
except mosq_test.TestError:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
if start_broker:
|
||||||
|
broker.terminate()
|
||||||
|
if mosq_test.wait_for_subprocess(broker):
|
||||||
|
print("broker not terminated")
|
||||||
|
if rc == 0: rc=1
|
||||||
|
(stdo, stde) = broker.communicate()
|
||||||
|
if rc:
|
||||||
|
print(stde.decode('utf-8'))
|
||||||
|
exit(rc)
|
||||||
|
else:
|
||||||
|
return rc
|
||||||
|
|
||||||
|
|
||||||
|
def all_tests(start_broker=False):
|
||||||
|
return do_test(start_broker)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
all_tests(True)
|
||||||
@@ -12,8 +12,9 @@ def do_test(start_broker, clean_session):
|
|||||||
connect1_packet = mosq_test.gen_connect("will-delay-test", proto_ver=5)
|
connect1_packet = mosq_test.gen_connect("will-delay-test", proto_ver=5)
|
||||||
connack1_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
|
connack1_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
|
||||||
|
|
||||||
props = mqtt5_props.gen_uint32_prop(mqtt5_props.WILL_DELAY_INTERVAL, 3)
|
props = mqtt5_props.gen_uint32_prop(mqtt5_props.SESSION_EXPIRY_INTERVAL, 60)
|
||||||
connect2_packet = mosq_test.gen_connect("will-delay-helper", proto_ver=5, will_topic="will/delay/test", will_payload=b"will delay", will_qos=2, will_properties=props, clean_session=clean_session)
|
will_props = mqtt5_props.gen_uint32_prop(mqtt5_props.WILL_DELAY_INTERVAL, 3)
|
||||||
|
connect2_packet = mosq_test.gen_connect("will-delay-helper", proto_ver=5, properties=props, will_topic="will/delay/test", will_payload=b"will delay", will_qos=2, will_properties=will_props, clean_session=clean_session)
|
||||||
connack2_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
|
connack2_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
|
||||||
|
|
||||||
subscribe_packet = mosq_test.gen_subscribe(mid, "will/delay/test", 0, proto_ver=5)
|
subscribe_packet = mosq_test.gen_subscribe(mid, "will/delay/test", 0, proto_ver=5)
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ msg_sequence_test:
|
|||||||
./07-will-delay-invalid-573191.py
|
./07-will-delay-invalid-573191.py
|
||||||
./07-will-delay-reconnect.py
|
./07-will-delay-reconnect.py
|
||||||
./07-will-delay-recover.py
|
./07-will-delay-recover.py
|
||||||
|
./07-will-delay-session-expiry-0.py
|
||||||
./07-will-delay-session-expiry.py
|
./07-will-delay-session-expiry.py
|
||||||
./07-will-delay-session-expiry2.py
|
./07-will-delay-session-expiry2.py
|
||||||
./07-will-delay.py
|
./07-will-delay.py
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ tests = [
|
|||||||
(1, './07-will-delay-invalid-573191.py'),
|
(1, './07-will-delay-invalid-573191.py'),
|
||||||
(1, './07-will-delay-reconnect.py'),
|
(1, './07-will-delay-reconnect.py'),
|
||||||
(1, './07-will-delay-recover.py'),
|
(1, './07-will-delay-recover.py'),
|
||||||
|
(1, './07-will-delay-session-expiry-0.py'),
|
||||||
(1, './07-will-delay-session-expiry.py'),
|
(1, './07-will-delay-session-expiry.py'),
|
||||||
(1, './07-will-delay-session-expiry2.py'),
|
(1, './07-will-delay-session-expiry2.py'),
|
||||||
(1, './07-will-delay.py'),
|
(1, './07-will-delay.py'),
|
||||||
|
|||||||
Reference in New Issue
Block a user