[zeromq-dev] Question about zmq_recv len and truncate

Bruno D. Rodrigues bruno.rodrigues at litux.org
Fri Oct 11 22:45:41 CEST 2013

Hello all,

I'm curious about a comment on a certain behaviour of zmq_recv that affected me when using it over the Java bindings.

The sentence in question is the following: http://api.zeromq.org/3-2:zmq-recv
"The zmq_recv() function shall return number of bytes in the message if successful. Note that the value can exceed the value of the len parameter in case the message was truncated."

and on the code, zmq.cpp 493
    //  At the moment an oversized message is silently truncated.

The context I was trying was a PUB server where I inject random messages, which I can't control (JSONs with some hundred bytes to several hundred kilobytes), and on the other side a SUB consuming them. This was over the Java bindings, using zmq git master (or 4.0.1) and jzmq 3 git master (or 3.0.1).

If I use the simpler memcpy heavy versions (send(byte[]) and byte[] x = socket.recv()), everything works as expected, but I was trying the other alternatives that allows to use direct ByteBuffers and avoid the memcpy operations. 
Or explicitly, the recv(byte[] buffer, int len) and the recv(no copy)(ByteBuffer but, int len)

What happens is that unless I pre-create a buffer of the maximum expected size (like 16MB), messages bigger than my buffer size will not only be truncated, but will also break on java when the callback tries to set the ByteBuffer position to a value larger than the limit.
jzmq Socket.cpp 
703     setByteBufferPosition(env, buffer, rc);
728         env->CallVoidMethod(buffer, setPositionHandle, pos + rc);

On top of this, as my C/C++ is quite forgotten since I was forced to move to Java, I couldn't follow exactly where the zmq_msg_t content is filled up, but a grep by malloc scared me as it seems possible to telnet into the server, send the right header prefix, and then announce an incoming message of several GB, which is blindly followed by the malloc, to then be discarded by the truncate reported above. (this can be mitigated by setting a maxMessageSize somewhere depending on the bindings, it seems, but hadn't tested it yet)

In simpler words:
- is it possible to receive a message of unknown size using the methods that receive my own buffers? If not, why do those methods exist at all?
- is it possible to crash a server with out of memory by sending a couple message headers with a huge len value?

I'd like to help fixing whatever I can do, but I'm lost now on where to pick stuff up, architecturally speaking. could the recv(buffer) return the next part of the same message, as I expected? 

Thanks in advance
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 235 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20131011/0838599a/attachment.sig>

More information about the zeromq-dev mailing list