From f217c9a3b51cf38c2d58f1afe712df86356523a4 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 11 May 2014 12:03:46 +0000 Subject: [PATCH] -big cleanup of test_server code, also fixing #3394 --- src/util/test_server.c | 232 ++++++++++++++++++++++++++++++++--------- 1 file changed, 182 insertions(+), 50 deletions(-) diff --git a/src/util/test_server.c b/src/util/test_server.c index c39744f8a..4ef4439e7 100644 --- a/src/util/test_server.c +++ b/src/util/test_server.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2009, 2010 Christian Grothoff (and other contributing authors) + (C) 2009, 2010, 2014 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -24,28 +24,63 @@ #include "platform.h" #include "gnunet_util_lib.h" +/** + * TCP port to use for the server. + */ #define PORT 12435 +/** + * Timeout to use for operations. + */ #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2) +/** + * Test message type. + */ #define MY_TYPE 128 + +/** + * Test message type. + */ #define MY_TYPE2 129 +/** + * Handle for the server. + */ static struct GNUNET_SERVER_Handle *server; +/** + * Handle for the client. + */ static struct GNUNET_CLIENT_Connection *cc; +/** + * Handle of the server for the client. + */ static struct GNUNET_SERVER_Client *argclient; +/** + * Our configuration. + */ static struct GNUNET_CONFIGURATION_Handle *cfg; +/** + * Number indiciating in which phase of the test we are. + */ static int ok; +/** + * Final task invoked to clean up. + * + * @param cls NULL + * @param tc scheduler context + */ static void -finish_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +finish_up (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { - GNUNET_assert (ok == 6); + GNUNET_assert (7 == ok); ok = 0; GNUNET_SERVER_destroy (server); GNUNET_CLIENT_disconnect (cc); @@ -53,48 +88,122 @@ finish_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } +/** + * The server has received the second message, initiate clean up. + * + * @param cls NULL + * @param client client we got the message from + * @param message the message + */ static void -recv_fin_cb (void *cls, struct GNUNET_SERVER_Client *client, +recv_fin_cb (void *cls, + struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { - GNUNET_assert (ok == 5); - ok = 6; + GNUNET_assert (6 == ok); + ok = 7; GNUNET_SERVER_receive_done (client, GNUNET_OK); GNUNET_SCHEDULER_add_now (&finish_up, NULL); } +/** + * The client connected to the server and is now allowed + * to send a second message. We send one. + * + * @param cls NULL + * @param size number of bytes that can be transmitted + * @param buf where to copy the message + * @return number of bytes copied to @a buf + */ +static size_t +transmit_second_message (void *cls, + size_t size, + void *buf) +{ + struct GNUNET_MessageHeader msg; + + GNUNET_assert (5 == ok); + ok = 6; + GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); + msg.type = htons (MY_TYPE2); + msg.size = htons (sizeof (struct GNUNET_MessageHeader)); + memcpy (buf, &msg, sizeof (struct GNUNET_MessageHeader)); + return sizeof (struct GNUNET_MessageHeader); +} + + +/** + * We have received the reply from the server, check that we are at + * the right stage and queue the next message to the server. Cleans + * up #argclient. + * + * @param cls NULL + * @param msg message we got from the server + */ static void -first_reply_handler (void *cls, const struct GNUNET_MessageHeader *msg) +first_reply_handler (void *cls, + const struct GNUNET_MessageHeader *msg) { - GNUNET_assert (ok == 4); + GNUNET_assert (4 == ok); ok = 5; - GNUNET_SERVER_receive_done (argclient, GNUNET_OK); - GNUNET_SERVER_client_drop (argclient); - argclient = NULL; + GNUNET_assert (NULL != + GNUNET_CLIENT_notify_transmit_ready (cc, + sizeof (struct GNUNET_MessageHeader), + TIMEOUT, + GNUNET_YES, + &transmit_second_message, + NULL)); } +/** + * Send a reply of type #MY_TYPE from the server to the client. + * Checks that we are in the right phase and transmits the + * reply. Cleans up #argclient state. + * + * @param cls NULL + * @param size number of bytes we are allowed to send + * @param buf where to copy the reply + * @return number of bytes written to @a buf + */ static size_t -reply_msg (void *cls, size_t size, void *buf) +reply_msg (void *cls, + size_t size, + void *buf) { struct GNUNET_MessageHeader msg; - GNUNET_assert (ok == 3); + GNUNET_assert (3 == ok); ok = 4; GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); msg.type = htons (MY_TYPE); msg.size = htons (sizeof (struct GNUNET_MessageHeader)); memcpy (buf, &msg, sizeof (struct GNUNET_MessageHeader)); + GNUNET_assert (NULL != argclient); + GNUNET_SERVER_receive_done (argclient, GNUNET_OK); + GNUNET_SERVER_client_drop (argclient); + argclient = NULL; return sizeof (struct GNUNET_MessageHeader); } +/** + * Function called whenever the server receives a message of + * type #MY_TYPE. Checks that we are at the stage where + * we expect the first message, then sends a reply. Stores + * the handle to the client in #argclient. + * + * @param cls NULL + * @param client client that sent the message + * @param message the message we received + */ static void -recv_cb (void *cls, struct GNUNET_SERVER_Client *client, +recv_cb (void *cls, + struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { - GNUNET_assert (ok == 2); + GNUNET_assert (2 == ok); ok = 3; argclient = client; GNUNET_SERVER_client_keep (argclient); @@ -108,51 +217,56 @@ recv_cb (void *cls, struct GNUNET_SERVER_Client *client, } -static struct GNUNET_SERVER_MessageHandler handlers[] = { - {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)}, - {&recv_fin_cb, NULL, MY_TYPE2, sizeof (struct GNUNET_MessageHeader)}, - {NULL, NULL, 0, 0} -}; - - -static size_t -transmit_second_message (void *cls, size_t size, void *buf) -{ - struct GNUNET_MessageHeader msg; - - GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); - msg.type = htons (MY_TYPE2); - msg.size = htons (sizeof (struct GNUNET_MessageHeader)); - memcpy (buf, &msg, sizeof (struct GNUNET_MessageHeader)); - return sizeof (struct GNUNET_MessageHeader); -} - - +/** + * The client connected to the server and is now allowed + * to send a first message. We transmit a simple message, + * ask for a second transmission and get ready to receive + * a response. + * + * @param cls NULL + * @param size number of bytes that can be transmitted + * @param buf where to copy the message + * @return number of bytes copied to @a buf + */ static size_t -transmit_initial_message (void *cls, size_t size, void *buf) +transmit_initial_message (void *cls, + size_t size, + void *buf) { struct GNUNET_MessageHeader msg; - GNUNET_assert (ok == 1); + GNUNET_assert (1 == ok); ok = 2; GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); msg.type = htons (MY_TYPE); msg.size = htons (sizeof (struct GNUNET_MessageHeader)); memcpy (buf, &msg, sizeof (struct GNUNET_MessageHeader)); - GNUNET_assert (NULL != - GNUNET_CLIENT_notify_transmit_ready (cc, - sizeof (struct - GNUNET_MessageHeader), - TIMEOUT, GNUNET_YES, - &transmit_second_message, - NULL)); GNUNET_CLIENT_receive (cc, &first_reply_handler, NULL, TIMEOUT); return sizeof (struct GNUNET_MessageHeader); } +/** + * Message handlers for the server. + */ +static struct GNUNET_SERVER_MessageHandler handlers[] = { + {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)}, + {&recv_fin_cb, NULL, MY_TYPE2, sizeof (struct GNUNET_MessageHeader)}, + {NULL, NULL, 0, 0} +}; + + +/** + * First task run by the scheduler. Initializes the server and + * a client and asks for a transmission from the client to the + * server. + * + * @param cls NULL + * @param tc scheduler context + */ static void -task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { struct sockaddr_in sa; struct sockaddr *sap[2]; @@ -168,14 +282,23 @@ task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) #endif sa.sin_family = AF_INET; sa.sin_port = htons (PORT); - server = GNUNET_SERVER_create (NULL, NULL, sap, slens, TIMEOUT, GNUNET_NO); + server = GNUNET_SERVER_create (NULL, NULL, + sap, slens, + TIMEOUT, GNUNET_NO); GNUNET_assert (server != NULL); GNUNET_SERVER_add_handlers (server, handlers); cfg = GNUNET_CONFIGURATION_create (); - GNUNET_CONFIGURATION_set_value_number (cfg, "test-server", "PORT", PORT); - GNUNET_CONFIGURATION_set_value_string (cfg, "test-server", "HOSTNAME", + GNUNET_CONFIGURATION_set_value_number (cfg, + "test-server", + "PORT", + PORT); + GNUNET_CONFIGURATION_set_value_string (cfg, + "test-server", + "HOSTNAME", "localhost"); - GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME", + GNUNET_CONFIGURATION_set_value_string (cfg, + "resolver", + "HOSTNAME", "localhost"); cc = GNUNET_CLIENT_connect ("test-server", cfg); GNUNET_assert (cc != NULL); @@ -189,10 +312,19 @@ task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } +/** + * Runs the test. + * + * @param argc length of @a argv + * @param argv command line arguments (ignored) + * @return 0 on success, otherwise phase of failure + */ int main (int argc, char *argv[]) { - GNUNET_log_setup ("test_server", "WARNING", NULL); + GNUNET_log_setup ("test_server", + "WARNING", + NULL); ok = 1; GNUNET_SCHEDULER_run (&task, &ok); return ok; -- 2.25.1