mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-27 07:31:03 +08:00
Merge pull request #2659 from bluca/fix_getrandom
Problems: test_security_curve occasionally hangs or fails due to ECONNABORTED
This commit is contained in:
commit
612d81a831
@ -148,13 +148,42 @@ enum zap_protocol_t
|
||||
zap_too_many_parts
|
||||
};
|
||||
|
||||
static void zap_handler_generic (void *handler, zap_protocol_t zap_protocol)
|
||||
static void zap_handler_generic (void *ctx, zap_protocol_t zap_protocol)
|
||||
{
|
||||
void *control = zmq_socket (ctx, ZMQ_REQ);
|
||||
assert (control);
|
||||
int rc = zmq_connect (control, "inproc://handler-control");
|
||||
assert (rc == 0);
|
||||
|
||||
void *handler = zmq_socket (ctx, ZMQ_REP);
|
||||
assert (handler);
|
||||
rc = zmq_bind (handler, "inproc://zeromq.zap.01");
|
||||
assert (rc == 0);
|
||||
|
||||
// Signal main thread that we are ready
|
||||
rc = s_send (control, "GO");
|
||||
assert (rc == 2);
|
||||
|
||||
zmq_pollitem_t items [] = {
|
||||
{ control, 0, ZMQ_POLLIN, 0 },
|
||||
{ handler, 0, ZMQ_POLLIN, 0 },
|
||||
};
|
||||
|
||||
// Process ZAP requests forever
|
||||
while (true) {
|
||||
while (zmq_poll (items, 2, -1) >= 0) {
|
||||
if (items [0].revents & ZMQ_POLLIN) {
|
||||
char *buf = s_recv (control);
|
||||
assert (buf);
|
||||
assert (streq (buf, "STOP"));
|
||||
free (buf);
|
||||
break; // Terminating - main thread signal
|
||||
}
|
||||
if (!(items [1].revents & ZMQ_POLLIN))
|
||||
continue;
|
||||
|
||||
char *version = s_recv (handler);
|
||||
if (!version)
|
||||
break; // Terminating
|
||||
break; // Terminating - peer's socket closed
|
||||
|
||||
char *sequence = s_recv (handler);
|
||||
char *domain = s_recv (handler);
|
||||
@ -206,37 +235,43 @@ static void zap_handler_generic (void *handler, zap_protocol_t zap_protocol)
|
||||
|
||||
zmq_atomic_counter_inc (zap_requests_handled);
|
||||
}
|
||||
zmq_close (handler);
|
||||
rc = zmq_unbind (handler, "inproc://zeromq.zap.01");
|
||||
assert (rc == 0);
|
||||
close_zero_linger (handler);
|
||||
|
||||
rc = s_send (control, "STOPPED");
|
||||
assert (rc == 7);
|
||||
close_zero_linger (control);
|
||||
}
|
||||
|
||||
static void zap_handler (void *handler)
|
||||
static void zap_handler (void *ctx)
|
||||
{
|
||||
zap_handler_generic (handler, zap_ok);
|
||||
zap_handler_generic (ctx, zap_ok);
|
||||
}
|
||||
|
||||
static void zap_handler_wrong_version (void *handler)
|
||||
static void zap_handler_wrong_version (void *ctx)
|
||||
{
|
||||
zap_handler_generic (handler, zap_wrong_version);
|
||||
zap_handler_generic (ctx, zap_wrong_version);
|
||||
}
|
||||
|
||||
static void zap_handler_wrong_request_id (void *handler)
|
||||
static void zap_handler_wrong_request_id (void *ctx)
|
||||
{
|
||||
zap_handler_generic (handler, zap_wrong_request_id);
|
||||
zap_handler_generic (ctx, zap_wrong_request_id);
|
||||
}
|
||||
|
||||
static void zap_handler_wrong_status_invalid (void *handler)
|
||||
static void zap_handler_wrong_status_invalid (void *ctx)
|
||||
{
|
||||
zap_handler_generic (handler, zap_status_invalid);
|
||||
zap_handler_generic (ctx, zap_status_invalid);
|
||||
}
|
||||
|
||||
static void zap_handler_wrong_status_internal_error (void *handler)
|
||||
static void zap_handler_wrong_status_internal_error (void *ctx)
|
||||
{
|
||||
zap_handler_generic (handler, zap_status_internal_error);
|
||||
zap_handler_generic (ctx, zap_status_internal_error);
|
||||
}
|
||||
|
||||
static void zap_handler_too_many_parts (void *handler)
|
||||
static void zap_handler_too_many_parts (void *ctx)
|
||||
{
|
||||
zap_handler_generic (handler, zap_too_many_parts);
|
||||
zap_handler_generic (ctx, zap_too_many_parts);
|
||||
}
|
||||
|
||||
void *create_and_connect_curve_client (void *ctx,
|
||||
@ -276,8 +311,8 @@ void expect_new_client_curve_bounce_fail (void *ctx,
|
||||
// expects that one or more occurrences of the expected event are received
|
||||
// via the specified socket monitor
|
||||
// returns the number of occurrences of the expected event
|
||||
// interrupts, if a ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL/EPIPE/ECONNRESET
|
||||
// occurs; in this case, 0 is returned
|
||||
// interrupts, if a ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL with EPIPE, ECONNRESET
|
||||
// or ECONNABORTED occurs; in this case, 0 is returned
|
||||
// this should be investigated further, see
|
||||
// https://github.com/zeromq/libzmq/issues/2644
|
||||
int expect_monitor_event_multiple (void *server_mon,
|
||||
@ -295,11 +330,12 @@ int expect_monitor_event_multiple (void *server_mon,
|
||||
!= -1) {
|
||||
timeout = 250;
|
||||
|
||||
// ignore errors with EPIPE/ECONNRESET, which happen sporadically
|
||||
// ignore errors with EPIPE/ECONNRESET/ECONNABORTED, which can happen
|
||||
// ECONNRESET can happen on very slow machines, when the engine writes
|
||||
// to the peer and then tries to read the socket before the peer reads
|
||||
// ECONNABORTED happens when a client aborts a connection via RST/timeout
|
||||
if (event == ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL &&
|
||||
(err == EPIPE || err == ECONNRESET)) {
|
||||
(err == EPIPE || err == ECONNRESET || err == ECONNABORTED)) {
|
||||
fprintf (stderr, "Ignored event: %x (err = %i)\n", event, err);
|
||||
client_closed_connection = 1;
|
||||
break;
|
||||
@ -360,13 +396,17 @@ void setup_context_and_server_side (void **ctx,
|
||||
zap_requests_handled = zmq_atomic_counter_new ();
|
||||
assert (zap_requests_handled != NULL);
|
||||
|
||||
// We create and bind ZAP socket in main thread to avoid case
|
||||
// where child thread does not start up fast enough.
|
||||
*handler = zmq_socket (*ctx, ZMQ_REP);
|
||||
assert (*handler);
|
||||
int rc = zmq_bind (*handler, "inproc://zeromq.zap.01");
|
||||
int rc = zmq_bind (*handler, "inproc://handler-control");
|
||||
assert (rc == 0);
|
||||
*zap_thread = zmq_threadstart (zap_handler_, *handler);
|
||||
|
||||
*zap_thread = zmq_threadstart (zap_handler_, *ctx);
|
||||
|
||||
char *buf = s_recv (*handler);
|
||||
assert (buf);
|
||||
assert (streq (buf, "GO"));
|
||||
free (buf);
|
||||
|
||||
// Server socket will accept connections
|
||||
*server = zmq_socket (*ctx, ZMQ_DEALER);
|
||||
@ -413,19 +453,30 @@ void setup_context_and_server_side (void **ctx,
|
||||
void shutdown_context_and_server_side (void *ctx,
|
||||
void *zap_thread,
|
||||
void *server,
|
||||
void *server_mon)
|
||||
void *server_mon,
|
||||
void *handler)
|
||||
{
|
||||
int rc = s_send (handler, "STOP");
|
||||
assert (rc == 4);
|
||||
char *buf = s_recv (handler);
|
||||
assert (buf);
|
||||
assert (streq (buf, "STOPPED"));
|
||||
free (buf);
|
||||
rc = zmq_unbind (handler, "inproc://handler-control");
|
||||
assert (rc == 0);
|
||||
close_zero_linger (handler);
|
||||
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
close_zero_linger (server_mon);
|
||||
#endif
|
||||
close_zero_linger (server);
|
||||
|
||||
int rc = zmq_ctx_term (ctx);
|
||||
assert (rc == 0);
|
||||
|
||||
// Wait until ZAP handler terminates
|
||||
zmq_threadclose (zap_thread);
|
||||
|
||||
rc = zmq_ctx_term (ctx);
|
||||
assert (rc == 0);
|
||||
|
||||
zmq_atomic_counter_destroy (&zap_requests_handled);
|
||||
}
|
||||
|
||||
@ -635,7 +686,8 @@ int main (void)
|
||||
&server_mon, my_endpoint);
|
||||
test_curve_security_with_valid_credentials (ctx, my_endpoint, server,
|
||||
server_mon, timeout);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
char garbage_key [] = "0000000000000000000000000000000000000000";
|
||||
|
||||
@ -646,7 +698,8 @@ int main (void)
|
||||
&server_mon, my_endpoint);
|
||||
test_garbage_key (ctx, server, server_mon, my_endpoint, garbage_key,
|
||||
valid_client_public, valid_client_secret);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
// Check CURVE security with a garbage client public key
|
||||
// This will be caught by the curve_server class, not passed to ZAP
|
||||
@ -655,7 +708,8 @@ int main (void)
|
||||
&server_mon, my_endpoint);
|
||||
test_garbage_key (ctx, server, server_mon, my_endpoint, valid_server_public,
|
||||
garbage_key, valid_client_secret);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
// Check CURVE security with a garbage client secret key
|
||||
// This will be caught by the curve_server class, not passed to ZAP
|
||||
@ -664,30 +718,35 @@ int main (void)
|
||||
&server_mon, my_endpoint);
|
||||
test_garbage_key (ctx, server, server_mon, my_endpoint, valid_server_public,
|
||||
valid_client_public, garbage_key);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
|
||||
&server_mon, my_endpoint);
|
||||
test_curve_security_with_bogus_client_credentials (ctx, my_endpoint, server,
|
||||
server_mon, timeout);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
|
||||
&server_mon, my_endpoint);
|
||||
test_curve_security_with_null_client_credentials (ctx, my_endpoint, server,
|
||||
server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
|
||||
&server_mon, my_endpoint);
|
||||
test_curve_security_with_plain_client_credentials (ctx, my_endpoint, server,
|
||||
server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
|
||||
&server_mon, my_endpoint);
|
||||
test_curve_security_unauthenticated_message (my_endpoint, server, timeout);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
// Invalid ZAP protocol tests
|
||||
|
||||
@ -697,7 +756,8 @@ int main (void)
|
||||
&zap_handler_wrong_version);
|
||||
test_curve_security_zap_protocol_error (ctx, my_endpoint, server,
|
||||
server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
// wrong request id
|
||||
setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
|
||||
@ -705,7 +765,8 @@ int main (void)
|
||||
&zap_handler_wrong_request_id);
|
||||
test_curve_security_zap_protocol_error (ctx, my_endpoint, server,
|
||||
server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
// status invalid (not a 3-digit number)
|
||||
setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
|
||||
@ -713,7 +774,8 @@ int main (void)
|
||||
&zap_handler_wrong_status_invalid);
|
||||
test_curve_security_zap_protocol_error (ctx, my_endpoint, server,
|
||||
server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
// too many parts
|
||||
setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
|
||||
@ -721,7 +783,8 @@ int main (void)
|
||||
&zap_handler_too_many_parts);
|
||||
test_curve_security_zap_protocol_error (ctx, my_endpoint, server,
|
||||
server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
// ZAP non-standard cases
|
||||
|
||||
@ -740,7 +803,8 @@ int main (void)
|
||||
0, 0
|
||||
#endif
|
||||
);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
ctx = zmq_ctx_new ();
|
||||
test_curve_security_invalid_keysize (ctx);
|
||||
|
Loading…
x
Reference in New Issue
Block a user