Rejig unix socket support.

This commit is contained in:
Roger A. Light 2019-10-30 21:48:53 +00:00
parent 493720fa4d
commit d49988fa6f
4 changed files with 69 additions and 41 deletions

View File

@ -1058,7 +1058,7 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S
</listitem>
</varlistentry>
<varlistentry>
<term><option>listener</option> <replaceable>port</replaceable> <replaceable><optional>bind address/host</optional></replaceable></term>
<term><option>listener</option> <replaceable>port</replaceable> <replaceable><optional>bind address/host/unix socket path</optional></replaceable></term>
<listitem>
<para>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 <option>bind_address</option>
nor <option>port</option> options are used then the
default listener will not be started.</para>
<para>The <option>bind address/host</option> 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.</para>
<para>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.</para>
<para>This option may be specified multiple times. See
also the <option>mount_point</option>
option.</para>
@ -1159,7 +1166,7 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S
</listitem>
</varlistentry>
<varlistentry>
<term><option>socket_domain</option> [ ipv4 | ipv6 | unix ] [path to unix socket]</term>
<term><option>socket_domain</option> [ ipv4 | ipv6 ]</term>
<listitem>
<para>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>socket_domain</option> option.</para>
<para>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: <option>socket_domain unix &lt;path to socket&gt;</option>. For example: <option>socket_domain unix /tmp/mosquitto.sock</option></para>
<para>Not reloaded on reload signal.</para>
</listitem>
</varlistentry>

View File

@ -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 <path to socket>
# e.g. `socket_domain unix /tmp/mosquitto.sock`
#
#socket_domain
# Bind the listener to a specific interface. This is similar to

View File

@ -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; i<config->listener_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; i<config->listener_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; i<config->listener_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;

View File

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