mirror of
https://github.com/zeromq/libzmq.git
synced 2025-10-27 19:10:22 +01:00
Support addressing TIPC Port Identity
ZeroMQ currently supports location independent addressing using TIPC
Port Names with tipc://{type,instance}. This commits adds support for
connecting and binding using TIPC Port Identity addresses. To connect
using Port Identities the expected format is tipc://<Z.C.N:Ref>, e.g.
"tipc://<1.2.3:123123>". To bind using TIPC Port Identities the expected
format is "tipc://<*>".
This commit is contained in:
@@ -41,6 +41,7 @@
|
|||||||
zmq::tipc_address_t::tipc_address_t ()
|
zmq::tipc_address_t::tipc_address_t ()
|
||||||
{
|
{
|
||||||
memset (&address, 0, sizeof address);
|
memset (&address, 0, sizeof address);
|
||||||
|
_random = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
zmq::tipc_address_t::tipc_address_t (const sockaddr *sa, socklen_t sa_len)
|
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);
|
memset (&address, 0, sizeof address);
|
||||||
if (sa->sa_family == AF_TIPC)
|
if (sa->sa_family == AF_TIPC)
|
||||||
memcpy (&address, sa, sa_len);
|
memcpy (&address, sa, sa_len);
|
||||||
|
|
||||||
|
_random = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
zmq::tipc_address_t::~tipc_address_t ()
|
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)
|
int zmq::tipc_address_t::resolve (const char *name)
|
||||||
{
|
{
|
||||||
unsigned int type = 0;
|
unsigned int type = 0;
|
||||||
unsigned int lower = 0;
|
unsigned int lower = 0;
|
||||||
unsigned int upper = 0;
|
unsigned int upper = 0;
|
||||||
|
unsigned int ref = 0;
|
||||||
unsigned int z = 1, c = 0, n = 0;
|
unsigned int z = 1, c = 0, n = 0;
|
||||||
char eof;
|
char eof;
|
||||||
const char *domain;
|
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. */
|
/* Fetch optional domain suffix. */
|
||||||
if ((domain = strchr (name, '@'))) {
|
if ((domain = strchr (name, '@'))) {
|
||||||
if (sscanf (domain, "@%u.%u.%u%c", &z, &c, &n, &eof) != 3)
|
if (sscanf (domain, "@%u.%u.%u%c", &z, &c, &n, &eof) != 3)
|
||||||
@@ -93,6 +114,25 @@ nameseq:
|
|||||||
address.addr.nameseq.upper = upper;
|
address.addr.nameseq.upper = upper;
|
||||||
address.scope = TIPC_ZONE_SCOPE;
|
address.scope = TIPC_ZONE_SCOPE;
|
||||||
return 0;
|
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_)
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
s << "tipc://"
|
if (address.addrtype == TIPC_ADDR_NAMESEQ
|
||||||
<< "{" << address.addr.nameseq.type;
|
|| address.addrtype == TIPC_ADDR_NAME) {
|
||||||
s << ", " << address.addr.nameseq.lower;
|
s << "tipc://"
|
||||||
s << ", " << address.addr.nameseq.upper << "}";
|
<< "{" << address.addr.nameseq.type;
|
||||||
addr_ = s.str ();
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,10 +54,16 @@ class tipc_address_t
|
|||||||
// The opposite to resolve()
|
// The opposite to resolve()
|
||||||
int to_string (std::string &addr_);
|
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;
|
const sockaddr *addr () const;
|
||||||
socklen_t addrlen () const;
|
socklen_t addrlen () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool _random;
|
||||||
struct sockaddr_tipc address;
|
struct sockaddr_tipc address;
|
||||||
|
|
||||||
tipc_address_t (const tipc_address_t &);
|
tipc_address_t (const tipc_address_t &);
|
||||||
|
|||||||
@@ -204,6 +204,11 @@ int zmq::tipc_connecter_t::open ()
|
|||||||
{
|
{
|
||||||
zmq_assert (s == retired_fd);
|
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.
|
// Create the socket.
|
||||||
s = open_socket (AF_TIPC, SOCK_STREAM, 0);
|
s = open_socket (AF_TIPC, SOCK_STREAM, 0);
|
||||||
if (s == -1)
|
if (s == -1)
|
||||||
|
|||||||
@@ -137,12 +137,27 @@ int zmq::tipc_listener_t::set_address (const char *addr_)
|
|||||||
if (s == -1)
|
if (s == -1)
|
||||||
return -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);
|
address.to_string (endpoint);
|
||||||
|
|
||||||
// Bind the socket to tipc name.
|
// Bind the socket to tipc name
|
||||||
rc = bind (s, address.addr (), address.addrlen ());
|
if (address.is_service ()) {
|
||||||
if (rc != 0)
|
rc = bind (s, address.addr (), address.addrlen ());
|
||||||
goto error;
|
if (rc != 0)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
// Listen for incoming connections.
|
// Listen for incoming connections.
|
||||||
rc = listen (s, options.backlog);
|
rc = listen (s, options.backlog);
|
||||||
|
|||||||
Reference in New Issue
Block a user