aboutsummaryrefslogtreecommitdiff
path: root/src/util/test_server_disconnect.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/test_server_disconnect.c')
-rw-r--r--src/util/test_server_disconnect.c241
1 files changed, 241 insertions, 0 deletions
diff --git a/src/util/test_server_disconnect.c b/src/util/test_server_disconnect.c
new file mode 100644
index 000000000..60604b35c
--- /dev/null
+++ b/src/util/test_server_disconnect.c
@@ -0,0 +1,241 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 Christian Grothoff (and other contributing authors)
4
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
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20/**
21 * @file util/test_server_disconnect.c
22 * @brief tests for server.c and client.c,
23 * specifically client_disconnect
24 */
25#include "platform.h"
26#include "gnunet_common.h"
27#include "gnunet_scheduler_lib.h"
28#include "gnunet_client_lib.h"
29#include "gnunet_server_lib.h"
30#include "gnunet_time_lib.h"
31
32#define VERBOSE GNUNET_NO
33
34#define PORT 22335
35
36#define MY_TYPE 128
37
38
39static struct GNUNET_SERVER_Handle *server;
40
41static struct GNUNET_CLIENT_Connection *client;
42
43static struct GNUNET_SCHEDULER_Handle *sched;
44
45static struct GNUNET_CONFIGURATION_Handle *cfg;
46
47static int ok;
48
49static void
50send_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
51{
52 struct GNUNET_SERVER_Client *argclient = cls;
53 GNUNET_assert (ok == 3);
54 ok++;
55 GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
56}
57
58static void
59server_disconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
60{
61 struct GNUNET_SERVER_Client *argclient = cls;
62 GNUNET_assert (ok == 5);
63 ok++;
64 GNUNET_SERVER_client_disconnect (argclient);
65}
66
67
68static void
69recv_cb (void *cls,
70 struct GNUNET_SERVER_Handle *server,
71 struct GNUNET_SERVER_Client *argclient,
72 const struct GNUNET_MessageHeader *message)
73{
74 void *addr;
75 size_t addrlen;
76 struct sockaddr_in sa;
77 struct sockaddr_in *have;
78
79 GNUNET_assert (GNUNET_OK ==
80 GNUNET_SERVER_client_get_address (argclient,
81 &addr, &addrlen));
82
83 GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
84 have = addr;
85 memset (&sa, 0, sizeof (sa));
86 sa.sin_family = AF_INET;
87 sa.sin_port = have->sin_port;
88 sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
89 GNUNET_assert (0 == memcmp (&sa, addr, addrlen));
90 GNUNET_free (addr);
91 switch (ok)
92 {
93 case 2:
94 ok++;
95 GNUNET_SCHEDULER_add_delayed (sched,
96 GNUNET_YES,
97 GNUNET_SCHEDULER_PRIORITY_KEEP,
98 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
99 GNUNET_TIME_relative_multiply
100 (GNUNET_TIME_UNIT_MILLISECONDS, 50),
101 &send_done, argclient);
102 break;
103 case 4:
104 ok++;
105 GNUNET_SCHEDULER_add_delayed (sched,
106 GNUNET_YES,
107 GNUNET_SCHEDULER_PRIORITY_KEEP,
108 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
109 GNUNET_TIME_relative_multiply
110 (GNUNET_TIME_UNIT_MILLISECONDS, 50),
111 &server_disconnect, argclient);
112 GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
113 break;
114 default:
115 GNUNET_assert (0);
116 }
117
118}
119
120static void
121disconnect_notify (void *cls, const struct GNUNET_MessageHeader *msg)
122{
123 GNUNET_assert (msg == NULL);
124 GNUNET_assert (ok == 7);
125 ok = 0;
126 GNUNET_CLIENT_disconnect (client);
127 GNUNET_SCHEDULER_shutdown (sched);
128 GNUNET_CONFIGURATION_destroy (cfg);
129}
130
131
132/**
133 * Functions with this signature are called whenever a client
134 * is disconnected on the network level.
135 *
136 * @param cls closure
137 * @param client identification of the client
138 */
139static void
140notify_disconnect (void *cls, struct GNUNET_SERVER_Client *clientarg)
141{
142 GNUNET_assert (ok == 6);
143 ok++;
144 GNUNET_CLIENT_receive (client,
145 &disconnect_notify,
146 NULL, GNUNET_TIME_UNIT_FOREVER_REL);
147}
148
149
150static size_t
151notify_ready (void *cls, size_t size, void *buf)
152{
153 struct GNUNET_MessageHeader *msg;
154
155 GNUNET_assert (size >= 256);
156 GNUNET_assert (1 == ok);
157 ok++;
158 msg = buf;
159 msg->type = htons (MY_TYPE);
160 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
161 msg++;
162 msg->type = htons (MY_TYPE);
163 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
164 return 2 * sizeof (struct GNUNET_MessageHeader);
165}
166
167
168static struct GNUNET_SERVER_MessageHandler handlers[] = {
169 {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)},
170 {NULL, NULL, 0, 0}
171};
172
173
174static void
175task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
176{
177 struct sockaddr_in sa;
178
179 sched = tc->sched;
180 memset (&sa, 0, sizeof (sa));
181 sa.sin_family = AF_INET;
182 sa.sin_port = htons (PORT);
183 server = GNUNET_SERVER_create (tc->sched,
184 NULL,
185 NULL,
186 (const struct sockaddr *) &sa,
187 sizeof (sa),
188 1024,
189 GNUNET_TIME_relative_multiply
190 (GNUNET_TIME_UNIT_MILLISECONDS, 250),
191 GNUNET_NO);
192 GNUNET_assert (server != NULL);
193 handlers[0].callback_cls = cls;
194 GNUNET_SERVER_add_handlers (server, handlers);
195 GNUNET_SERVER_disconnect_notify (server, &notify_disconnect, cls);
196 cfg = GNUNET_CONFIGURATION_create ();
197 GNUNET_CONFIGURATION_set_value_number (cfg, "test", "PORT", PORT);
198 GNUNET_CONFIGURATION_set_value_string (cfg, "test", "HOSTNAME",
199 "localhost");
200 client = GNUNET_CLIENT_connect (tc->sched, "test", cfg);
201 GNUNET_assert (client != NULL);
202 GNUNET_CLIENT_notify_transmit_ready (client,
203 256,
204 GNUNET_TIME_relative_multiply
205 (GNUNET_TIME_UNIT_MILLISECONDS, 250),
206 &notify_ready, NULL);
207}
208
209
210/**
211 * Main method, starts scheduler with task1,
212 * checks that "ok" is correct at the end.
213 */
214static int
215check ()
216{
217
218 ok = 1;
219 GNUNET_SCHEDULER_run (&task, NULL);
220 return ok;
221}
222
223
224int
225main (int argc, char *argv[])
226{
227 int ret = 0;
228
229 GNUNET_log_setup ("test_server_disconnect",
230#if VERBOSE
231 "DEBUG",
232#else
233 "WARNING",
234#endif
235 NULL);
236 ret += check ();
237
238 return ret;
239}
240
241/* end of test_server_disconnect.c */