diff --git a/ChangeLog.txt b/ChangeLog.txt
index 5225bf7f..d1edaccd 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -8,6 +8,8 @@ Broker:
- Use AF_UNSPEC etc. instead of PF_UNSPEC to comply with POSIX. Closes #863.
- Remove use of AI_ADDRCONFIG, which means the broker can be used on systems
where only the loopback interface is defined. Closes #869, Closes #901.
+- Fix IPv6 addresses not being able to be used as bridge addresses.
+ Closes #886.
1.5 - 20180502
diff --git a/man/mosquitto.conf.5.xml b/man/mosquitto.conf.5.xml
index 9347cfc5..3d171e99 100644
--- a/man/mosquitto.conf.5.xml
+++ b/man/mosquitto.conf.5.xml
@@ -1030,6 +1030,8 @@
bridge to connect to. This must be given for each
bridge connection. If the port is not specified, the
default of 1883 is used.
+ If you use an IPv6 address, then the port is not
+ optional.Multiple host addresses can be specified on the
address config. See the
option for more details on the behaviour of bridges
diff --git a/mosquitto.conf b/mosquitto.conf
index 93f66f3d..96450050 100644
--- a/mosquitto.conf
+++ b/mosquitto.conf
@@ -658,21 +658,29 @@
# Create a new bridge using the "connection" option as described below. Set
# options for the bridges using the remaining parameters. You must specify the
# address and at least one topic to subscribe to.
+#
# Each connection must have a unique name.
+#
# The address line may have multiple host address and ports specified. See
# below in the round_robin description for more details on bridge behaviour if
-# multiple addresses are used.
+# multiple addresses are used. Note that if you use an IPv6 address, then you
+# are required to specify a port.
+#
# The direction that the topic will be shared can be chosen by
# specifying out, in or both, where the default value is out.
# The QoS level of the bridged communication can be specified with the next
# topic option. The default QoS level is 0, to change the QoS the topic
# direction must also be given.
+#
# The local and remote prefix options allow a topic to be remapped when it is
# bridged to/from the remote broker. This provides the ability to place a topic
# tree in an appropriate location.
+#
# For more details see the mosquitto.conf man page.
+#
# Multiple topics can be specified per connection, but be careful
# not to create any loops.
+#
# If you are using bridges with cleansession set to false (the default), then
# you may get unexpected behaviour from incoming topics if you change what
# topics you are subscribing to. This is because the remote broker keeps the
diff --git a/src/conf.c b/src/conf.c
index 06513348..721207d5 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -714,6 +714,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
int tmp_int;
char *saveptr = NULL;
#ifdef WITH_BRIDGE
+ char *tmp_char;
struct mosquitto__bridge *cur_bridge = NULL;
struct mosquitto__bridge_topic *cur_topic;
#endif
@@ -732,10 +733,7 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
#endif
int len;
struct mosquitto__listener *cur_listener = &config->default_listener;
-#ifdef WITH_BRIDGE
- char *address;
int i;
-#endif
int lineno_ext;
struct mosquitto__security_options *cur_security_options = NULL;
@@ -773,22 +771,33 @@ int config__read_file_core(struct mosquitto__config *config, bool reload, struct
cur_bridge->addresses[cur_bridge->address_count-1].address = token;
}
for(i=0; iaddress_count; i++){
- address = strtok_r(cur_bridge->addresses[i].address, ":", &saveptr);
- if(address){
- token = strtok_r(NULL, ":", &saveptr);
- if(token){
- tmp_int = atoi(token);
- if(tmp_int < 1 || tmp_int > 65535){
- log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid port value (%d).", tmp_int);
- return MOSQ_ERR_INVAL;
- }
- cur_bridge->addresses[i].port = tmp_int;
- }else{
- cur_bridge->addresses[i].port = 1883;
+ /* cur_bridge->addresses[i].address is now
+ * "address[:port]". If address is an IPv6 address,
+ * then port is required. We must check for the :
+ * backwards. */
+ tmp_char = strrchr(cur_bridge->addresses[i].address, ':');
+ if(tmp_char){
+ /* Remove ':', so cur_bridge->addresses[i].address
+ * now just looks like the address. */
+ tmp_char[0] = '\0';
+
+ /* The remainder of the string */
+ tmp_int = atoi(&tmp_char[1]);
+ if(tmp_int < 1 || tmp_int > 65535){
+ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid port value (%d).", tmp_int);
+ return MOSQ_ERR_INVAL;
}
- cur_bridge->addresses[i].address = mosquitto__strdup(address);
- conf__attempt_resolve(address, "bridge address", MOSQ_LOG_WARNING, "Warning");
+ cur_bridge->addresses[i].port = tmp_int;
+ }else{
+ cur_bridge->addresses[i].port = 1883;
}
+ /* This looks a bit weird, but isn't. Before this
+ * call, cur_bridge->addresses[i].address points
+ * to the tokenised part of the line, it will be
+ * reused in a future parse of a config line so we
+ * must duplicate it. */
+ cur_bridge->addresses[i].address = mosquitto__strdup(cur_bridge->addresses[i].address);
+ conf__attempt_resolve(cur_bridge->addresses[i].address, "bridge address", MOSQ_LOG_WARNING, "Warning");
}
if(cur_bridge->address_count == 0){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Empty address value in configuration.");