diff --git a/src/tipc_address.cpp b/src/tipc_address.cpp index 44020b29..548e13ee 100644 --- a/src/tipc_address.cpp +++ b/src/tipc_address.cpp @@ -41,6 +41,7 @@ zmq::tipc_address_t::tipc_address_t () { memset (&address, 0, sizeof address); + _random = false; } zmq::tipc_address_t::tipc_address_t (const sockaddr *sa, socklen_t sa_len) @@ -50,22 +51,42 @@ zmq::tipc_address_t::tipc_address_t (const sockaddr *sa, socklen_t sa_len) memset (&address, 0, sizeof address); if (sa->sa_family == AF_TIPC) memcpy (&address, sa, sa_len); + + _random = false; } zmq::tipc_address_t::~tipc_address_t () { } +void zmq::tipc_address_t::set_random () +{ + _random = true; +} +bool zmq::tipc_address_t::is_random () const +{ + return _random; +} +bool zmq::tipc_address_t::is_service () const +{ + if (address.addrtype == TIPC_ADDR_ID) + return false; + + return true; +} int zmq::tipc_address_t::resolve (const char *name) { unsigned int type = 0; unsigned int lower = 0; unsigned int upper = 0; + unsigned int ref = 0; unsigned int z = 1, c = 0, n = 0; char eof; const char *domain; - const int res = sscanf (name, "{%u,%u,%u}", &type, &lower, &upper); + int res = sscanf (name, "{%u,%u,%u}", &type, &lower, &upper); + if (res == 0) + goto portid; /* Fetch optional domain suffix. */ if ((domain = strchr (name, '@'))) { if (sscanf (domain, "@%u.%u.%u%c", &z, &c, &n, &eof) != 3) @@ -93,6 +114,25 @@ nameseq: address.addr.nameseq.upper = upper; address.scope = TIPC_ZONE_SCOPE; return 0; +portid: + res = sscanf (name, "<%u.%u.%u:%u>", &z, &c, &n, &ref); + if (res == 4) { + address.family = AF_TIPC; + address.addrtype = TIPC_ADDR_ID; + address.addr.id.node = tipc_addr (z, c, n); + address.addr.id.ref = ref; + address.scope = 0; + return 0; + } else if (strncmp (name, "<*>", 3) == 0) { + set_random (); + address.family = AF_TIPC; + address.addrtype = TIPC_ADDR_ID; + address.addr.id.node = 0; + address.addr.id.ref = 0; + address.scope = 0; + return 0; + } else + return EINVAL; } int zmq::tipc_address_t::to_string (std::string &addr_) @@ -102,11 +142,28 @@ int zmq::tipc_address_t::to_string (std::string &addr_) return -1; } std::stringstream s; - s << "tipc://" - << "{" << address.addr.nameseq.type; - s << ", " << address.addr.nameseq.lower; - s << ", " << address.addr.nameseq.upper << "}"; - addr_ = s.str (); + if (address.addrtype == TIPC_ADDR_NAMESEQ + || address.addrtype == TIPC_ADDR_NAME) { + s << "tipc://" + << "{" << address.addr.nameseq.type; + s << ", " << address.addr.nameseq.lower; + s << ", " << address.addr.nameseq.upper << "}"; + addr_ = s.str (); + } else if (address.addrtype == TIPC_ADDR_ID) { + s << "tipc://" + << "<" << tipc_zone (address.addr.id.node); + s << "." << tipc_cluster (address.addr.id.node); + s << "." << tipc_node (address.addr.id.node); + s << ":" << address.addr.id.ref << ">"; + addr_ = s.str (); + } else if (is_random ()) { + s << "tipc://" + << "<" << tipc_zone (address.addr.id.node); + s << "." << tipc_cluster (address.addr.id.node); + s << "." << tipc_node (address.addr.id.node); + s << ":" << address.addr.id.ref << ">"; + addr_ = s.str (); + } return 0; } diff --git a/src/tipc_address.hpp b/src/tipc_address.hpp index 287d91bc..c6a8d277 100644 --- a/src/tipc_address.hpp +++ b/src/tipc_address.hpp @@ -54,10 +54,16 @@ class tipc_address_t // The opposite to resolve() int to_string (std::string &addr_); + // Handling different TIPC address types + bool is_service () const; + bool is_random () const; + void set_random (); + const sockaddr *addr () const; socklen_t addrlen () const; private: + bool _random; struct sockaddr_tipc address; tipc_address_t (const tipc_address_t &); diff --git a/src/tipc_connecter.cpp b/src/tipc_connecter.cpp index 58b9b5ab..ad900a06 100644 --- a/src/tipc_connecter.cpp +++ b/src/tipc_connecter.cpp @@ -204,6 +204,11 @@ int zmq::tipc_connecter_t::open () { zmq_assert (s == retired_fd); + // Cannot connect to random tipc addresses + if (addr->resolved.tipc_addr->is_random ()) { + errno = EINVAL; + return -1; + } // Create the socket. s = open_socket (AF_TIPC, SOCK_STREAM, 0); if (s == -1) diff --git a/src/tipc_listener.cpp b/src/tipc_listener.cpp index 4ad8fdae..ab8fdd4d 100644 --- a/src/tipc_listener.cpp +++ b/src/tipc_listener.cpp @@ -137,12 +137,27 @@ int zmq::tipc_listener_t::set_address (const char *addr_) if (s == -1) return -1; + // If address was randomly assigned, update address object to reflect the actual address + if (address.is_random ()) { + struct sockaddr_storage ss; + socklen_t sl = sizeof (ss); + int rc = getsockname (s, (sockaddr *) &ss, &sl); + if (rc != 0) { + return rc; + } + + tipc_address_t addr ((struct sockaddr *) &ss, sl); + } + + address.to_string (endpoint); - // Bind the socket to tipc name. - rc = bind (s, address.addr (), address.addrlen ()); - if (rc != 0) - goto error; + // Bind the socket to tipc name + if (address.is_service ()) { + rc = bind (s, address.addr (), address.addrlen ()); + if (rc != 0) + goto error; + } // Listen for incoming connections. rc = listen (s, options.backlog);