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 :)
_______________________________________________
zeromq-dev mailing list
[email protected]
http://lists.zeromq.org/mailman/listinfo/zeromq-dev