mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-13 10:52:56 +01:00
Problem: ip_resolver allows wildcard ports for non-bindable sockets
Solution: return an error in this situation but still allow using an explicit "0" if somebody really wants to connect to port 0. This shouldn't break any existing code because a "*" port was already rejected in an early test in the TCP path in zmq::socket_base_t::connect.
This commit is contained in:
parent
889ac2eb3d
commit
406c348771
@ -117,8 +117,17 @@ int zmq::ip_resolver_t::resolve (ip_addr_t *ip_addr_, const char *name_)
|
||||
addr = std::string (name_, delim - name_);
|
||||
std::string port_str = std::string (delim + 1);
|
||||
|
||||
if (port_str == "*" || port_str == "0") {
|
||||
// Resolve wildcard to 0 to allow autoselection of port
|
||||
if (port_str == "*") {
|
||||
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;
|
||||
} else {
|
||||
// Parse the port number (0 is not a valid port).
|
||||
|
@ -210,6 +210,18 @@ static void test_bind_any (int ipv6_)
|
||||
}
|
||||
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_)
|
||||
{
|
||||
zmq::ip_resolver_options_t resolver_opts;
|
||||
@ -240,15 +252,25 @@ static void test_nobind_addr_anyport (int ipv6_)
|
||||
|
||||
resolver_opts.expect_port (true).ipv6 (ipv6_);
|
||||
|
||||
// This however works. Should it ? For the time being I'm going to
|
||||
// keep it that way for backcompat but I can't imagine why you'd
|
||||
// want a wildcard port if you're not binding.
|
||||
const char *expected = ipv6_ ? "::ffff:127.0.0.1" : "127.0.0.1";
|
||||
const char *fallback = ipv6_ ? "127.0.0.1" : NULL;
|
||||
test_resolve (resolver_opts, "127.0.0.1:*", expected, 0, 0, fallback);
|
||||
// Wildcard port should be rejected for non-bindable addresses
|
||||
test_resolve (resolver_opts, "127.0.0.1:*", NULL);
|
||||
}
|
||||
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 *fallback = ipv6_ ? "127.0.0.1" : NULL;
|
||||
test_resolve (resolver_opts, "127.0.0.1:0", expected, 0, 0, fallback);
|
||||
}
|
||||
MAKE_TEST_V4V6 (test_nobind_addr_port0)
|
||||
|
||||
static void test_parse_ipv4_simple ()
|
||||
{
|
||||
zmq::ip_resolver_options_t resolver_opts;
|
||||
@ -501,7 +523,7 @@ static void test_parse_ipv6_port_any ()
|
||||
{
|
||||
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);
|
||||
}
|
||||
@ -810,12 +832,16 @@ int main (void)
|
||||
|
||||
RUN_TEST (test_bind_any_ipv4);
|
||||
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_ipv6);
|
||||
RUN_TEST (test_nobind_any_port_ipv4);
|
||||
RUN_TEST (test_nobind_any_port_ipv6);
|
||||
RUN_TEST (test_nobind_addr_anyport_ipv4);
|
||||
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_zero);
|
||||
RUN_TEST (test_parse_ipv4_max);
|
||||
|
Loading…
Reference in New Issue
Block a user