Unverified Commit 801559c5 authored by Luca Boccassi's avatar Luca Boccassi Committed by GitHub

Merge pull request #3077 from simias/port_check

Problem: ip_resolver allows wildcard ports for non-bindable sockets
parents 889ac2eb 406c3487
...@@ -117,8 +117,17 @@ int zmq::ip_resolver_t::resolve (ip_addr_t *ip_addr_, const char *name_) ...@@ -117,8 +117,17 @@ int zmq::ip_resolver_t::resolve (ip_addr_t *ip_addr_, const char *name_)
addr = std::string (name_, delim - name_); addr = std::string (name_, delim - name_);
std::string port_str = std::string (delim + 1); std::string port_str = std::string (delim + 1);
if (port_str == "*" || port_str == "0") { if (port_str == "*") {
// Resolve wildcard to 0 to allow autoselection of port if (options.bindable ()) {
// Resolve wildcard to 0 to allow autoselection of port
port = 0;
} else {
errno = EINVAL;
return -1;
}
} else if (port_str == "0") {
// Using "0" for a bind address is equivalent to using "*". For a
// connectable address it could be used to connect to port 0.
port = 0; port = 0;
} else { } else {
// Parse the port number (0 is not a valid port). // Parse the port number (0 is not a valid port).
......
...@@ -210,6 +210,18 @@ static void test_bind_any (int ipv6_) ...@@ -210,6 +210,18 @@ static void test_bind_any (int ipv6_)
} }
MAKE_TEST_V4V6 (test_bind_any) MAKE_TEST_V4V6 (test_bind_any)
static void test_bind_any_port0 (int ipv6_)
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.bindable (true).expect_port (true).ipv6 (ipv6_);
// Should be equivalent to "*:*"
const char *expected = ipv6_ ? "::" : "0.0.0.0";
test_resolve (resolver_opts, "*:0", expected, 0);
}
MAKE_TEST_V4V6 (test_bind_any_port0)
static void test_nobind_any (int ipv6_) static void test_nobind_any (int ipv6_)
{ {
zmq::ip_resolver_options_t resolver_opts; zmq::ip_resolver_options_t resolver_opts;
...@@ -240,14 +252,24 @@ static void test_nobind_addr_anyport (int ipv6_) ...@@ -240,14 +252,24 @@ static void test_nobind_addr_anyport (int ipv6_)
resolver_opts.expect_port (true).ipv6 (ipv6_); resolver_opts.expect_port (true).ipv6 (ipv6_);
// This however works. Should it ? For the time being I'm going to // Wildcard port should be rejected for non-bindable addresses
// keep it that way for backcompat but I can't imagine why you'd test_resolve (resolver_opts, "127.0.0.1:*", NULL);
// want a wildcard port if you're not binding. }
MAKE_TEST_V4V6 (test_nobind_addr_anyport)
static void test_nobind_addr_port0 (int ipv6_)
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true).ipv6 (ipv6_);
// Connecting to port 0 is allowed, although it might not be massively
// useful
const char *expected = ipv6_ ? "::ffff:127.0.0.1" : "127.0.0.1"; const char *expected = ipv6_ ? "::ffff:127.0.0.1" : "127.0.0.1";
const char *fallback = ipv6_ ? "127.0.0.1" : NULL; const char *fallback = ipv6_ ? "127.0.0.1" : NULL;
test_resolve (resolver_opts, "127.0.0.1:*", expected, 0, 0, fallback); test_resolve (resolver_opts, "127.0.0.1:0", expected, 0, 0, fallback);
} }
MAKE_TEST_V4V6 (test_nobind_addr_anyport) MAKE_TEST_V4V6 (test_nobind_addr_port0)
static void test_parse_ipv4_simple () static void test_parse_ipv4_simple ()
{ {
...@@ -501,7 +523,7 @@ static void test_parse_ipv6_port_any () ...@@ -501,7 +523,7 @@ static void test_parse_ipv6_port_any ()
{ {
zmq::ip_resolver_options_t resolver_opts; zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true).expect_port (true); resolver_opts.ipv6 (true).expect_port (true).bindable (true);
test_resolve (resolver_opts, "[1234::1]:*", "1234::1", 0); test_resolve (resolver_opts, "[1234::1]:*", "1234::1", 0);
} }
...@@ -810,12 +832,16 @@ int main (void) ...@@ -810,12 +832,16 @@ int main (void)
RUN_TEST (test_bind_any_ipv4); RUN_TEST (test_bind_any_ipv4);
RUN_TEST (test_bind_any_ipv6); RUN_TEST (test_bind_any_ipv6);
RUN_TEST (test_bind_any_port0_ipv4);
RUN_TEST (test_bind_any_port0_ipv6);
RUN_TEST (test_nobind_any_ipv4); RUN_TEST (test_nobind_any_ipv4);
RUN_TEST (test_nobind_any_ipv6); RUN_TEST (test_nobind_any_ipv6);
RUN_TEST (test_nobind_any_port_ipv4); RUN_TEST (test_nobind_any_port_ipv4);
RUN_TEST (test_nobind_any_port_ipv6); RUN_TEST (test_nobind_any_port_ipv6);
RUN_TEST (test_nobind_addr_anyport_ipv4); RUN_TEST (test_nobind_addr_anyport_ipv4);
RUN_TEST (test_nobind_addr_anyport_ipv6); RUN_TEST (test_nobind_addr_anyport_ipv6);
RUN_TEST (test_nobind_addr_port0_ipv4);
RUN_TEST (test_nobind_addr_port0_ipv6);
RUN_TEST (test_parse_ipv4_simple); RUN_TEST (test_parse_ipv4_simple);
RUN_TEST (test_parse_ipv4_zero); RUN_TEST (test_parse_ipv4_zero);
RUN_TEST (test_parse_ipv4_max); RUN_TEST (test_parse_ipv4_max);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment