Skip to content

Commit

Permalink
Add support for unix sockets to broker, lib, and clients.
Browse files Browse the repository at this point in the history
  • Loading branch information
ralight committed Oct 8, 2019
1 parent fad184c commit 499e2f2
Show file tree
Hide file tree
Showing 21 changed files with 299 additions and 23 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
4 changes: 4 additions & 0 deletions ChangeLog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions buildtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
'WITH_THREADING',
'WITH_TLS',
'WITH_TLS_PSK',
'WITH_UNIX_SOCKETS',
'WITH_WEBSOCKETS',
'WITH_WRAP',
]
Expand Down
15 changes: 12 additions & 3 deletions client/client_shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions client/client_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ and the Eclipse Distribution License is available at
#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;
Expand Down
4 changes: 3 additions & 1 deletion client/pub_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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");
Expand Down
4 changes: 3 additions & 1 deletion client/rr_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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");
Expand Down
4 changes: 3 additions & 1 deletion client/sub_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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");
Expand Down
9 changes: 9 additions & 0 deletions config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
# =============================================================================
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions lib/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)){
Expand Down Expand Up @@ -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){
Expand Down
57 changes: 55 additions & 2 deletions lib/net_mosq.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ and the Eclipse Distribution License is available at
# include <netinet/in.h>
#endif

#ifdef WITH_UNIX_SOCKETS
# include <sys/un.h>
#endif

#ifdef __QNX__
#include <net/netbyte.h>
#endif
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 5 additions & 1 deletion lib/tls_mosq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 5 additions & 1 deletion man/mosquitto.conf.5.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 &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>
Expand Down
16 changes: 16 additions & 0 deletions man/mosquitto_pub.1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down
16 changes: 16 additions & 0 deletions man/mosquitto_rr.1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down
16 changes: 16 additions & 0 deletions man/mosquitto_sub.1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down
Loading

0 comments on commit 499e2f2

Please sign in to comment.