From d49988fa6ffc665524c788de933cde40dc038b92 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 30 Oct 2019 21:48:53 +0000 Subject: [PATCH] Rejig unix socket support. --- man/mosquitto.conf.5.xml | 15 ++++---- mosquitto.conf | 15 ++++---- src/conf.c | 78 ++++++++++++++++++++++++++-------------- src/net.c | 2 +- 4 files changed, 69 insertions(+), 41 deletions(-) diff --git a/man/mosquitto.conf.5.xml b/man/mosquitto.conf.5.xml index 7d48703d..6f9001a8 100644 --- a/man/mosquitto.conf.5.xml +++ b/man/mosquitto.conf.5.xml @@ -1058,7 +1058,7 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S - port bind address/host + port bind address/host/unix socket path Listen for incoming network connection on the specified port. A second optional argument allows @@ -1067,11 +1067,18 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S neither the global nor options are used then the default listener will not be started. + The option allows this listener to be bound to a specific IP address by passing an IP address or hostname. For websockets listeners, it is only possible to pass an IP address here. + + On systems that support Unix Domain Sockets, this + option can also be used to create a Unix socket rather + than opening a TCP socket. In this case, the port must + be set to 0, and the unix socket path must be given. + This option may be specified multiple times. See also the option. @@ -1159,7 +1166,7 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S - [ ipv4 | ipv6 | unix ] [path to unix socket] + [ ipv4 | ipv6 ] By default, a listener will attempt to listen on all supported IP protocol versions. If you do not @@ -1176,10 +1183,6 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S use IPv6. If you want support for both IPv4 and IPv6, then do not use the option. - On systems that support Unix Domain Sockets, this - option can also be used to create a Unix socket rather - than opening a TCP socket. In this case, the option - should be in the form: . For example: Not reloaded on reload signal. diff --git a/mosquitto.conf b/mosquitto.conf index a9b13d62..c4367c07 100644 --- a/mosquitto.conf +++ b/mosquitto.conf @@ -372,7 +372,14 @@ # interface. By default, mosquitto will listen on all interfaces. # Note that for a websockets listener it is not possible to bind to a host # name. -# listener port-number [ip address/host name] +# +# On systems that support Unix Domain Sockets, it is also possible +# to create a # Unix socket rather than opening a TCP socket. In +# this case, the port number should be set to 0 and a unix socket +# path must be provided, e.g. +# listener 0 /tmp/mosquitto.sock +# +# listener port-number [ip address/host name/unix socket path] #listener # By default, a listener will attempt to listen on all supported IP protocol @@ -386,12 +393,6 @@ # force the listener to only use IPv6. If you want support for both IPv4 and # IPv6, then do not use the socket_domain option. # -# On systems that support Unix Domain Sockets, this option can also be used to -# create a Unix socket rather than opening a TCP socket. In this case, the -# option should be in the form: -# socket_domain unix -# e.g. `socket_domain unix /tmp/mosquitto.sock` -# #socket_domain # Bind the listener to a specific interface. This is similar to diff --git a/src/conf.c b/src/conf.c index e4342571..94eb18db 100644 --- a/src/conf.c +++ b/src/conf.c @@ -1369,18 +1369,48 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct token = strtok_r(NULL, " ", &saveptr); if(token){ tmp_int = atoi(token); +#ifdef WITH_UNIX_SOCKETS + if(tmp_int < 0 || tmp_int > 65535){ +#else if(tmp_int < 1 || tmp_int > 65535){ +#endif log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid port value (%d).", tmp_int); return MOSQ_ERR_INVAL; } + /* Look for bind address / unix socket path */ + token = strtok_r(NULL, " ", &saveptr); + if (token != NULL && token[0] == '#'){ + token = NULL; + } + + if(tmp_int == 0 && token == NULL){ + log__printf(NULL, MOSQ_LOG_ERR, "Error: A listener with port 0 must provide a Unix socket path."); + return MOSQ_ERR_INVAL; + } + if(reload){ - /* We reload listeners settings based on port number. - * If the port number doesn't already exist, exit with a complaint. */ + /* We reload listeners settings based on port number/unix socket path. + * If the port number/unix path doesn't already exist, exit with a complaint. */ cur_listener = NULL; - for(i=0; ilistener_count; i++){ - if(config->listeners[i].port == tmp_int){ - cur_listener = &config->listeners[i]; +#ifdef WITH_UNIX_SOCKETS + if(tmp_int == 0){ + for(i=0; ilistener_count; i++){ + if(config->listeners[i].unix_socket_path != NULL + && strcmp(config->listeners[i].unix_socket_path, token) == 0){ + + cur_listener = &config->listeners[i]; + break; + } + } + }else +#endif + { + for(i=0; ilistener_count; i++){ + if(config->listeners[i].port == tmp_int){ + cur_listener = &config->listeners[i]; + break; + } } } if(!cur_listener){ @@ -1403,15 +1433,24 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct 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; - } + mosquitto__free(cur_listener->host); + cur_listener->host = NULL; + +#ifdef WITH_UNIX_SOCKETS + mosquitto__free(cur_listener->unix_socket_path); + cur_listener->unix_socket_path = NULL; +#endif + if(token){ - cur_listener->host = mosquitto__strdup(token); - }else{ - cur_listener->host = NULL; +#ifdef WITH_UNIX_SOCKETS + if(cur_listener->port == 0){ + cur_listener->unix_socket_path = mosquitto__strdup(token); + }else +#endif + { + cur_listener->host = mosquitto__strdup(token); + } } }else{ log__printf(NULL, MOSQ_LOG_ERR, "Error: Empty listener value in configuration."); @@ -1907,21 +1946,6 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct cur_listener->socket_domain = AF_INET; }else if(!strcmp(token, "ipv6")){ cur_listener->socket_domain = AF_INET6; -#ifdef WITH_UNIX_SOCKETS - }else if(!strcmp(token, "unix")){ - cur_listener->socket_domain = AF_UNIX; - token = strtok_r(NULL, " ", &saveptr); - if(token){ - cur_listener->unix_socket_path = mosquitto__strdup(token); - if(cur_listener->unix_socket_path == NULL){ - log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); - return MOSQ_ERR_NOMEM; - } - }else{ - log__printf(NULL, MOSQ_LOG_ERR, "Error: Empty socket_domain unix socket path in configuration."); - return MOSQ_ERR_INVAL; - } -#endif }else{ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid socket_domain value \"%s\" in configuration.", token); return MOSQ_ERR_INVAL; diff --git a/src/net.c b/src/net.c index 91812636..3df68bc1 100644 --- a/src/net.c +++ b/src/net.c @@ -730,7 +730,7 @@ int net__socket_listen(struct mosquitto__listener *listener) if(!listener) return MOSQ_ERR_INVAL; #ifdef WITH_UNIX_SOCKETS - if(listener->socket_domain == AF_UNIX){ + if(listener->port == 0 && listener->unix_socket_path != NULL){ rc = net__socket_listen_unix(listener); }else #endif