Fix IPv6 addresses not being able to be used as bridge addresses.

Closes #886.

Signed-off-by: Roger A. Light <roger@atchoo.org>
This commit is contained in:
Roger A. Light 2018-08-02 13:01:02 +01:00
parent bcf76b9cb6
commit b07e0c08bf
4 changed files with 39 additions and 18 deletions

View File

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

View File

@ -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.</para>
<para>If you use an IPv6 address, then the port is not
optional.</para>
<para>Multiple host addresses can be specified on the
address config. See the <option>round_robin</option>
option for more details on the behaviour of bridges

View File

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

View File

@ -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; i<cur_bridge->address_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.");