0
0
mirror of https://github.com/zeromq/libzmq.git synced 2024-12-27 07:31:03 +08:00

Problem: backward incompatible change to NULL with ZAP

Solution: like for other mechanism, do not enforce strict ZAP protocol
adherence unless the specific socket option is enabled with NULL auth.

Add test to exercise this functionality, and fix ZAP test to set the
socket option when it uses NULL auth.

See: https://github.com/zeromq/pyzmq/pull/1152
This commit is contained in:
Luca Boccassi 2018-03-22 19:27:23 +00:00
parent e4b3bd8631
commit 1c5a63e939
3 changed files with 67 additions and 19 deletions

View File

@ -69,24 +69,27 @@ int zmq::null_mechanism_t::next_handshake_command (msg_t *msg_)
errno = EAGAIN; errno = EAGAIN;
return -1; return -1;
} }
// Given this is a backward-incompatible change, it's behind a socket
// option disabled by default.
int rc = session->zap_connect (); int rc = session->zap_connect ();
if (rc == -1) { if (rc == -1 && options.zap_enforce_domain) {
session->get_socket ()->event_handshake_failed_no_detail ( session->get_socket ()->event_handshake_failed_no_detail (
session->get_endpoint (), EFAULT); session->get_endpoint (), EFAULT);
return -1; return -1;
} else if (rc == 0) {
send_zap_request ();
zap_request_sent = true;
// TODO actually, it is quite unlikely that we can read the ZAP
// reply already, but removing this has some strange side-effect
// (probably because the pipe's in_active flag is true until a read
// is attempted)
rc = receive_and_process_zap_reply ();
if (rc != 0)
return -1;
zap_reply_received = true;
} }
send_zap_request ();
zap_request_sent = true;
// TODO actually, it is quite unlikely that we can read the ZAP
// reply already, but removing this has some strange side-effect
// (probably because the pipe's in_active flag is true until a read
// is attempted)
rc = receive_and_process_zap_reply ();
if (rc != 0)
return -1;
zap_reply_received = true;
} }
if (zap_reply_received && status_code != "200") { if (zap_reply_received && status_code != "200") {

View File

@ -88,12 +88,55 @@ int main (void)
void *ctx = zmq_ctx_new (); void *ctx = zmq_ctx_new ();
assert (ctx); assert (ctx);
// We first test client/server with a ZAP domain but with no handler
// If there is no handler, libzmq should ignore the ZAP option unless
// ZMQ_ZAP_ENFORCE_DOMAIN is set
void *server = zmq_socket (ctx, ZMQ_DEALER);
assert (server);
void *client = zmq_socket (ctx, ZMQ_DEALER);
assert (client);
int rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "TEST", 5);
assert (rc == 0);
rc = zmq_bind (server, "tcp://127.0.0.1:*");
assert (rc == 0);
rc = zmq_getsockopt (server, ZMQ_LAST_ENDPOINT, my_endpoint, &len);
assert (rc == 0);
rc = zmq_connect (client, my_endpoint);
assert (rc == 0);
bounce (server, client);
close_zero_linger (client);
close_zero_linger (server);
#ifdef ZMQ_ZAP_ENFORCE_DOMAIN
// Now set ZMQ_ZAP_ENFORCE_DOMAIN which strictly enforces the ZAP
// RFC but is backward-incompatible, now it should fail
server = zmq_socket (ctx, ZMQ_DEALER);
assert (server);
client = zmq_socket (ctx, ZMQ_DEALER);
assert (client);
int required = 1;
rc =
zmq_setsockopt (server, ZMQ_ZAP_ENFORCE_DOMAIN, &required, sizeof (int));
assert (rc == 0);
rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "TEST", 5);
assert (rc == 0);
rc = zmq_bind (server, "tcp://127.0.0.1:*");
assert (rc == 0);
rc = zmq_getsockopt (server, ZMQ_LAST_ENDPOINT, my_endpoint, &len);
assert (rc == 0);
rc = zmq_connect (client, my_endpoint);
assert (rc == 0);
expect_bounce_fail (server, client);
close_zero_linger (client);
close_zero_linger (server);
#endif
// Spawn ZAP handler // Spawn ZAP handler
// We create and bind ZAP socket in main thread to avoid case // We create and bind ZAP socket in main thread to avoid case
// where child thread does not start up fast enough. // where child thread does not start up fast enough.
void *handler = zmq_socket (ctx, ZMQ_REP); void *handler = zmq_socket (ctx, ZMQ_REP);
assert (handler); assert (handler);
int rc = zmq_bind (handler, "inproc://zeromq.zap.01"); rc = zmq_bind (handler, "inproc://zeromq.zap.01");
assert (rc == 0); assert (rc == 0);
void *zap_thread = zmq_threadstart (&zap_handler, handler); void *zap_thread = zmq_threadstart (&zap_handler, handler);
@ -101,9 +144,9 @@ int main (void)
// We first test client/server with no ZAP domain // We first test client/server with no ZAP domain
// Libzmq does not call our ZAP handler, the connect must succeed // Libzmq does not call our ZAP handler, the connect must succeed
void *server = zmq_socket (ctx, ZMQ_DEALER); server = zmq_socket (ctx, ZMQ_DEALER);
assert (server); assert (server);
void *client = zmq_socket (ctx, ZMQ_DEALER); client = zmq_socket (ctx, ZMQ_DEALER);
assert (client); assert (client);
rc = zmq_bind (server, "tcp://127.0.0.1:*"); rc = zmq_bind (server, "tcp://127.0.0.1:*");
assert (rc == 0); assert (rc == 0);

View File

@ -326,10 +326,12 @@ void test_zap_errors (socket_config_fn server_socket_config_,
#ifdef ZMQ_ZAP_ENFORCE_DOMAIN #ifdef ZMQ_ZAP_ENFORCE_DOMAIN
// no ZAP handler // no ZAP handler
int enforce = 1;
fprintf (stderr, "test_zap_unsuccessful no ZAP handler started\n"); fprintf (stderr, "test_zap_unsuccessful no ZAP handler started\n");
setup_context_and_server_side (&ctx, &handler, &zap_thread, &server, setup_context_and_server_side (
&server_mon, my_endpoint, NULL, &ctx, &handler, &zap_thread, &server, &server_mon, my_endpoint, NULL,
server_socket_config_); server_socket_config_,
server_socket_config_data_ ? server_socket_config_data_ : &enforce);
test_zap_unsuccessful_no_handler ( test_zap_unsuccessful_no_handler (
ctx, my_endpoint, server, server_mon, ctx, my_endpoint, server, server_mon,
#ifdef ZMQ_BUILD_DRAFT_API #ifdef ZMQ_BUILD_DRAFT_API