Allow binding a listener to a specific network interface
Signed-off-by: Steven Lawrance <stl@koffein.net>
This commit is contained in:
parent
b2c0c3d573
commit
208c3d3e85
@ -803,6 +803,16 @@
|
||||
<para>Not reloaded on reload signal.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>bind_interface</option> <replaceable>device</replaceable></term>
|
||||
<listitem>
|
||||
<para>Listen for incoming network connections only on
|
||||
the specified interface. This is similar to the
|
||||
preceding option but useful when an interface has
|
||||
multiple addresses or the address may change.</para>
|
||||
<para>Not reloaded on reload signal.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>http_dir</option> <replaceable>directory</replaceable></term>
|
||||
<listitem>
|
||||
|
@ -207,6 +207,11 @@
|
||||
# Port to use for the default listener.
|
||||
#port 1883
|
||||
|
||||
# Bind the listener to a specific interface. This is similar to
|
||||
# bind_address above but useful when an interface has multiple
|
||||
# addresses or the address may change. Only available on Linux.
|
||||
#bind_interface eth0
|
||||
|
||||
# The maximum number of client connections to allow. This is
|
||||
# a per listener setting.
|
||||
# Default is -1, which means unlimited connections.
|
||||
|
@ -291,6 +291,7 @@ void config__cleanup(struct mosquitto__config *config)
|
||||
if(config->listeners){
|
||||
for(i=0; i<config->listener_count; i++){
|
||||
mosquitto__free(config->listeners[i].host);
|
||||
mosquitto__free(config->listeners[i].bind_interface);
|
||||
mosquitto__free(config->listeners[i].mount_point);
|
||||
mosquitto__free(config->listeners[i].socks);
|
||||
mosquitto__free(config->listeners[i].security_options.auto_id_prefix);
|
||||
@ -915,6 +916,14 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
|
||||
if(conf__attempt_resolve(config->default_listener.host, "bind_address", MOSQ_LOG_ERR, "Error")){
|
||||
return MOSQ_ERR_INVAL;
|
||||
}
|
||||
}else if(!strcmp(token, "bind_interface")){
|
||||
#ifdef SO_BINDTODEVICE
|
||||
if(reload) continue; // Listeners not valid for reloading.
|
||||
if(conf__parse_string(&token, "bind_interface", &cur_listener->bind_interface, saveptr)) return MOSQ_ERR_INVAL;
|
||||
#else
|
||||
log__printf(NULL, MOSQ_LOG_ERR, "Error: bind_interface specified but socket option not available.");
|
||||
return MOSQ_ERR_INVAL;
|
||||
#endif
|
||||
}else if(!strcmp(token, "bridge_attempt_unsubscribe")){
|
||||
#ifdef WITH_BRIDGE
|
||||
if(reload) continue; // FIXME
|
||||
|
@ -212,6 +212,7 @@ struct mosquitto__listener {
|
||||
int fd;
|
||||
uint16_t port;
|
||||
char *host;
|
||||
char *bind_interface;
|
||||
int max_connections;
|
||||
char *mount_point;
|
||||
mosq_sock_t *socks;
|
||||
|
18
src/net.c
18
src/net.c
@ -22,6 +22,7 @@ Contributors:
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <net/if.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
@ -395,6 +396,9 @@ int net__socket_listen(struct mosquitto__listener *listener)
|
||||
X509_LOOKUP *lookup;
|
||||
ENGINE *engine = NULL;
|
||||
#endif
|
||||
#ifdef SO_BINDTODEVICE
|
||||
struct ifreq ifr;
|
||||
#endif
|
||||
|
||||
if(!listener) return MOSQ_ERR_INVAL;
|
||||
|
||||
@ -446,6 +450,20 @@ int net__socket_listen(struct mosquitto__listener *listener)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef SO_BINDTODEVICE
|
||||
if(listener->bind_interface){
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strncpy(ifr.ifr_name, listener->bind_interface, sizeof(ifr.ifr_name)-1);
|
||||
ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
|
||||
log__printf(NULL, MOSQ_LOG_INFO, "Binding listener to interface \"%s\".", ifr.ifr_name);
|
||||
if(setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) {
|
||||
net__print_error(MOSQ_LOG_ERR, "Error: %s");
|
||||
COMPAT_CLOSE(sock);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(bind(sock, rp->ai_addr, rp->ai_addrlen) == -1){
|
||||
net__print_error(MOSQ_LOG_ERR, "Error: %s");
|
||||
COMPAT_CLOSE(sock);
|
||||
|
Loading…
Reference in New Issue
Block a user