run_echo_server (GThreadedSocketService *service,
                 GSocketConnection      *connection,
                 GObject                *source_object,
                 gpointer                user_data)
{
  TestConnection *test = user_data;
  GTlsConnection *tlsconn;
  GTlsCertificate *cert;
  GError *error = NULL;
  GInputStream *istream;
  GOutputStream *ostream;
  gssize nread, nwrote, total;
  gchar buf[128];

  if (test->server_certificate)
    {
      cert = g_object_ref (test->server_certificate);
    }
  else
    {
      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_tls_server_connection_new (G_IO_STREAM (connection),
                                                         cert, &error);
  g_assert_no_error (error);
  g_object_unref (cert);

  tlsconn = G_TLS_CONNECTION (test->server_connection);
  g_tls_connection_handshake (tlsconn, NULL, &error);
  g_assert_no_error (error);

  istream = g_io_stream_get_input_stream (test->server_connection);
  ostream = g_io_stream_get_output_stream (test->server_connection);

  while (TRUE)
    {
      nread = g_input_stream_read (istream, buf, sizeof (buf), NULL, &error);
      g_assert_no_error (error);
      g_assert_cmpint (nread, >=, 0);

      if (nread == 0)
        break;

      for (total = 0; total < nread; total += nwrote)
        {
          nwrote = g_output_stream_write (ostream, buf + total, nread - total, NULL, &error);
          g_assert_no_error (error);
        }

      if (test->rehandshake)
        {
          test->rehandshake = FALSE;
          g_tls_connection_handshake (tlsconn, NULL, &error);
          g_assert_no_error (error);
        }
    }

  g_io_stream_close (test->server_connection, NULL, &error);
  g_assert_no_error (error);
  test->server_running = FALSE;
}
run_echo_server (GThreadedSocketService *service,
                 GSocketConnection      *connection,
                 GObject                *source_object,
                 gpointer                user_data)
{
  TestConnection *test = user_data;
  GTlsConnection *tlsconn;
  GTlsCertificate *cert;
  GError *error = NULL;
  GInputStream *istream;
  GOutputStream *ostream;
  gssize nread, nwrote, total;
  gchar buf[128];

  if (test->server_certificate)
    {
      cert = g_object_ref (test->server_certificate);
    }
  else
    {
      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_tls_server_connection_new (G_IO_STREAM (connection),
                                                         cert, &error);
  g_assert_no_error (error);
  g_object_unref (cert);

  tlsconn = G_TLS_CONNECTION (test->server_connection);
  g_tls_connection_handshake (tlsconn, NULL, &error);
  g_assert_no_error (error);

  istream = g_io_stream_get_input_stream (test->server_connection);
  ostream = g_io_stream_get_output_stream (test->server_connection);

  while (TRUE)
    {
      nread = g_input_stream_read (istream, buf, sizeof (buf), NULL, &error);
      g_assert_no_error (error);
      g_assert_cmpint (nread, >=, 0);

      if (nread == 0)
        break;

      for (total = 0; total < nread; total += nwrote)
        {
          nwrote = g_output_stream_write (ostream, buf + total, nread - total, NULL, &error);
          g_assert_no_error (error);
        }

      if (test->rehandshake)
        {
          test->rehandshake = FALSE;
          g_tls_connection_handshake (tlsconn, NULL, &error);
          g_assert_no_error (error);
        }
    }

  g_io_stream_close (test->server_connection, NULL, &error);
  g_assert_no_error (error);
  test->server_running = FALSE;
}