diff --git a/ChangeLog.txt b/ChangeLog.txt index d8e00efc..14d77fb3 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -40,6 +40,8 @@ Clients: - mosquitto_sub will now exit if all subscriptions were denied. - Add `--nodelay` to all clients to allow them to use the MOSQ_OPT_TCP_NODELAY option. +- Add `-x` to all clients to all the session-expiry-interval property to be + easily set for MQTT v5 clients. 1.6.8 - 20191128 diff --git a/client/client_shared.c b/client/client_shared.c index 05581bda..b0531fe7 100644 --- a/client/client_shared.c +++ b/client/client_shared.c @@ -366,10 +366,20 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char * } #endif - if(cfg->clean_session == false && (cfg->id_prefix || !cfg->id)){ + if(cfg->protocol_version != 5 && cfg->clean_session == false && (cfg->id_prefix || !cfg->id)){ fprintf(stderr, "Error: You must provide a client id if you are using the -c option.\n"); return 1; } + if(cfg->protocol_version == 5 && cfg->session_expiry_interval > 0){ + if(cfg->session_expiry_interval == UINT32_MAX && (cfg->id_prefix || !cfg->id)){ + fprintf(stderr, "Error: You must provide a client id if you are using an infinite session expiry interval.\n"); + return 1; + } + rc = mosquitto_property_add_int32(&cfg->connect_props, MQTT_PROP_SESSION_EXPIRY_INTERVAL, cfg->session_expiry_interval); + if(rc){ + fprintf(stderr, "Error adding property session-expiry-interval\n"); + } + } if(pub_or_sub == CLIENT_SUB){ if(cfg->topic_count == 0){ @@ -1083,6 +1093,32 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c cfg->will_topic = strdup(argv[i+1]); } i++; + }else if(!strcmp(argv[i], "-x")){ + if(i==argc-1){ + fprintf(stderr, "Error: -x argument given but no session expiry interval specified.\n\n"); + return 1; + }else{ + if(!strcmp(argv[i+1], "∞")){ + cfg->session_expiry_interval = UINT32_MAX; + }else{ + char *endptr = NULL; + cfg->session_expiry_interval = strtol(argv[i+1], &endptr, 0); + if(endptr == argv[i+1] || endptr[0] != '\0'){ + /* Entirety of argument wasn't a number */ + fprintf(stderr, "Error: session-expiry-interval not a number.\n\n"); + return 1; + } + if(cfg->session_expiry_interval > UINT32_MAX || cfg->session_expiry_interval < -1){ + fprintf(stderr, "Error: session-expiry-interval out of range.\n\n"); + return 1; + } + if(cfg->session_expiry_interval == -1){ + /* Convenience value for infinity. */ + cfg->session_expiry_interval = UINT32_MAX; + } + } + } + i++; }else{ goto unknown_option; } diff --git a/client/client_shared.h b/client/client_shared.h index 1d3235aa..5dc5e8ed 100644 --- a/client/client_shared.h +++ b/client/client_shared.h @@ -106,6 +106,7 @@ struct mosq_config { bool pretty; /* sub, rr */ int timeout; /* sub */ int sub_opts; /* sub */ + long session_expiry_interval; #ifdef WITH_SOCKS char *socks5_host; int socks5_port; diff --git a/client/pub_client.c b/client/pub_client.c index 156a4693..2b7a5baf 100644 --- a/client/pub_client.c +++ b/client/pub_client.c @@ -369,7 +369,7 @@ void print_usage(void) printf("mosquitto_pub version %s running on libmosquitto %d.%d.%d.\n\n", VERSION, major, minor, revision); printf("Usage: mosquitto_pub {[-h host] [--unix path] [-p port] [-u username] [-P password] -t topic | -L URL}\n"); printf(" {-f file | -l | -n | -m message}\n"); - printf(" [-c] [-k keepalive] [-q qos] [-r] [--repeat N] [--repeat-delay time]\n"); + printf(" [-c] [-k keepalive] [-q qos] [-r] [--repeat N] [--repeat-delay time] [-x session-expiry]\n"); #ifdef WITH_SRV printf(" [-A bind_address] [--nodelay] [-S]\n"); #else @@ -398,6 +398,11 @@ void print_usage(void) printf(" -A : bind the outgoing socket to this host/ip address. Use to control which interface\n"); printf(" the client communicates over.\n"); printf(" -d : enable debug messages.\n"); + printf(" -c : disable clean session/enable persistent client mode\n"); + printf(" When this argument is used, the broker will be instructed not to clean existing sessions\n"); + printf(" for the same client id when the client connects, and sessions will never expire when the\n"); + printf(" client disconnects. MQTT v5 clients can change their session expiry interval with the -x\n"); + printf(" argument.\n"); printf(" -D : Define MQTT v5 properties. See the documentation for more details.\n"); printf(" -f : send the contents of a file as the message.\n"); printf(" -h : mqtt host to connect to. Defaults to localhost.\n"); @@ -423,6 +428,10 @@ void print_usage(void) printf(" -u : provide a username\n"); printf(" -V : specify the version of the MQTT protocol to use when connecting.\n"); printf(" Can be mqttv5, mqttv311 or mqttv31. Defaults to mqttv311.\n"); + printf(" -x : Set the session-expiry-interval property on the CONNECT packet. Applies to MQTT v5\n"); + printf(" clients only. Set to 0-4294967294 to specify the session will expire in that many\n"); + printf(" seconds after the client disconnects, or use -1, 4294967295, or ∞ for a session\n"); + printf(" that does not expire. Defaults to -1 if -c is also given, or 0 if -c not given.\n"); printf(" --help : display this message.\n"); printf(" --nodelay : disable Nagle's algorithm, to reduce socket sending latency at the possible\n"); printf(" expense of more packets being sent.\n"); diff --git a/client/rr_client.c b/client/rr_client.c index e6b41098..6bb1b6b3 100644 --- a/client/rr_client.c +++ b/client/rr_client.c @@ -163,7 +163,7 @@ void print_usage(void) printf(" with v3.1.1 brokers.\n"); printf("mosquitto_rr version %s running on libmosquitto %d.%d.%d.\n\n", VERSION, major, minor, revision); printf("Usage: mosquitto_rr {[-h host] [--unix path] [-p port] [-u username] [-P password] -t topic | -L URL} -e response-topic\n"); - printf(" [-c] [-k keepalive] [-q qos] [-R]\n"); + printf(" [-c] [-k keepalive] [-q qos] [-R] [-x session-expiry-interval\n"); printf(" [-F format]\n"); #ifndef WIN32 printf(" [-W timeout_secs]\n"); @@ -192,7 +192,11 @@ void print_usage(void) printf(" mosquitto_rr --help\n\n"); printf(" -A : bind the outgoing socket to this host/ip address. Use to control which interface\n"); printf(" the client communicates over.\n"); - printf(" -c : disable 'clean session' (store subscription and pending messages when client disconnects).\n"); + printf(" -c : disable clean session/enable persistent client mode\n"); + printf(" When this argument is used, the broker will be instructed not to clean existing sessions\n"); + printf(" for the same client id when the client connects, and sessions will never expire when the\n"); + printf(" client disconnects. MQTT v5 clients can change their session expiry interval with the -x\n"); + printf(" argument.\n"); printf(" -d : enable debug messages.\n"); printf(" -D : Define MQTT v5 properties. See the documentation for more details.\n"); printf(" -F : output format.\n"); @@ -217,6 +221,10 @@ void print_usage(void) #ifndef WIN32 printf(" -W : Specifies a timeout in seconds how long to wait for a response.\n"); #endif + printf(" -x : Set the session-expiry-interval property on the CONNECT packet. Applies to MQTT v5\n"); + printf(" clients only. Set to 0-4294967294 to specify the session will expire in that many\n"); + printf(" seconds after the client disconnects, or use -1, 4294967295, or ∞ for a session\n"); + printf(" that does not expire. Defaults to -1 if -c is also given, or 0 if -c not given.\n"); printf(" --help : display this message.\n"); printf(" --nodelay : disable Nagle's algorithm, to reduce socket sending latency at the possible\n"); printf(" expense of more packets being sent.\n"); diff --git a/client/sub_client.c b/client/sub_client.c index e2172888..697512cd 100644 --- a/client/sub_client.c +++ b/client/sub_client.c @@ -181,7 +181,7 @@ void print_usage(void) printf("mosquitto_sub is a simple mqtt client that will subscribe to a set of topics and print all messages it receives.\n"); printf("mosquitto_sub version %s running on libmosquitto %d.%d.%d.\n\n", VERSION, major, minor, revision); printf("Usage: mosquitto_sub {[-h host] [--unix path] [-p port] [-u username] [-P password] -t topic | -L URL [-t topic]}\n"); - printf(" [-c] [-k keepalive] [-q qos]\n"); + printf(" [-c] [-k keepalive] [-q qos] [-x session-expiry-interval]\n"); printf(" [-C msg_count] [-E] [-R] [--retained-only] [--remove-retained] [-T filter_out] [-U topic ...]\n"); printf(" [-F format]\n"); #ifndef WIN32 @@ -211,7 +211,11 @@ void print_usage(void) printf(" mosquitto_sub --help\n\n"); printf(" -A : bind the outgoing socket to this host/ip address. Use to control which interface\n"); printf(" the client communicates over.\n"); - printf(" -c : disable 'clean session' (store subscription and pending messages when client disconnects).\n"); + printf(" -c : disable clean session/enable persistent client mode\n"); + printf(" When this argument is used, the broker will be instructed not to clean existing sessions\n"); + printf(" for the same client id when the client connects, and sessions will never expire when the\n"); + printf(" client disconnects. MQTT v5 clients can change their session expiry interval with the -x\n"); + printf(" argument.\n"); printf(" -C : disconnect and exit after receiving the 'msg_count' messages.\n"); printf(" -d : enable debug messages.\n"); printf(" -D : Define MQTT v5 properties. See the documentation for more details.\n"); @@ -242,6 +246,10 @@ void print_usage(void) #ifndef WIN32 printf(" -W : Specifies a timeout in seconds how long to process incoming MQTT messages.\n"); #endif + printf(" -x : Set the session-expiry-interval property on the CONNECT packet. Applies to MQTT v5\n"); + printf(" clients only. Set to 0-4294967294 to specify the session will expire in that many\n"); + printf(" seconds after the client disconnects, or use -1, 4294967295, or ∞ for a session\n"); + printf(" that does not expire. Defaults to -1 if -c is also given, or 0 if -c not given.\n"); printf(" --help : display this message.\n"); printf(" --nodelay : disable Nagle's algorithm, to reduce socket sending latency at the possible\n"); printf(" expense of more packets being sent.\n"); diff --git a/man/mosquitto_pub.1.xml b/man/mosquitto_pub.1.xml index 971055ac..b61d1478 100644 --- a/man/mosquitto_pub.1.xml +++ b/man/mosquitto_pub.1.xml @@ -42,6 +42,8 @@ count seconds + protocol-version + session-expiry-interval file @@ -83,7 +85,6 @@ socks-url - protocol-version mosquitto_pub @@ -141,11 +142,18 @@ - Disable the 'clean session' flag. This means that all - of the subscriptions for the client will be maintained - after it disconnects, along with subsequent QoS 1 and QoS 2 - messages that arrive. When the client reconnects, it will - receive all of the queued messages. + Disable 'clean session' / enable persistent client mode. + When this argument is used, the broker will be instructed + not to clean existing sessions for the same client id when + the client connects, and sessions will never expire when + the client disconnects. MQTT v5 clients can change their + session expiry interval with the argument. + + When a session is persisted on the broker, the subscriptions + for the client will be maintained after it disconnects, along + with subsequent QoS 1 and QoS 2 messages that arrive. When the + client reconnects and does not clean the session, it will + receive all of the queued messages. If using this option, the client id must be set manually with @@ -607,6 +615,19 @@ the client disconnects unexpectedly. + + + + Set the session-expiry-interval property on the CONNECT packet. + Applies to MQTT v5 clients only. Set to 0-4294967294 to specify + the session will expire in that many seconds after the client + disconnects, or use -1, 4294967295, or ∞ for a session that does + not expire. Defaults to -1 if -c is also given, or 0 if -c not + given. + If the session is set to never expire, either with -x or -c, then + a client id must be provided. + + @@ -640,7 +661,7 @@ (16-bit unsigned integer) (8-bit unsigned integer) (8-bit unsigned integer) - (32-bit unsigned integer) + (32-bit unsigned integer, note use instead) (16-bit unsigned integer) (UTF-8 string pair) diff --git a/man/mosquitto_rr.1.xml b/man/mosquitto_rr.1.xml index 515c7fd2..683e212f 100644 --- a/man/mosquitto_rr.1.xml +++ b/man/mosquitto_rr.1.xml @@ -54,6 +54,7 @@ protocol-version message-processing-timeout + session-expiry-interval socks-url @@ -148,11 +149,18 @@ - Disable the 'clean session' flag. This means that all - of the subscriptions for the client will be maintained - after it disconnects, along with subsequent QoS 1 and QoS 2 - messages that arrive. When the client reconnects, it will - receive all of the queued messages. + Disable 'clean session' / enable persistent client mode. + When this argument is used, the broker will be instructed + not to clean existing sessions for the same client id when + the client connects, and sessions will never expire when + the client disconnects. MQTT v5 clients can change their + session expiry interval with the argument. + + When a session is persisted on the broker, the subscriptions + for the client will be maintained after it disconnects, along + with subsequent QoS 1 and QoS 2 messages that arrive. When the + client reconnects and does not clean the session, it will + receive all of the queued messages. If using this option, the client id must be set manually with @@ -636,6 +644,19 @@ the client disconnects unexpectedly. + + + + Set the session-expiry-interval property on the CONNECT packet. + Applies to MQTT v5 clients only. Set to 0-4294967294 to specify + the session will expire in that many seconds after the client + disconnects, or use -1, 4294967295, or ∞ for a session that does + not expire. Defaults to -1 if -c is also given, or 0 if -c not + given. + If the session is set to never expire, either with -x or -c, then + a client id must be provided. + + @@ -785,7 +806,7 @@ (16-bit unsigned integer) (8-bit unsigned integer) (8-bit unsigned integer) - (32-bit unsigned integer) + (32-bit unsigned integer, note use instead) (16-bit unsigned integer) (UTF-8 string pair) diff --git a/man/mosquitto_sub.1.xml b/man/mosquitto_sub.1.xml index e7b27bba..a899a841 100644 --- a/man/mosquitto_sub.1.xml +++ b/man/mosquitto_sub.1.xml @@ -56,6 +56,7 @@ protocol-version message-processing-timeout + session-expiry-interval socks-url @@ -153,11 +154,18 @@ - Disable the 'clean session' flag. This means that all - of the subscriptions for the client will be maintained - after it disconnects, along with subsequent QoS 1 and QoS 2 - messages that arrive. When the client reconnects, it will - receive all of the queued messages. + Disable 'clean session' / enable persistent client mode. + When this argument is used, the broker will be instructed + not to clean existing sessions for the same client id when + the client connects, and sessions will never expire when + the client disconnects. MQTT v5 clients can change their + session expiry interval with the argument. + + When a session is persisted on the broker, the subscriptions + for the client will be maintained after it disconnects, along + with subsequent QoS 1 and QoS 2 messages that arrive. When the + client reconnects and does not clean the session, it will + receive all of the queued messages. If using this option, the client id must be set manually with @@ -753,6 +761,19 @@ mosquitto_sub -t 'bbc/#' -T bbc/bbc1 --remove-retained the client disconnects unexpectedly. + + + + Set the session-expiry-interval property on the CONNECT packet. + Applies to MQTT v5 clients only. Set to 0-4294967294 to specify + the session will expire in that many seconds after the client + disconnects, or use -1, 4294967295, or ∞ for a session that does + not expire. Defaults to -1 if -c is also given, or 0 if -c not + given. + If the session is set to never expire, either with -x or -c, then + a client id must be provided. + + @@ -903,7 +924,7 @@ mosquitto_sub -t 'bbc/#' -T bbc/bbc1 --remove-retained (16-bit unsigned integer) (8-bit unsigned integer) (8-bit unsigned integer) - (32-bit unsigned integer) + (32-bit unsigned integer, note use instead) (16-bit unsigned integer) (UTF-8 string pair)