Add support to the ROUTER socket to reassign identities upon name collision.

This commit is contained in:
Mark Barbisan
2013-10-30 23:45:46 -04:00
parent 2a03d541dc
commit 3825f3b300
3 changed files with 44 additions and 3 deletions

View File

@@ -35,7 +35,8 @@ zmq::router_t::router_t (class ctx_t *parent_, uint32_t tid_, int sid_) :
mandatory (false),
// raw_sock functionality in ROUTER is deprecated
raw_sock (false),
probe_router (false)
probe_router (false),
reassign_identities(false)
{
options.type = ZMQ_ROUTER;
options.recv_identity = true;
@@ -111,6 +112,12 @@ int zmq::router_t::xsetsockopt (int option_, const void *optval_,
return 0;
}
break;
case ZMQ_ROUTER_REASSIGN_IDENTITES:
if (is_int && value >= 0) {
reassign_identities = (value != 0);
return 0;
}
break;
default:
break;
@@ -394,9 +401,37 @@ bool zmq::router_t::identify_peer (pipe_t *pipe_)
outpipes_t::iterator it = outpipes.find (identity);
msg.close ();
// Ignore peers with duplicate ID.
if (it != outpipes.end ())
return false;
{
if (!reassign_identities) {
// Ignore peers with duplicate ID.
return false;
}
else
{
// We will allow the new connection to take over this
// identity. Temporarily assign a new identity to the
// existing pipe so we can terminate it asynchronously.
unsigned char buf [5];
buf [0] = 0;
put_uint32 (buf + 1, next_peer_id++);
blob_t new_identity = blob_t (buf, sizeof buf);
it->second.pipe->set_identity (new_identity);
outpipe_t existing_outpipe =
{it->second.pipe, it->second.active};
ok = outpipes.insert (outpipes_t::value_type (
new_identity, existing_outpipe)).second;
zmq_assert (ok);
// Remove the existing identity entry to allow the new
// connection to take the identity.
outpipes.erase (it);
existing_outpipe.pipe->terminate (true);
}
}
}
}