Commit 2566c02a authored by Pieter Hintjens's avatar Pieter Hintjens

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.
parent ae3b2734
......@@ -67,6 +67,8 @@ ERRORS
Non-blocking mode was requested and the message cannot be sent at the moment.
*ENOTSUP*::
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*::
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
......
......@@ -58,6 +58,8 @@ ERRORS
Non-blocking mode was requested and the message cannot be sent at the moment.
*ENOTSUP*::
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*::
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
......
......@@ -63,6 +63,8 @@ ERRORS
Non-blocking mode was requested and the message cannot be sent at the moment.
*ENOTSUP*::
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*::
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
......
......@@ -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_)
{
// CLIENT sockets do not allow multipart data (ZMQ_SNDMORE)
if (msg_->flags () & msg_t::more) {
errno = EINVAL;
return -1;
}
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_)
{
// 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.
uint32_t routing_id = msg_->get_routing_id ();
outpipes_t::iterator it = outpipes.find (routing_id);
......@@ -108,7 +113,6 @@ int zmq::server_t::xsend (msg_t *msg_)
errno = EHOSTUNREACH;
return -1;
}
bool ok = it->second.pipe->write (msg_);
if (unlikely (!ok)) {
// Message failed to send - we must close it ourselves.
......@@ -118,7 +122,6 @@ int zmq::server_t::xsend (msg_t *msg_)
else
it->second.pipe->flush ();
// Detach the message from the data buffer.
int rc = msg_->init ();
errno_assert (rc == 0);
......
This diff is collapsed.
......@@ -347,7 +347,7 @@ static int
s_sendmsg (zmq::socket_base_t *s_, zmq_msg_t *msg_, int flags_)
{
int sz = (int) zmq_msg_size (msg_);
int rc = s_->send ((zmq::msg_t*) msg_, flags_);
int rc = s_->send ((zmq::msg_t *) msg_, flags_);
if (unlikely (rc < 0))
return -1;
return sz;
......@@ -393,7 +393,7 @@ int zmq_send_const (void *s_, const void *buf_, size_t len_, int flags_)
return -1;
}
zmq_msg_t msg;
int rc = zmq_msg_init_data (&msg, (void*)buf_, len_, NULL, NULL);
int rc = zmq_msg_init_data (&msg, (void *)buf_, len_, NULL, NULL);
if (rc != 0)
return -1;
......
......@@ -31,7 +31,7 @@
int main (void)
{
setup_test_environment();
setup_test_environment ();
void *ctx = zmq_ctx_new ();
assert (ctx);
......@@ -51,36 +51,43 @@ int main (void)
char *data = (char *) zmq_msg_data (&msg);
data [0] = 1;
rc = zmq_msg_send(&msg, client, 0);
rc = zmq_msg_send (&msg, client, ZMQ_SNDMORE);
assert (rc == -1);
rc = zmq_msg_send (&msg, client, 0);
assert (rc == 1);
rc = zmq_msg_init (&msg);
assert (rc == 0);
rc = zmq_msg_recv (&msg, server, 0);
assert (rc == 1);
assert (rc == 1);
uint32_t routing_id = zmq_msg_routing_id (&msg);
assert (routing_id != 0);
rc = zmq_msg_close(&msg);
rc = zmq_msg_close (&msg);
assert (rc == 0);
rc = zmq_msg_init_size (&msg, 1);
assert (rc == 0);
assert (rc == 0);
data = (char *)zmq_msg_data(&msg);
data = (char *)zmq_msg_data (&msg);
data[0] = 2;
rc = zmq_msg_set_routing_id(&msg, routing_id);
assert (rc == 0);
rc = zmq_msg_set_routing_id (&msg, routing_id);
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);
rc = zmq_msg_recv(&msg, client, 0);
rc = zmq_msg_recv (&msg, client, 0);
assert (rc == 1);
rc = zmq_msg_close(&msg);
rc = zmq_msg_close (&msg);
assert (rc == 0);
rc = zmq_close (server);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment