libzmq: Problem: outgoing messages are still queued when auth fails
This is related to #882 but specifically for thread-safe socket types.
Issue description
When ZAP is enabled and the connection succeeds but the authentication fails, the socket will still queue outgoing messages. This means that the application code will never be able to tell that the authentication failed via the send call (until the hwm is reached). This is a huge footgun in my opinion.
Currently this issue can be mitigated by making connect calls blocking by creating a PAIR socket that would wait for a handshake event (success or failure) via zmq_socket_monitor. However this adds overhead to every connect call.
But this mitigation cannot work on thread safe types since multiple thread since making multiple concurrent connect calls would not guarantee that their PAIR socket would receive the appropriate event for their endpoint (e.g. first connect call receives the event for the endpoint of the second call and vice versa).
Mitigation Ideas
Make the an API similar tozmq_socket_monitorbut with aPUBsocket instead of aPAIR. The message sent would the same as the first frame of the current APIzmq_socket_monitorbut the message topic would be the endpoint string. This way multiple concurrent connect calls would be guaranteed to received the events associated with their endpoint. Note that this cannot work with aRADIOsocket since the maximum group length is of 15 chars. This works but its not ideal.- Add a socket option / API flag so that the socket stays in mute state until a
ZMQ_EVENT_HANDSHAKE_SUCCEEDEDevent. This would cause thesendcall to fail withEAGAINif the autentication failed (similar to if the connection failed). Probably too hard to implement. Add a zmq function call that blocks and returns only when the authentication succeeded or failed. Maybe a methods that calls connect underneat then wait until the event if received. This seems pretty ideal.
Edit1: Mitigation ideas that cannot work were crossed-out.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 37 (28 by maintainers)
Now that I think about it, every authentication call has to go through a ZAP handler (since I enable ZAP on all my sockets), which means i can intercept them. I could use a RADIO socket directly in the ZAP handler and generate my own events. Then I could block waiting for the appropriate handshake event to be received etc.Thanks for the response, your inprox socket proxying gave me this idea.edit: This only work if you dont need to connect to an outside socket.
yes, it is safe. The same behavior with any multiple connects, which is socket dependent.
https://github.com/zeromq/libzmq/blob/master/src/socket_base.cpp#L806
So it might be ignored or connect multiple times to the same address.
Are you using multiple connects or only one? I’m thinking of a few solutions: