static bool with_transaction_fail_transient_txn (mongoc_client_session_t *session, void *ctx, bson_t **reply, bson_error_t *error) { bson_t labels; _mongoc_usleep (session->with_txn_timeout_ms * 1000); *reply = bson_new (); BSON_APPEND_ARRAY_BEGIN (*reply, "errorLabels", &labels); BSON_APPEND_UTF8 (&labels, "0", TRANSIENT_TXN_ERR); return false; }
static bool auto_ismaster (request_t *request, void *data) { const char *response_json = (const char *) data; char *quotes_replaced; bson_t response; bson_error_t error; if (!request->is_command || strcasecmp (request->command_name, "ismaster")) { return false; } quotes_replaced = single_quotes_to_double (response_json); if (!bson_init_from_json (&response, quotes_replaced, -1, &error)) { fprintf (stderr, "%s\n", error.message); fflush (stderr); abort (); } if (mock_server_get_rand_delay (request->server)) { _mongoc_usleep ((int64_t) (rand () % 10) * 1000); } if (mock_server_get_verbose (request->server)) { printf ("%5.2f %hu <- %hu \t%s\n", mock_server_get_uptime_sec (request->server), request->client_port, mock_server_get_port (request->server), quotes_replaced); fflush (stdout); } mock_server_reply_simple (request->server, request->client, &request->request_rpc, MONGOC_REPLY_NONE, &response, 0); bson_destroy (&response); bson_free (quotes_replaced); request_destroy (request); return true; }
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); }
/** run as a child thread by test_mongoc_tls_hangup * * It: * 1. spins up * 2. binds and listens to a random port * 3. notifies the client of its port through a condvar * 4. accepts a request * 5. reads a byte * 7. hangs up */ static void * ssl_error_server (void *ptr) { ssl_test_data_t *data = (ssl_test_data_t *)ptr; mongoc_stream_t *sock_stream; mongoc_stream_t *ssl_stream; mongoc_socket_t *listen_sock; mongoc_socket_t *conn_sock; socklen_t sock_len; char buf; ssize_t r; mongoc_iovec_t iov; struct sockaddr_in server_addr = { 0 }; iov.iov_base = &buf; iov.iov_len = 1; listen_sock = mongoc_socket_new (AF_INET, SOCK_STREAM, 0); assert (listen_sock); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); server_addr.sin_port = htons (0); r = mongoc_socket_bind (listen_sock, (struct sockaddr *)&server_addr, sizeof server_addr); assert (r == 0); sock_len = sizeof (server_addr); r = mongoc_socket_getsockname (listen_sock, (struct sockaddr *)&server_addr, &sock_len); assert (r == 0); r = mongoc_socket_listen (listen_sock, 10); assert (r == 0); mongoc_mutex_lock (&data->cond_mutex); data->server_port = ntohs (server_addr.sin_port); mongoc_cond_signal (&data->cond); mongoc_mutex_unlock (&data->cond_mutex); conn_sock = mongoc_socket_accept (listen_sock, -1); assert (conn_sock); sock_stream = mongoc_stream_socket_new (conn_sock); assert (sock_stream); ssl_stream = mongoc_stream_tls_new (sock_stream, data->server, 0); assert (ssl_stream); switch (data->behavior) { case SSL_TEST_BEHAVIOR_STALL_BEFORE_HANDSHAKE: _mongoc_usleep (data->handshake_stall_ms * 1000); break; case SSL_TEST_BEHAVIOR_HANGUP_AFTER_HANDSHAKE: r = mongoc_stream_tls_do_handshake (ssl_stream, TIMEOUT); assert (r); r = mongoc_stream_readv (ssl_stream, &iov, 1, 1, TIMEOUT); assert (r == 1); break; case SSL_TEST_BEHAVIOR_NORMAL: default: fprintf (stderr, "unimplemented ssl_test_behavior_t\n"); abort (); } data->server_result->result = SSL_TEST_SUCCESS; mongoc_stream_close (ssl_stream); mongoc_stream_destroy (ssl_stream); mongoc_socket_destroy (listen_sock); return NULL; }