/** This is the testing function for the ssl-test lib * * The basic idea is that you spin up a client and server, which will * communicate over a mongoc-stream-tls, with varying mongoc_ssl_opt's. The * client and server speak a simple echo protocol, so all we're really testing * here is that any given configuration succeeds or fails as it should */ void ssl_test (mongoc_ssl_opt_t *client, mongoc_ssl_opt_t *server, const char *host, ssl_test_result_t *client_result, ssl_test_result_t *server_result) { ssl_test_data_t data = {0}; mongoc_thread_t threads[2]; int i, r; data.server = server; data.client = client; data.client_result = client_result; data.server_result = server_result; data.host = host; mongoc_mutex_init (&data.cond_mutex); mongoc_cond_init (&data.cond); r = mongoc_thread_create (threads, &ssl_test_server, &data); BSON_ASSERT (r == 0); r = mongoc_thread_create (threads + 1, &ssl_test_client, &data); BSON_ASSERT (r == 0); for (i = 0; i < 2; i++) { r = mongoc_thread_join (threads[i]); BSON_ASSERT (r == 0); } mongoc_mutex_destroy (&data.cond_mutex); mongoc_cond_destroy (&data.cond); }
static void test_mongoc_tls_handshake_stall (void) { mongoc_ssl_opt_t sopt = { 0 }; mongoc_ssl_opt_t copt = { 0 }; ssl_test_result_t sr; ssl_test_result_t cr; ssl_test_data_t data = { 0 }; mongoc_thread_t threads[2]; int i, r; sopt.pem_file = PEMFILE_NOPASS; sopt.weak_cert_validation = 1; copt.weak_cert_validation = 1; data.server = &sopt; data.client = &copt; data.behavior = SSL_TEST_BEHAVIOR_STALL_BEFORE_HANDSHAKE; data.handshake_stall_ms = 300; data.server_result = &sr; data.client_result = &cr; data.host = "localhost"; mongoc_mutex_init (&data.cond_mutex); mongoc_cond_init (&data.cond); r = mongoc_thread_create (threads, &ssl_error_server, &data); assert (r == 0); r = mongoc_thread_create (threads + 1, &handshake_stall_client, &data); assert (r == 0); for (i = 0; i < 2; i++) { r = mongoc_thread_join (threads[i]); assert (r == 0); } mongoc_mutex_destroy (&data.cond_mutex); mongoc_cond_destroy (&data.cond); ASSERT (cr.result == SSL_TEST_SUCCESS); ASSERT (sr.result == SSL_TEST_SUCCESS); }
static void test_mongoc_socket_sendv (void) { socket_test_data_t data = { 0 }; mongoc_thread_t threads[2]; int i, r; mongoc_mutex_init (&data.cond_mutex); mongoc_cond_init (&data.cond); r = mongoc_thread_create (threads, &sendv_test_server, &data); assert (r == 0); r = mongoc_thread_create (threads + 1, &sendv_test_client, &data); assert (r == 0); for (i = 0; i < 2; i++) { r = mongoc_thread_join (threads[i]); assert (r == 0); } mongoc_mutex_destroy (&data.cond_mutex); mongoc_cond_destroy (&data.cond); }
bool future_wait (future_t *future) { int64_t deadline = bson_get_monotonic_time () + get_future_timeout_ms (); bool resolved; mongoc_mutex_lock (&future->mutex); while (!future->resolved && bson_get_monotonic_time () <= deadline) { mongoc_cond_timedwait (&future->cond, &future->mutex, get_future_timeout_ms ()); } resolved = future->resolved; mongoc_mutex_unlock (&future->mutex); if (resolved) { future->awaited = true; /* free memory */ mongoc_thread_join (future->thread); } return resolved; }
static void * main_thread (void *data) { mock_server_t *server = (mock_server_t *)data; mongoc_socket_t *client_sock; bool stopped; uint16_t port; mongoc_stream_t *client_stream; worker_closure_t *closure; mongoc_thread_t thread; mongoc_array_t worker_threads; size_t i; mongoc_mutex_lock (&server->mutex); server->running = true; mongoc_cond_signal (&server->cond); mongoc_mutex_unlock (&server->mutex); for (; ;) { client_sock = mongoc_socket_accept_ex ( server->sock, bson_get_monotonic_time () + TIMEOUT, &port); mongoc_mutex_lock (&server->mutex); stopped = server->stopped; mongoc_mutex_unlock (&server->mutex); if (stopped) { break; } if (client_sock) { if (mock_server_get_verbose (server)) { printf ("%5.2f %hu -> server port %hu (connected)\n", mock_server_get_uptime_sec (server), port, server->port); fflush (stdout); } client_stream = mongoc_stream_socket_new (client_sock); #ifdef MONGOC_ENABLE_SSL mongoc_mutex_lock (&server->mutex); if (server->ssl) { server->ssl_opts.weak_cert_validation = 1; client_stream = mongoc_stream_tls_new (client_stream, &server->ssl_opts, 0); if (!client_stream) { mongoc_mutex_unlock (&server->mutex); perror ("Failed to attach tls stream"); break; } } mongoc_mutex_unlock (&server->mutex); #endif closure = (worker_closure_t *)bson_malloc (sizeof *closure); closure->server = server; closure->client_stream = client_stream; closure->port = port; mongoc_thread_create (&thread, worker_thread, closure); mongoc_mutex_lock (&server->mutex); _mongoc_array_append_val (&server->worker_threads, thread); mongoc_mutex_unlock (&server->mutex); } } /* copy list of worker threads and join them all */ _mongoc_array_init (&worker_threads, sizeof (mongoc_thread_t)); mongoc_mutex_lock (&server->mutex); _mongoc_array_copy (&worker_threads, &server->worker_threads); mongoc_mutex_unlock (&server->mutex); for (i = 0; i < worker_threads.len; i++) { mongoc_thread_join ( _mongoc_array_index (&worker_threads, mongoc_thread_t, i)); } _mongoc_array_destroy (&worker_threads); mongoc_mutex_lock (&server->mutex); server->running = false; mongoc_mutex_unlock (&server->mutex); return NULL; }
void mock_server_destroy (mock_server_t *server) { size_t i; autoresponder_handle_t *handle; int64_t deadline = bson_get_monotonic_time () + 10 * 1000 * 1000; request_t *request; mongoc_mutex_lock (&server->mutex); if (server->running) { server->stopped = true; } mongoc_mutex_unlock (&server->mutex); while (bson_get_monotonic_time () <= deadline) { /* wait 10 seconds */ mongoc_mutex_lock (&server->mutex); if (!server->running) { mongoc_mutex_unlock (&server->mutex); break; } mongoc_mutex_unlock (&server->mutex); _mongoc_usleep (1000); } mongoc_mutex_lock (&server->mutex); if (server->running) { fprintf (stderr, "server still running after timeout\n"); fflush (stderr); abort (); } mongoc_mutex_unlock (&server->mutex); mongoc_thread_join (server->main_thread); _mongoc_array_destroy (&server->worker_threads); for (i = 0; i < server->autoresponders.len; i++) { handle = &_mongoc_array_index (&server->autoresponders, autoresponder_handle_t, i); autoresponder_handle_destroy (handle); } _mongoc_array_destroy (&server->autoresponders); mongoc_cond_destroy (&server->cond); mongoc_mutex_unlock (&server->mutex); mongoc_mutex_destroy (&server->mutex); mongoc_socket_destroy (server->sock); bson_free (server->uri_str); mongoc_uri_destroy (server->uri); while ((request = (request_t *) q_get_nowait (server->q))) { request_destroy (request); } q_destroy (server->q); bson_free (server); }