Commit 9c6aa1e9 authored by Pieter Hintjens's avatar Pieter Hintjens

Merge pull request #848 from Prarrot/master

Changed fail behavior of CONNECT_RID to an assert failure instead of silent failure.
parents 14c6cba2 188e76a7
...@@ -75,9 +75,9 @@ data transfer with the named id. This option applies only to the first ...@@ -75,9 +75,9 @@ data transfer with the named id. This option applies only to the first
subsequent call to zmq_connect(), calls thereafter use default connection subsequent call to zmq_connect(), calls thereafter use default connection
behavior. behavior.
Typical use is to set this socket option on each zmq_connect() attempt Typical use is to set this socket option ahead of each zmq_connect() attempt
to a new host. Each connection should be assigned a unique name. Duplicated to a new host. Each connection MUST be assigned a unique name. Assigning a
names will trigger default connection behavior. name that is already in use is not allowed.
Useful when connecting ROUTER to ROUTER, or STREAM to STREAM, as it Useful when connecting ROUTER to ROUTER, or STREAM to STREAM, as it
allows for immediate sending to peers. Outbound id framing requirements allows for immediate sending to peers. Outbound id framing requirements
......
...@@ -393,9 +393,8 @@ bool zmq::router_t::identify_peer (pipe_t *pipe_) ...@@ -393,9 +393,8 @@ bool zmq::router_t::identify_peer (pipe_t *pipe_)
connect_rid.length()); connect_rid.length());
connect_rid.clear (); connect_rid.clear ();
outpipes_t::iterator it = outpipes.find (identity); outpipes_t::iterator it = outpipes.find (identity);
if (it != outpipes.end ()) { if (it != outpipes.end ())
return false; // duplicate connection zmq_assert(false); // Not allowed to duplicate an existing rid
}
} }
else else
if (options.raw_sock) { // Always assign identity for raw-socket if (options.raw_sock) { // Always assign identity for raw-socket
......
...@@ -268,10 +268,10 @@ void zmq::stream_t::identify_peer (pipe_t *pipe_) ...@@ -268,10 +268,10 @@ void zmq::stream_t::identify_peer (pipe_t *pipe_)
connect_rid.clear (); connect_rid.clear ();
outpipes_t::iterator it = outpipes.find (identity); outpipes_t::iterator it = outpipes.find (identity);
if (it != outpipes.end ()) if (it != outpipes.end ())
goto d; zmq_assert(false);
} }
else { else {
d: put_uint32 (buffer + 1, next_rid++); put_uint32 (buffer + 1, next_rid++);
identity = blob_t (buffer, sizeof buffer); identity = blob_t (buffer, sizeof buffer);
memcpy (options.identity, identity.data (), identity.size ()); memcpy (options.identity, identity.data (), identity.size ());
options.identity_size = identity.size (); options.identity_size = identity.size ();
......
/* /*
Copyright (c) 2007-2014 Contributors as noted in the AUTHORS file Copyright (c) 2007-2014 Contributors as noted in the AUTHORS file
...@@ -21,116 +20,162 @@ ...@@ -21,116 +20,162 @@
#include "testutil.hpp" #include "testutil.hpp"
void test_stream_2_stream(void* ctx){ void test_stream_2_stream(void* ctx_){
void *rbind, *rconn1; void *rbind, *rconn1;
int ret; int ret;
char buff[256]; char buff[256];
char msg[] = "hi 1"; char msg[] = "hi 1";
const char *bindip = "tcp://127.0.0.1:12001"; const char *bindip = "tcp://127.0.0.1:5556";
rbind = zmq_socket(ctx,ZMQ_STREAM); int zero = 0;
rconn1 = zmq_socket(ctx,ZMQ_STREAM);
assert(rbind && rconn1 ); // Set up listener STREAM.
ret = zmq_bind(rbind,bindip); rbind = zmq_socket (ctx_, ZMQ_STREAM);
assert(0 == ret); assert (rbind);
ret = zmq_setsockopt(rconn1,ZMQ_CONNECT_RID,"conn1",6); ret = zmq_setsockopt (rbind, ZMQ_LINGER, &zero, sizeof (zero));
assert(0 == ret); assert (0 == ret);
ret = zmq_connect(rconn1,bindip); ret = zmq_bind (rbind, bindip);
/*test duplicate connect attempt*/
ret = zmq_setsockopt(rconn1,ZMQ_CONNECT_RID,"conn1",6);
assert(0 == ret); assert(0 == ret);
ret = zmq_connect(rconn1,bindip);
// Set up connection stream.
rconn1 = zmq_socket (ctx_, ZMQ_STREAM);
assert (rconn1);
ret = zmq_setsockopt (rconn1, ZMQ_LINGER, &zero, sizeof (zero));
assert (0 == ret);
// Do the connection.
ret = zmq_setsockopt (rconn1, ZMQ_CONNECT_RID, "conn1", 6);
assert (0 == ret);
ret = zmq_connect (rconn1, bindip);
/* Uncomment to test assert on duplicate rid.
// Test duplicate connect attempt.
ret = zmq_setsockopt (rconn1, ZMQ_CONNECT_RID, "conn1", 6);
assert (0 == ret);
ret = zmq_connect (rconn1, bindip);
assert (0 == ret);
*/
// Send data to the bound stream.
ret = zmq_send (rconn1, "conn1", 6, ZMQ_SNDMORE);
assert (6 == ret);
ret = zmq_send (rconn1, msg, 5, 0);
assert (5 == ret);
// Accept data on the bound stream.
ret = zmq_recv (rbind, buff, 256, 0);
assert (ret && 0 == buff[0]);
assert (0 == buff[0]);
ret = zmq_recv (rbind, buff, 256, 0);
assert (0 == ret);
// Handle close of the socket.
ret = zmq_recv (rbind, buff, 256, 0);
assert (ret);
assert (0 == buff[0]);
ret = zmq_recv (rbind, buff+128, 128, 0);
assert (5 == ret);
assert ('h' == buff[128]);
ret = zmq_unbind (rbind, bindip);
assert(0 == ret); assert(0 == ret);
ret = zmq_send(rconn1,"conn1",6,ZMQ_SNDMORE); ret = zmq_close (rbind);
assert(6 == ret);
ret = zmq_send(rconn1,msg,5,0);
assert(5 == ret);
ret = zmq_recv(rbind,buff,256,0);
assert(ret && 0 == buff[0]);
ret = zmq_recv(rbind,buff,256,0);
assert(0 == ret); assert(0 == ret);
ret = zmq_close (rconn1);
// close the duplicate socket
ret = zmq_recv(rbind,buff,256,0);
assert(ret && 0 == buff[0]);
ret = zmq_recv(rbind,buff+128,128,0);
assert(0 == ret); assert(0 == ret);
// handle the good socket
ret = zmq_recv(rbind,buff,256,0);
assert(ret && 0 == buff[0]);
ret = zmq_recv(rbind,buff+128,128,0);
assert(5 == ret && 'h' == buff[128] );
zmq_unbind(rbind,bindip);
zmq_close(rbind);
zmq_close(rconn1);
} }
void test_router_2_router(void* ctx,bool named){ void test_router_2_router(void* ctx,bool named){
void *rbind, *rconn1; void *rbind, *rconn1;
int ret; int ret;
char buff[256]; char buff[256];
char msg[] = "hi 1"; char msg[] = "hi 1";
const char *bindip = "tcp://127.0.0.1:12001"; const char *bindip = "tcp://127.0.0.1:5556";
rbind = zmq_socket(ctx,ZMQ_ROUTER); int zero = 0;
rconn1 = zmq_socket(ctx,ZMQ_ROUTER);
assert(rbind && rconn1 ); // Create bind socket.
ret = zmq_bind(rbind,bindip); rbind = zmq_socket (ctx, ZMQ_ROUTER);
assert(0 == ret); assert (rbind);
if(named){/*here we check if this interferes with bound socket naming */ ret = zmq_setsockopt (rbind, ZMQ_LINGER, &zero, sizeof (zero));
assert (0 == ret);
ret = zmq_bind (rbind, bindip);
assert (0 == ret);
// Create connection socket.
rconn1 = zmq_socket (ctx, ZMQ_ROUTER);
assert (rconn1);
ret = zmq_setsockopt (rconn1, ZMQ_LINGER, &zero, sizeof (zero));
assert (0 == ret);
// If we're in named mode, set some identities.
if (named) {
ret = zmq_setsockopt (rbind, ZMQ_IDENTITY, "X", 1); ret = zmq_setsockopt (rbind, ZMQ_IDENTITY, "X", 1);
ret = zmq_setsockopt (rconn1, ZMQ_IDENTITY, "Y", 1); ret = zmq_setsockopt (rconn1, ZMQ_IDENTITY, "Y", 1);
} }
ret = zmq_setsockopt(rconn1,ZMQ_CONNECT_RID,"conn1",6);
assert(0 == ret); // Make call to connect using a connect_rid.
ret = zmq_connect(rconn1,bindip); ret = zmq_setsockopt (rconn1, ZMQ_CONNECT_RID, "conn1", 6);
assert(0 == ret); assert (0 == ret);
/*test duplicate connect attempt*/ ret = zmq_connect (rconn1, bindip);
ret = zmq_setsockopt(rconn1,ZMQ_CONNECT_RID,"conn1",6); assert (0 == ret);
assert(0 == ret); /* Uncomment to test assert on duplicate rid
ret = zmq_connect(rconn1,bindip); // Test duplicate connect attempt.
assert(0 == ret); ret = zmq_setsockopt (rconn1, ZMQ_CONNECT_RID, "conn1", 6);
ret = zmq_send(rconn1,"conn1",6,ZMQ_SNDMORE); assert (0 == ret);
assert(6 == ret); ret = zmq_connect (rconn1, bindip);
ret = zmq_send(rconn1,msg,5,0); assert (0 == ret);
assert(5 == ret); */
// Send some data.
ret = zmq_recv(rbind,buff,256,0); ret = zmq_send (rconn1, "conn1", 6, ZMQ_SNDMORE);
if(named) assert(ret && 'Y' == buff[0]); assert (6 == ret);
else assert(ret && 0 == buff[0]); ret = zmq_send (rconn1, msg, 5, 0);
ret = zmq_recv(rbind,buff+128,128,0); assert (5 == ret);
assert(5 == ret && 'h' == buff[128] );
if(named) { // Receive the name.
ret = zmq_send(rbind,buff,1,ZMQ_SNDMORE); ret = zmq_recv (rbind, buff, 256, 0);
assert(1 == ret); if (named)
assert (ret && 'Y' == buff[0]);
else
assert (ret && 0 == buff[0]);
// Receive the data.
ret = zmq_recv (rbind, buff+128, 128, 0);
assert(5 == ret && 'h' == buff[128]);
// Send some data back.
if (named) {
ret = zmq_send (rbind, buff, 1, ZMQ_SNDMORE);
assert (1 == ret);
} }
else { else {
ret = zmq_send(rbind,buff,5,ZMQ_SNDMORE); ret = zmq_send (rbind, buff, 5, ZMQ_SNDMORE);
assert(5 == ret); assert (5 == ret);
} }
ret = zmq_send_const(rbind,"ok",3,0); ret = zmq_send_const (rbind, "ok", 3, 0);
assert(3 == ret); assert (3 == ret);
/*if bound socket identity naming a problem, we'll likely see something funky here */ // If bound socket identity naming a problem, we'll likely see something funky here.
ret = zmq_recv(rconn1,buff,256,0); ret = zmq_recv (rconn1, buff, 256, 0);
assert('c' == buff[0] && 6 == ret); assert ('c' == buff[0] && 6 == ret);
ret = zmq_recv(rconn1,buff+128,128,0); ret = zmq_recv (rconn1, buff+128, 128, 0);
assert(3 == ret && 'o' == buff[128] ); assert (3 == ret && 'o' == buff[128]);
zmq_unbind(rbind,bindip); ret = zmq_unbind (rbind, bindip);
zmq_close(rbind); assert(0 == ret);
zmq_close(rconn1); ret = zmq_close (rbind);
assert(0 == ret);
ret = zmq_close (rconn1);
assert(0 == ret);
} }
int main (void) int main (void)
{ {
void *ctx; void *ctx;
setup_test_environment(); setup_test_environment ();
ctx = zmq_ctx_new (); ctx = zmq_ctx_new ();
assert (ctx); assert (ctx);
test_stream_2_stream(ctx); test_stream_2_stream (ctx);
test_router_2_router(ctx,false); test_router_2_router (ctx, false);
test_router_2_router(ctx,true); test_router_2_router (ctx, true);
zmq_ctx_destroy(ctx); zmq_ctx_destroy (ctx);
printf ("'test_connect_rid' passed"); printf ("'test_connect_rid' passed");
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment