mirror of
https://github.com/zeromq/libzmq.git
synced 2025-01-21 02:00:36 +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
|
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
|
ZMQ_FD: Retrieve file descriptor associated with the socket
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The 'ZMQ_FD' option shall retrieve the file descriptor associated with the
|
The 'ZMQ_FD' option shall retrieve the file descriptor associated with the
|
||||||
|
@ -319,6 +319,18 @@ Option value unit:: connections
|
|||||||
Default value:: 100
|
Default value:: 100
|
||||||
Applicable socket types:: all, only for connection-oriented transports.
|
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
|
RETURN VALUE
|
||||||
------------
|
------------
|
||||||
|
@ -204,6 +204,7 @@ ZMQ_EXPORT int zmq_term (void *context);
|
|||||||
#define ZMQ_BACKLOG 19
|
#define ZMQ_BACKLOG 19
|
||||||
#define ZMQ_RECOVERY_IVL_MSEC 20 /* opt. recovery time, reconcile in 3.x */
|
#define ZMQ_RECOVERY_IVL_MSEC 20 /* opt. recovery time, reconcile in 3.x */
|
||||||
#define ZMQ_RECONNECT_IVL_MAX 21
|
#define ZMQ_RECONNECT_IVL_MAX 21
|
||||||
|
#define ZMQ_MAXMSGSIZE 22
|
||||||
|
|
||||||
/* Send/recv options. */
|
/* Send/recv options. */
|
||||||
#define ZMQ_NOBLOCK 1
|
#define ZMQ_NOBLOCK 1
|
||||||
|
@ -25,9 +25,10 @@
|
|||||||
#include "wire.hpp"
|
#include "wire.hpp"
|
||||||
#include "err.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_),
|
decoder_base_t <decoder_t> (bufsize_),
|
||||||
destination (NULL)
|
destination (NULL),
|
||||||
|
maxmsgsize (maxmsgsize_)
|
||||||
{
|
{
|
||||||
zmq_msg_init (&in_progress);
|
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
|
// 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
|
// close it before calling zmq_msg_init_size, however, it's a 0-byte
|
||||||
// message and thus we can treat it as uninitialised...
|
// 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) {
|
if (rc != 0 && errno == ENOMEM) {
|
||||||
rc = zmq_msg_init (&in_progress);
|
rc = zmq_msg_init (&in_progress);
|
||||||
errno_assert (rc == 0);
|
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
|
// 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
|
// close it before calling zmq_msg_init_size, however, it's a 0-byte
|
||||||
// message and thus we can treat it as uninitialised...
|
// 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) {
|
if (rc != 0 && errno == ENOMEM) {
|
||||||
rc = zmq_msg_init (&in_progress);
|
rc = zmq_msg_init (&in_progress);
|
||||||
errno_assert (rc == 0);
|
errno_assert (rc == 0);
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "err.hpp"
|
#include "err.hpp"
|
||||||
|
#include "stdint.hpp"
|
||||||
|
|
||||||
#include "../include/zmq.h"
|
#include "../include/zmq.h"
|
||||||
|
|
||||||
@ -180,7 +181,7 @@ namespace zmq
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
decoder_t (size_t bufsize_);
|
decoder_t (size_t bufsize_, int64_t maxmsgsize_);
|
||||||
~decoder_t ();
|
~decoder_t ();
|
||||||
|
|
||||||
void set_inout (struct i_inout *destination_);
|
void set_inout (struct i_inout *destination_);
|
||||||
@ -196,6 +197,8 @@ namespace zmq
|
|||||||
unsigned char tmpbuf [8];
|
unsigned char tmpbuf [8];
|
||||||
::zmq_msg_t in_progress;
|
::zmq_msg_t in_progress;
|
||||||
|
|
||||||
|
int64_t maxmsgsize;
|
||||||
|
|
||||||
decoder_t (const decoder_t&);
|
decoder_t (const decoder_t&);
|
||||||
void operator = (const decoder_t&);
|
void operator = (const decoder_t&);
|
||||||
};
|
};
|
||||||
|
@ -39,6 +39,7 @@ zmq::options_t::options_t () :
|
|||||||
reconnect_ivl (100),
|
reconnect_ivl (100),
|
||||||
reconnect_ivl_max (0),
|
reconnect_ivl_max (0),
|
||||||
backlog (100),
|
backlog (100),
|
||||||
|
maxmsgsize (-1),
|
||||||
requires_in (false),
|
requires_in (false),
|
||||||
requires_out (false),
|
requires_out (false),
|
||||||
immediate_connect (true)
|
immediate_connect (true)
|
||||||
@ -182,6 +183,14 @@ int zmq::options_t::setsockopt (int option_, const void *optval_,
|
|||||||
backlog = *((int*) optval_);
|
backlog = *((int*) optval_);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
case ZMQ_MAXMSGSIZE:
|
||||||
|
if (optvallen_ != sizeof (int64_t)) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
maxmsgsize = *((int64_t*) optval_);
|
||||||
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@ -328,6 +337,15 @@ int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_)
|
|||||||
*optvallen_ = sizeof (int);
|
*optvallen_ = sizeof (int);
|
||||||
return 0;
|
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;
|
errno = EINVAL;
|
||||||
|
@ -69,6 +69,9 @@ namespace zmq
|
|||||||
// Maximum backlog for pending connections.
|
// Maximum backlog for pending connections.
|
||||||
int backlog;
|
int backlog;
|
||||||
|
|
||||||
|
// Maximal size of message to handle.
|
||||||
|
int64_t maxmsgsize;
|
||||||
|
|
||||||
// These options are never set by the user directly. Instead they are
|
// These options are never set by the user directly. Instead they are
|
||||||
// provided by the specific socket type.
|
// provided by the specific socket type.
|
||||||
bool requires_in;
|
bool requires_in;
|
||||||
|
@ -211,7 +211,8 @@ void zmq::pgm_receiver_t::in_event ()
|
|||||||
it->second.joined = true;
|
it->second.joined = true;
|
||||||
|
|
||||||
// Create and connect decoder for the peer.
|
// 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);
|
alloc_assert (it->second.decoder);
|
||||||
it->second.decoder->set_inout (inout);
|
it->second.decoder->set_inout (inout);
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
zmq::zmq_engine_t::zmq_engine_t (fd_t fd_, const options_t &options_) :
|
zmq::zmq_engine_t::zmq_engine_t (fd_t fd_, const options_t &options_) :
|
||||||
inpos (NULL),
|
inpos (NULL),
|
||||||
insize (0),
|
insize (0),
|
||||||
decoder (in_batch_size),
|
decoder (in_batch_size, options_.maxmsgsize),
|
||||||
outpos (NULL),
|
outpos (NULL),
|
||||||
outsize (0),
|
outsize (0),
|
||||||
encoder (out_batch_size),
|
encoder (out_batch_size),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user