diff options
author | Christian Grothoff <christian@grothoff.org> | 2014-05-11 12:03:46 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2014-05-11 12:03:46 +0000 |
commit | f217c9a3b51cf38c2d58f1afe712df86356523a4 (patch) | |
tree | c912a34c0d49694fa6714f48938758fb9f2bb1e0 /src/util | |
parent | 979fa0529ac13a2676c036818e2aaee9bee26aff (diff) | |
download | gnunet-f217c9a3b51cf38c2d58f1afe712df86356523a4.tar.gz gnunet-f217c9a3b51cf38c2d58f1afe712df86356523a4.zip |
-big cleanup of test_server code, also fixing #3394
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/test_server.c | 232 |
1 files 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 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2009, 2010 Christian Grothoff (and other contributing authors) | 3 | (C) 2009, 2010, 2014 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -24,28 +24,63 @@ | |||
24 | #include "platform.h" | 24 | #include "platform.h" |
25 | #include "gnunet_util_lib.h" | 25 | #include "gnunet_util_lib.h" |
26 | 26 | ||
27 | /** | ||
28 | * TCP port to use for the server. | ||
29 | */ | ||
27 | #define PORT 12435 | 30 | #define PORT 12435 |
28 | 31 | ||
32 | /** | ||
33 | * Timeout to use for operations. | ||
34 | */ | ||
29 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2) | 35 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2) |
30 | 36 | ||
37 | /** | ||
38 | * Test message type. | ||
39 | */ | ||
31 | #define MY_TYPE 128 | 40 | #define MY_TYPE 128 |
41 | |||
42 | /** | ||
43 | * Test message type. | ||
44 | */ | ||
32 | #define MY_TYPE2 129 | 45 | #define MY_TYPE2 129 |
33 | 46 | ||
47 | /** | ||
48 | * Handle for the server. | ||
49 | */ | ||
34 | static struct GNUNET_SERVER_Handle *server; | 50 | static struct GNUNET_SERVER_Handle *server; |
35 | 51 | ||
52 | /** | ||
53 | * Handle for the client. | ||
54 | */ | ||
36 | static struct GNUNET_CLIENT_Connection *cc; | 55 | static struct GNUNET_CLIENT_Connection *cc; |
37 | 56 | ||
57 | /** | ||
58 | * Handle of the server for the client. | ||
59 | */ | ||
38 | static struct GNUNET_SERVER_Client *argclient; | 60 | static struct GNUNET_SERVER_Client *argclient; |
39 | 61 | ||
62 | /** | ||
63 | * Our configuration. | ||
64 | */ | ||
40 | static struct GNUNET_CONFIGURATION_Handle *cfg; | 65 | static struct GNUNET_CONFIGURATION_Handle *cfg; |
41 | 66 | ||
67 | /** | ||
68 | * Number indiciating in which phase of the test we are. | ||
69 | */ | ||
42 | static int ok; | 70 | static int ok; |
43 | 71 | ||
44 | 72 | ||
73 | /** | ||
74 | * Final task invoked to clean up. | ||
75 | * | ||
76 | * @param cls NULL | ||
77 | * @param tc scheduler context | ||
78 | */ | ||
45 | static void | 79 | static void |
46 | finish_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 80 | finish_up (void *cls, |
81 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
47 | { | 82 | { |
48 | GNUNET_assert (ok == 6); | 83 | GNUNET_assert (7 == ok); |
49 | ok = 0; | 84 | ok = 0; |
50 | GNUNET_SERVER_destroy (server); | 85 | GNUNET_SERVER_destroy (server); |
51 | GNUNET_CLIENT_disconnect (cc); | 86 | GNUNET_CLIENT_disconnect (cc); |
@@ -53,48 +88,122 @@ finish_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
53 | } | 88 | } |
54 | 89 | ||
55 | 90 | ||
91 | /** | ||
92 | * The server has received the second message, initiate clean up. | ||
93 | * | ||
94 | * @param cls NULL | ||
95 | * @param client client we got the message from | ||
96 | * @param message the message | ||
97 | */ | ||
56 | static void | 98 | static void |
57 | recv_fin_cb (void *cls, struct GNUNET_SERVER_Client *client, | 99 | recv_fin_cb (void *cls, |
100 | struct GNUNET_SERVER_Client *client, | ||
58 | const struct GNUNET_MessageHeader *message) | 101 | const struct GNUNET_MessageHeader *message) |
59 | { | 102 | { |
60 | GNUNET_assert (ok == 5); | 103 | GNUNET_assert (6 == ok); |
61 | ok = 6; | 104 | ok = 7; |
62 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 105 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
63 | GNUNET_SCHEDULER_add_now (&finish_up, NULL); | 106 | GNUNET_SCHEDULER_add_now (&finish_up, NULL); |
64 | } | 107 | } |
65 | 108 | ||
66 | 109 | ||
110 | /** | ||
111 | * The client connected to the server and is now allowed | ||
112 | * to send a second message. We send one. | ||
113 | * | ||
114 | * @param cls NULL | ||
115 | * @param size number of bytes that can be transmitted | ||
116 | * @param buf where to copy the message | ||
117 | * @return number of bytes copied to @a buf | ||
118 | */ | ||
119 | static size_t | ||
120 | transmit_second_message (void *cls, | ||
121 | size_t size, | ||
122 | void *buf) | ||
123 | { | ||
124 | struct GNUNET_MessageHeader msg; | ||
125 | |||
126 | GNUNET_assert (5 == ok); | ||
127 | ok = 6; | ||
128 | GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); | ||
129 | msg.type = htons (MY_TYPE2); | ||
130 | msg.size = htons (sizeof (struct GNUNET_MessageHeader)); | ||
131 | memcpy (buf, &msg, sizeof (struct GNUNET_MessageHeader)); | ||
132 | return sizeof (struct GNUNET_MessageHeader); | ||
133 | } | ||
134 | |||
135 | |||
136 | /** | ||
137 | * We have received the reply from the server, check that we are at | ||
138 | * the right stage and queue the next message to the server. Cleans | ||
139 | * up #argclient. | ||
140 | * | ||
141 | * @param cls NULL | ||
142 | * @param msg message we got from the server | ||
143 | */ | ||
67 | static void | 144 | static void |
68 | first_reply_handler (void *cls, const struct GNUNET_MessageHeader *msg) | 145 | first_reply_handler (void *cls, |
146 | const struct GNUNET_MessageHeader *msg) | ||
69 | { | 147 | { |
70 | GNUNET_assert (ok == 4); | 148 | GNUNET_assert (4 == ok); |
71 | ok = 5; | 149 | ok = 5; |
72 | GNUNET_SERVER_receive_done (argclient, GNUNET_OK); | 150 | GNUNET_assert (NULL != |
73 | GNUNET_SERVER_client_drop (argclient); | 151 | GNUNET_CLIENT_notify_transmit_ready (cc, |
74 | argclient = NULL; | 152 | sizeof (struct GNUNET_MessageHeader), |
153 | TIMEOUT, | ||
154 | GNUNET_YES, | ||
155 | &transmit_second_message, | ||
156 | NULL)); | ||
75 | } | 157 | } |
76 | 158 | ||
77 | 159 | ||
160 | /** | ||
161 | * Send a reply of type #MY_TYPE from the server to the client. | ||
162 | * Checks that we are in the right phase and transmits the | ||
163 | * reply. Cleans up #argclient state. | ||
164 | * | ||
165 | * @param cls NULL | ||
166 | * @param size number of bytes we are allowed to send | ||
167 | * @param buf where to copy the reply | ||
168 | * @return number of bytes written to @a buf | ||
169 | */ | ||
78 | static size_t | 170 | static size_t |
79 | reply_msg (void *cls, size_t size, void *buf) | 171 | reply_msg (void *cls, |
172 | size_t size, | ||
173 | void *buf) | ||
80 | { | 174 | { |
81 | struct GNUNET_MessageHeader msg; | 175 | struct GNUNET_MessageHeader msg; |
82 | 176 | ||
83 | GNUNET_assert (ok == 3); | 177 | GNUNET_assert (3 == ok); |
84 | ok = 4; | 178 | ok = 4; |
85 | GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); | 179 | GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); |
86 | msg.type = htons (MY_TYPE); | 180 | msg.type = htons (MY_TYPE); |
87 | msg.size = htons (sizeof (struct GNUNET_MessageHeader)); | 181 | msg.size = htons (sizeof (struct GNUNET_MessageHeader)); |
88 | memcpy (buf, &msg, sizeof (struct GNUNET_MessageHeader)); | 182 | memcpy (buf, &msg, sizeof (struct GNUNET_MessageHeader)); |
183 | GNUNET_assert (NULL != argclient); | ||
184 | GNUNET_SERVER_receive_done (argclient, GNUNET_OK); | ||
185 | GNUNET_SERVER_client_drop (argclient); | ||
186 | argclient = NULL; | ||
89 | return sizeof (struct GNUNET_MessageHeader); | 187 | return sizeof (struct GNUNET_MessageHeader); |
90 | } | 188 | } |
91 | 189 | ||
92 | 190 | ||
191 | /** | ||
192 | * Function called whenever the server receives a message of | ||
193 | * type #MY_TYPE. Checks that we are at the stage where | ||
194 | * we expect the first message, then sends a reply. Stores | ||
195 | * the handle to the client in #argclient. | ||
196 | * | ||
197 | * @param cls NULL | ||
198 | * @param client client that sent the message | ||
199 | * @param message the message we received | ||
200 | */ | ||
93 | static void | 201 | static void |
94 | recv_cb (void *cls, struct GNUNET_SERVER_Client *client, | 202 | recv_cb (void *cls, |
203 | struct GNUNET_SERVER_Client *client, | ||
95 | const struct GNUNET_MessageHeader *message) | 204 | const struct GNUNET_MessageHeader *message) |
96 | { | 205 | { |
97 | GNUNET_assert (ok == 2); | 206 | GNUNET_assert (2 == ok); |
98 | ok = 3; | 207 | ok = 3; |
99 | argclient = client; | 208 | argclient = client; |
100 | GNUNET_SERVER_client_keep (argclient); | 209 | GNUNET_SERVER_client_keep (argclient); |
@@ -108,51 +217,56 @@ recv_cb (void *cls, struct GNUNET_SERVER_Client *client, | |||
108 | } | 217 | } |
109 | 218 | ||
110 | 219 | ||
111 | static struct GNUNET_SERVER_MessageHandler handlers[] = { | 220 | /** |
112 | {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)}, | 221 | * The client connected to the server and is now allowed |
113 | {&recv_fin_cb, NULL, MY_TYPE2, sizeof (struct GNUNET_MessageHeader)}, | 222 | * to send a first message. We transmit a simple message, |
114 | {NULL, NULL, 0, 0} | 223 | * ask for a second transmission and get ready to receive |
115 | }; | 224 | * a response. |
116 | 225 | * | |
117 | 226 | * @param cls NULL | |
118 | static size_t | 227 | * @param size number of bytes that can be transmitted |
119 | transmit_second_message (void *cls, size_t size, void *buf) | 228 | * @param buf where to copy the message |
120 | { | 229 | * @return number of bytes copied to @a buf |
121 | struct GNUNET_MessageHeader msg; | 230 | */ |
122 | |||
123 | GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); | ||
124 | msg.type = htons (MY_TYPE2); | ||
125 | msg.size = htons (sizeof (struct GNUNET_MessageHeader)); | ||
126 | memcpy (buf, &msg, sizeof (struct GNUNET_MessageHeader)); | ||
127 | return sizeof (struct GNUNET_MessageHeader); | ||
128 | } | ||
129 | |||
130 | |||
131 | static size_t | 231 | static size_t |
132 | transmit_initial_message (void *cls, size_t size, void *buf) | 232 | transmit_initial_message (void *cls, |
233 | size_t size, | ||
234 | void *buf) | ||
133 | { | 235 | { |
134 | struct GNUNET_MessageHeader msg; | 236 | struct GNUNET_MessageHeader msg; |
135 | 237 | ||
136 | GNUNET_assert (ok == 1); | 238 | GNUNET_assert (1 == ok); |
137 | ok = 2; | 239 | ok = 2; |
138 | GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); | 240 | GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); |
139 | msg.type = htons (MY_TYPE); | 241 | msg.type = htons (MY_TYPE); |
140 | msg.size = htons (sizeof (struct GNUNET_MessageHeader)); | 242 | msg.size = htons (sizeof (struct GNUNET_MessageHeader)); |
141 | memcpy (buf, &msg, sizeof (struct GNUNET_MessageHeader)); | 243 | memcpy (buf, &msg, sizeof (struct GNUNET_MessageHeader)); |
142 | GNUNET_assert (NULL != | ||
143 | GNUNET_CLIENT_notify_transmit_ready (cc, | ||
144 | sizeof (struct | ||
145 | GNUNET_MessageHeader), | ||
146 | TIMEOUT, GNUNET_YES, | ||
147 | &transmit_second_message, | ||
148 | NULL)); | ||
149 | GNUNET_CLIENT_receive (cc, &first_reply_handler, NULL, TIMEOUT); | 244 | GNUNET_CLIENT_receive (cc, &first_reply_handler, NULL, TIMEOUT); |
150 | return sizeof (struct GNUNET_MessageHeader); | 245 | return sizeof (struct GNUNET_MessageHeader); |
151 | } | 246 | } |
152 | 247 | ||
153 | 248 | ||
249 | /** | ||
250 | * Message handlers for the server. | ||
251 | */ | ||
252 | static struct GNUNET_SERVER_MessageHandler handlers[] = { | ||
253 | {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)}, | ||
254 | {&recv_fin_cb, NULL, MY_TYPE2, sizeof (struct GNUNET_MessageHeader)}, | ||
255 | {NULL, NULL, 0, 0} | ||
256 | }; | ||
257 | |||
258 | |||
259 | /** | ||
260 | * First task run by the scheduler. Initializes the server and | ||
261 | * a client and asks for a transmission from the client to the | ||
262 | * server. | ||
263 | * | ||
264 | * @param cls NULL | ||
265 | * @param tc scheduler context | ||
266 | */ | ||
154 | static void | 267 | static void |
155 | task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 268 | task (void *cls, |
269 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
156 | { | 270 | { |
157 | struct sockaddr_in sa; | 271 | struct sockaddr_in sa; |
158 | struct sockaddr *sap[2]; | 272 | struct sockaddr *sap[2]; |
@@ -168,14 +282,23 @@ task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
168 | #endif | 282 | #endif |
169 | sa.sin_family = AF_INET; | 283 | sa.sin_family = AF_INET; |
170 | sa.sin_port = htons (PORT); | 284 | sa.sin_port = htons (PORT); |
171 | server = GNUNET_SERVER_create (NULL, NULL, sap, slens, TIMEOUT, GNUNET_NO); | 285 | server = GNUNET_SERVER_create (NULL, NULL, |
286 | sap, slens, | ||
287 | TIMEOUT, GNUNET_NO); | ||
172 | GNUNET_assert (server != NULL); | 288 | GNUNET_assert (server != NULL); |
173 | GNUNET_SERVER_add_handlers (server, handlers); | 289 | GNUNET_SERVER_add_handlers (server, handlers); |
174 | cfg = GNUNET_CONFIGURATION_create (); | 290 | cfg = GNUNET_CONFIGURATION_create (); |
175 | GNUNET_CONFIGURATION_set_value_number (cfg, "test-server", "PORT", PORT); | 291 | GNUNET_CONFIGURATION_set_value_number (cfg, |
176 | GNUNET_CONFIGURATION_set_value_string (cfg, "test-server", "HOSTNAME", | 292 | "test-server", |
293 | "PORT", | ||
294 | PORT); | ||
295 | GNUNET_CONFIGURATION_set_value_string (cfg, | ||
296 | "test-server", | ||
297 | "HOSTNAME", | ||
177 | "localhost"); | 298 | "localhost"); |
178 | GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME", | 299 | GNUNET_CONFIGURATION_set_value_string (cfg, |
300 | "resolver", | ||
301 | "HOSTNAME", | ||
179 | "localhost"); | 302 | "localhost"); |
180 | cc = GNUNET_CLIENT_connect ("test-server", cfg); | 303 | cc = GNUNET_CLIENT_connect ("test-server", cfg); |
181 | GNUNET_assert (cc != NULL); | 304 | GNUNET_assert (cc != NULL); |
@@ -189,10 +312,19 @@ task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
189 | } | 312 | } |
190 | 313 | ||
191 | 314 | ||
315 | /** | ||
316 | * Runs the test. | ||
317 | * | ||
318 | * @param argc length of @a argv | ||
319 | * @param argv command line arguments (ignored) | ||
320 | * @return 0 on success, otherwise phase of failure | ||
321 | */ | ||
192 | int | 322 | int |
193 | main (int argc, char *argv[]) | 323 | main (int argc, char *argv[]) |
194 | { | 324 | { |
195 | GNUNET_log_setup ("test_server", "WARNING", NULL); | 325 | GNUNET_log_setup ("test_server", |
326 | "WARNING", | ||
327 | NULL); | ||
196 | ok = 1; | 328 | ok = 1; |
197 | GNUNET_SCHEDULER_run (&task, &ok); | 329 | GNUNET_SCHEDULER_run (&task, &ok); |
198 | return ok; | 330 | return ok; |