mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-13 10:52:56 +01:00
ZMQ_MAXMSGSIZE option added
The new option allows user to guard against peers sending oversized messages. Connection to peer sending oversized message is dropped. Signed-off-by: Martin Sustrik <sustrik@250bpm.com>
This commit is contained in:
parent
4c7446211a
commit
5fcef1cac4
@ -311,6 +311,20 @@ Default value:: 100
|
||||
Applicable socket types:: all, only for connection-oriented transports
|
||||
|
||||
|
||||
ZMQ_MAXMSGSIZE: Maximum acceptable inbound message size
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The options shall retrieve limit for the inbound messages. If a peer sends
|
||||
a message larger than ZMQ_MAXMSGSIZE it is disconnected. Value of -1 means
|
||||
'no limit'.
|
||||
|
||||
[horizontal]
|
||||
Option value type:: int64_t
|
||||
Option value unit:: bytes
|
||||
Default value:: -1
|
||||
Applicable socket types:: all
|
||||
|
||||
|
||||
ZMQ_FD: Retrieve file descriptor associated with the socket
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The 'ZMQ_FD' option shall retrieve the file descriptor associated with the
|
||||
|
@ -319,6 +319,18 @@ Option value unit:: connections
|
||||
Default value:: 100
|
||||
Applicable socket types:: all, only for connection-oriented transports.
|
||||
|
||||
ZMQ_MAXMSGSIZE: Maximum acceptable inbound message size
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Limits the size of the inbound message. If a peer sends a message larger than
|
||||
ZMQ_MAXMSGSIZE it is disconnected. Value of -1 means 'no limit'.
|
||||
|
||||
[horizontal]
|
||||
Option value type:: int64_t
|
||||
Option value unit:: bytes
|
||||
Default value:: -1
|
||||
Applicable socket types:: all
|
||||
|
||||
|
||||
RETURN VALUE
|
||||
------------
|
||||
|
@ -204,6 +204,7 @@ ZMQ_EXPORT int zmq_term (void *context);
|
||||
#define ZMQ_BACKLOG 19
|
||||
#define ZMQ_RECOVERY_IVL_MSEC 20 /* opt. recovery time, reconcile in 3.x */
|
||||
#define ZMQ_RECONNECT_IVL_MAX 21
|
||||
#define ZMQ_MAXMSGSIZE 22
|
||||
|
||||
/* Send/recv options. */
|
||||
#define ZMQ_NOBLOCK 1
|
||||
|
@ -25,9 +25,10 @@
|
||||
#include "wire.hpp"
|
||||
#include "err.hpp"
|
||||
|
||||
zmq::decoder_t::decoder_t (size_t bufsize_) :
|
||||
zmq::decoder_t::decoder_t (size_t bufsize_, int64_t maxmsgsize_) :
|
||||
decoder_base_t <decoder_t> (bufsize_),
|
||||
destination (NULL)
|
||||
destination (NULL),
|
||||
maxmsgsize (maxmsgsize_)
|
||||
{
|
||||
zmq_msg_init (&in_progress);
|
||||
|
||||
@ -63,7 +64,13 @@ bool zmq::decoder_t::one_byte_size_ready ()
|
||||
// in_progress is initialised at this point so in theory we should
|
||||
// close it before calling zmq_msg_init_size, however, it's a 0-byte
|
||||
// message and thus we can treat it as uninitialised...
|
||||
int rc = zmq_msg_init_size (&in_progress, *tmpbuf - 1);
|
||||
int rc;
|
||||
if (maxmsgsize >= 0 && (int64_t) (*tmpbuf - 1) > maxmsgsize) {
|
||||
rc = -1;
|
||||
errno = ENOMEM;
|
||||
}
|
||||
else
|
||||
rc = zmq_msg_init_size (&in_progress, *tmpbuf - 1);
|
||||
if (rc != 0 && errno == ENOMEM) {
|
||||
rc = zmq_msg_init (&in_progress);
|
||||
errno_assert (rc == 0);
|
||||
@ -92,7 +99,13 @@ bool zmq::decoder_t::eight_byte_size_ready ()
|
||||
// in_progress is initialised at this point so in theory we should
|
||||
// close it before calling zmq_msg_init_size, however, it's a 0-byte
|
||||
// message and thus we can treat it as uninitialised...
|
||||
int rc = zmq_msg_init_size (&in_progress, size - 1);
|
||||
int rc;
|
||||
if (maxmsgsize >= 0 && (int64_t) (size - 1) > maxmsgsize) {
|
||||
rc = -1;
|
||||
errno = ENOMEM;
|
||||
}
|
||||
else
|
||||
rc = zmq_msg_init_size (&in_progress, size - 1);
|
||||
if (rc != 0 && errno == ENOMEM) {
|
||||
rc = zmq_msg_init (&in_progress);
|
||||
errno_assert (rc == 0);
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "err.hpp"
|
||||
#include "stdint.hpp"
|
||||
|
||||
#include "../include/zmq.h"
|
||||
|
||||
@ -180,7 +181,7 @@ namespace zmq
|
||||
{
|
||||
public:
|
||||
|
||||
decoder_t (size_t bufsize_);
|
||||
decoder_t (size_t bufsize_, int64_t maxmsgsize_);
|
||||
~decoder_t ();
|
||||
|
||||
void set_inout (struct i_inout *destination_);
|
||||
@ -196,6 +197,8 @@ namespace zmq
|
||||
unsigned char tmpbuf [8];
|
||||
::zmq_msg_t in_progress;
|
||||
|
||||
int64_t maxmsgsize;
|
||||
|
||||
decoder_t (const decoder_t&);
|
||||
void operator = (const decoder_t&);
|
||||
};
|
||||
|
@ -39,6 +39,7 @@ zmq::options_t::options_t () :
|
||||
reconnect_ivl (100),
|
||||
reconnect_ivl_max (0),
|
||||
backlog (100),
|
||||
maxmsgsize (-1),
|
||||
requires_in (false),
|
||||
requires_out (false),
|
||||
immediate_connect (true)
|
||||
@ -182,6 +183,14 @@ int zmq::options_t::setsockopt (int option_, const void *optval_,
|
||||
backlog = *((int*) optval_);
|
||||
return 0;
|
||||
|
||||
case ZMQ_MAXMSGSIZE:
|
||||
if (optvallen_ != sizeof (int64_t)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
maxmsgsize = *((int64_t*) optval_);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
errno = EINVAL;
|
||||
@ -328,6 +337,15 @@ int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_)
|
||||
*optvallen_ = sizeof (int);
|
||||
return 0;
|
||||
|
||||
case ZMQ_MAXMSGSIZE:
|
||||
if (*optvallen_ < sizeof (int64_t)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
*((int64_t*) optval_) = maxmsgsize;
|
||||
*optvallen_ = sizeof (int64_t);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
errno = EINVAL;
|
||||
|
@ -69,6 +69,9 @@ namespace zmq
|
||||
// Maximum backlog for pending connections.
|
||||
int backlog;
|
||||
|
||||
// Maximal size of message to handle.
|
||||
int64_t maxmsgsize;
|
||||
|
||||
// These options are never set by the user directly. Instead they are
|
||||
// provided by the specific socket type.
|
||||
bool requires_in;
|
||||
|
@ -211,7 +211,8 @@ void zmq::pgm_receiver_t::in_event ()
|
||||
it->second.joined = true;
|
||||
|
||||
// Create and connect decoder for the peer.
|
||||
it->second.decoder = new (std::nothrow) decoder_t (0);
|
||||
it->second.decoder = new (std::nothrow) decoder_t (0,
|
||||
options.maxmsgsize);
|
||||
alloc_assert (it->second.decoder);
|
||||
it->second.decoder->set_inout (inout);
|
||||
}
|
||||
|
@ -35,7 +35,7 @@
|
||||
zmq::zmq_engine_t::zmq_engine_t (fd_t fd_, const options_t &options_) :
|
||||
inpos (NULL),
|
||||
insize (0),
|
||||
decoder (in_batch_size),
|
||||
decoder (in_batch_size, options_.maxmsgsize),
|
||||
outpos (NULL),
|
||||
outsize (0),
|
||||
encoder (out_batch_size),
|
||||
|
Loading…
Reference in New Issue
Block a user