mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-12 18:40:27 +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:
parent
4c7c9b87bf
commit
78aa9b1983
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 &);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user