diff options
Diffstat (limited to 'sql/wsrep_sst.cc')
-rw-r--r-- | sql/wsrep_sst.cc | 76 |
1 files changed, 66 insertions, 10 deletions
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index d805b4c64eb..d2f74e57559 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -1225,35 +1225,46 @@ std::string wsrep_sst_prepare() /* Figure out SST receive address. Common for all SST methods. */ + wsp::Address* addr_in_parser= NULL; + // Attempt 1: wsrep_sst_receive_address if (wsrep_sst_receive_address && - strcmp (wsrep_sst_receive_address, WSREP_SST_ADDRESS_AUTO)) + strcmp(wsrep_sst_receive_address, WSREP_SST_ADDRESS_AUTO)) { - addr_in= wsrep_sst_receive_address; - } + addr_in_parser = new wsp::Address(wsrep_sst_receive_address); + if (!addr_in_parser->is_valid()) + { + WSREP_ERROR("Could not parse wsrep_sst_receive_address : %s", + wsrep_sst_receive_address); + unireg_abort(1); + } + } //Attempt 2: wsrep_node_address - else if (wsrep_node_address && strlen(wsrep_node_address)) + else if (wsrep_node_address && *wsrep_node_address) { - wsp::Address addr(wsrep_node_address); + addr_in_parser = new wsp::Address(wsrep_node_address); - if (!addr.is_valid()) + if (addr_in_parser->is_valid()) + { + // we must not inherit the port number from this address: + addr_in_parser->set_port(0); + } + else { WSREP_ERROR("Could not parse wsrep_node_address : %s", wsrep_node_address); throw wsrep::runtime_error("Failed to prepare for SST. Unrecoverable"); } - memcpy(ip_buf, addr.get_address(), addr.get_address_len()); - addr_in= ip_buf; } // Attempt 3: Try to get the IP from the list of available interfaces. else { - ssize_t ret= wsrep_guess_ip (ip_buf, ip_max); + ssize_t ret= wsrep_guess_ip(ip_buf, ip_max); if (ret && ret < ip_max) { - addr_in= ip_buf; + addr_in_parser = new wsp::Address(ip_buf); } else { @@ -1263,6 +1274,51 @@ std::string wsrep_sst_prepare() } } + assert(addr_in_parser); + + size_t len= addr_in_parser->get_address_len(); + bool is_ipv6= addr_in_parser->is_ipv6(); + const char* address= addr_in_parser->get_address(); + + if (len > (is_ipv6 ? ip_max - 2 : ip_max)) + { + WSREP_ERROR("Address to accept state transfer is too long: '%s'", + address); + unireg_abort(1); + } + + if (is_ipv6) + { + /* wsrep_sst_*.sh scripts requite ipv6 addreses to be in square breackets */ + ip_buf[0] = '['; + /* the length (len) already includes the null byte: */ + memcpy(ip_buf + 1, address, len - 1); + ip_buf[len] = ']'; + ip_buf[len + 1] = 0; + len += 2; + } + else + { + memcpy(ip_buf, address, len); + } + + int port= addr_in_parser->get_port(); + if (port) + { + size_t space= ip_max - len; + ip_buf[len - 1] = ':'; + int ret= snprintf(ip_buf + len, ip_max - len, "%d", port); + if (ret <= 0 || (size_t) ret > space) + { + WSREP_ERROR("Address to accept state transfer is too long: '%s:%d'", + address, port); + unireg_abort(1); + } + } + + delete addr_in_parser; + addr_in = ip_buf; + ssize_t addr_len= -ENOSYS; method = wsrep_sst_method; if (!strcmp(method, WSREP_SST_MYSQLDUMP)) |