zeromq / czmq

High-level C binding for ØMQ
czmq.zeromq.org
Mozilla Public License 2.0
1.16k stars 523 forks source link

zauth `zsock_bind()` fails when called for the second time from a different thread #2239

Open joaofl opened 1 year ago

joaofl commented 1 year ago

I am working on a tcp network of self discoverable nodes using zyre/czmq. During the development, I run some functional tests by instantiating many nodes from a single process, on different threads, so that I have the basics of the network logic tested for every modification I do.

That worked fine until I recently tried to add a authentication using the zauth actor, which worked just fine when nodes are instantiated in different Linux processes, but fails when nodes are instantiated from a single (test) process. I narrowed down the issue to the following assert in czmq/src/zauth.c:83:

static self_t *
s_self_new (zsock_t *pipe, zcertstore_t *certstore)
{
    ...
    int rc = zsock_bind (self->handler, ZAP_ENDPOINT); //line 82
    assert (rc == 0);
    ...
}

Where the error is:

czmq/src/zauth.c:84: s_self_new: Assertion `rc == 0' failed.

Where:

#define ZAP_ENDPOINT  "inproc://zeromq.zap.01"

The interesting part is that, if I remove the assert, my network behaves as expected, and my tests PASS just fine, even though rc=-1 on all the subsequent calls to zsock_bind.

It also solves the problem if I set the endpoint to tcp, with each node using a different (free) port, like below:

#define ZAP_ENDPOINT  "tcp://127.0.0.1:*[60000-]"

Very honestly, I started recently with zmq, and I dont have the knowledge to judge if this is the expected behavior, or why it does not work from a single thread with inproc, and if this is a bug/limitation, how to fix it.

Any ideas on how to address this are appreciated.