mirror of
https://github.com/zeromq/libzmq.git
synced 2025-10-29 04:17:57 +01:00
Problem: CLIENT and SERVER don't check SNDMORE
These sockets don't handle multipart data, so if callers send it, they drop frames, and things break silently. Solution: if the caller tries to use ZMQ_SNDMORE, return -1 and set errno to EINVAL.
This commit is contained in:
@@ -67,6 +67,8 @@ ERRORS
|
|||||||
Non-blocking mode was requested and the message cannot be sent at the moment.
|
Non-blocking mode was requested and the message cannot be sent at the moment.
|
||||||
*ENOTSUP*::
|
*ENOTSUP*::
|
||||||
The _zmq_msg_send()_ operation is not supported by this socket type.
|
The _zmq_msg_send()_ operation is not supported by this socket type.
|
||||||
|
*EINVAL*::
|
||||||
|
The sender tried to send multipart data, which the socket type does not allow.
|
||||||
*EFSM*::
|
*EFSM*::
|
||||||
The _zmq_msg_send()_ operation cannot be performed on this socket at the moment
|
The _zmq_msg_send()_ operation cannot be performed on this socket at the moment
|
||||||
due to the socket not being in the appropriate state. This error may occur with
|
due to the socket not being in the appropriate state. This error may occur with
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ ERRORS
|
|||||||
Non-blocking mode was requested and the message cannot be sent at the moment.
|
Non-blocking mode was requested and the message cannot be sent at the moment.
|
||||||
*ENOTSUP*::
|
*ENOTSUP*::
|
||||||
The _zmq_send()_ operation is not supported by this socket type.
|
The _zmq_send()_ operation is not supported by this socket type.
|
||||||
|
*EINVAL*::
|
||||||
|
The sender tried to send multipart data, which the socket type does not allow.
|
||||||
*EFSM*::
|
*EFSM*::
|
||||||
The _zmq_send()_ operation cannot be performed on this socket at the moment
|
The _zmq_send()_ operation cannot be performed on this socket at the moment
|
||||||
due to the socket not being in the appropriate state. This error may occur with
|
due to the socket not being in the appropriate state. This error may occur with
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ ERRORS
|
|||||||
Non-blocking mode was requested and the message cannot be sent at the moment.
|
Non-blocking mode was requested and the message cannot be sent at the moment.
|
||||||
*ENOTSUP*::
|
*ENOTSUP*::
|
||||||
The _zmq_sendmsg()_ operation is not supported by this socket type.
|
The _zmq_sendmsg()_ operation is not supported by this socket type.
|
||||||
|
*EINVAL*::
|
||||||
|
The sender tried to send multipart data, which the socket type does not allow.
|
||||||
*EFSM*::
|
*EFSM*::
|
||||||
The _zmq_sendmsg()_ operation cannot be performed on this socket at the moment
|
The _zmq_sendmsg()_ operation cannot be performed on this socket at the moment
|
||||||
due to the socket not being in the appropriate state. This error may occur with
|
due to the socket not being in the appropriate state. This error may occur with
|
||||||
|
|||||||
@@ -54,6 +54,11 @@ void zmq::client_t::xattach_pipe (pipe_t *pipe_, bool subscribe_to_all_)
|
|||||||
|
|
||||||
int zmq::client_t::xsend (msg_t *msg_)
|
int zmq::client_t::xsend (msg_t *msg_)
|
||||||
{
|
{
|
||||||
|
// CLIENT sockets do not allow multipart data (ZMQ_SNDMORE)
|
||||||
|
if (msg_->flags () & msg_t::more) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return lb.sendpipe (msg_, NULL);
|
return lb.sendpipe (msg_, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,11 @@ void zmq::server_t::xwrite_activated (pipe_t *pipe_)
|
|||||||
|
|
||||||
int zmq::server_t::xsend (msg_t *msg_)
|
int zmq::server_t::xsend (msg_t *msg_)
|
||||||
{
|
{
|
||||||
|
// SERVER sockets do not allow multipart data (ZMQ_SNDMORE)
|
||||||
|
if (msg_->flags () & msg_t::more) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
// Find the pipe associated with the routing stored in the message.
|
// Find the pipe associated with the routing stored in the message.
|
||||||
uint32_t routing_id = msg_->get_routing_id ();
|
uint32_t routing_id = msg_->get_routing_id ();
|
||||||
outpipes_t::iterator it = outpipes.find (routing_id);
|
outpipes_t::iterator it = outpipes.find (routing_id);
|
||||||
@@ -108,7 +113,6 @@ int zmq::server_t::xsend (msg_t *msg_)
|
|||||||
errno = EHOSTUNREACH;
|
errno = EHOSTUNREACH;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ok = it->second.pipe->write (msg_);
|
bool ok = it->second.pipe->write (msg_);
|
||||||
if (unlikely (!ok)) {
|
if (unlikely (!ok)) {
|
||||||
// Message failed to send - we must close it ourselves.
|
// Message failed to send - we must close it ourselves.
|
||||||
@@ -118,7 +122,6 @@ int zmq::server_t::xsend (msg_t *msg_)
|
|||||||
else
|
else
|
||||||
it->second.pipe->flush ();
|
it->second.pipe->flush ();
|
||||||
|
|
||||||
|
|
||||||
// Detach the message from the data buffer.
|
// Detach the message from the data buffer.
|
||||||
int rc = msg_->init ();
|
int rc = msg_->init ();
|
||||||
errno_assert (rc == 0);
|
errno_assert (rc == 0);
|
||||||
|
|||||||
@@ -96,7 +96,7 @@
|
|||||||
if (thread_safe) \
|
if (thread_safe) \
|
||||||
sync.lock();
|
sync.lock();
|
||||||
|
|
||||||
#define EXIT_MUTEX() \
|
#define EXIT_MUTEX(); \
|
||||||
if (thread_safe) \
|
if (thread_safe) \
|
||||||
sync.unlock();
|
sync.unlock();
|
||||||
|
|
||||||
@@ -1047,7 +1047,7 @@ int zmq::socket_base_t::send (msg_t *msg_, int flags_)
|
|||||||
|
|
||||||
msg_->reset_metadata ();
|
msg_->reset_metadata ();
|
||||||
|
|
||||||
// Try to send the message.
|
// Try to send the message using method in each socket class
|
||||||
rc = xsend (msg_);
|
rc = xsend (msg_);
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
EXIT_MUTEX ();
|
EXIT_MUTEX ();
|
||||||
@@ -1426,7 +1426,6 @@ void zmq::socket_base_t::in_event ()
|
|||||||
// of the reaper thread. Process any commands from other threads/sockets
|
// of the reaper thread. Process any commands from other threads/sockets
|
||||||
// that may be available at the moment. Ultimately, the socket will
|
// that may be available at the moment. Ultimately, the socket will
|
||||||
// be destroyed.
|
// be destroyed.
|
||||||
|
|
||||||
ENTER_MUTEX ();
|
ENTER_MUTEX ();
|
||||||
|
|
||||||
// If the socket is thread safe we need to unsignal the reaper signaler
|
// If the socket is thread safe we need to unsignal the reaper signaler
|
||||||
|
|||||||
@@ -51,11 +51,15 @@ int main (void)
|
|||||||
char *data = (char *) zmq_msg_data (&msg);
|
char *data = (char *) zmq_msg_data (&msg);
|
||||||
data [0] = 1;
|
data [0] = 1;
|
||||||
|
|
||||||
|
rc = zmq_msg_send (&msg, client, ZMQ_SNDMORE);
|
||||||
|
assert (rc == -1);
|
||||||
|
|
||||||
rc = zmq_msg_send (&msg, client, 0);
|
rc = zmq_msg_send (&msg, client, 0);
|
||||||
assert (rc == 1);
|
assert (rc == 1);
|
||||||
|
|
||||||
rc = zmq_msg_init (&msg);
|
rc = zmq_msg_init (&msg);
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
|
|
||||||
rc = zmq_msg_recv (&msg, server, 0);
|
rc = zmq_msg_recv (&msg, server, 0);
|
||||||
assert (rc == 1);
|
assert (rc == 1);
|
||||||
|
|
||||||
@@ -74,6 +78,9 @@ int main (void)
|
|||||||
rc = zmq_msg_set_routing_id (&msg, routing_id);
|
rc = zmq_msg_set_routing_id (&msg, routing_id);
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
|
|
||||||
|
rc = zmq_msg_send (&msg, server, ZMQ_SNDMORE);
|
||||||
|
assert (rc == -1);
|
||||||
|
|
||||||
rc = zmq_msg_send (&msg, server, 0);
|
rc = zmq_msg_send (&msg, server, 0);
|
||||||
assert (rc == 1);
|
assert (rc == 1);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user