aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/Makefile.am13
-rw-r--r--src/util/mq.c481
-rw-r--r--src/util/test_mq.c114
-rw-r--r--src/util/test_mq_client.c171
4 files changed, 779 insertions, 0 deletions
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index ac855c25e..491006a42 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -90,6 +90,7 @@ libgnunetutil_la_SOURCES = \
90 getopt_helpers.c \ 90 getopt_helpers.c \
91 helper.c \ 91 helper.c \
92 load.c \ 92 load.c \
93 mq.c \
93 network.c \ 94 network.c \
94 os_installation.c \ 95 os_installation.c \
95 os_network.c \ 96 os_network.c \
@@ -230,6 +231,8 @@ check_PROGRAMS = \
230 test_connection_timeout \ 231 test_connection_timeout \
231 test_connection_timeout_no_connect \ 232 test_connection_timeout_no_connect \
232 test_connection_transmit_cancel \ 233 test_connection_transmit_cancel \
234 test_mq \
235 test_mq_client \
233 test_os_network \ 236 test_os_network \
234 test_os_priority \ 237 test_os_priority \
235 test_peer \ 238 test_peer \
@@ -416,6 +419,16 @@ test_connection_transmit_cancel_SOURCES = \
416test_connection_transmit_cancel_LDADD = \ 419test_connection_transmit_cancel_LDADD = \
417 $(top_builddir)/src/util/libgnunetutil.la 420 $(top_builddir)/src/util/libgnunetutil.la
418 421
422test_mq_SOURCES = \
423 test_mq.c
424test_mq_LDADD = \
425 $(top_builddir)/src/util/libgnunetutil.la
426
427test_mq_client_SOURCES = \
428 test_mq_client.c
429test_mq_client_LDADD = \
430 $(top_builddir)/src/util/libgnunetutil.la
431
419test_os_network_SOURCES = \ 432test_os_network_SOURCES = \
420 test_os_network.c 433 test_os_network.c
421test_os_network_LDADD = \ 434test_os_network_LDADD = \
diff --git a/src/util/mq.c b/src/util/mq.c
new file mode 100644
index 000000000..36cacd30b
--- /dev/null
+++ b/src/util/mq.c
@@ -0,0 +1,481 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012 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/**
22 * @author Florian Dold
23 * @file util/mq.c
24 * @brief general purpose request queue
25 */
26
27#include "platform.h"
28#include "gnunet_common.h"
29#include "gnunet_util_lib.h"
30
31#define LOG(kind,...) GNUNET_log_from (kind, "mq",__VA_ARGS__)
32
33
34
35struct ServerClientSocketState
36{
37 struct GNUNET_SERVER_Client *client;
38 struct GNUNET_SERVER_TransmitHandle* th;
39};
40
41
42struct ClientConnectionState
43{
44 /**
45 * Did we call receive?
46 */
47 int receive_active;
48 struct GNUNET_CLIENT_Connection *connection;
49 struct GNUNET_CLIENT_TransmitHandle *th;
50};
51
52
53
54
55/**
56 * Call the right callback for a message.
57 *
58 * @param mq message queue with the handlers
59 * @param mh message to dispatch
60 */
61void
62GNUNET_MQ_dispatch (struct GNUNET_MQ_MessageQueue *mq, const struct GNUNET_MessageHeader *mh)
63{
64 const struct GNUNET_MQ_Handler *handler;
65 int handled = GNUNET_NO;
66
67 handler = mq->handlers;
68 if (NULL == handler)
69 return;
70 for (; NULL != handler->cb; handler++)
71 {
72 if (handler->type == ntohs (mh->type))
73 {
74 handler->cb (mq->handlers_cls, mh);
75 handled = GNUNET_YES;
76 }
77 }
78
79 if (GNUNET_NO == handled)
80 LOG (GNUNET_ERROR_TYPE_WARNING, "no handler for message of type %d\n", ntohs (mh->type));
81}
82
83
84void
85GNUNET_MQ_discard (struct GNUNET_MQ_Message *mqm)
86{
87 GNUNET_assert (NULL == mqm->parent_queue);
88 GNUNET_free (mqm);
89}
90
91
92/**
93 * Send a message with the give message queue.
94 * May only be called once per message.
95 *
96 * @param mq message queue
97 * @param mqm the message to send.
98 */
99void
100GNUNET_MQ_send (struct GNUNET_MQ_MessageQueue *mq, struct GNUNET_MQ_Message *mqm)
101{
102 GNUNET_assert (NULL != mq);
103 mq->send_impl (mq, mqm);
104}
105
106
107struct GNUNET_MQ_Message *
108GNUNET_MQ_msg_ (struct GNUNET_MessageHeader **mhp, uint16_t size, uint16_t type)
109{
110 struct GNUNET_MQ_Message *mqm;
111
112 mqm = GNUNET_malloc (sizeof *mqm + size);
113 mqm->mh = (struct GNUNET_MessageHeader *) &mqm[1];
114 mqm->mh->size = htons (size);
115 mqm->mh->type = htons (type);
116 if (NULL != mhp)
117 *mhp = mqm->mh;
118 return mqm;
119}
120
121
122int
123GNUNET_MQ_nest_ (struct GNUNET_MQ_Message **mqmp,
124 const void *data, uint16_t len)
125{
126 size_t new_size;
127 size_t old_size;
128
129 GNUNET_assert (NULL != mqmp);
130 /* there's no data to append => do nothing */
131 if (NULL == data)
132 return GNUNET_OK;
133 old_size = ntohs ((*mqmp)->mh->size);
134 /* message too large to concatenate? */
135 if (((uint16_t) (old_size + len)) < len)
136 return GNUNET_SYSERR;
137 new_size = old_size + len;
138 *mqmp = GNUNET_realloc (*mqmp, sizeof (struct GNUNET_MQ_Message) + new_size);
139 (*mqmp)->mh = (struct GNUNET_MessageHeader *) &(*mqmp)[1];
140 memcpy (((void *) (*mqmp)->mh) + old_size, data, new_size - old_size);
141 (*mqmp)->mh->size = htons (new_size);
142 return GNUNET_OK;
143}
144
145
146
147
148/*** Transmit a queued message to the session's client.
149 *
150 * @param cls consensus session
151 * @param size number of bytes available in buf
152 * @param buf where the callee should write the message
153 * @return number of bytes written to buf
154 */
155static size_t
156transmit_queued (void *cls, size_t size,
157 void *buf)
158{
159 struct GNUNET_MQ_MessageQueue *mq = cls;
160 struct GNUNET_MQ_Message *mqm = mq->current_msg;
161 struct ServerClientSocketState *state = mq->impl_state;
162 size_t msg_size;
163
164 GNUNET_assert (NULL != buf);
165
166 if (NULL != mqm->sent_cb)
167 {
168 mqm->sent_cb (mqm->sent_cls);
169 }
170
171 mq->current_msg = NULL;
172 GNUNET_assert (NULL != mqm);
173 msg_size = ntohs (mqm->mh->size);
174 GNUNET_assert (size >= msg_size);
175 memcpy (buf, mqm->mh, msg_size);
176 GNUNET_free (mqm);
177 state->th = NULL;
178
179 if (NULL != mq->msg_head)
180 {
181 mq->current_msg = mq->msg_head;
182 GNUNET_CONTAINER_DLL_remove (mq->msg_head, mq->msg_tail, mq->current_msg);
183 state->th =
184 GNUNET_SERVER_notify_transmit_ready (state->client, msg_size,
185 GNUNET_TIME_UNIT_FOREVER_REL,
186 &transmit_queued, mq);
187 }
188 return msg_size;
189}
190
191
192
193static void
194server_client_destroy_impl (struct GNUNET_MQ_MessageQueue *mq)
195{
196 struct ServerClientSocketState *state;
197
198 GNUNET_assert (NULL != mq);
199 state = mq->impl_state;
200 GNUNET_assert (NULL != state);
201 GNUNET_SERVER_client_drop (state->client);
202 GNUNET_free (state);
203}
204
205static void
206server_client_send_impl (struct GNUNET_MQ_MessageQueue *mq, struct GNUNET_MQ_Message *mqm)
207{
208 struct ServerClientSocketState *state;
209 int msize;
210
211 GNUNET_assert (NULL != mq);
212 state = mq->impl_state;
213 GNUNET_assert (NULL != state);
214
215 if (NULL != state->th)
216 {
217 GNUNET_CONTAINER_DLL_insert_tail (mq->msg_head, mq->msg_tail, mqm);
218 return;
219 }
220 GNUNET_assert (NULL == mq->msg_head);
221 GNUNET_assert (NULL == mq->current_msg);
222 msize = ntohs (mqm->mh->size);
223 mq->current_msg = mqm;
224 state->th =
225 GNUNET_SERVER_notify_transmit_ready (state->client, msize,
226 GNUNET_TIME_UNIT_FOREVER_REL,
227 &transmit_queued, mq);
228}
229
230
231struct GNUNET_MQ_MessageQueue *
232GNUNET_MQ_queue_for_server_client (struct GNUNET_SERVER_Client *client)
233{
234 struct GNUNET_MQ_MessageQueue *mq;
235 struct ServerClientSocketState *scss;
236
237 mq = GNUNET_new (struct GNUNET_MQ_MessageQueue);
238 scss = GNUNET_new (struct ServerClientSocketState);
239 mq->impl_state = scss;
240 scss->client = client;
241 GNUNET_SERVER_client_keep (client);
242 mq->send_impl = server_client_send_impl;
243 mq->destroy_impl = server_client_destroy_impl;
244 return mq;
245}
246
247
248/**
249 * Type of a function to call when we receive a message
250 * from the service.
251 *
252 * @param cls closure
253 * @param msg message received, NULL on timeout or fatal error
254 */
255static void
256handle_client_message (void *cls,
257 const struct GNUNET_MessageHeader *msg)
258{
259 struct GNUNET_MQ_MessageQueue *mq = cls;
260 struct ClientConnectionState *state;
261
262 state = mq->impl_state;
263
264 if (NULL == msg)
265 {
266 if (NULL == mq->error_handler)
267 LOG (GNUNET_ERROR_TYPE_WARNING, "ignoring read error (no handler installed)\n");
268 mq->error_handler (mq->handlers_cls, GNUNET_MQ_ERROR_READ);
269 return;
270 }
271
272 GNUNET_CLIENT_receive (state->connection, handle_client_message, mq,
273 GNUNET_TIME_UNIT_FOREVER_REL);
274
275 GNUNET_MQ_dispatch (mq, msg);
276}
277
278
279/**
280 * Transmit a queued message to the session's client.
281 *
282 * @param cls consensus session
283 * @param size number of bytes available in buf
284 * @param buf where the callee should write the message
285 * @return number of bytes written to buf
286 */
287static size_t
288connection_client_transmit_queued (void *cls, size_t size,
289 void *buf)
290{
291 struct GNUNET_MQ_MessageQueue *mq = cls;
292 struct GNUNET_MQ_Message *mqm = mq->current_msg;
293 struct ClientConnectionState *state = mq->impl_state;
294 size_t msg_size;
295
296 if (NULL == buf)
297 {
298 if (NULL == mq->error_handler)
299 {
300 LOG (GNUNET_ERROR_TYPE_WARNING, "read error, but no error handler installed\n");
301 return 0;
302 }
303 mq->error_handler (mq->handlers_cls, GNUNET_MQ_ERROR_READ);
304 return 0;
305 }
306
307 if ((NULL != mq->handlers) && (GNUNET_NO == state->receive_active))
308 {
309 state->receive_active = GNUNET_YES;
310 GNUNET_CLIENT_receive (state->connection, handle_client_message, mq,
311 GNUNET_TIME_UNIT_FOREVER_REL);
312 }
313
314
315 GNUNET_assert (NULL != mqm);
316
317 if (NULL != mqm->sent_cb)
318 {
319 mqm->sent_cb (mqm->sent_cls);
320 }
321
322 mq->current_msg = NULL;
323 GNUNET_assert (NULL != buf);
324 msg_size = ntohs (mqm->mh->size);
325 GNUNET_assert (size >= msg_size);
326 memcpy (buf, mqm->mh, msg_size);
327 GNUNET_free (mqm);
328 state->th = NULL;
329 if (NULL != mq->msg_head)
330 {
331 mq->current_msg = mq->msg_head;
332 GNUNET_CONTAINER_DLL_remove (mq->msg_head, mq->msg_tail, mq->current_msg);
333 state->th =
334 GNUNET_CLIENT_notify_transmit_ready (state->connection, ntohs (mq->current_msg->mh->size),
335 GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO,
336 &connection_client_transmit_queued, mq);
337 }
338 return msg_size;
339}
340
341
342
343static void
344connection_client_destroy_impl (struct GNUNET_MQ_MessageQueue *mq)
345{
346 GNUNET_free (mq->impl_state);
347}
348
349static void
350connection_client_send_impl (struct GNUNET_MQ_MessageQueue *mq,
351 struct GNUNET_MQ_Message *mqm)
352{
353 struct ClientConnectionState *state = mq->impl_state;
354 int msize;
355
356 GNUNET_assert (NULL != state);
357
358 if (NULL != state->th)
359 {
360 GNUNET_CONTAINER_DLL_insert_tail (mq->msg_head, mq->msg_tail, mqm);
361 return;
362 }
363 GNUNET_assert (NULL == mq->current_msg);
364 mq->current_msg = mqm;
365 msize = ntohs (mqm->mh->size);
366 state->th =
367 GNUNET_CLIENT_notify_transmit_ready (state->connection, msize,
368 GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO,
369 &connection_client_transmit_queued, mq);
370}
371
372
373
374
375
376struct GNUNET_MQ_MessageQueue *
377GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection *connection,
378 const struct GNUNET_MQ_Handler *handlers,
379 void *cls)
380{
381 struct GNUNET_MQ_MessageQueue *mq;
382 struct ClientConnectionState *state;
383
384 GNUNET_assert (NULL != connection);
385
386 mq = GNUNET_new (struct GNUNET_MQ_MessageQueue);
387 mq->handlers = handlers;
388 mq->handlers_cls = cls;
389 state = GNUNET_new (struct ClientConnectionState);
390 state->connection = connection;
391 mq->impl_state = state;
392 mq->send_impl = connection_client_send_impl;
393 mq->destroy_impl = connection_client_destroy_impl;
394
395 return mq;
396}
397
398
399void
400GNUNET_MQ_replace_handlers (struct GNUNET_MQ_MessageQueue *mq,
401 const struct GNUNET_MQ_Handler *new_handlers,
402 void *cls)
403{
404 mq->handlers = new_handlers;
405 mq->handlers_cls = cls;
406}
407
408
409/**
410 * Associate the assoc_data in mq with a unique request id.
411 *
412 * @param mq message queue, id will be unique for the queue
413 * @param mqm message to associate
414 * @param assoc_data to associate
415 */
416uint32_t
417GNUNET_MQ_assoc_add (struct GNUNET_MQ_MessageQueue *mq,
418 struct GNUNET_MQ_Message *mqm,
419 void *assoc_data)
420{
421 uint32_t id;
422
423 if (NULL == mq->assoc_map)
424 {
425 mq->assoc_map = GNUNET_CONTAINER_multihashmap32_create (8);
426 mq->assoc_id = 1;
427 }
428 id = mq->assoc_id++;
429 GNUNET_CONTAINER_multihashmap32_put (mq->assoc_map, id, assoc_data,
430 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
431 return id;
432}
433
434
435
436void *
437GNUNET_MQ_assoc_get (struct GNUNET_MQ_MessageQueue *mq, uint32_t request_id)
438{
439 if (NULL == mq->assoc_map)
440 return NULL;
441 return GNUNET_CONTAINER_multihashmap32_get (mq->assoc_map, request_id);
442}
443
444
445void *
446GNUNET_MQ_assoc_remove (struct GNUNET_MQ_MessageQueue *mq, uint32_t request_id)
447{
448 void *val;
449
450 if (NULL == mq->assoc_map)
451 return NULL;
452 val = GNUNET_CONTAINER_multihashmap32_get (mq->assoc_map, request_id);
453 GNUNET_assert (NULL != val);
454 GNUNET_CONTAINER_multihashmap32_remove (mq->assoc_map, request_id, val);
455 return val;
456}
457
458
459void
460GNUNET_MQ_notify_sent (struct GNUNET_MQ_Message *mqm,
461 GNUNET_MQ_NotifyCallback cb,
462 void *cls)
463{
464 mqm->sent_cb = cb;
465 mqm->sent_cls = cls;
466}
467
468
469void
470GNUNET_MQ_destroy (struct GNUNET_MQ_MessageQueue *mq)
471{
472 /* FIXME: destroy all pending messages in the queue */
473
474 if (NULL != mq->destroy_impl)
475 {
476 mq->destroy_impl (mq);
477 }
478
479 GNUNET_free (mq);
480}
481
diff --git a/src/util/test_mq.c b/src/util/test_mq.c
new file mode 100644
index 000000000..161b40a20
--- /dev/null
+++ b/src/util/test_mq.c
@@ -0,0 +1,114 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012 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 3, 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/**
22 * @file set/test_mq.c
23 * @brief simple tests for mq
24 */
25#include "platform.h"
26#include "gnunet_util_lib.h"
27#include "gnunet_testing_lib.h"
28
29
30GNUNET_NETWORK_STRUCT_BEGIN
31
32struct MyMessage
33{
34 struct GNUNET_MessageHeader header;
35 uint32_t x GNUNET_PACKED;
36};
37
38GNUNET_NETWORK_STRUCT_END
39
40void
41test1 (void)
42{
43 struct GNUNET_MQ_Message *mqm;
44 struct MyMessage *mm;
45
46 mm = NULL;
47 mqm = NULL;
48
49 mqm = GNUNET_MQ_msg (mm, 42);
50 GNUNET_assert (NULL != mqm);
51 GNUNET_assert (NULL != mm);
52 GNUNET_assert (42 == ntohs (mm->header.type));
53 GNUNET_assert (sizeof (struct MyMessage) == ntohs (mm->header.size));
54}
55
56
57void
58test2 (void)
59{
60 struct GNUNET_MQ_Message *mqm;
61 struct MyMessage *mm;
62 int res;
63 char *s = "foo";
64
65 mqm = GNUNET_MQ_msg (mm, 42);
66 res = GNUNET_MQ_nest (mqm, s, strlen(s));
67 GNUNET_assert (GNUNET_OK == res);
68 res = GNUNET_MQ_nest (mqm, s, strlen(s));
69 GNUNET_assert (GNUNET_OK == res);
70 res = GNUNET_MQ_nest (mqm, NULL, 0);
71 GNUNET_assert (GNUNET_OK == res);
72
73 GNUNET_assert (strlen (s) * 2 + sizeof (struct MyMessage) == ntohs (mm->header.size));
74
75 res = GNUNET_MQ_nest_mh (mqm, &mm->header);
76 GNUNET_assert (GNUNET_OK == res);
77 GNUNET_assert (2 * (strlen (s) * 2 + sizeof (struct MyMessage)) == ntohs (mm->header.size));
78
79 res = GNUNET_MQ_nest (mqm, (void *) 0xF00BA, 0xFFF0);
80 GNUNET_assert (GNUNET_OK != res);
81
82 GNUNET_MQ_discard (mqm);
83}
84
85
86void
87test3 (void)
88{
89 struct GNUNET_MQ_Message *mqm;
90 struct GNUNET_MessageHeader *mh;
91
92 mqm = GNUNET_MQ_msg_header (42);
93 /* how could the above be checked? */
94
95 GNUNET_MQ_discard (mqm);
96
97 mqm = GNUNET_MQ_msg_header_extra (mh, 20, 42);
98 GNUNET_assert (42 == ntohs (mh->type));
99 GNUNET_assert (sizeof (struct GNUNET_MessageHeader) + 20 == ntohs (mh->size));
100}
101
102
103int
104main (int argc, char **argv)
105{
106
107 GNUNET_log_setup ("test-mq", "INFO", NULL);
108 test1 ();
109 test2 ();
110 test3 ();
111
112 return 0;
113}
114
diff --git a/src/util/test_mq_client.c b/src/util/test_mq_client.c
new file mode 100644
index 000000000..b7eb1516a
--- /dev/null
+++ b/src/util/test_mq_client.c
@@ -0,0 +1,171 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012 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 3, 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/**
22 * @file util/test_mq_client.c
23 * @brief tests for mq with connection client
24 */
25#include "platform.h"
26#include "gnunet_common.h"
27#include "gnunet_util_lib.h"
28
29#define PORT 23336
30
31#define MY_TYPE 128
32
33
34static struct GNUNET_SERVER_Handle *server;
35
36static struct GNUNET_CLIENT_Connection *client;
37
38static struct GNUNET_CONFIGURATION_Handle *cfg;
39
40static int ok;
41
42static int notify = GNUNET_NO;
43
44static int received = 0;
45
46
47static void
48recv_cb (void *cls, struct GNUNET_SERVER_Client *argclient,
49 const struct GNUNET_MessageHeader *message)
50{
51 received++;
52
53 printf ("received\n");
54
55
56 if ((received == 2) && (GNUNET_YES == notify))
57 {
58 printf ("done\n");
59 GNUNET_SERVER_receive_done (argclient, GNUNET_NO);
60 return;
61 }
62
63 GNUNET_SERVER_receive_done (argclient, GNUNET_YES);
64}
65
66
67static void
68clean_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
69{
70 GNUNET_SERVER_destroy (server);
71 server = NULL;
72 GNUNET_CONFIGURATION_destroy (cfg);
73 cfg = NULL;
74}
75
76
77/**
78 * Functions with this signature are called whenever a client
79 * is disconnected on the network level.
80 *
81 * @param cls closure
82 * @param client identification of the client
83 */
84static void
85notify_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
86{
87 if (client == NULL)
88 return;
89 ok = 0;
90 GNUNET_SCHEDULER_add_now (&clean_up, NULL);
91}
92
93
94static struct GNUNET_SERVER_MessageHandler handlers[] = {
95 {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)},
96 {NULL, NULL, 0, 0}
97};
98
99void send_cb (void *cls)
100{
101 printf ("notify sent\n");
102 notify = GNUNET_YES;
103}
104
105void test_mq (struct GNUNET_CLIENT_Connection *client)
106{
107 struct GNUNET_MQ_MessageQueue *mq;
108 struct GNUNET_MQ_Message *mqm;
109
110 /* FIXME: test handling responses */
111 mq = GNUNET_MQ_queue_for_connection_client (client, NULL, NULL);
112
113 mqm = GNUNET_MQ_msg_header (MY_TYPE);
114 GNUNET_MQ_send (mq, mqm);
115
116 mqm = GNUNET_MQ_msg_header (MY_TYPE);
117 GNUNET_MQ_notify_sent (mqm, send_cb, NULL);
118 GNUNET_MQ_send (mq, mqm);
119
120 /* FIXME: add a message that will be canceled */
121}
122
123
124static void
125task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
126{
127 struct sockaddr_in sa;
128 struct sockaddr *sap[2];
129 socklen_t slens[2];
130
131 sap[0] = (struct sockaddr *) &sa;
132 slens[0] = sizeof (sa);
133 sap[1] = NULL;
134 slens[1] = 0;
135 memset (&sa, 0, sizeof (sa));
136#if HAVE_SOCKADDR_IN_SIN_LEN
137 sa.sin_len = sizeof (sa);
138#endif
139 sa.sin_family = AF_INET;
140 sa.sin_port = htons (PORT);
141 server =
142 GNUNET_SERVER_create (NULL, NULL, sap, slens,
143 GNUNET_TIME_relative_multiply
144 (GNUNET_TIME_UNIT_MILLISECONDS, 250), GNUNET_NO);
145 GNUNET_assert (server != NULL);
146 handlers[0].callback_cls = cls;
147 GNUNET_SERVER_add_handlers (server, handlers);
148 GNUNET_SERVER_disconnect_notify (server, &notify_disconnect, cls);
149 cfg = GNUNET_CONFIGURATION_create ();
150 GNUNET_CONFIGURATION_set_value_number (cfg, "test", "PORT", PORT);
151 GNUNET_CONFIGURATION_set_value_string (cfg, "test", "HOSTNAME", "localhost");
152 GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME",
153 "localhost");
154 client = GNUNET_CLIENT_connect ("test", cfg);
155 GNUNET_assert (client != NULL);
156
157 test_mq (client);
158}
159
160
161int
162main (int argc, char *argv[])
163{
164 GNUNET_log_setup ("test-mq-client",
165 "INFO",
166 NULL);
167 ok = 1;
168 GNUNET_SCHEDULER_run (&task, NULL);
169 return ok;
170}
171