Send topic alias maximum from the broker.
This commit is contained in:
parent
e4db8707a6
commit
75c2a39d2c
@ -952,6 +952,16 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S
|
||||
<para>Not reloaded on reload signal.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>max_topic_alias</option> <replaceable>number</replaceable></term>
|
||||
<listitem>
|
||||
<para>This option sets the maximum number topic aliases
|
||||
that an MQTT v5 client is allowed to create. It
|
||||
applies per listener. Defaults to 10. Set to 0 to
|
||||
disallow topic aliases.</para>
|
||||
<para>Not reloaded on reload signal.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>mount_point</option> <replaceable>topic prefix</replaceable></term>
|
||||
<listitem>
|
||||
|
12
src/conf.c
12
src/conf.c
@ -272,6 +272,7 @@ void config__init(struct mosquitto_db *db, struct mosquitto__config *config)
|
||||
config->default_listener.protocol = mp_mqtt;
|
||||
config->default_listener.security_options.allow_anonymous = -1;
|
||||
config->default_listener.maximum_qos = 2;
|
||||
config->default_listener.max_topic_alias = 10;
|
||||
}
|
||||
|
||||
void config__cleanup(struct mosquitto__config *config)
|
||||
@ -507,6 +508,7 @@ int config__parse_args(struct mosquitto_db *db, struct mosquitto__config *config
|
||||
config->listeners[config->listener_count-1].tls_engine = config->default_listener.tls_engine;
|
||||
config->listeners[config->listener_count-1].tls_keyform = config->default_listener.tls_keyform;
|
||||
config->listeners[config->listener_count-1].tls_engine_kpass_sha1 = config->default_listener.tls_engine_kpass_sha1;
|
||||
config->listeners[config->listener_count-1].max_topic_alias = config->default_listener.max_topic_alias;
|
||||
config->listeners[config->listener_count-1].cafile = config->default_listener.cafile;
|
||||
config->listeners[config->listener_count-1].capath = config->default_listener.capath;
|
||||
config->listeners[config->listener_count-1].certfile = config->default_listener.certfile;
|
||||
@ -1344,6 +1346,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
|
||||
cur_listener->protocol = mp_mqtt;
|
||||
cur_listener->port = tmp_int;
|
||||
cur_listener->maximum_qos = 2;
|
||||
cur_listener->max_topic_alias = 10;
|
||||
token = strtok_r(NULL, " ", &saveptr);
|
||||
if (token != NULL && token[0] == '#'){
|
||||
token = NULL;
|
||||
@ -2072,6 +2075,15 @@ 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, "max_topic_alias")){
|
||||
if(reload) continue; // Listeners not valid for reloading.
|
||||
token = strtok_r(NULL, " ", &saveptr);
|
||||
if(token){
|
||||
cur_listener->max_topic_alias = atoi(token);
|
||||
if(cur_listener->max_topic_alias < 0) cur_listener->max_topic_alias = -1;
|
||||
}else{
|
||||
log__printf(NULL, MOSQ_LOG_ERR, "Error: Empty max_topic_alias value in configuration.");
|
||||
}
|
||||
}else if(!strcmp(token, "try_private")){
|
||||
#ifdef WITH_BRIDGE
|
||||
if(reload) continue; // FIXME
|
||||
|
@ -300,6 +300,12 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context)
|
||||
goto handle_connect_error;
|
||||
}
|
||||
}
|
||||
if(protocol_version == PROTOCOL_VERSION_v5 && context->listener->max_topic_alias > 0){
|
||||
if(mosquitto_property_add_int16(&connack_props, MQTT_PROP_TOPIC_ALIAS_MAXIMUM, context->listener->max_topic_alias)){
|
||||
rc = MOSQ_ERR_NOMEM;
|
||||
goto handle_connect_error;
|
||||
}
|
||||
}
|
||||
|
||||
if(packet__read_byte(&context->in_packet, &connect_flags)){
|
||||
rc = 1;
|
||||
|
@ -51,7 +51,7 @@ int handle__publish(struct mosquitto_db *db, struct mosquitto *context)
|
||||
mosquitto_property *p, *p_prev;
|
||||
mosquitto_property *msg_properties = NULL, *msg_properties_last;
|
||||
uint32_t message_expiry_interval = 0;
|
||||
uint16_t topic_alias = 0;
|
||||
int topic_alias = -1;
|
||||
uint8_t reason_code = 0;
|
||||
|
||||
#ifdef WITH_BRIDGE
|
||||
@ -160,19 +160,20 @@ int handle__publish(struct mosquitto_db *db, struct mosquitto *context)
|
||||
}
|
||||
mosquitto_property_free_all(&properties);
|
||||
|
||||
if(topic && topic_alias){
|
||||
if(topic_alias == 0 || topic_alias > context->listener->max_topic_alias){
|
||||
send__disconnect(context, MQTT_RC_TOPIC_ALIAS_INVALID, NULL);
|
||||
return MOSQ_ERR_PROTOCOL;
|
||||
}else if(topic_alias > 0){
|
||||
if(topic){
|
||||
rc = alias__add(context, topic, topic_alias);
|
||||
if(rc) return rc;
|
||||
}else if(topic == NULL && topic_alias){
|
||||
}else{
|
||||
rc = alias__find(context, &topic, topic_alias);
|
||||
if(rc){
|
||||
if(context->protocol == mosq_p_mqtt5){
|
||||
send__disconnect(context, MQTT_RC_TOPIC_ALIAS_INVALID, NULL);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
}else if(topic == NULL && topic_alias == 0){
|
||||
return MOSQ_ERR_PROTOCOL;
|
||||
}
|
||||
}
|
||||
if(mosquitto_validate_utf8(topic, slen) != MOSQ_ERR_SUCCESS){
|
||||
log__printf(NULL, MOSQ_LOG_INFO, "Client %s sent topic with invalid UTF-8, disconnecting.", context->id);
|
||||
|
@ -212,6 +212,7 @@ struct mosquitto__listener {
|
||||
int socket_domain;
|
||||
bool use_username_as_clientid;
|
||||
uint8_t maximum_qos;
|
||||
uint16_t max_topic_alias;
|
||||
#ifdef WITH_TLS
|
||||
char *cafile;
|
||||
char *capath;
|
||||
|
@ -9,7 +9,7 @@ rc = 1
|
||||
keepalive = 10
|
||||
props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_AUTHENTICATION_METHOD, "basic")
|
||||
connect_packet = mosq_test.gen_connect("connect-test", proto_ver=5, keepalive=keepalive, properties=props)
|
||||
connack_packet = mosq_test.gen_connack(rc=mqtt5_rc.MQTT_RC_BAD_AUTHENTICATION_METHOD, proto_ver=5)
|
||||
connack_packet = mosq_test.gen_connack(rc=mqtt5_rc.MQTT_RC_BAD_AUTHENTICATION_METHOD, proto_ver=5, properties=None)
|
||||
|
||||
port = mosq_test.get_port()
|
||||
broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
|
||||
|
37
test/broker/12-prop-topic-alias-invalid.py
Executable file
37
test/broker/12-prop-topic-alias-invalid.py
Executable file
@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Test whether the broker handles a topic alias of >max_topic_alias correctly.
|
||||
# MQTTv5
|
||||
|
||||
from mosq_test_helper import *
|
||||
|
||||
def do_test(value):
|
||||
rc = 1
|
||||
|
||||
keepalive = 10
|
||||
connect_packet = mosq_test.gen_connect("test", proto_ver=5, keepalive=keepalive)
|
||||
connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
|
||||
|
||||
props = mqtt5_props.gen_uint16_prop(mqtt5_props.PROP_TOPIC_ALIAS, value)
|
||||
publish_packet = mosq_test.gen_publish(topic="test/topic", qos=0, payload="12345678901234567890", proto_ver=5, properties=props)
|
||||
|
||||
disconnect_packet = mosq_test.gen_disconnect(reason_code=mqtt5_rc.MQTT_RC_TOPIC_ALIAS_INVALID, proto_ver=5)
|
||||
port = mosq_test.get_port()
|
||||
broker = mosq_test.start_broker(filename=os.path.basename(__file__), port=port)
|
||||
|
||||
try:
|
||||
sock = mosq_test.do_client_connect(connect_packet, connack_packet, port=port)
|
||||
sock.send(publish_packet)
|
||||
if mosq_test.expect_packet(sock, "disconnect", disconnect_packet):
|
||||
rc = 0
|
||||
finally:
|
||||
broker.terminate()
|
||||
broker.wait()
|
||||
(stdo, stde) = broker.communicate()
|
||||
if rc:
|
||||
print(stde)
|
||||
exit(rc)
|
||||
|
||||
|
||||
do_test(11)
|
||||
|
@ -198,3 +198,4 @@ endif
|
||||
./12-prop-session-expiry-invalid.py
|
||||
./12-prop-subpub-content-type.py
|
||||
./12-prop-subpub-payload-format.py
|
||||
./12-prop-topic-alias-invalid.py
|
||||
|
@ -165,6 +165,7 @@ tests = [
|
||||
(1, './12-prop-session-expiry-invalid.py'),
|
||||
(1, './12-prop-subpub-content-type.py'),
|
||||
(1, './12-prop-subpub-payload-format.py'),
|
||||
(1, './12-prop-topic-alias-invalid.py'),
|
||||
]
|
||||
|
||||
ptest.run_tests(tests)
|
||||
|
@ -389,6 +389,10 @@ def gen_connect(client_id, clean_session=True, keepalive=60, username=None, pass
|
||||
|
||||
def gen_connack(flags=0, rc=0, proto_ver=4, properties=""):
|
||||
if proto_ver == 5:
|
||||
if properties is not None:
|
||||
properties = mqtt5_props.gen_uint16_prop(mqtt5_props.PROP_TOPIC_ALIAS_MAXIMUM, 10) + properties
|
||||
else:
|
||||
properties = ""
|
||||
properties = mqtt5_props.prop_finalise(properties)
|
||||
|
||||
packet = struct.pack('!BBBB', 32, 2+len(properties), flags, rc) + properties
|
||||
|
Loading…
Reference in New Issue
Block a user