mirror of
https://github.com/zeromq/libzmq.git
synced 2025-02-20 22:31:34 +01:00
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).
This commit is contained in:
parent
0b36b84243
commit
2dc8579412
@ -44,6 +44,8 @@
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
|
||||
#include "ip_resolver.hpp"
|
||||
|
||||
zmq::udp_address_t::udp_address_t () : is_multicast (false)
|
||||
{
|
||||
memset (&bind_address, 0, sizeof bind_address);
|
||||
@ -56,37 +58,28 @@ zmq::udp_address_t::~udp_address_t ()
|
||||
|
||||
int zmq::udp_address_t::resolve (const char *name_, bool bind_)
|
||||
{
|
||||
// Find the ':' at end that separates address from the port number.
|
||||
const char *delimiter = strrchr (name_, ':');
|
||||
if (!delimiter) {
|
||||
errno = EINVAL;
|
||||
ip_resolver_options_t resolver_opts;
|
||||
|
||||
resolver_opts.bindable (bind_)
|
||||
.allow_dns (!bind_)
|
||||
.allow_nic_name (bind_)
|
||||
.expect_port (true)
|
||||
.ipv6 (false);
|
||||
|
||||
ip_resolver_t resolver (resolver_opts);
|
||||
ip_addr_t addr;
|
||||
|
||||
int rc = resolver.resolve (&addr, name_);
|
||||
if (rc != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Separate the address/port.
|
||||
std::string addr_str (name_, delimiter - name_);
|
||||
std::string port_str (delimiter + 1);
|
||||
|
||||
// Parse the port number (0 is not a valid port).
|
||||
uint16_t port = (uint16_t) atoi (port_str.c_str ());
|
||||
if (port == 0) {
|
||||
errno = EINVAL;
|
||||
if (addr.generic.sa_family != AF_INET) {
|
||||
// Shouldn't happen
|
||||
return -1;
|
||||
}
|
||||
|
||||
dest_address.sin_family = AF_INET;
|
||||
dest_address.sin_port = htons (port);
|
||||
|
||||
// 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;
|
||||
}
|
||||
dest_address = addr.ipv4;
|
||||
|
||||
// we will check only first byte of IP
|
||||
// and if it from 224 to 239, then it can
|
||||
@ -110,7 +103,7 @@ int zmq::udp_address_t::resolve (const char *name_, bool bind_)
|
||||
bind_address = dest_address;
|
||||
else {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -89,14 +89,12 @@ static void test_resolve_ipv4_bind ()
|
||||
|
||||
static void test_resolve_ipv4_bind_any ()
|
||||
{
|
||||
// Wildcard port not supported
|
||||
test_resolve ("*:*", NULL, 0, "0.0.0.0");
|
||||
test_resolve ("*:*", "0.0.0.0", 0, "0.0.0.0");
|
||||
}
|
||||
|
||||
static void test_resolve_ipv4_bind_anyport ()
|
||||
{
|
||||
// Wildcard port not supported
|
||||
test_resolve ("127.0.0.1:*", NULL, 0, "127.0.0.1");
|
||||
test_resolve ("127.0.0.1:*", "127.0.0.1", 0, "127.0.0.1");
|
||||
}
|
||||
|
||||
static void test_resolve_ipv4_bind_any_port ()
|
||||
@ -115,6 +113,11 @@ static void test_resolve_ipv4_connect_anyport ()
|
||||
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 ()
|
||||
{
|
||||
test_resolve ("239.0.0.1:1234", "239.0.0.1", 1234, "0.0.0.0", true);
|
||||
@ -149,6 +152,7 @@ int main (void)
|
||||
RUN_TEST (test_resolve_ipv4_bind_any_port);
|
||||
RUN_TEST (test_resolve_ipv4_connect_any);
|
||||
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_connect_mcast);
|
||||
RUN_TEST (test_resolve_ipv6_simple);
|
||||
|
Loading…
x
Reference in New Issue
Block a user