X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=tls%2Ftests%2Fdtls-connection.c;h=78b2ceeca99241e4871d3ed50729366afae8723f;hb=f032098bcb82432a475f0570b8b88ef40a7af777;hp=1304d967343fb42c8ceb4a5a3edebe30e5f13ede;hpb=e1744c81348ca0414526096f3537d5725942abb1;p=platform%2Fupstream%2Fglib-networking.git diff --git a/tls/tests/dtls-connection.c b/tls/tests/dtls-connection.c index 1304d96..78b2cee 100644 --- a/tls/tests/dtls-connection.c +++ b/tls/tests/dtls-connection.c @@ -27,10 +27,13 @@ #include "config.h" +#include "lossy-socket.h" #include "mock-interaction.h" #include +#ifdef BACKEND_IS_GNUTLS #include +#endif #include #include @@ -68,6 +71,8 @@ typedef struct { gboolean server_should_disappear; /* whether the server should stop responding before sending a message */ gboolean server_should_close; /* whether the server should close gracefully once it’s sent a message */ GTlsAuthenticationMode auth_mode; + IOPredicateFunc client_loss_inducer; + IOPredicateFunc server_loss_inducer; } TestData; typedef struct { @@ -77,6 +82,7 @@ typedef struct { GMainContext *server_context; gboolean loop_finished; GSocket *server_socket; + GDatagramBased *server_transport; GSource *server_source; GTlsDatabase *database; GDatagramBased *server_connection; @@ -89,9 +95,7 @@ typedef struct { gboolean expect_server_error; GError *server_error; gboolean server_running; -#if GLIB_CHECK_VERSION(2, 60, 0) const gchar * const *server_protocols; -#endif char buf[128]; gssize nread, nwrote; @@ -107,18 +111,33 @@ setup_connection (TestConnection *test, gconstpointer data) } /* Waits about 10 seconds for @var to be NULL/FALSE */ -#define WAIT_UNTIL_UNSET(var) \ - if (var) \ - { \ - int i; \ - \ - for (i = 0; i < 13 && (var); i++) \ - { \ - g_usleep (1000 * (1 << i)); \ - g_main_context_iteration (NULL, FALSE); \ - } \ - \ - g_assert (!(var)); \ +#define WAIT_UNTIL_UNSET(var) \ + if (var) \ + { \ + int i; \ + \ + for (i = 0; i < 13 && (var); i++) \ + { \ + g_usleep (1000 * (1 << i)); \ + g_main_context_iteration (test->client_context, FALSE); \ + } \ + \ + g_assert_true (!(var)); \ + } + +/* Waits about 10 seconds for @var's ref_count to drop to 1 */ +#define WAIT_UNTIL_UNREFFED(var) \ + if (var) \ + { \ + int i; \ + \ + for (i = 0; i < 13 && G_OBJECT (var)->ref_count > 1; i++) \ + { \ + g_usleep (1000 * (1 << i)); \ + g_main_context_iteration (test->client_context, FALSE); \ + } \ + \ + g_assert_cmpuint (G_OBJECT (var)->ref_count, ==, 1); \ } static void @@ -137,12 +156,13 @@ teardown_connection (TestConnection *test, gconstpointer data) { WAIT_UNTIL_UNSET (test->server_running); - g_object_add_weak_pointer (G_OBJECT (test->server_connection), - (gpointer *)&test->server_connection); + WAIT_UNTIL_UNREFFED (test->server_connection); g_object_unref (test->server_connection); - WAIT_UNTIL_UNSET (test->server_connection); + test->server_connection = NULL; } + g_clear_object (&test->server_transport); + if (test->server_socket) { g_socket_close (test->server_socket, &error); @@ -151,25 +171,23 @@ teardown_connection (TestConnection *test, gconstpointer data) /* The outstanding accept_async will hold a ref on test->server_socket, * which we want to wait for it to release if we're valgrinding. */ - g_object_add_weak_pointer (G_OBJECT (test->server_socket), (gpointer *)&test->server_socket); + WAIT_UNTIL_UNREFFED (test->server_socket); g_object_unref (test->server_socket); - WAIT_UNTIL_UNSET (test->server_socket); + test->server_socket = NULL; } if (test->client_connection) { - g_object_add_weak_pointer (G_OBJECT (test->client_connection), - (gpointer *)&test->client_connection); + WAIT_UNTIL_UNREFFED (test->client_connection); g_object_unref (test->client_connection); - WAIT_UNTIL_UNSET (test->client_connection); + test->client_connection = NULL; } if (test->database) { - g_object_add_weak_pointer (G_OBJECT (test->database), - (gpointer *)&test->database); + WAIT_UNTIL_UNREFFED (test->database); g_object_unref (test->database); - WAIT_UNTIL_UNSET (test->database); + test->database = NULL; } g_clear_object (&test->address); @@ -209,6 +227,16 @@ start_server (TestConnection *test) g_inet_socket_address_get_port (iaddr)); test->server_socket = socket; + if (test->test_data->server_loss_inducer) + { + test->server_transport = lossy_socket_new (G_DATAGRAM_BASED (socket), + test->test_data->server_loss_inducer, + test); + } + else + { + test->server_transport = G_DATAGRAM_BASED (g_object_ref (socket)); + } test->server_running = TRUE; } @@ -247,7 +275,7 @@ on_rehandshake_finish (GObject *object, &message, 1, G_SOCKET_MSG_NONE, 0, NULL, &test->server_error); - g_main_context_iteration (NULL, FALSE); + g_main_context_iteration (test->server_context, FALSE); } while (g_error_matches (test->server_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)); @@ -294,7 +322,7 @@ on_rehandshake_finish_threaded (GObject *object, &message, 1, G_SOCKET_MSG_NONE, 0, NULL, &test->server_error); - g_main_context_iteration (NULL, FALSE); + g_main_context_iteration (test->server_context, FALSE); } while (g_error_matches (test->server_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)); @@ -386,7 +414,7 @@ on_incoming_connection (GSocket *socket, cert = g_tls_certificate_new_from_file (tls_test_file_path ("server-and-key.pem"), &error); g_assert_no_error (error); - test->server_connection = g_dtls_server_connection_new (G_DATAGRAM_BASED (socket), + test->server_connection = g_dtls_server_connection_new (test->server_transport, cert, &error); g_debug ("%s: Server connection %p on socket %p", G_STRFUNC, test->server_connection, socket); g_assert_no_error (error); @@ -400,13 +428,11 @@ on_incoming_connection (GSocket *socket, if (test->database) g_dtls_connection_set_database (G_DTLS_CONNECTION (test->server_connection), test->database); -#if GLIB_CHECK_VERSION(2, 60, 0) if (test->server_protocols) { g_dtls_connection_set_advertised_protocols (G_DTLS_CONNECTION (test->server_connection), test->server_protocols); } -#endif if (test->test_data->server_should_disappear) { @@ -421,7 +447,7 @@ on_incoming_connection (GSocket *socket, &message, 1, G_SOCKET_MSG_NONE, 0, NULL, &test->server_error); - g_main_context_iteration (NULL, FALSE); + g_main_context_iteration (test->server_context, FALSE); } while (g_error_matches (test->server_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)); @@ -494,7 +520,7 @@ on_incoming_connection_threaded (GSocket *socket, cert = g_tls_certificate_new_from_file (tls_test_file_path ("server-and-key.pem"), &error); g_assert_no_error (error); - test->server_connection = g_dtls_server_connection_new (G_DATAGRAM_BASED (socket), + test->server_connection = g_dtls_server_connection_new (test->server_transport, cert, &error); g_debug ("%s: Server connection %p on socket %p", G_STRFUNC, test->server_connection, socket); g_assert_no_error (error); @@ -522,7 +548,7 @@ on_incoming_connection_threaded (GSocket *socket, G_SOCKET_MSG_NONE, test->test_data->server_timeout, NULL, &test->server_error); - g_main_context_iteration (NULL, FALSE); + g_main_context_iteration (test->server_context, FALSE); } while (g_error_matches (test->server_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)); @@ -595,6 +621,7 @@ start_server_and_connect_to_it (TestConnection *test, { GError *error = NULL; GSocket *socket; + GDatagramBased *transport; start_server_service (test, threaded); @@ -605,7 +632,19 @@ start_server_and_connect_to_it (TestConnection *test, g_socket_connect (socket, test->address, NULL, &error); g_assert_no_error (error); - return G_DATAGRAM_BASED (socket); + if (test->test_data->client_loss_inducer) + { + transport = lossy_socket_new (G_DATAGRAM_BASED (socket), + test->test_data->client_loss_inducer, + test); + g_object_unref (socket); + } + else + { + transport = G_DATAGRAM_BASED (socket); + } + + return transport; } static void @@ -629,7 +668,7 @@ read_test_data_async (TestConnection *test) G_SOCKET_MSG_NONE, test->test_data->client_timeout, NULL, &test->read_error); - g_main_context_iteration (NULL, FALSE); + g_main_context_iteration (test->client_context, FALSE); } while (g_error_matches (test->read_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)); @@ -737,81 +776,14 @@ test_connection_timeouts_read (TestConnection *test, g_assert_error (test->read_error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT); } -static void -test_alpn (TestConnection *test, - const char * const *client_protocols, - const char * const *server_protocols, - const char *negotiated_protocol) -{ -#if GLIB_CHECK_VERSION(2, 60, 0) - GDatagramBased *connection; - GError *error = NULL; - - test->server_protocols = server_protocols; - - test->database = g_tls_file_database_new (tls_test_file_path ("ca-roots.pem"), &error); - g_assert_no_error (error); - g_assert (test->database); - - connection = start_server_and_connect_to_it (test, FALSE); - test->client_connection = g_dtls_client_connection_new (connection, test->identity, &error); - g_assert_no_error (error); - g_object_unref (connection); - - if (client_protocols) - { - g_dtls_connection_set_advertised_protocols (G_DTLS_CONNECTION (test->client_connection), - client_protocols); - } - - g_tls_connection_set_database (G_TLS_CONNECTION (test->client_connection), test->database); - - read_test_data_async (test); - while (!test->loop_finished) - g_main_context_iteration (test->client_context, TRUE); - - g_assert_no_error (test->server_error); - g_assert_no_error (test->read_error); - - g_assert_cmpstr (g_dtls_connection_get_negotiated_protocol (G_DTLS_CONNECTION (test->server_connection)), ==, negotiated_protocol); - g_assert_cmpstr (g_dtls_connection_get_negotiated_protocol (G_DTLS_CONNECTION (test->client_connection)), ==, negotiated_protocol); -#else - g_test_skip ("no support for ALPN in this GLib version"); -#endif -} - -static void -test_alpn_match (TestConnection *test, gconstpointer data) -{ - const char * const client_protocols[] = { "one", "two", "three", NULL }; - const char * const server_protocols[] = { "four", "seven", "nine", "two", NULL }; - - test_alpn (test, client_protocols, server_protocols, "two"); -} - -static void -test_alpn_no_match (TestConnection *test, gconstpointer data) -{ - const char * const client_protocols[] = { "one", "two", "three", NULL }; - const char * const server_protocols[] = { "four", "seven", "nine", NULL }; - - test_alpn (test, client_protocols, server_protocols, NULL); -} - -static void -test_alpn_client_only (TestConnection *test, gconstpointer data) -{ - const char * const client_protocols[] = { "one", "two", "three", NULL }; - - test_alpn (test, client_protocols, NULL, NULL); -} - -static void -test_alpn_server_only (TestConnection *test, gconstpointer data) +static IODecision +drop_first_outgoing (const IODetails *io, + gpointer user_data) { - const char * const server_protocols[] = { "four", "seven", "nine", "two", NULL }; + if (io->direction == IO_OUT && io->serial == 1) + return IO_DROP; - test_alpn (test, NULL, server_protocols, NULL); + return IO_KEEP; } int @@ -824,6 +796,7 @@ main (int argc, FALSE, /* server_should_disappear */ TRUE, /* server_should_close */ G_TLS_AUTHENTICATION_NONE, /* auth_mode */ + NULL, NULL, /* loss inducers */ }; const TestData server_timeout = { 1000 * G_USEC_PER_SEC, /* server_timeout */ @@ -831,6 +804,7 @@ main (int argc, FALSE, /* server_should_disappear */ TRUE, /* server_should_close */ G_TLS_AUTHENTICATION_NONE, /* auth_mode */ + NULL, NULL, /* loss inducers */ }; const TestData nonblocking = { 0, /* server_timeout */ @@ -838,6 +812,7 @@ main (int argc, FALSE, /* server_should_disappear */ TRUE, /* server_should_close */ G_TLS_AUTHENTICATION_NONE, /* auth_mode */ + NULL, NULL, /* loss inducers */ }; const TestData client_timeout = { 0, /* server_timeout */ @@ -845,6 +820,23 @@ main (int argc, TRUE, /* server_should_disappear */ TRUE, /* server_should_close */ G_TLS_AUTHENTICATION_NONE, /* auth_mode */ + NULL, NULL, /* loss inducers */ + }; + const TestData client_loss = { + -1, /* server_timeout */ + 0, /* client_timeout */ + FALSE, /* server_should_disappear */ + TRUE, /* server_should_close */ + G_TLS_AUTHENTICATION_NONE, /* auth_mode */ + drop_first_outgoing, NULL, /* loss inducers */ + }; + const TestData server_loss = { + -1, /* server_timeout */ + 0, /* client_timeout */ + FALSE, /* server_should_disappear */ + TRUE, /* server_should_close */ + G_TLS_AUTHENTICATION_NONE, /* auth_mode */ + NULL, drop_first_outgoing, /* loss inducers */ }; int ret; int i; @@ -872,41 +864,33 @@ main (int argc, g_setenv ("GSETTINGS_BACKEND", "memory", TRUE); g_setenv ("GIO_USE_TLS", BACKEND, TRUE); - g_assert (g_ascii_strcasecmp (G_OBJECT_TYPE_NAME (g_tls_backend_get_default ()), "GTlsBackend" BACKEND) == 0); + g_assert_cmpint (g_ascii_strcasecmp (G_OBJECT_TYPE_NAME (g_tls_backend_get_default ()), "GTlsBackend" BACKEND), ==, 0); - g_test_add ("/dtls/connection/basic/blocking", TestConnection, &blocking, + g_test_add ("/dtls/" BACKEND "/connection/basic/blocking", TestConnection, &blocking, setup_connection, test_basic_connection, teardown_connection); - g_test_add ("/dtls/connection/basic/timeout", TestConnection, &server_timeout, + g_test_add ("/dtls/" BACKEND "/connection/basic/timeout", TestConnection, &server_timeout, setup_connection, test_basic_connection, teardown_connection); - g_test_add ("/dtls/connection/basic/nonblocking", + g_test_add ("/dtls/" BACKEND "/connection/basic/nonblocking", TestConnection, &nonblocking, setup_connection, test_basic_connection, teardown_connection); - g_test_add ("/dtls/connection/threaded/blocking", TestConnection, &blocking, + g_test_add ("/dtls/" BACKEND "/connection/threaded/blocking", TestConnection, &blocking, setup_connection, test_threaded_connection, teardown_connection); - g_test_add ("/dtls/connection/threaded/timeout", + g_test_add ("/dtls/" BACKEND "/connection/threaded/timeout", TestConnection, &server_timeout, setup_connection, test_threaded_connection, teardown_connection); - g_test_add ("/dtls/connection/threaded/nonblocking", + g_test_add ("/dtls/" BACKEND "/connection/threaded/nonblocking", TestConnection, &nonblocking, setup_connection, test_threaded_connection, teardown_connection); - g_test_add ("/dtls/connection/timeouts/read", TestConnection, &client_timeout, + g_test_add ("/dtls/" BACKEND "/connection/timeouts/read", TestConnection, &client_timeout, setup_connection, test_connection_timeouts_read, teardown_connection); - g_test_add ("/dtls/connection/alpn/match", TestConnection, &blocking, - setup_connection, test_alpn_match, - teardown_connection); - g_test_add ("/dtls/connection/alpn/no-match", TestConnection, &blocking, - setup_connection, test_alpn_no_match, - teardown_connection); - g_test_add ("/dtls/connection/alpn/client-only", TestConnection, &blocking, - setup_connection, test_alpn_client_only, - teardown_connection); - g_test_add ("/dtls/connection/alpn/server-only", TestConnection, &blocking, - setup_connection, test_alpn_server_only, - teardown_connection); + g_test_add ("/dtls/" BACKEND "/connection/lossy/client", TestConnection, &client_loss, + setup_connection, test_basic_connection, teardown_connection); + g_test_add ("/dtls/" BACKEND "/connection/lossy/server", TestConnection, &server_loss, + setup_connection, test_basic_connection, teardown_connection); ret = g_test_run ();