aboutsummaryrefslogtreecommitdiff
path: root/src/peerinfo
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-05-03 09:24:06 +0000
committerChristian Grothoff <christian@grothoff.org>2012-05-03 09:24:06 +0000
commit3fa11d0813d624a080039bb65786100ae626f854 (patch)
tree0c909d65e60bf35d57e1647d4f1df1ddd379549e /src/peerinfo
parent115e8f7ff84e503ce97ea1f985c1474c866eb6d4 (diff)
downloadgnunet-3fa11d0813d624a080039bb65786100ae626f854.tar.gz
gnunet-3fa11d0813d624a080039bb65786100ae626f854.zip
-fixing #2298
Diffstat (limited to 'src/peerinfo')
-rw-r--r--src/peerinfo/peerinfo_api.c319
1 files changed, 182 insertions, 137 deletions
diff --git a/src/peerinfo/peerinfo_api.c b/src/peerinfo/peerinfo_api.c
index 5eb58af44..4564df727 100644
--- a/src/peerinfo/peerinfo_api.c
+++ b/src/peerinfo/peerinfo_api.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2001, 2002, 2004, 2005, 2007, 2009, 2010 Christian Grothoff (and other contributing authors) 3 (C) 2001, 2002, 2004, 2005, 2007, 2009, 2010, 2012 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
@@ -31,7 +31,7 @@
31#include "gnunet_time_lib.h" 31#include "gnunet_time_lib.h"
32#include "peerinfo.h" 32#include "peerinfo.h"
33 33
34#define LOG(kind,...) GNUNET_log_from (kind, "nse-api",__VA_ARGS__) 34#define LOG(kind,...) GNUNET_log_from (kind, "peerinfo-api",__VA_ARGS__)
35 35
36/** 36/**
37 * Function to call after transmission has succeeded. 37 * Function to call after transmission has succeeded.
@@ -69,15 +69,63 @@ struct TransmissionQueueEntry
69 void *cont_cls; 69 void *cont_cls;
70 70
71 /** 71 /**
72 * Number of bytes of the request message (follows after this struct).
73 */
74 size_t size;
75
76};
77
78
79/**
80 * Context for an iteration request.
81 */
82struct GNUNET_PEERINFO_IteratorContext
83{
84
85 /**
86 * Kept in a DLL.
87 */
88 struct GNUNET_PEERINFO_IteratorContext *next;
89
90 /**
91 * Kept in a DLL.
92 */
93 struct GNUNET_PEERINFO_IteratorContext *prev;
94
95 /**
96 * Handle to the PEERINFO service.
97 */
98 struct GNUNET_PEERINFO_Handle *h;
99
100 /**
101 * Function to call with the results.
102 */
103 GNUNET_PEERINFO_Processor callback;
104
105 /**
106 * Closure for 'callback'.
107 */
108 void *callback_cls;
109
110 /**
111 * Our entry in the transmission queue.
112 */
113 struct TransmissionQueueEntry *tqe;
114
115 /**
116 * Task responsible for timeout.
117 */
118 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
119
120 /**
72 * Timeout for the operation. 121 * Timeout for the operation.
73 */ 122 */
74 struct GNUNET_TIME_Absolute timeout; 123 struct GNUNET_TIME_Absolute timeout;
75 124
76 /** 125 /**
77 * Number of bytes of the request message (follows after this struct). 126 * Are we now receiving?
78 */ 127 */
79 size_t size; 128 int in_receive;
80
81}; 129};
82 130
83 131
@@ -112,6 +160,16 @@ struct GNUNET_PEERINFO_Handle
112 struct GNUNET_CLIENT_TransmitHandle *th; 160 struct GNUNET_CLIENT_TransmitHandle *th;
113 161
114 /** 162 /**
163 * Head of iterator DLL.
164 */
165 struct GNUNET_PEERINFO_IteratorContext *ic_head;
166
167 /**
168 * Tail of iterator DLL.
169 */
170 struct GNUNET_PEERINFO_IteratorContext *ic_tail;
171
172 /**
115 * ID for a reconnect task. 173 * ID for a reconnect task.
116 */ 174 */
117 GNUNET_SCHEDULER_TaskIdentifier r_task; 175 GNUNET_SCHEDULER_TaskIdentifier r_task;
@@ -135,12 +193,12 @@ struct GNUNET_PEERINFO_Handle
135struct GNUNET_PEERINFO_Handle * 193struct GNUNET_PEERINFO_Handle *
136GNUNET_PEERINFO_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) 194GNUNET_PEERINFO_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
137{ 195{
138 struct GNUNET_PEERINFO_Handle *ret; 196 struct GNUNET_PEERINFO_Handle *h;
139 197
140 ret = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_Handle)); 198 h = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_Handle));
141 ret->client = GNUNET_CLIENT_connect ("peerinfo", cfg); 199 h->client = GNUNET_CLIENT_connect ("peerinfo", cfg);
142 ret->cfg = cfg; 200 h->cfg = cfg;
143 return ret; 201 return h;
144} 202}
145 203
146 204
@@ -157,7 +215,14 @@ void
157GNUNET_PEERINFO_disconnect (struct GNUNET_PEERINFO_Handle *h) 215GNUNET_PEERINFO_disconnect (struct GNUNET_PEERINFO_Handle *h)
158{ 216{
159 struct TransmissionQueueEntry *tqe; 217 struct TransmissionQueueEntry *tqe;
218 struct GNUNET_PEERINFO_IteratorContext *ic;
160 219
220 while (NULL != (ic = h->ic_head))
221 {
222 GNUNET_break (GNUNET_YES == ic->in_receive);
223 ic->in_receive = GNUNET_NO;
224 GNUNET_PEERINFO_iterate_cancel (ic);
225 }
161 while (NULL != (tqe = h->tq_head)) 226 while (NULL != (tqe = h->tq_head))
162 { 227 {
163 GNUNET_CONTAINER_DLL_remove (h->tq_head, h->tq_tail, tqe); 228 GNUNET_CONTAINER_DLL_remove (h->tq_head, h->tq_tail, tqe);
@@ -165,7 +230,7 @@ GNUNET_PEERINFO_disconnect (struct GNUNET_PEERINFO_Handle *h)
165 tqe->cont (tqe->cont_cls, GNUNET_SYSERR); 230 tqe->cont (tqe->cont_cls, GNUNET_SYSERR);
166 GNUNET_free (tqe); 231 GNUNET_free (tqe);
167 } 232 }
168 if (h->th != NULL) 233 if (NULL != h->th)
169 { 234 {
170 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); 235 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
171 h->th = NULL; 236 h->th = NULL;
@@ -202,6 +267,7 @@ trigger_transmit (struct GNUNET_PEERINFO_Handle *h);
202static void 267static void
203reconnect (struct GNUNET_PEERINFO_Handle *h); 268reconnect (struct GNUNET_PEERINFO_Handle *h);
204 269
270
205/** 271/**
206 * Task scheduled to re-try connecting to the peerinfo service. 272 * Task scheduled to re-try connecting to the peerinfo service.
207 * 273 *
@@ -226,7 +292,7 @@ reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
226static void 292static void
227reconnect (struct GNUNET_PEERINFO_Handle *h) 293reconnect (struct GNUNET_PEERINFO_Handle *h)
228{ 294{
229 if (h->r_task != GNUNET_SCHEDULER_NO_TASK) 295 if (GNUNET_SCHEDULER_NO_TASK != h->r_task)
230 { 296 {
231 GNUNET_SCHEDULER_cancel (h->r_task); 297 GNUNET_SCHEDULER_cancel (h->r_task);
232 h->r_task = GNUNET_SCHEDULER_NO_TASK; 298 h->r_task = GNUNET_SCHEDULER_NO_TASK;
@@ -241,6 +307,7 @@ reconnect (struct GNUNET_PEERINFO_Handle *h)
241 GNUNET_CLIENT_disconnect (h->client); 307 GNUNET_CLIENT_disconnect (h->client);
242 h->client = NULL; 308 h->client = NULL;
243 } 309 }
310 h->in_receive = GNUNET_NO;
244 h->client = GNUNET_CLIENT_connect ("peerinfo", h->cfg); 311 h->client = GNUNET_CLIENT_connect ("peerinfo", h->cfg);
245 if (NULL == h->client) 312 if (NULL == h->client)
246 { 313 {
@@ -270,26 +337,32 @@ do_transmit (void *cls, size_t size, void *buf)
270 size_t ret; 337 size_t ret;
271 338
272 h->th = NULL; 339 h->th = NULL;
273 if (tqe == NULL) 340 if (NULL == tqe)
274 return 0; 341 return 0; /* request was cancelled in the meantime */
275 if (buf == NULL) 342 if (NULL == buf)
276 { 343 {
344 /* peerinfo service died */
277 LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 345 LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
278 _("Failed to transmit message to `%s' service.\n"), "PEERINFO"); 346 "Failed to transmit message to `%s' service.\n", "PEERINFO");
279 GNUNET_CONTAINER_DLL_remove (h->tq_head, h->tq_tail, tqe); 347 GNUNET_CONTAINER_DLL_remove (h->tq_head, h->tq_tail, tqe);
280 reconnect (h); 348 reconnect (h);
281 if (tqe->cont != NULL) 349 if (NULL != tqe->cont)
282 tqe->cont (tqe->cont_cls, GNUNET_SYSERR); 350 tqe->cont (tqe->cont_cls, GNUNET_SYSERR);
283 GNUNET_free (tqe); 351 GNUNET_free (tqe);
284 return 0; 352 return 0;
285 } 353 }
286 ret = tqe->size; 354 ret = tqe->size;
287 GNUNET_assert (size >= ret); 355 if (size < ret)
288 memcpy (buf, &tqe[1], ret); 356 {
357 /* change in head of queue (i.e. cancel + add), try again */
358 trigger_transmit (h);
359 return 0;
360 }
289 LOG (GNUNET_ERROR_TYPE_DEBUG, 361 LOG (GNUNET_ERROR_TYPE_DEBUG,
290 "Transmitting request of size %u to `%s' service.\n", ret, "PEERINFO"); 362 "Transmitting request of size %u to `%s' service.\n", ret, "PEERINFO");
363 memcpy (buf, &tqe[1], ret);
291 GNUNET_CONTAINER_DLL_remove (h->tq_head, h->tq_tail, tqe); 364 GNUNET_CONTAINER_DLL_remove (h->tq_head, h->tq_tail, tqe);
292 if (tqe->cont != NULL) 365 if (NULL != tqe->cont)
293 tqe->cont (tqe->cont_cls, GNUNET_OK); 366 tqe->cont (tqe->cont_cls, GNUNET_OK);
294 else 367 else
295 trigger_transmit (h); 368 trigger_transmit (h);
@@ -310,21 +383,22 @@ trigger_transmit (struct GNUNET_PEERINFO_Handle *h)
310 struct TransmissionQueueEntry *tqe; 383 struct TransmissionQueueEntry *tqe;
311 384
312 if (NULL == (tqe = h->tq_head)) 385 if (NULL == (tqe = h->tq_head))
313 return; 386 return; /* no requests queued */
314 if (h->th != NULL) 387 if (NULL != h->th)
315 return; 388 return; /* request already pending */
316 if (h->in_receive == GNUNET_YES) 389 if (GNUNET_YES == h->in_receive)
317 return; 390 return; /* still reading replies from last request */
318 if (NULL == h->client) 391 if (NULL == h->client)
319 { 392 {
393 /* disconnected, try to reconnect */
320 reconnect (h); 394 reconnect (h);
321 return; 395 return;
322 } 396 }
323 h->th = 397 h->th =
324 GNUNET_CLIENT_notify_transmit_ready (h->client, tqe->size, 398 GNUNET_CLIENT_notify_transmit_ready (h->client, tqe->size,
325 GNUNET_TIME_absolute_get_remaining 399 GNUNET_TIME_UNIT_FOREVER_REL,
326 (tqe->timeout), GNUNET_YES, 400 GNUNET_YES,
327 &do_transmit, h); 401 &do_transmit, h);
328} 402}
329 403
330 404
@@ -353,7 +427,6 @@ GNUNET_PEERINFO_add_peer (struct GNUNET_PEERINFO_Handle *h,
353 GNUNET_i2s (&peer), hs, "HELLO"); 427 GNUNET_i2s (&peer), hs, "HELLO");
354 tqe = GNUNET_malloc (sizeof (struct TransmissionQueueEntry) + hs); 428 tqe = GNUNET_malloc (sizeof (struct TransmissionQueueEntry) + hs);
355 tqe->size = hs; 429 tqe->size = hs;
356 tqe->timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
357 memcpy (&tqe[1], hello, hs); 430 memcpy (&tqe[1], hello, hs);
358 GNUNET_CONTAINER_DLL_insert_after (h->tq_head, h->tq_tail, h->tq_tail, tqe); 431 GNUNET_CONTAINER_DLL_insert_after (h->tq_head, h->tq_tail, h->tq_tail, tqe);
359 trigger_transmit (h); 432 trigger_transmit (h);
@@ -361,50 +434,10 @@ GNUNET_PEERINFO_add_peer (struct GNUNET_PEERINFO_Handle *h,
361 434
362 435
363/** 436/**
364 * Context for an iteration request. 437 * Type of a function to call when we receive a message from the
365 */ 438 * service. Call the iterator with the result and (if applicable)
366struct GNUNET_PEERINFO_IteratorContext 439 * continue to receive more messages or trigger processing the next
367{ 440 * event (if applicable).
368 /**
369 * Handle to the PEERINFO service.
370 */
371 struct GNUNET_PEERINFO_Handle *h;
372
373 /**
374 * Function to call with the results.
375 */
376 GNUNET_PEERINFO_Processor callback;
377
378 /**
379 * Closure for 'callback'.
380 */
381 void *callback_cls;
382
383 /**
384 * Our entry in the transmission queue.
385 */
386 struct TransmissionQueueEntry *tqe;
387
388 /**
389 * Task responsible for timeout.
390 */
391 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
392
393 /**
394 * Timeout for the operation.
395 */
396 struct GNUNET_TIME_Absolute timeout;
397
398 /**
399 * Are we now receiving?
400 */
401 int in_receive;
402};
403
404
405/**
406 * Type of a function to call when we receive a message
407 * from the service.
408 * 441 *
409 * @param cls closure 442 * @param cls closure
410 * @param msg message received, NULL on timeout or fatal error 443 * @param msg message received, NULL on timeout or fatal error
@@ -413,46 +446,49 @@ static void
413peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg) 446peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg)
414{ 447{
415 struct GNUNET_PEERINFO_IteratorContext *ic = cls; 448 struct GNUNET_PEERINFO_IteratorContext *ic = cls;
449 struct GNUNET_PEERINFO_Handle *h = ic->h;
416 const struct InfoMessage *im; 450 const struct InfoMessage *im;
417 const struct GNUNET_HELLO_Message *hello; 451 const struct GNUNET_HELLO_Message *hello;
452 GNUNET_PEERINFO_Processor cb;
453 void *cb_cls;
418 uint16_t ms; 454 uint16_t ms;
419 455
420 ic->h->in_receive = GNUNET_NO; 456 h->in_receive = GNUNET_NO;
421 if (msg == NULL) 457 ic->in_receive = GNUNET_NO;
458 cb = ic->callback;
459 cb_cls = ic->callback_cls;
460 if (NULL == msg)
422 { 461 {
423 reconnect (ic->h); 462 /* peerinfo service died, signal error */
424 if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK) 463 GNUNET_PEERINFO_iterate_cancel (ic);
425 GNUNET_SCHEDULER_cancel (ic->timeout_task); 464 reconnect (h);
426 if (ic->callback != NULL) 465 if (NULL != cb)
427 ic->callback (ic->callback_cls, NULL, NULL, 466 cb (cb_cls, NULL, NULL,
428 _("Failed to receive response from `PEERINFO' service.")); 467 _("Failed to receive response from `PEERINFO' service."));
429 GNUNET_free (ic);
430 return; 468 return;
431 } 469 }
432 if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END) 470 if (GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END == ntohs (msg->type))
433 { 471 {
472 /* normal end of list of peers, signal end, process next pending request */
434 LOG (GNUNET_ERROR_TYPE_DEBUG, 473 LOG (GNUNET_ERROR_TYPE_DEBUG,
435 "Received end of list of peers from `%s' service\n", "PEERINFO"); 474 "Received end of list of peers from `%s' service\n", "PEERINFO");
436 trigger_transmit (ic->h); 475 GNUNET_PEERINFO_iterate_cancel (ic);
437 if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK) 476 trigger_transmit (h);
438 GNUNET_SCHEDULER_cancel (ic->timeout_task); 477 if (NULL != cb)
439 if (ic->callback != NULL) 478 cb (cb_cls, NULL, NULL, NULL);
440 ic->callback (ic->callback_cls, NULL, NULL, NULL);
441 GNUNET_free (ic);
442 return; 479 return;
443 } 480 }
444 ms = ntohs (msg->size); 481 ms = ntohs (msg->size);
445 if ((ms < sizeof (struct InfoMessage)) || 482 if ((ms < sizeof (struct InfoMessage)) ||
446 (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_PEERINFO_INFO)) 483 (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_PEERINFO_INFO))
447 { 484 {
485 /* malformed message */
448 GNUNET_break (0); 486 GNUNET_break (0);
449 reconnect (ic->h); 487 GNUNET_PEERINFO_iterate_cancel (ic);
450 if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK) 488 reconnect (h);
451 GNUNET_SCHEDULER_cancel (ic->timeout_task); 489 if (NULL != cb)
452 if (ic->callback != NULL) 490 cb (cb_cls, NULL, NULL,
453 ic->callback (ic->callback_cls, NULL, NULL, 491 _("Received invalid message from `PEERINFO' service."));
454 _("Received invalid message from `PEERINFO' service."));
455 GNUNET_free (ic);
456 return; 492 return;
457 } 493 }
458 im = (const struct InfoMessage *) msg; 494 im = (const struct InfoMessage *) msg;
@@ -463,26 +499,27 @@ peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg)
463 hello = (const struct GNUNET_HELLO_Message *) &im[1]; 499 hello = (const struct GNUNET_HELLO_Message *) &im[1];
464 if (ms != sizeof (struct InfoMessage) + GNUNET_HELLO_size (hello)) 500 if (ms != sizeof (struct InfoMessage) + GNUNET_HELLO_size (hello))
465 { 501 {
502 /* malformed message */
466 GNUNET_break (0); 503 GNUNET_break (0);
467 reconnect (ic->h); 504 GNUNET_PEERINFO_iterate_cancel (ic);
468 if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK) 505 reconnect (h);
469 GNUNET_SCHEDULER_cancel (ic->timeout_task); 506 if (NULL != cb)
470 if (ic->callback != NULL) 507 cb (cb_cls, NULL, NULL,
471 ic->callback (ic->callback_cls, NULL, NULL, 508 _("Received invalid message from `PEERINFO' service."));
472 _("Received invalid message from `PEERINFO' service."));
473 GNUNET_free (ic);
474 return; 509 return;
475 } 510 }
476 } 511 }
512 /* normal data message */
477 LOG (GNUNET_ERROR_TYPE_DEBUG, 513 LOG (GNUNET_ERROR_TYPE_DEBUG,
478 "Received %u bytes of `%s' information about peer `%s' from `%s' service\n", 514 "Received %u bytes of `%s' information about peer `%s' from `%s' service\n",
479 (hello == NULL) ? 0 : (unsigned int) GNUNET_HELLO_size (hello), "HELLO", 515 (hello == NULL) ? 0 : (unsigned int) GNUNET_HELLO_size (hello), "HELLO",
480 GNUNET_i2s (&im->peer), "PEERINFO"); 516 GNUNET_i2s (&im->peer), "PEERINFO");
481 ic->h->in_receive = GNUNET_YES; 517 h->in_receive = GNUNET_YES;
482 if (ic->callback != NULL) 518 ic->in_receive = GNUNET_YES;
483 ic->callback (ic->callback_cls, &im->peer, hello, NULL); 519 GNUNET_CLIENT_receive (h->client, &peerinfo_handler, ic,
484 GNUNET_CLIENT_receive (ic->h->client, &peerinfo_handler, ic,
485 GNUNET_TIME_absolute_get_remaining (ic->timeout)); 520 GNUNET_TIME_absolute_get_remaining (ic->timeout));
521 if (NULL != cb)
522 cb (cb_cls, &im->peer, hello, NULL);
486} 523}
487 524
488 525
@@ -497,28 +534,27 @@ static void
497iterator_start_receive (void *cls, int transmit_success) 534iterator_start_receive (void *cls, int transmit_success)
498{ 535{
499 struct GNUNET_PEERINFO_IteratorContext *ic = cls; 536 struct GNUNET_PEERINFO_IteratorContext *ic = cls;
537 struct GNUNET_PEERINFO_Handle *h = ic->h;
538 GNUNET_PEERINFO_Processor cb;
539 void *cb_cls;
500 540
541 ic->tqe = NULL;
501 if (GNUNET_OK != transmit_success) 542 if (GNUNET_OK != transmit_success)
502 { 543 {
503 if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK) 544 cb = ic->callback;
504 { 545 cb_cls = ic->callback_cls;
505 GNUNET_SCHEDULER_cancel (ic->timeout_task); 546 GNUNET_PEERINFO_iterate_cancel (ic);
506 ic->timeout_task = GNUNET_SCHEDULER_NO_TASK; 547 reconnect (h);
507 } 548 if (NULL != cb)
508 reconnect (ic->h); 549 cb (cb_cls, NULL, NULL,
509 if (ic->callback != NULL) 550 _("Failed to transmit iteration request to `PEERINFO' service"));
510 ic->callback (ic->callback_cls, NULL, NULL,
511 _
512 ("Failed to transmit iteration request to `PEERINFO' service"));
513 GNUNET_free (ic);
514 return; 551 return;
515 } 552 }
516 LOG (GNUNET_ERROR_TYPE_DEBUG, "Waiting for response from `%s' service.\n", 553 LOG (GNUNET_ERROR_TYPE_DEBUG, "Waiting for response from `%s' service.\n",
517 "PEERINFO"); 554 "PEERINFO");
518 ic->h->in_receive = GNUNET_YES; 555 h->in_receive = GNUNET_YES;
519 ic->in_receive = GNUNET_YES; 556 ic->in_receive = GNUNET_YES;
520 ic->tqe = NULL; 557 GNUNET_CLIENT_receive (h->client, &peerinfo_handler, ic,
521 GNUNET_CLIENT_receive (ic->h->client, &peerinfo_handler, ic,
522 GNUNET_TIME_absolute_get_remaining (ic->timeout)); 558 GNUNET_TIME_absolute_get_remaining (ic->timeout));
523} 559}
524 560
@@ -533,18 +569,16 @@ static void
533signal_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 569signal_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
534{ 570{
535 struct GNUNET_PEERINFO_IteratorContext *ic = cls; 571 struct GNUNET_PEERINFO_IteratorContext *ic = cls;
572 GNUNET_PEERINFO_Processor cb;
573 void *cb_cls;
536 574
537 ic->timeout_task = GNUNET_SCHEDULER_NO_TASK; 575 ic->timeout_task = GNUNET_SCHEDULER_NO_TASK;
538 if (!ic->in_receive) 576 cb = ic->callback;
539 GNUNET_CONTAINER_DLL_remove (ic->h->tq_head, ic->h->tq_tail, ic->tqe); 577 cb_cls = ic->callback_cls;
540 else 578 GNUNET_PEERINFO_iterate_cancel (ic);
541 reconnect (ic->h); 579 if (NULL != cb)
542 ic->callback (ic->callback_cls, NULL, NULL, 580 cb (cb_cls, NULL, NULL,
543 _ 581 _("Timeout transmitting iteration request to `PEERINFO' service."));
544 ("Timeout transmitting iteration request to `PEERINFO' service."));
545 ic->callback = NULL;
546 GNUNET_free_non_null (ic->tqe);
547 GNUNET_free (ic);
548} 582}
549 583
550 584
@@ -575,7 +609,7 @@ GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h,
575 struct GNUNET_PEERINFO_IteratorContext *ic; 609 struct GNUNET_PEERINFO_IteratorContext *ic;
576 struct TransmissionQueueEntry *tqe; 610 struct TransmissionQueueEntry *tqe;
577 611
578 if (peer == NULL) 612 if (NULL == peer)
579 { 613 {
580 LOG (GNUNET_ERROR_TYPE_DEBUG, 614 LOG (GNUNET_ERROR_TYPE_DEBUG,
581 "Requesting list of peers from PEERINFO service\n"); 615 "Requesting list of peers from PEERINFO service\n");
@@ -609,10 +643,12 @@ GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h,
609 ic->timeout = GNUNET_TIME_relative_to_absolute (timeout); 643 ic->timeout = GNUNET_TIME_relative_to_absolute (timeout);
610 ic->timeout_task = 644 ic->timeout_task =
611 GNUNET_SCHEDULER_add_delayed (timeout, &signal_timeout, ic); 645 GNUNET_SCHEDULER_add_delayed (timeout, &signal_timeout, ic);
612 tqe->timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
613 tqe->cont = &iterator_start_receive; 646 tqe->cont = &iterator_start_receive;
614 tqe->cont_cls = ic; 647 tqe->cont_cls = ic;
615 GNUNET_CONTAINER_DLL_insert_after (h->tq_head, h->tq_tail, h->tq_tail, tqe); 648 GNUNET_CONTAINER_DLL_insert_after (h->tq_head, h->tq_tail, h->tq_tail, tqe);
649 GNUNET_CONTAINER_DLL_insert (h->ic_head,
650 h->ic_tail,
651 ic);
616 trigger_transmit (h); 652 trigger_transmit (h);
617 return ic; 653 return ic;
618} 654}
@@ -626,7 +662,13 @@ GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h,
626void 662void
627GNUNET_PEERINFO_iterate_cancel (struct GNUNET_PEERINFO_IteratorContext *ic) 663GNUNET_PEERINFO_iterate_cancel (struct GNUNET_PEERINFO_IteratorContext *ic)
628{ 664{
629 if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK) 665 struct GNUNET_PEERINFO_Handle *h;
666
667 h = ic->h;
668 GNUNET_CONTAINER_DLL_remove (h->ic_head,
669 h->ic_tail,
670 ic);
671 if (GNUNET_SCHEDULER_NO_TASK != ic->timeout_task)
630 { 672 {
631 GNUNET_SCHEDULER_cancel (ic->timeout_task); 673 GNUNET_SCHEDULER_cancel (ic->timeout_task);
632 ic->timeout_task = GNUNET_SCHEDULER_NO_TASK; 674 ic->timeout_task = GNUNET_SCHEDULER_NO_TASK;
@@ -634,8 +676,11 @@ GNUNET_PEERINFO_iterate_cancel (struct GNUNET_PEERINFO_IteratorContext *ic)
634 ic->callback = NULL; 676 ic->callback = NULL;
635 if (GNUNET_YES == ic->in_receive) 677 if (GNUNET_YES == ic->in_receive)
636 return; /* need to finish processing */ 678 return; /* need to finish processing */
637 GNUNET_CONTAINER_DLL_remove (ic->h->tq_head, ic->h->tq_tail, ic->tqe); 679 if (NULL != ic->tqe)
638 GNUNET_free (ic->tqe); 680 {
681 GNUNET_CONTAINER_DLL_remove (h->tq_head, h->tq_tail, ic->tqe);
682 GNUNET_free (ic->tqe);
683 }
639 GNUNET_free (ic); 684 GNUNET_free (ic);
640} 685}
641 686