[zeromq-dev] [PATCH] Maximum message size

Mikael Helbo Kjær mhk at designtech.dk
Tue Nov 9 09:59:47 CET 2010


Hi Samuel

 

Well it was not intended as a DOS defense at all, more along the lines of a way to limit the size of messages that a receiver would be willing to accept in case of memory limits and the like. I was thinking off adding something similar to the sender to allow it to inform the API user that he is trying to send too much. And no the sender won’t be informed like with so many other things in zmq as far as I know, the message is just unceremoniously dropped which could be a problem for a sending REP socket I agree (Timeouts are important here). This was also intended to start this discussion so in that way the patch worked.

 

As for your critique of the actual patch:  you are completely right and I will take your code over mine.

 

Regards,

Mikael

 

I just joined this list a couple of days ago (as an happy 0MQ user) so I haven't participated to the maximum message size discussion. I will play the devil's advocate as what I like most in 0MQ is its simplicity, and I would not want it to become bloated with too many options.

If the goal is to protect yourself against wanted or unwanted denial of service (DOS) which would fill up the buffers, this will probably not work as the attacker may then choose to send acceptably-sized requests that will use your processing time instead. The proper solution against DOS is probably either a firewall- or VPN-based one (in closed architectures) or a cryptographic one (if you want to offer a public service over 0MQ, or if you have to deploy a distributed application over a hostile network -- this has already been discussed in another thread).

So we can assume the nodes trust each other (as this doesn't rule out the problematic DOS cases). What will happen if the limit is reached? Will the sender be informed of the failure so that it can at least log it? (it cannot report it as an error, as this is an asynchronous failure)

Moreover, I am concerned about the possible inconsistencies arising from the use of this option in a distributed application: if a receiver limits what it is able to receive, how would the sender know it? If, for example, you set the limit on a REP socket, the sender may be stuck in its recv() call because it will never receive an answer (to a never-received query) and it will not be informed of it. If you set it on a REQ socket, the same scenario may happen because the answer may be discarded.

Also, this hunk bugs me:

     //  There has to be at least one byte (the flags) in the message).
-    if (!size) {
+    if (!size && !under_maximum_size(size)) {
         decoding_error ();
         return false;
     }

How did you test your code? It looks to me as "under_maximum_size(size)" is only called when "size" is zero. Didn't you mean "if (!size || !under_maximum_size(size))"?

This one seems dubious too:

+        inline bool under_maximum_size (size_t size)
+        {
+            return (max_msgsize != 0 && size < max_msgsize);
+        }
+

Didn't you mean "return max_msgsize == 0 || size <= max_msgsize"?

(as a side note, rather than using a negation in the first hunk, I would have used:

inline bool over_maximum_size(size_t size)
{
  return max_msgsize && size > max_msgsize;
}

and

if (!size || over_maximum_size(size)) {
  decoding_error();
  return false;
}

but this is a style issue :)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20101109/a3824d06/attachment.htm>


More information about the zeromq-dev mailing list