mirror of
https://github.com/eclipse-mosquitto/mosquitto.git
synced 2026-05-21 12:24:29 +02:00
Add support for unix sockets to broker, lib, and clients.
This commit is contained in:
parent
fad184c9c2
commit
499e2f2e98
|
|
@ -43,6 +43,12 @@ else (WITH_TLS)
|
|||
set (OPENSSL_INCLUDE_DIR "")
|
||||
endif (WITH_TLS)
|
||||
|
||||
|
||||
option(WITH_UNIX_SOCKETS "Include Unix Domain Socket support?" ON)
|
||||
if (WITH_UNIX_SOCKETS AND NOT WIN32)
|
||||
add_definitions("-DWITH_UNIX_SOCKETS")
|
||||
endif (WITH_UNIX_SOCKETS AND NOT WIN32)
|
||||
|
||||
option(WITH_SOCKS "Include SOCKS5 support?" ON)
|
||||
if (WITH_SOCKS)
|
||||
add_definitions("-DWITH_SOCKS")
|
||||
|
|
|
|||
|
|
@ -2,15 +2,19 @@ Broker:
|
|||
- When running as root, if dropping privileges to the "mosquitto" user fails,
|
||||
then try "nobody" instead. This reduces the burden on users installing
|
||||
Mosquitto themselves.
|
||||
- Add support for Unix domain socket listeners.
|
||||
|
||||
Client library:
|
||||
- Client no longer generates random client ids for v3.1.1 clients, these are
|
||||
now expected to be generated on the broker. This matches the behaviour for
|
||||
v5 clients. Closes #291.
|
||||
- Add support for connecting to brokers through Unix domain sockets.
|
||||
|
||||
Clients:
|
||||
- Add timeout return code (27) for `mosquitto_sub -W <secs>` and
|
||||
`mosquitto_rr -W <secs>`. Closes #275.
|
||||
- Add support for connecting to brokers through Unix domain sockets with the
|
||||
`--unix` argument.
|
||||
|
||||
|
||||
1.6.7 - 20190925
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ build_variants = [
|
|||
'WITH_THREADING',
|
||||
'WITH_TLS',
|
||||
'WITH_TLS_PSK',
|
||||
'WITH_UNIX_SOCKETS',
|
||||
'WITH_WEBSOCKETS',
|
||||
'WITH_WRAP',
|
||||
]
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ static int check_format(const char *str)
|
|||
void init_config(struct mosq_config *cfg, int pub_or_sub)
|
||||
{
|
||||
memset(cfg, 0, sizeof(*cfg));
|
||||
cfg->port = -1;
|
||||
cfg->port = PORT_UNDEFINED;
|
||||
cfg->max_inflight = 20;
|
||||
cfg->keepalive = 60;
|
||||
cfg->clean_session = true;
|
||||
|
|
@ -742,7 +742,7 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c
|
|||
return 1;
|
||||
}else{
|
||||
cfg->port = atoi(argv[i+1]);
|
||||
if(cfg->port<1 || cfg->port>65535){
|
||||
if(cfg->port<0 || cfg->port>65535){
|
||||
fprintf(stderr, "Error: Invalid port given: %d\n", cfg->port);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -974,6 +974,15 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c
|
|||
cfg->username = strdup(argv[i+1]);
|
||||
}
|
||||
i++;
|
||||
}else if(!strcmp(argv[i], "--unix")){
|
||||
if(i==argc-1){
|
||||
fprintf(stderr, "Error: --unix argument given but no socket path specified.\n\n");
|
||||
return 1;
|
||||
}else{
|
||||
cfg->host = strdup(argv[i+1]);
|
||||
cfg->port = 0;
|
||||
}
|
||||
i++;
|
||||
}else if(!strcmp(argv[i], "-V") || !strcmp(argv[i], "--protocol-version")){
|
||||
if(i==argc-1){
|
||||
fprintf(stderr, "Error: --protocol-version argument given but no version specified.\n\n");
|
||||
|
|
@ -1174,7 +1183,7 @@ int client_connect(struct mosquitto *mosq, struct mosq_config *cfg)
|
|||
int rc;
|
||||
int port;
|
||||
|
||||
if(cfg->port < 0){
|
||||
if(cfg->port == PORT_UNDEFINED){
|
||||
#ifdef WITH_TLS
|
||||
if(cfg->cafile || cfg->capath
|
||||
# ifdef FINAL_WITH_TLS_PSK
|
||||
|
|
|
|||
|
|
@ -38,6 +38,9 @@ Contributors:
|
|||
#define CLIENT_RR 3
|
||||
#define CLIENT_RESPONSE_TOPIC 4
|
||||
|
||||
#define PORT_UNDEFINED -1
|
||||
#define PORT_UNIX 0
|
||||
|
||||
struct mosq_config {
|
||||
char *id;
|
||||
char *id_prefix;
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ void print_usage(void)
|
|||
mosquitto_lib_version(&major, &minor, &revision);
|
||||
printf("mosquitto_pub is a simple mqtt client that will publish a message on a single topic and exit.\n");
|
||||
printf("mosquitto_pub version %s running on libmosquitto %d.%d.%d.\n\n", VERSION, major, minor, revision);
|
||||
printf("Usage: mosquitto_pub {[-h host] [-p port] [-u username] [-P password] -t topic | -L URL}\n");
|
||||
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");
|
||||
#ifdef WITH_SRV
|
||||
|
|
@ -405,6 +405,8 @@ void print_usage(void)
|
|||
printf(" --repeat : if publish mode is -f, -m, or -s, then repeat the publish N times.\n");
|
||||
printf(" --repeat-delay : if using --repeat, wait time seconds between publishes. Defaults to 0.\n");
|
||||
printf(" --quiet : don't print error messages.\n");
|
||||
printf(" --unix : connect to a broker through a unix domain socket instead of a TCP socket,\n");
|
||||
printf(" e.g. /tmp/mosquitto.sock\n");
|
||||
printf(" --will-payload : payload for the client Will, which is sent by the broker in case of\n");
|
||||
printf(" unexpected disconnection. If not given and will-topic is set, a zero\n");
|
||||
printf(" length message will be sent.\n");
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ void print_usage(void)
|
|||
printf(" Defaults to MQTT v5, where the Request-Response feature will be used, but v3.1.1 can also be used\n");
|
||||
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] [-p port] [-u username] [-P password] -t topic | -L URL} -e response-topic\n");
|
||||
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(" [-F format]\n");
|
||||
#ifndef WIN32
|
||||
|
|
@ -219,6 +219,8 @@ void print_usage(void)
|
|||
#endif
|
||||
printf(" --help : display this message.\n");
|
||||
printf(" --quiet : don't print error messages.\n");
|
||||
printf(" --unix : connect to a broker through a unix domain socket instead of a TCP socket,\n");
|
||||
printf(" e.g. /tmp/mosquitto.sock\n");
|
||||
printf(" --will-payload : payload for the client Will, which is sent by the broker in case of\n");
|
||||
printf(" unexpected disconnection. If not given and will-topic is set, a zero\n");
|
||||
printf(" length message will be sent.\n");
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ void print_usage(void)
|
|||
mosquitto_lib_version(&major, &minor, &revision);
|
||||
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] [-p port] [-u username] [-P password] -t topic | -L URL [-t topic]}\n");
|
||||
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 msg_count] [-E] [-R] [--retained-only] [--remove-retained] [-T filter_out] [-U topic ...]\n");
|
||||
printf(" [-F format]\n");
|
||||
|
|
@ -244,6 +244,8 @@ void print_usage(void)
|
|||
printf(" first non-retained message is received.\n");
|
||||
printf(" --remove-retained : send a message to the server to clear any received retained messages\n");
|
||||
printf(" Use -T to filter out messages you do not want to be cleared.\n");
|
||||
printf(" --unix : connect to a broker through a unix domain socket instead of a TCP socket,\n");
|
||||
printf(" e.g. /tmp/mosquitto.sock\n");
|
||||
printf(" --will-payload : payload for the client Will, which is sent by the broker in case of\n");
|
||||
printf(" unexpected disconnection. If not given and will-topic is set, a zero\n");
|
||||
printf(" length message will be sent.\n");
|
||||
|
|
|
|||
|
|
@ -97,6 +97,9 @@ WITH_BUNDLED_DEPS:=yes
|
|||
# Build with coverage options
|
||||
WITH_COVERAGE:=no
|
||||
|
||||
# Build with unix domain socket support
|
||||
WITH_UNIX_SOCKETS:=yes
|
||||
|
||||
# =============================================================================
|
||||
# End of user configuration
|
||||
# =============================================================================
|
||||
|
|
@ -272,6 +275,12 @@ ifeq ($(WITH_DOCS),yes)
|
|||
MAKE_ALL:=$(MAKE_ALL) docs
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_UNIX_SOCKETS),yes)
|
||||
BROKER_CPPFLAGS:=$(BROKER_CPPFLAGS) -DWITH_UNIX_SOCKETS
|
||||
LIB_CPPFLAGS:=$(LIB_CPPFLAGS) -DWITH_UNIX_SOCKETS
|
||||
CLIENT_CPPFLAGS:=$(CLIENT_CPPFLAGS) -DWITH_UNIX_SOCKETS
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_WEBSOCKETS),yes)
|
||||
BROKER_CPPFLAGS:=$(BROKER_CPPFLAGS) -DWITH_WEBSOCKETS
|
||||
BROKER_LDADD:=$(BROKER_LDADD) -lwebsockets
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ static int mosquitto__connect_init(struct mosquitto *mosq, const char *host, int
|
|||
int rc;
|
||||
|
||||
if(!mosq) return MOSQ_ERR_INVAL;
|
||||
if(!host || port <= 0) return MOSQ_ERR_INVAL;
|
||||
if(!host || port < 0) return MOSQ_ERR_INVAL;
|
||||
|
||||
/* Only MQTT v3.1 requires a client id to be sent */
|
||||
if(mosq->id == NULL && (mosq->protocol == mosq_p_mqtt31)){
|
||||
|
|
@ -160,7 +160,7 @@ static int mosquitto__reconnect(struct mosquitto *mosq, bool blocking, const mos
|
|||
int rc;
|
||||
|
||||
if(!mosq) return MOSQ_ERR_INVAL;
|
||||
if(!mosq->host || mosq->port <= 0) return MOSQ_ERR_INVAL;
|
||||
if(!mosq->host || mosq->port < 0) return MOSQ_ERR_INVAL;
|
||||
if(mosq->protocol != mosq_p_mqtt5 && properties) return MOSQ_ERR_NOT_SUPPORTED;
|
||||
|
||||
if(properties){
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ Contributors:
|
|||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_UNIX_SOCKETS
|
||||
# include <sys/un.h>
|
||||
#endif
|
||||
|
||||
#ifdef __QNX__
|
||||
#include <net/netbyte.h>
|
||||
#endif
|
||||
|
|
@ -364,7 +368,7 @@ int net__try_connect_step2(struct mosquitto *mosq, uint16_t port, mosq_sock_t *s
|
|||
#endif
|
||||
|
||||
|
||||
int net__try_connect(const char *host, uint16_t port, mosq_sock_t *sock, const char *bind_address, bool blocking)
|
||||
static int net__try_connect_tcp(const char *host, uint16_t port, mosq_sock_t *sock, const char *bind_address, bool blocking)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *ainfo, *rp;
|
||||
|
|
@ -461,6 +465,55 @@ int net__try_connect(const char *host, uint16_t port, mosq_sock_t *sock, const c
|
|||
}
|
||||
|
||||
|
||||
#ifdef WITH_UNIX_SOCKETS
|
||||
static int net__try_connect_unix(const char *host, mosq_sock_t *sock)
|
||||
{
|
||||
struct sockaddr_un addr;
|
||||
int s;
|
||||
int rc;
|
||||
|
||||
if(host == NULL || strlen(host) == 0 || strlen(host) > sizeof(addr.sun_path)-1){
|
||||
return MOSQ_ERR_INVAL;
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, host, sizeof(addr.sun_path)-1);
|
||||
|
||||
s = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if(s < 0){
|
||||
return MOSQ_ERR_ERRNO;
|
||||
}
|
||||
rc = net__socket_nonblock(&s);
|
||||
if(rc) return rc;
|
||||
|
||||
rc = connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un));
|
||||
if(rc < 0){
|
||||
close(s);
|
||||
return MOSQ_ERR_ERRNO;
|
||||
}
|
||||
|
||||
*sock = s;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int net__try_connect(const char *host, uint16_t port, mosq_sock_t *sock, const char *bind_address, bool blocking)
|
||||
{
|
||||
if(port == 0){
|
||||
#ifdef WITH_UNIX_SOCKETS
|
||||
return net__try_connect_unix(host, sock);
|
||||
#else
|
||||
return MOSQ_ERR_NOT_SUPPORTED;
|
||||
#endif
|
||||
}else{
|
||||
return net__try_connect_tcp(host, port, sock, bind_address, blocking);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_TLS
|
||||
void net__print_ssl_error(struct mosquitto *mosq)
|
||||
{
|
||||
|
|
@ -827,7 +880,7 @@ int net__socket_connect(struct mosquitto *mosq, const char *host, uint16_t port,
|
|||
mosq_sock_t sock = INVALID_SOCKET;
|
||||
int rc, rc2;
|
||||
|
||||
if(!mosq || !host || !port) return MOSQ_ERR_INVAL;
|
||||
if(!mosq || !host || port < 0) return MOSQ_ERR_INVAL;
|
||||
|
||||
rc = net__try_connect(host, port, &sock, bind_address, blocking);
|
||||
if(rc > 0) return rc;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,11 @@ int mosquitto__server_certificate_verify(int preverify_ok, X509_STORE_CTX *ctx)
|
|||
mosq = SSL_get_ex_data(ssl, tls_ex_index_mosq);
|
||||
if(!mosq) return 0;
|
||||
|
||||
if(mosq->tls_insecure == false){
|
||||
if(mosq->tls_insecure == false
|
||||
#ifndef WITH_BROKER
|
||||
&& mosq->port != 0 /* no hostname checking for unix sockets */
|
||||
#endif
|
||||
){
|
||||
if(X509_STORE_CTX_get_error_depth(ctx) == 0){
|
||||
/* FIXME - use X509_check_host() etc. for sufficiently new openssl (>=1.1.x) */
|
||||
cert = X509_STORE_CTX_get_current_cert(ctx);
|
||||
|
|
|
|||
|
|
@ -1159,7 +1159,7 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>socket_domain</option> [ ipv4 | ipv6 ]</term>
|
||||
<term><option>socket_domain</option> [ ipv4 | ipv6 | unix ] [path to unix socket]</term>
|
||||
<listitem>
|
||||
<para>By default, a listener will attempt to listen on
|
||||
all supported IP protocol versions. If you do not
|
||||
|
|
@ -1176,6 +1176,10 @@ 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 <path to socket></option>. For example: <option>socket_domain unix /tmp/mosquitto.sock</option></para>
|
||||
<para>Not reloaded on reload signal.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
<group choice='req'>
|
||||
<arg choice='plain'>
|
||||
<arg><option>-h</option> <replaceable>hostname</replaceable></arg>
|
||||
<arg><option>--unix</option> <replaceable>socket path</replaceable></arg>
|
||||
<arg><option>-p</option> <replaceable>port-number</replaceable></arg>
|
||||
<arg><option>-u</option> <replaceable>username</replaceable></arg>
|
||||
<arg><option>-P</option> <replaceable>password</replaceable></arg>
|
||||
|
|
@ -537,6 +538,21 @@
|
|||
argument.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>--unix</option></term>
|
||||
<listitem>
|
||||
<para>Connect to a broker through a local unix domain socket
|
||||
instead of a TCP socket. This is a replacement for
|
||||
<option>-h</option> and <option>-L</option>. For example:
|
||||
<option>mosquitto_pub --unix /tmp/mosquitto.sock ...</option>
|
||||
</para>
|
||||
<para>See the <option>socket_domain</option> option in
|
||||
<refentrytitle>
|
||||
<link xlink:href="mosquitto-conf-5.html">mosquitto.conf</link>
|
||||
</refentrytitle><manvolnum>5</manvolnum>
|
||||
to configure Mosquitto to listen on a unix socket.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-V</option></term>
|
||||
<term><option>--protocol-version</option></term>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
<group choice='req'>
|
||||
<arg choice='plain'>
|
||||
<arg><option>-h</option> <replaceable>hostname</replaceable></arg>
|
||||
<arg><option>--unix</option> <replaceable>socket path</replaceable></arg>
|
||||
<arg><option>-p</option> <replaceable>port-number</replaceable></arg>
|
||||
<arg><option>-u</option> <replaceable>username</replaceable></arg>
|
||||
<arg><option>-P</option> <replaceable>password</replaceable></arg>
|
||||
|
|
@ -545,6 +546,21 @@
|
|||
argument.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>--unix</option></term>
|
||||
<listitem>
|
||||
<para>Connect to a broker through a local unix domain socket
|
||||
instead of a TCP socket. This is a replacement for
|
||||
<option>-h</option> and <option>-L</option>. For example:
|
||||
<option>mosquitto_pub --unix /tmp/mosquitto.sock ...</option>
|
||||
</para>
|
||||
<para>See the <option>socket_domain</option> option in
|
||||
<refentrytitle>
|
||||
<link xlink:href="mosquitto-conf-5.html">mosquitto.conf</link>
|
||||
</refentrytitle><manvolnum>5</manvolnum>
|
||||
to configure Mosquitto to listen on a unix socket.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-v</option></term>
|
||||
<term><option>--verbose</option></term>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
<group choice='req'>
|
||||
<arg choice='plain'>
|
||||
<arg><option>-h</option> <replaceable>hostname</replaceable></arg>
|
||||
<arg><option>--unix</option> <replaceable>socket path</replaceable></arg>
|
||||
<arg><option>-p</option> <replaceable>port-number</replaceable></arg>
|
||||
<arg><option>-u</option> <replaceable>username</replaceable></arg>
|
||||
<arg><option>-P</option> <replaceable>password</replaceable></arg>
|
||||
|
|
@ -618,6 +619,21 @@ mosquitto_sub -t 'bbc/#' -T bbc/bbc1 --remove-retained</programlisting>
|
|||
argument.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>--unix</option></term>
|
||||
<listitem>
|
||||
<para>Connect to a broker through a local unix domain socket
|
||||
instead of a TCP socket. This is a replacement for
|
||||
<option>-h</option> and <option>-L</option>. For example:
|
||||
<option>mosquitto_pub --unix /tmp/mosquitto.sock ...</option>
|
||||
</para>
|
||||
<para>See the <option>socket_domain</option> option in
|
||||
<refentrytitle>
|
||||
<link xlink:href="mosquitto-conf-5.html">mosquitto.conf</link>
|
||||
</refentrytitle><manvolnum>5</manvolnum>
|
||||
to configure Mosquitto to listen on a unix socket.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-U</option></term>
|
||||
<term><option>--unsubscribe</option></term>
|
||||
|
|
|
|||
|
|
@ -375,6 +375,25 @@
|
|||
# listener port-number [ip address/host name]
|
||||
#listener
|
||||
|
||||
# By default, a listener will attempt to listen on all supported IP protocol
|
||||
# versions. If you do not have an IPv4 or IPv6 interface you may wish to
|
||||
# disable support for either of those protocol versions. In particular, note
|
||||
# that due to the limitations of the websockets library, it will only ever
|
||||
# attempt to open IPv6 sockets if IPv6 support is compiled in, and so will fail
|
||||
# if IPv6 is not available.
|
||||
#
|
||||
# Set to `ipv4` to force the listener to only use IPv4, or set to `ipv6` to
|
||||
# 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
|
||||
# the [ip address/host name] part of the listener definition, but is useful
|
||||
# when an interface has multiple addresses or the address may change. It is
|
||||
|
|
|
|||
18
src/conf.c
18
src/conf.c
|
|
@ -322,6 +322,9 @@ void config__cleanup(struct mosquitto__config *config)
|
|||
#endif
|
||||
#ifdef WITH_WEBSOCKETS
|
||||
mosquitto__free(config->listeners[i].http_dir);
|
||||
#endif
|
||||
#ifdef WITH_UNIX_SOCKETS
|
||||
mosquitto__free(config->listeners[i].unix_socket_path);
|
||||
#endif
|
||||
}
|
||||
mosquitto__free(config->listeners);
|
||||
|
|
@ -1894,6 +1897,21 @@ 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;
|
||||
|
|
|
|||
|
|
@ -377,14 +377,19 @@ int main(int argc, char *argv[])
|
|||
|
||||
log__printf(NULL, MOSQ_LOG_INFO, "mosquitto version %s terminating", VERSION);
|
||||
|
||||
#ifdef WITH_WEBSOCKETS
|
||||
for(i=0; i<int_db.config->listener_count; i++){
|
||||
#ifdef WITH_WEBSOCKETS
|
||||
if(int_db.config->listeners[i].ws_context){
|
||||
libwebsocket_context_destroy(int_db.config->listeners[i].ws_context);
|
||||
}
|
||||
mosquitto__free(int_db.config->listeners[i].ws_protocol);
|
||||
}
|
||||
#endif
|
||||
#ifdef WITH_UNIX_SOCKETS
|
||||
if(int_db.config->listeners[i].unix_socket_path != NULL){
|
||||
unlink(int_db.config->listeners[i].unix_socket_path);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* FIXME - this isn't quite right, all wills with will delay zero should be
|
||||
* sent now, but those with positive will delay should be persisted and
|
||||
|
|
|
|||
|
|
@ -272,6 +272,9 @@ struct mosquitto__listener {
|
|||
struct mosquitto__security_options security_options;
|
||||
struct mosquitto__unpwd *unpwd;
|
||||
struct mosquitto__unpwd *psk_id;
|
||||
#ifdef WITH_UNIX_SOCKETS
|
||||
char *unix_socket_path;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct mosquitto__config {
|
||||
|
|
|
|||
102
src/net.c
102
src/net.c
|
|
@ -41,6 +41,10 @@ Contributors:
|
|||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_UNIX_SOCKETS
|
||||
# include "sys/un.h"
|
||||
#endif
|
||||
|
||||
#ifdef __QNX__
|
||||
#include <net/netbyte.h>
|
||||
#endif
|
||||
|
|
@ -551,11 +555,7 @@ int net__tls_load_verify(struct mosquitto__listener *listener)
|
|||
}
|
||||
|
||||
|
||||
/* Creates a socket and listens on port 'port'.
|
||||
* Returns 1 on failure
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int net__socket_listen(struct mosquitto__listener *listener)
|
||||
static int net__socket_listen_tcp(struct mosquitto__listener *listener)
|
||||
{
|
||||
mosq_sock_t sock = INVALID_SOCKET;
|
||||
struct addrinfo hints;
|
||||
|
|
@ -655,17 +655,92 @@ int net__socket_listen(struct mosquitto__listener *listener)
|
|||
}
|
||||
freeaddrinfo(ainfo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_UNIX_SOCKETS
|
||||
static int net__socket_listen_unix(struct mosquitto__listener *listener)
|
||||
{
|
||||
struct sockaddr_un addr;
|
||||
int sock;
|
||||
|
||||
if(listener->unix_socket_path == NULL){
|
||||
return MOSQ_ERR_INVAL;
|
||||
}
|
||||
if(strlen(listener->unix_socket_path) > sizeof(addr.sun_path)-1){
|
||||
log__printf(NULL, MOSQ_LOG_ERR, "Error: Path to unix socket is too long \"%s\".", listener->unix_socket_path);
|
||||
return MOSQ_ERR_INVAL;
|
||||
}
|
||||
|
||||
unlink(listener->unix_socket_path);
|
||||
log__printf(NULL, MOSQ_LOG_INFO, "Opening unix listen socket on path %s.", listener->unix_socket_path);
|
||||
memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, listener->unix_socket_path, sizeof(addr.sun_path)-1);
|
||||
|
||||
sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if(sock == INVALID_SOCKET){
|
||||
net__print_error(MOSQ_LOG_ERR, "Error creating unix socket: %s");
|
||||
return 1;
|
||||
}
|
||||
listener->sock_count++;
|
||||
listener->socks = mosquitto__realloc(listener->socks, sizeof(mosq_sock_t)*listener->sock_count);
|
||||
if(!listener->socks){
|
||||
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
|
||||
return MOSQ_ERR_NOMEM;
|
||||
}
|
||||
listener->socks[listener->sock_count-1] = sock;
|
||||
|
||||
|
||||
if(bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1){
|
||||
net__print_error(MOSQ_LOG_ERR, "Error binding unix socket: %s");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(listen(sock, 10) == -1){
|
||||
net__print_error(MOSQ_LOG_ERR, "Error listening to unix socket: %s");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(net__socket_nonblock(&sock)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Creates a socket and listens on port 'port'.
|
||||
* Returns 1 on failure
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int net__socket_listen(struct mosquitto__listener *listener)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if(!listener) return MOSQ_ERR_INVAL;
|
||||
|
||||
#ifdef WITH_UNIX_SOCKETS
|
||||
if(listener->socket_domain == AF_UNIX){
|
||||
rc = net__socket_listen_unix(listener);
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
rc = net__socket_listen_tcp(listener);
|
||||
}
|
||||
if(rc) return rc;
|
||||
|
||||
/* We need to have at least one working socket. */
|
||||
if(listener->sock_count > 0){
|
||||
#ifdef WITH_TLS
|
||||
if((listener->cafile || listener->capath) && listener->certfile && listener->keyfile){
|
||||
if(net__tls_server_ctx(listener)){
|
||||
COMPAT_CLOSE(sock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(net__tls_load_verify(listener)){
|
||||
COMPAT_CLOSE(sock);
|
||||
return 1;
|
||||
}
|
||||
# ifdef FINAL_WITH_TLS_PSK
|
||||
|
|
@ -678,7 +753,6 @@ int net__socket_listen(struct mosquitto__listener *listener)
|
|||
}
|
||||
|
||||
if(net__tls_server_ctx(listener)){
|
||||
COMPAT_CLOSE(sock);
|
||||
return 1;
|
||||
}
|
||||
SSL_CTX_set_psk_server_callback(listener->ssl_ctx, psk_server_callback);
|
||||
|
|
@ -687,7 +761,6 @@ int net__socket_listen(struct mosquitto__listener *listener)
|
|||
if(rc == 0){
|
||||
log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to set TLS PSK hint.");
|
||||
net__print_error(MOSQ_LOG_ERR, "Error: %s");
|
||||
COMPAT_CLOSE(sock);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -716,6 +789,17 @@ int net__socket_get_address(mosq_sock_t sock, char *buf, int len)
|
|||
if(inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&addr)->sin6_addr.s6_addr, buf, len)){
|
||||
return 0;
|
||||
}
|
||||
#ifdef WITH_UNIX_SOCKETS
|
||||
}else if(addr.ss_family == AF_UNIX){
|
||||
struct sockaddr_un un;
|
||||
addrlen = sizeof(struct sockaddr_un);
|
||||
if(!getsockname(sock, (struct sockaddr *)&un, &addrlen)){
|
||||
snprintf(buf, len, "%s", un.sun_path);
|
||||
}else{
|
||||
snprintf(buf, len, "unix-socket");
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
|
|
|||
Loading…
Reference in a new issue