summaryrefslogtreecommitdiff
path: root/sql/wsrep_sst.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/wsrep_sst.cc')
-rw-r--r--sql/wsrep_sst.cc76
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))