Problem: ZMTP 3.1 PING Context not implemented

Solution: if a PING message contains a context, echo it back in the
PONG message. In order to do so, create the PONG message when PING
is received and store it in the engine.
After the PING the engine goes straight to encoding and sending, so
there can always be at most one pending PING.
Add tests for various contexts.
This commit is contained in:
Luca Boccassi
2018-04-28 18:11:37 +01:00
committed by Simon Giesecke
parent 5482b1ca45
commit b331caad06
3 changed files with 81 additions and 28 deletions

View File

@@ -98,6 +98,8 @@ zmq::stream_engine_t::stream_engine_t (fd_t fd_,
{
int rc = tx_msg.init ();
errno_assert (rc == 0);
rc = pong_msg.init ();
errno_assert (rc == 0);
// Put the socket into non-blocking mode.
unblock_socket (s);
@@ -1059,11 +1061,8 @@ int zmq::stream_engine_t::produce_pong_message (msg_t *msg_)
int rc = 0;
zmq_assert (mechanism != NULL);
rc = msg_->init_size (5);
rc = msg_->move (pong_msg);
errno_assert (rc == 0);
msg_->set_flags (msg_t::command);
memcpy (msg_->data (), "\4PONG", 5);
rc = mechanism->encode (msg_);
next_msg = &stream_engine_t::pull_and_encode;
@@ -1086,6 +1085,20 @@ int zmq::stream_engine_t::process_heartbeat_message (msg_t *msg_)
has_ttl_timer = true;
}
// As per ZMTP 3.1 the PING command might contain an up to 16 bytes
// context which needs to be PONGed back, so build the pong message
// here and store it. Truncate it if it's too long.
// Given the engine goes straight to out_event, sequential PINGs will
// not be a problem.
size_t context_len = msg_->size () - 7 > 16 ? 16 : msg_->size () - 7;
int rc = pong_msg.init_size (5 + context_len);
errno_assert (rc == 0);
pong_msg.set_flags (msg_t::command);
memcpy (pong_msg.data (), "\4PONG", 5);
if (context_len > 0)
memcpy (((uint8_t *) pong_msg.data ()) + 5,
((uint8_t *) msg_->data ()) + 7, context_len);
next_msg = &stream_engine_t::produce_pong_message;
out_event ();
}