Commit 2dc85794 authored by Lionel Flandrin's avatar Lionel Flandrin

Problem: the UDP address code uses an ad hoc custom parser

Solution: replace it with the ip_resolver code shared with the TCP
address code

It simplifies the UDP parsing code and makes it behave more like the
TCP counterpart, in particular it's not possible to connect to hosts
by name and bind by NIC names.

It also adds support for "*" port resolving to 0 (useful to let the OS
allocate the port number).
parent 0b36b842
...@@ -44,6 +44,8 @@ ...@@ -44,6 +44,8 @@
#include <ctype.h> #include <ctype.h>
#endif #endif
#include "ip_resolver.hpp"
zmq::udp_address_t::udp_address_t () : is_multicast (false) zmq::udp_address_t::udp_address_t () : is_multicast (false)
{ {
memset (&bind_address, 0, sizeof bind_address); memset (&bind_address, 0, sizeof bind_address);
...@@ -56,38 +58,29 @@ zmq::udp_address_t::~udp_address_t () ...@@ -56,38 +58,29 @@ zmq::udp_address_t::~udp_address_t ()
int zmq::udp_address_t::resolve (const char *name_, bool bind_) int zmq::udp_address_t::resolve (const char *name_, bool bind_)
{ {
// Find the ':' at end that separates address from the port number. ip_resolver_options_t resolver_opts;
const char *delimiter = strrchr (name_, ':');
if (!delimiter) {
errno = EINVAL;
return -1;
}
// Separate the address/port. resolver_opts.bindable (bind_)
std::string addr_str (name_, delimiter - name_); .allow_dns (!bind_)
std::string port_str (delimiter + 1); .allow_nic_name (bind_)
.expect_port (true)
.ipv6 (false);
// Parse the port number (0 is not a valid port). ip_resolver_t resolver (resolver_opts);
uint16_t port = (uint16_t) atoi (port_str.c_str ()); ip_addr_t addr;
if (port == 0) {
errno = EINVAL; int rc = resolver.resolve (&addr, name_);
if (rc != 0) {
return -1; return -1;
} }
dest_address.sin_family = AF_INET; if (addr.generic.sa_family != AF_INET) {
dest_address.sin_port = htons (port); // Shouldn't happen
// Only when the udp should bind we allow * as the address
if (addr_str == "*" && bind_)
dest_address.sin_addr.s_addr = htonl (INADDR_ANY);
else
dest_address.sin_addr.s_addr = inet_addr (addr_str.c_str ());
if (dest_address.sin_addr.s_addr == INADDR_NONE) {
errno = EINVAL;
return -1; return -1;
} }
dest_address = addr.ipv4;
// we will check only first byte of IP // we will check only first byte of IP
// and if it from 224 to 239, then it can // and if it from 224 to 239, then it can
// represent multicast IP. // represent multicast IP.
...@@ -110,7 +103,7 @@ int zmq::udp_address_t::resolve (const char *name_, bool bind_) ...@@ -110,7 +103,7 @@ int zmq::udp_address_t::resolve (const char *name_, bool bind_)
bind_address = dest_address; bind_address = dest_address;
else { else {
bind_address.sin_family = AF_INET; bind_address.sin_family = AF_INET;
bind_address.sin_port = htons (port); bind_address.sin_port = dest_address.sin_port;
bind_address.sin_addr.s_addr = htonl (INADDR_ANY); bind_address.sin_addr.s_addr = htonl (INADDR_ANY);
} }
......
...@@ -89,14 +89,12 @@ static void test_resolve_ipv4_bind () ...@@ -89,14 +89,12 @@ static void test_resolve_ipv4_bind ()
static void test_resolve_ipv4_bind_any () static void test_resolve_ipv4_bind_any ()
{ {
// Wildcard port not supported test_resolve ("*:*", "0.0.0.0", 0, "0.0.0.0");
test_resolve ("*:*", NULL, 0, "0.0.0.0");
} }
static void test_resolve_ipv4_bind_anyport () static void test_resolve_ipv4_bind_anyport ()
{ {
// Wildcard port not supported test_resolve ("127.0.0.1:*", "127.0.0.1", 0, "127.0.0.1");
test_resolve ("127.0.0.1:*", NULL, 0, "127.0.0.1");
} }
static void test_resolve_ipv4_bind_any_port () static void test_resolve_ipv4_bind_any_port ()
...@@ -115,6 +113,11 @@ static void test_resolve_ipv4_connect_anyport () ...@@ -115,6 +113,11 @@ static void test_resolve_ipv4_connect_anyport ()
test_resolve ("127.0.0.1:*", NULL); test_resolve ("127.0.0.1:*", NULL);
} }
static void test_resolve_ipv4_connect_port0 ()
{
test_resolve ("127.0.0.1:0", "127.0.0.1", 0);
}
static void test_resolve_ipv4_bind_mcast () static void test_resolve_ipv4_bind_mcast ()
{ {
test_resolve ("239.0.0.1:1234", "239.0.0.1", 1234, "0.0.0.0", true); test_resolve ("239.0.0.1:1234", "239.0.0.1", 1234, "0.0.0.0", true);
...@@ -149,6 +152,7 @@ int main (void) ...@@ -149,6 +152,7 @@ int main (void)
RUN_TEST (test_resolve_ipv4_bind_any_port); RUN_TEST (test_resolve_ipv4_bind_any_port);
RUN_TEST (test_resolve_ipv4_connect_any); RUN_TEST (test_resolve_ipv4_connect_any);
RUN_TEST (test_resolve_ipv4_connect_anyport); RUN_TEST (test_resolve_ipv4_connect_anyport);
RUN_TEST (test_resolve_ipv4_connect_port0);
RUN_TEST (test_resolve_ipv4_bind_mcast); RUN_TEST (test_resolve_ipv4_bind_mcast);
RUN_TEST (test_resolve_ipv4_connect_mcast); RUN_TEST (test_resolve_ipv4_connect_mcast);
RUN_TEST (test_resolve_ipv6_simple); RUN_TEST (test_resolve_ipv6_simple);
......
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