diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-05-03 09:24:06 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-05-03 09:24:06 +0000 |
commit | 3fa11d0813d624a080039bb65786100ae626f854 (patch) | |
tree | 0c909d65e60bf35d57e1647d4f1df1ddd379549e | |
parent | 115e8f7ff84e503ce97ea1f985c1474c866eb6d4 (diff) | |
download | gnunet-3fa11d0813d624a080039bb65786100ae626f854.tar.gz gnunet-3fa11d0813d624a080039bb65786100ae626f854.zip |
-fixing #2298
-rw-r--r-- | src/hostlist/hostlist-server.c | 88 | ||||
-rw-r--r-- | src/peerinfo/peerinfo_api.c | 319 |
2 files changed, 228 insertions, 179 deletions
diff --git a/src/hostlist/hostlist-server.c b/src/hostlist/hostlist-server.c index 7bd74dca5..af46110ca 100644 --- a/src/hostlist/hostlist-server.c +++ b/src/hostlist/hostlist-server.c | |||
@@ -89,6 +89,18 @@ static struct GNUNET_PEERINFO_IteratorContext *pitr; | |||
89 | static struct GNUNET_PEERINFO_Handle *peerinfo; | 89 | static struct GNUNET_PEERINFO_Handle *peerinfo; |
90 | 90 | ||
91 | /** | 91 | /** |
92 | * Set if we are allowed to advertise our hostlist to others. | ||
93 | */ | ||
94 | static int advertising; | ||
95 | |||
96 | /** | ||
97 | * Buffer for the hostlist address | ||
98 | */ | ||
99 | static char *hostlist_uri; | ||
100 | |||
101 | |||
102 | |||
103 | /** | ||
92 | * Context for host processor. | 104 | * Context for host processor. |
93 | */ | 105 | */ |
94 | struct HostSet | 106 | struct HostSet |
@@ -98,15 +110,6 @@ struct HostSet | |||
98 | char *data; | 110 | char *data; |
99 | }; | 111 | }; |
100 | 112 | ||
101 | /** | ||
102 | * Set if we are allowed to advertise our hostlist to others. | ||
103 | */ | ||
104 | static int advertising; | ||
105 | |||
106 | /** | ||
107 | * Buffer for the hostlist address | ||
108 | */ | ||
109 | static char *hostlist_uri; | ||
110 | 113 | ||
111 | 114 | ||
112 | /** | 115 | /** |
@@ -115,7 +118,7 @@ static char *hostlist_uri; | |||
115 | static void | 118 | static void |
116 | finish_response (struct HostSet *results) | 119 | finish_response (struct HostSet *results) |
117 | { | 120 | { |
118 | if (response != NULL) | 121 | if (NULL != response) |
119 | MHD_destroy_response (response); | 122 | MHD_destroy_response (response); |
120 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 123 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
121 | "Creating hostlist response with %u bytes\n", | 124 | "Creating hostlist response with %u bytes\n", |
@@ -123,7 +126,7 @@ finish_response (struct HostSet *results) | |||
123 | response = | 126 | response = |
124 | MHD_create_response_from_data (results->size, results->data, MHD_YES, | 127 | MHD_create_response_from_data (results->size, results->data, MHD_YES, |
125 | MHD_NO); | 128 | MHD_NO); |
126 | if ((daemon_handle_v4 == NULL) && (daemon_handle_v6 == NULL)) | 129 | if ((NULL == daemon_handle_v4) && (NULL == daemon_handle_v6)) |
127 | { | 130 | { |
128 | MHD_destroy_response (response); | 131 | MHD_destroy_response (response); |
129 | response = NULL; | 132 | response = NULL; |
@@ -173,7 +176,7 @@ host_processor (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
173 | size_t s; | 176 | size_t s; |
174 | int has_addr; | 177 | int has_addr; |
175 | 178 | ||
176 | if (err_msg != NULL) | 179 | if (NULL != err_msg) |
177 | { | 180 | { |
178 | GNUNET_assert (NULL == peer); | 181 | GNUNET_assert (NULL == peer); |
179 | pitr = NULL; | 182 | pitr = NULL; |
@@ -182,13 +185,13 @@ host_processor (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
182 | err_msg); | 185 | err_msg); |
183 | return; | 186 | return; |
184 | } | 187 | } |
185 | if (peer == NULL) | 188 | if (NULL == peer) |
186 | { | 189 | { |
187 | pitr = NULL; | 190 | pitr = NULL; |
188 | finish_response (results); | 191 | finish_response (results); |
189 | return; | 192 | return; |
190 | } | 193 | } |
191 | if (hello == NULL) | 194 | if (NULL == hello) |
192 | return; | 195 | return; |
193 | has_addr = GNUNET_NO; | 196 | has_addr = GNUNET_NO; |
194 | GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &check_has_addr, &has_addr); | 197 | GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &check_has_addr, &has_addr); |
@@ -270,7 +273,7 @@ access_handler_callback (void *cls, struct MHD_Connection *connection, | |||
270 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Sending 100 CONTINUE reply\n")); | 273 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Sending 100 CONTINUE reply\n")); |
271 | return MHD_YES; /* send 100 continue */ | 274 | return MHD_YES; /* send 100 continue */ |
272 | } | 275 | } |
273 | if (*upload_data_size != 0) | 276 | if (0 != *upload_data_size) |
274 | { | 277 | { |
275 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 278 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
276 | _("Refusing `%s' request with %llu bytes of upload data\n"), | 279 | _("Refusing `%s' request with %llu bytes of upload data\n"), |
@@ -281,7 +284,7 @@ access_handler_callback (void *cls, struct MHD_Connection *connection, | |||
281 | GNUNET_YES); | 284 | GNUNET_YES); |
282 | return MHD_NO; /* do not support upload data */ | 285 | return MHD_NO; /* do not support upload data */ |
283 | } | 286 | } |
284 | if (response == NULL) | 287 | if (NULL == response) |
285 | { | 288 | { |
286 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 289 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
287 | _ | 290 | _ |
@@ -309,13 +312,12 @@ static size_t | |||
309 | adv_transmit_ready (void *cls, size_t size, void *buf) | 312 | adv_transmit_ready (void *cls, size_t size, void *buf) |
310 | { | 313 | { |
311 | static uint64_t hostlist_adv_count; | 314 | static uint64_t hostlist_adv_count; |
312 | |||
313 | size_t transmission_size; | 315 | size_t transmission_size; |
314 | size_t uri_size; /* Including \0 termination! */ | 316 | size_t uri_size; /* Including \0 termination! */ |
315 | struct GNUNET_MessageHeader header; | 317 | struct GNUNET_MessageHeader header; |
316 | char *cbuf; | 318 | char *cbuf; |
317 | 319 | ||
318 | if (buf == NULL) | 320 | if (NULL == buf) |
319 | { | 321 | { |
320 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 322 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
321 | "Transmission failed, buffer invalid!\n"); | 323 | "Transmission failed, buffer invalid!\n"); |
@@ -359,7 +361,7 @@ connect_handler (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
359 | 361 | ||
360 | if (!advertising) | 362 | if (!advertising) |
361 | return; | 363 | return; |
362 | if (hostlist_uri == NULL) | 364 | if (NULL == hostlist_uri) |
363 | return; | 365 | return; |
364 | size = strlen (hostlist_uri) + 1; | 366 | size = strlen (hostlist_uri) + 1; |
365 | if (size + sizeof (struct GNUNET_MessageHeader) >= | 367 | if (size + sizeof (struct GNUNET_MessageHeader) >= |
@@ -400,6 +402,7 @@ disconnect_handler (void *cls, const struct GNUNET_PeerIdentity *peer) | |||
400 | /* nothing to do */ | 402 | /* nothing to do */ |
401 | } | 403 | } |
402 | 404 | ||
405 | |||
403 | /** | 406 | /** |
404 | * PEERINFO calls this function to let us know about a possible peer | 407 | * PEERINFO calls this function to let us know about a possible peer |
405 | * that we might want to connect to. | 408 | * that we might want to connect to. |
@@ -417,19 +420,20 @@ process_notify (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
417 | 420 | ||
418 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 421 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
419 | "Peerinfo is notifying us to rebuild our hostlist\n"); | 422 | "Peerinfo is notifying us to rebuild our hostlist\n"); |
420 | if (err_msg != NULL) | 423 | if (NULL != err_msg) |
421 | { | ||
422 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 424 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
423 | _("Error in communication with PEERINFO service\n")); | 425 | _("Error in communication with PEERINFO service: %s\n"), |
424 | /* return; */ | 426 | err_msg); |
425 | } | 427 | if (NULL != pitr) |
428 | return; /* re-build already in progress ... */ | ||
426 | results = GNUNET_malloc (sizeof (struct HostSet)); | 429 | results = GNUNET_malloc (sizeof (struct HostSet)); |
427 | GNUNET_assert (peerinfo != NULL); | 430 | GNUNET_assert (NULL != peerinfo); |
428 | pitr = | 431 | pitr = |
429 | GNUNET_PEERINFO_iterate (peerinfo, NULL, GNUNET_TIME_UNIT_MINUTES, | 432 | GNUNET_PEERINFO_iterate (peerinfo, NULL, GNUNET_TIME_UNIT_MINUTES, |
430 | &host_processor, results); | 433 | &host_processor, results); |
431 | } | 434 | } |
432 | 435 | ||
436 | |||
433 | /** | 437 | /** |
434 | * Function that queries MHD's select sets and | 438 | * Function that queries MHD's select sets and |
435 | * starts the task waiting for them. | 439 | * starts the task waiting for them. |
@@ -541,7 +545,7 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, | |||
541 | cfg = c; | 545 | cfg = c; |
542 | stats = st; | 546 | stats = st; |
543 | peerinfo = GNUNET_PEERINFO_connect (cfg); | 547 | peerinfo = GNUNET_PEERINFO_connect (cfg); |
544 | if (peerinfo == NULL) | 548 | if (NULL == peerinfo) |
545 | { | 549 | { |
546 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 550 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
547 | _("Could not access PEERINFO service. Exiting.\n")); | 551 | _("Could not access PEERINFO service. Exiting.\n")); |
@@ -551,7 +555,7 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, | |||
551 | GNUNET_CONFIGURATION_get_value_number (cfg, "HOSTLIST", "HTTPPORT", | 555 | GNUNET_CONFIGURATION_get_value_number (cfg, "HOSTLIST", "HTTPPORT", |
552 | &port)) | 556 | &port)) |
553 | return GNUNET_SYSERR; | 557 | return GNUNET_SYSERR; |
554 | if ((port == 0) || (port > UINT16_MAX)) | 558 | if ((0 == port) || (port > UINT16_MAX)) |
555 | { | 559 | { |
556 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 560 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
557 | _("Invalid port number %llu. Exiting.\n"), port); | 561 | _("Invalid port number %llu. Exiting.\n"), port); |
@@ -590,7 +594,7 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, | |||
590 | } | 594 | } |
591 | else | 595 | else |
592 | ip = NULL; | 596 | ip = NULL; |
593 | if (ip != NULL) | 597 | if (NULL != ip) |
594 | { | 598 | { |
595 | if (1 == inet_pton (AF_INET, ip, &i4)) | 599 | if (1 == inet_pton (AF_INET, ip, &i4)) |
596 | { | 600 | { |
@@ -656,7 +660,7 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, | |||
656 | sa, | 660 | sa, |
657 | MHD_OPTION_END); | 661 | MHD_OPTION_END); |
658 | 662 | ||
659 | if ((daemon_handle_v6 == NULL) && (daemon_handle_v4 == NULL)) | 663 | if ((NULL == daemon_handle_v6) && (NULL == daemon_handle_v4)) |
660 | { | 664 | { |
661 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 665 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
662 | _("Could not start hostlist HTTP server on port %u\n"), | 666 | _("Could not start hostlist HTTP server on port %u\n"), |
@@ -672,7 +676,7 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, | |||
672 | if (daemon_handle_v6 != NULL) | 676 | if (daemon_handle_v6 != NULL) |
673 | hostlist_task_v6 = prepare_daemon (daemon_handle_v6); | 677 | hostlist_task_v6 = prepare_daemon (daemon_handle_v6); |
674 | 678 | ||
675 | notify = GNUNET_PEERINFO_notify (cfg, process_notify, NULL); | 679 | notify = GNUNET_PEERINFO_notify (cfg, &process_notify, NULL); |
676 | 680 | ||
677 | return GNUNET_OK; | 681 | return GNUNET_OK; |
678 | } | 682 | } |
@@ -685,11 +689,6 @@ void | |||
685 | GNUNET_HOSTLIST_server_stop () | 689 | GNUNET_HOSTLIST_server_stop () |
686 | { | 690 | { |
687 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist server shutdown\n"); | 691 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist server shutdown\n"); |
688 | if (NULL != notify) | ||
689 | { | ||
690 | GNUNET_PEERINFO_notify_cancel (notify); | ||
691 | notify = NULL; | ||
692 | } | ||
693 | if (GNUNET_SCHEDULER_NO_TASK != hostlist_task_v6) | 692 | if (GNUNET_SCHEDULER_NO_TASK != hostlist_task_v6) |
694 | { | 693 | { |
695 | GNUNET_SCHEDULER_cancel (hostlist_task_v6); | 694 | GNUNET_SCHEDULER_cancel (hostlist_task_v6); |
@@ -700,11 +699,6 @@ GNUNET_HOSTLIST_server_stop () | |||
700 | GNUNET_SCHEDULER_cancel (hostlist_task_v4); | 699 | GNUNET_SCHEDULER_cancel (hostlist_task_v4); |
701 | hostlist_task_v4 = GNUNET_SCHEDULER_NO_TASK; | 700 | hostlist_task_v4 = GNUNET_SCHEDULER_NO_TASK; |
702 | } | 701 | } |
703 | if (pitr != NULL) | ||
704 | { | ||
705 | GNUNET_PEERINFO_iterate_cancel (pitr); | ||
706 | pitr = NULL; | ||
707 | } | ||
708 | if (NULL != daemon_handle_v4) | 702 | if (NULL != daemon_handle_v4) |
709 | { | 703 | { |
710 | MHD_stop_daemon (daemon_handle_v4); | 704 | MHD_stop_daemon (daemon_handle_v4); |
@@ -715,12 +709,22 @@ GNUNET_HOSTLIST_server_stop () | |||
715 | MHD_stop_daemon (daemon_handle_v6); | 709 | MHD_stop_daemon (daemon_handle_v6); |
716 | daemon_handle_v6 = NULL; | 710 | daemon_handle_v6 = NULL; |
717 | } | 711 | } |
718 | if (response != NULL) | 712 | if (NULL != response) |
719 | { | 713 | { |
720 | MHD_destroy_response (response); | 714 | MHD_destroy_response (response); |
721 | response = NULL; | 715 | response = NULL; |
722 | } | 716 | } |
723 | if (peerinfo != NULL) | 717 | if (NULL != notify) |
718 | { | ||
719 | GNUNET_PEERINFO_notify_cancel (notify); | ||
720 | notify = NULL; | ||
721 | } | ||
722 | if (NULL != pitr) | ||
723 | { | ||
724 | GNUNET_PEERINFO_iterate_cancel (pitr); | ||
725 | pitr = NULL; | ||
726 | } | ||
727 | if (NULL != peerinfo) | ||
724 | { | 728 | { |
725 | GNUNET_PEERINFO_disconnect (peerinfo); | 729 | GNUNET_PEERINFO_disconnect (peerinfo); |
726 | peerinfo = NULL; | 730 | peerinfo = NULL; |
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 | */ | ||
82 | struct 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 | |||
135 | struct GNUNET_PEERINFO_Handle * | 193 | struct GNUNET_PEERINFO_Handle * |
136 | GNUNET_PEERINFO_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) | 194 | GNUNET_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 | |||
157 | GNUNET_PEERINFO_disconnect (struct GNUNET_PEERINFO_Handle *h) | 215 | GNUNET_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); | |||
202 | static void | 267 | static void |
203 | reconnect (struct GNUNET_PEERINFO_Handle *h); | 268 | reconnect (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) | |||
226 | static void | 292 | static void |
227 | reconnect (struct GNUNET_PEERINFO_Handle *h) | 293 | reconnect (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) |
366 | struct 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 | |||
413 | peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg) | 446 | peerinfo_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 | |||
497 | iterator_start_receive (void *cls, int transmit_success) | 534 | iterator_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 | |||
533 | signal_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 569 | signal_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, | |||
626 | void | 662 | void |
627 | GNUNET_PEERINFO_iterate_cancel (struct GNUNET_PEERINFO_IteratorContext *ic) | 663 | GNUNET_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 | ||