diff options
-rw-r--r-- | src/include/gnunet_protocols.h | 6 | ||||
-rw-r--r-- | src/include/gnunet_transport_service.h | 2 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport_clients.c | 2 | ||||
-rw-r--r-- | src/transport/gnunet-transport.c | 24 | ||||
-rw-r--r-- | src/transport/test_transport_api_monitor_peers.c | 12 | ||||
-rw-r--r-- | src/transport/transport_api_monitor_peers.c | 350 |
6 files changed, 202 insertions, 194 deletions
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 872c07623..eeceb545d 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -1369,6 +1369,12 @@ extern "C" | |||
1369 | */ | 1369 | */ |
1370 | #define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PLUGIN_SYNC 390 | 1370 | #define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PLUGIN_SYNC 390 |
1371 | 1371 | ||
1372 | /** | ||
1373 | * Response to #GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE_END | ||
1374 | * terminating list of replies. | ||
1375 | */ | ||
1376 | #define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE_END 391 | ||
1377 | |||
1372 | 1378 | ||
1373 | /******************************************************************************* | 1379 | /******************************************************************************* |
1374 | * FS-PUBLISH-HELPER IPC Messages | 1380 | * FS-PUBLISH-HELPER IPC Messages |
diff --git a/src/include/gnunet_transport_service.h b/src/include/gnunet_transport_service.h index 9eb003757..3683286a5 100644 --- a/src/include/gnunet_transport_service.h +++ b/src/include/gnunet_transport_service.h | |||
@@ -608,7 +608,6 @@ typedef void | |||
608 | * NULL for all peers | 608 | * NULL for all peers |
609 | * @param one_shot #GNUNET_YES to return the current state and then end (with NULL+NULL), | 609 | * @param one_shot #GNUNET_YES to return the current state and then end (with NULL+NULL), |
610 | * #GNUNET_NO to monitor peers continuously | 610 | * #GNUNET_NO to monitor peers continuously |
611 | * @param timeout how long is the lookup allowed to take at most | ||
612 | * @param peer_callback function to call with the results | 611 | * @param peer_callback function to call with the results |
613 | * @param peer_callback_cls closure for @a peer_callback | 612 | * @param peer_callback_cls closure for @a peer_callback |
614 | */ | 613 | */ |
@@ -616,7 +615,6 @@ struct GNUNET_TRANSPORT_PeerMonitoringContext * | |||
616 | GNUNET_TRANSPORT_monitor_peers (const struct GNUNET_CONFIGURATION_Handle *cfg, | 615 | GNUNET_TRANSPORT_monitor_peers (const struct GNUNET_CONFIGURATION_Handle *cfg, |
617 | const struct GNUNET_PeerIdentity *peer, | 616 | const struct GNUNET_PeerIdentity *peer, |
618 | int one_shot, | 617 | int one_shot, |
619 | struct GNUNET_TIME_Relative timeout, | ||
620 | GNUNET_TRANSPORT_PeerIterateCallback peer_callback, | 618 | GNUNET_TRANSPORT_PeerIterateCallback peer_callback, |
621 | void *peer_callback_cls); | 619 | void *peer_callback_cls); |
622 | 620 | ||
diff --git a/src/transport/gnunet-service-transport_clients.c b/src/transport/gnunet-service-transport_clients.c index 953ea54e5..b9bccc08b 100644 --- a/src/transport/gnunet-service-transport_clients.c +++ b/src/transport/gnunet-service-transport_clients.c | |||
@@ -1298,7 +1298,7 @@ clients_handle_monitor_peers (void *cls, | |||
1298 | GNUNET_SERVER_transmit_context_append_data (tc, | 1298 | GNUNET_SERVER_transmit_context_append_data (tc, |
1299 | NULL, | 1299 | NULL, |
1300 | 0, | 1300 | 0, |
1301 | GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE); | 1301 | GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE_END); |
1302 | } | 1302 | } |
1303 | GNUNET_SERVER_transmit_context_run (tc, | 1303 | GNUNET_SERVER_transmit_context_run (tc, |
1304 | GNUNET_TIME_UNIT_FOREVER_REL); | 1304 | GNUNET_TIME_UNIT_FOREVER_REL); |
diff --git a/src/transport/gnunet-transport.c b/src/transport/gnunet-transport.c index d7852893c..85f22a7f2 100644 --- a/src/transport/gnunet-transport.c +++ b/src/transport/gnunet-transport.c | |||
@@ -1875,8 +1875,11 @@ testservice_task (void *cls, | |||
1875 | } | 1875 | } |
1876 | else if (iterate_connections) /* -i: List information about peers once */ | 1876 | else if (iterate_connections) /* -i: List information about peers once */ |
1877 | { | 1877 | { |
1878 | pic = GNUNET_TRANSPORT_monitor_peers (cfg, (NULL == cpid) ? NULL : &pid, | 1878 | pic = GNUNET_TRANSPORT_monitor_peers (cfg, |
1879 | GNUNET_YES, TIMEOUT, &process_peer_iteration_cb, (void *) cfg); | 1879 | (NULL == cpid) ? NULL : &pid, |
1880 | GNUNET_YES, | ||
1881 | &process_peer_iteration_cb, | ||
1882 | (void *) cfg); | ||
1880 | op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, | 1883 | op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, |
1881 | &operation_timeout, | 1884 | &operation_timeout, |
1882 | NULL); | 1885 | NULL); |
@@ -1888,8 +1891,8 @@ testservice_task (void *cls, | |||
1888 | pic = GNUNET_TRANSPORT_monitor_peers (cfg, | 1891 | pic = GNUNET_TRANSPORT_monitor_peers (cfg, |
1889 | (NULL == cpid) ? NULL : &pid, | 1892 | (NULL == cpid) ? NULL : &pid, |
1890 | GNUNET_NO, | 1893 | GNUNET_NO, |
1891 | TIMEOUT, | 1894 | &process_peer_monitoring_cb, |
1892 | &process_peer_monitoring_cb, NULL); | 1895 | NULL); |
1893 | } | 1896 | } |
1894 | else if (monitor_plugins) /* -P: List information about plugins continuously */ | 1897 | else if (monitor_plugins) /* -P: List information about plugins continuously */ |
1895 | { | 1898 | { |
@@ -1933,7 +1936,7 @@ testservice_task (void *cls, | |||
1933 | GNUNET_break(0); | 1936 | GNUNET_break(0); |
1934 | return; | 1937 | return; |
1935 | } | 1938 | } |
1936 | 1939 | ||
1937 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, | 1940 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, |
1938 | NULL); | 1941 | NULL); |
1939 | } | 1942 | } |
@@ -1959,12 +1962,17 @@ run (void *cls, | |||
1959 | do_test_configuration (cfg); | 1962 | do_test_configuration (cfg); |
1960 | return; | 1963 | return; |
1961 | } | 1964 | } |
1962 | GNUNET_CLIENT_service_test ("transport", cfg, GNUNET_TIME_UNIT_SECONDS, | 1965 | GNUNET_CLIENT_service_test ("transport", |
1963 | &testservice_task, (void *) cfg); | 1966 | cfg, |
1967 | GNUNET_TIME_UNIT_SECONDS, | ||
1968 | &testservice_task, | ||
1969 | (void *) cfg); | ||
1964 | } | 1970 | } |
1965 | 1971 | ||
1972 | |||
1966 | int | 1973 | int |
1967 | main (int argc, char * const *argv) | 1974 | main (int argc, |
1975 | char * const *argv) | ||
1968 | { | 1976 | { |
1969 | int res; | 1977 | int res; |
1970 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { | 1978 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { |
diff --git a/src/transport/test_transport_api_monitor_peers.c b/src/transport/test_transport_api_monitor_peers.c index 549394944..90c96829d 100644 --- a/src/transport/test_transport_api_monitor_peers.c +++ b/src/transport/test_transport_api_monitor_peers.c | |||
@@ -450,14 +450,22 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
450 | ¬ify_receive, ¬ify_connect, | 450 | ¬ify_receive, ¬ify_connect, |
451 | ¬ify_disconnect, &start_cb, | 451 | ¬ify_disconnect, &start_cb, |
452 | NULL); | 452 | NULL); |
453 | pmc_p1 = GNUNET_TRANSPORT_monitor_peers (p1->cfg, NULL, GNUNET_NO, GNUNET_TIME_UNIT_FOREVER_REL, &monitor1_cb, NULL); | 453 | pmc_p1 = GNUNET_TRANSPORT_monitor_peers (p1->cfg, |
454 | NULL, | ||
455 | GNUNET_NO, | ||
456 | &monitor1_cb, | ||
457 | NULL); | ||
454 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer 1 started\n"); | 458 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer 1 started\n"); |
455 | 459 | ||
456 | p2 = GNUNET_TRANSPORT_TESTING_start_peer (tth, cfg_file_p2, 2, | 460 | p2 = GNUNET_TRANSPORT_TESTING_start_peer (tth, cfg_file_p2, 2, |
457 | ¬ify_receive, ¬ify_connect, | 461 | ¬ify_receive, ¬ify_connect, |
458 | ¬ify_disconnect, &start_cb, | 462 | ¬ify_disconnect, &start_cb, |
459 | NULL); | 463 | NULL); |
460 | pmc_p2 = GNUNET_TRANSPORT_monitor_peers (p2->cfg, NULL, GNUNET_NO, GNUNET_TIME_UNIT_FOREVER_REL, &monitor2_cb, NULL); | 464 | pmc_p2 = GNUNET_TRANSPORT_monitor_peers (p2->cfg, |
465 | NULL, | ||
466 | GNUNET_NO, | ||
467 | &monitor2_cb, | ||
468 | NULL); | ||
461 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer 1 started\n"); | 469 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer 1 started\n"); |
462 | if ((p1 == NULL) || (p2 == NULL)) | 470 | if ((p1 == NULL) || (p2 == NULL)) |
463 | { | 471 | { |
diff --git a/src/transport/transport_api_monitor_peers.c b/src/transport/transport_api_monitor_peers.c index 5d19ad6d7..a5c70fcfa 100644 --- a/src/transport/transport_api_monitor_peers.c +++ b/src/transport/transport_api_monitor_peers.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2009-2014 GNUnet e.V. | 3 | Copyright (C) 2009-2014, 2016 GNUnet e.V. |
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 |
@@ -54,7 +54,7 @@ struct GNUNET_TRANSPORT_PeerMonitoringContext | |||
54 | /** | 54 | /** |
55 | * Connection to the service. | 55 | * Connection to the service. |
56 | */ | 56 | */ |
57 | struct GNUNET_CLIENT_Connection *client; | 57 | struct GNUNET_MQ_Handle *mq; |
58 | 58 | ||
59 | /** | 59 | /** |
60 | * Configuration we use. | 60 | * Configuration we use. |
@@ -62,11 +62,6 @@ struct GNUNET_TRANSPORT_PeerMonitoringContext | |||
62 | const struct GNUNET_CONFIGURATION_Handle *cfg; | 62 | const struct GNUNET_CONFIGURATION_Handle *cfg; |
63 | 63 | ||
64 | /** | 64 | /** |
65 | * When should this operation time out? | ||
66 | */ | ||
67 | struct GNUNET_TIME_Absolute timeout; | ||
68 | |||
69 | /** | ||
70 | * Backoff for reconnect. | 65 | * Backoff for reconnect. |
71 | */ | 66 | */ |
72 | struct GNUNET_TIME_Relative backoff; | 67 | struct GNUNET_TIME_Relative backoff; |
@@ -165,76 +160,103 @@ GNUNET_TRANSPORT_ps2s (enum GNUNET_TRANSPORT_PeerState state) | |||
165 | 160 | ||
166 | 161 | ||
167 | /** | 162 | /** |
168 | * Function called with responses from the service. | 163 | * Task run to re-establish the connection. |
169 | * | 164 | * |
170 | * @param cls our `struct GNUNET_TRANSPORT_PeerMonitoringContext *` | 165 | * @param cls our `struct GNUNET_TRANSPORT_PeerMonitoringContext *` |
171 | * @param msg NULL on timeout or error, otherwise presumably a | ||
172 | * message with the human-readable address | ||
173 | */ | 166 | */ |
174 | static void | 167 | static void |
175 | peer_response_processor (void *cls, | 168 | do_peer_connect (void *cls); |
176 | const struct GNUNET_MessageHeader *msg); | ||
177 | 169 | ||
178 | 170 | ||
179 | /** | 171 | /** |
180 | * Send our subscription request to the service. | 172 | * Cut the existing connection and reconnect. |
181 | * | 173 | * |
182 | * @param pal_ctx our context | 174 | * @param pal_ctx our context |
183 | */ | 175 | */ |
184 | static void | 176 | static void |
185 | send_peer_mon_request (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx) | 177 | reconnect_peer_ctx (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx) |
186 | { | 178 | { |
187 | struct PeerMonitorMessage msg; | 179 | GNUNET_assert (GNUNET_NO == pal_ctx->one_shot); |
188 | 180 | GNUNET_MQ_destroy (pal_ctx->mq); | |
189 | msg.header.size = htons (sizeof (struct PeerMonitorMessage)); | 181 | pal_ctx->mq = NULL; |
190 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST); | 182 | pal_ctx->cb (pal_ctx->cb_cls, |
191 | msg.one_shot = htonl (pal_ctx->one_shot); | 183 | NULL, |
192 | msg.peer = pal_ctx->peer; | 184 | NULL, |
193 | GNUNET_assert (GNUNET_OK == | 185 | GNUNET_TRANSPORT_PS_NOT_CONNECTED, |
194 | GNUNET_CLIENT_transmit_and_get_response (pal_ctx->client, | 186 | GNUNET_TIME_UNIT_ZERO_ABS); |
195 | &msg.header, | 187 | pal_ctx->backoff = GNUNET_TIME_STD_BACKOFF (pal_ctx->backoff); |
196 | GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout), | 188 | pal_ctx->reconnect_task = GNUNET_SCHEDULER_add_delayed (pal_ctx->backoff, |
197 | GNUNET_YES, | 189 | &do_peer_connect, |
198 | &peer_response_processor, | 190 | pal_ctx); |
199 | pal_ctx)); | ||
200 | } | 191 | } |
201 | 192 | ||
202 | 193 | ||
203 | /** | 194 | /** |
204 | * Task run to re-establish the connection. | 195 | * Function called with responses from the service. |
205 | * | 196 | * |
206 | * @param cls our `struct GNUNET_TRANSPORT_PeerMonitoringContext *` | 197 | * @param cls our `struct GNUNET_TRANSPORT_PeerMonitoringContext *` |
198 | * @param msg message from service | ||
207 | */ | 199 | */ |
208 | static void | 200 | static void |
209 | do_peer_connect (void *cls) | 201 | handle_response_end (void *cls, |
202 | const struct GNUNET_MessageHeader *msg) | ||
210 | { | 203 | { |
211 | struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls; | 204 | struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls; |
212 | 205 | ||
213 | pal_ctx->reconnect_task = NULL; | 206 | if (pal_ctx->one_shot) |
214 | pal_ctx->client = GNUNET_CLIENT_connect ("transport", pal_ctx->cfg); | 207 | { |
215 | GNUNET_assert (NULL != pal_ctx->client); | 208 | /* iteration finished */ |
216 | send_peer_mon_request (pal_ctx); | 209 | pal_ctx->cb (pal_ctx->cb_cls, |
210 | NULL, | ||
211 | NULL, | ||
212 | GNUNET_TRANSPORT_PS_NOT_CONNECTED, | ||
213 | GNUNET_TIME_UNIT_ZERO_ABS); | ||
214 | GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx); | ||
215 | return; | ||
216 | } | ||
217 | /* not quite what we expected, reconnect */ | ||
218 | GNUNET_break (0); | ||
219 | reconnect_peer_ctx (pal_ctx); | ||
217 | } | 220 | } |
218 | 221 | ||
219 | 222 | ||
220 | /** | 223 | /** |
221 | * Cut the existing connection and reconnect. | 224 | * Function called to check responses from the service. |
222 | * | 225 | * |
223 | * @param pal_ctx our context | 226 | * @param cls our `struct GNUNET_TRANSPORT_PeerMonitoringContext *` |
227 | * @param pir_msg message with the human-readable address | ||
228 | * @return #GNUNET_OK if @a pir_msg is well-formed | ||
224 | */ | 229 | */ |
225 | static void | 230 | static int |
226 | reconnect_peer_ctx (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx) | 231 | check_response (void *cls, |
232 | const struct PeerIterateResponseMessage *pir_msg) | ||
227 | { | 233 | { |
228 | GNUNET_assert (GNUNET_NO == pal_ctx->one_shot); | 234 | uint16_t size = ntohs (pir_msg->header.size) - sizeof (*pir_msg); |
229 | GNUNET_CLIENT_disconnect (pal_ctx->client); | 235 | size_t alen = ntohl (pir_msg->addrlen); |
230 | pal_ctx->client = NULL; | 236 | size_t tlen = ntohl (pir_msg->pluginlen); |
231 | pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL, | 237 | const char *addr; |
232 | GNUNET_TRANSPORT_PS_NOT_CONNECTED, | 238 | const char *transport_name; |
233 | GNUNET_TIME_UNIT_ZERO_ABS); | 239 | |
234 | pal_ctx->backoff = GNUNET_TIME_STD_BACKOFF (pal_ctx->backoff); | 240 | if (size != tlen + alen) |
235 | pal_ctx->reconnect_task = GNUNET_SCHEDULER_add_delayed (pal_ctx->backoff, | 241 | { |
236 | &do_peer_connect, | 242 | GNUNET_break (0); |
237 | pal_ctx); | 243 | return GNUNET_SYSERR; |
244 | } | ||
245 | if ( (0 == tlen) && (0 == alen) ) | ||
246 | return GNUNET_OK; | ||
247 | if (0 == tlen) | ||
248 | { | ||
249 | GNUNET_break (0); /* This must not happen: address without plugin */ | ||
250 | return GNUNET_SYSERR; | ||
251 | } | ||
252 | addr = (const char *) &pir_msg[1]; | ||
253 | transport_name = &addr[alen]; | ||
254 | if (transport_name[tlen - 1] != '\0') | ||
255 | { | ||
256 | GNUNET_break (0); | ||
257 | return GNUNET_SYSERR; | ||
258 | } | ||
259 | return GNUNET_OK; | ||
238 | } | 260 | } |
239 | 261 | ||
240 | 262 | ||
@@ -242,143 +264,115 @@ reconnect_peer_ctx (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx) | |||
242 | * Function called with responses from the service. | 264 | * Function called with responses from the service. |
243 | * | 265 | * |
244 | * @param cls our `struct GNUNET_TRANSPORT_PeerMonitoringContext *` | 266 | * @param cls our `struct GNUNET_TRANSPORT_PeerMonitoringContext *` |
245 | * @param msg NULL on timeout or error, otherwise presumably a | 267 | * @param msg message with the human-readable address |
246 | * message with the human-readable address | ||
247 | */ | 268 | */ |
248 | static void | 269 | static void |
249 | peer_response_processor (void *cls, | 270 | handle_response (void *cls, |
250 | const struct GNUNET_MessageHeader *msg) | 271 | const struct PeerIterateResponseMessage *pir_msg) |
251 | { | 272 | { |
252 | struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls; | 273 | struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls; |
253 | struct PeerIterateResponseMessage *pir_msg; | ||
254 | struct GNUNET_HELLO_Address *address; | 274 | struct GNUNET_HELLO_Address *address; |
275 | size_t alen = ntohl (pir_msg->addrlen); | ||
276 | size_t tlen = ntohl (pir_msg->pluginlen); | ||
255 | const char *addr; | 277 | const char *addr; |
256 | const char *transport_name; | 278 | const char *transport_name; |
257 | uint16_t size; | ||
258 | size_t alen; | ||
259 | size_t tlen; | ||
260 | 279 | ||
261 | if (NULL == msg) | 280 | if ( (0 == tlen) && |
262 | { | 281 | (0 == alen) ) |
263 | if (pal_ctx->one_shot) | ||
264 | { | ||
265 | /* Disconnect */ | ||
266 | pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL, | ||
267 | GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS); | ||
268 | GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx); | ||
269 | } | ||
270 | else | ||
271 | { | ||
272 | reconnect_peer_ctx (pal_ctx); | ||
273 | } | ||
274 | return; | ||
275 | } | ||
276 | size = ntohs (msg->size); | ||
277 | GNUNET_break (ntohs (msg->type) == | ||
278 | GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE); | ||
279 | if (size == sizeof (struct GNUNET_MessageHeader)) | ||
280 | { | 282 | { |
281 | /* Done! */ | 283 | /* No address available */ |
282 | if (pal_ctx->one_shot) | 284 | pal_ctx->cb (pal_ctx->cb_cls, |
283 | { | 285 | &pir_msg->peer, |
284 | /* iteration finished */ | 286 | NULL, |
285 | pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL, | 287 | ntohl(pir_msg->state), |
286 | GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS); | 288 | GNUNET_TIME_absolute_ntoh (pir_msg->state_timeout)); |
287 | GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx); | ||
288 | } | ||
289 | else | ||
290 | { | ||
291 | reconnect_peer_ctx (pal_ctx); | ||
292 | } | ||
293 | return; | 289 | return; |
294 | } | 290 | } |
291 | addr = (const char *) &pir_msg[1]; | ||
292 | transport_name = &addr[alen]; | ||
293 | |||
294 | /* notify client */ | ||
295 | address = GNUNET_HELLO_address_allocate (&pir_msg->peer, | ||
296 | transport_name, | ||
297 | addr, | ||
298 | alen, | ||
299 | ntohl (pir_msg->local_address_info)); | ||
300 | pal_ctx->cb (pal_ctx->cb_cls, | ||
301 | &pir_msg->peer, | ||
302 | address, | ||
303 | ntohl (pir_msg->state), | ||
304 | GNUNET_TIME_absolute_ntoh (pir_msg->state_timeout)); | ||
305 | GNUNET_HELLO_address_free (address); | ||
306 | } | ||
295 | 307 | ||
296 | if ((size < sizeof (struct PeerIterateResponseMessage)) || | ||
297 | (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE)) | ||
298 | { | ||
299 | GNUNET_break (0); | ||
300 | if (pal_ctx->one_shot) | ||
301 | { | ||
302 | /* iteration finished (with error) */ | ||
303 | pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL, | ||
304 | GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS); | ||
305 | GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx); | ||
306 | } | ||
307 | else | ||
308 | { | ||
309 | reconnect_peer_ctx (pal_ctx); | ||
310 | } | ||
311 | return; | ||
312 | } | ||
313 | 308 | ||
314 | pir_msg = (struct PeerIterateResponseMessage *) msg; | ||
315 | tlen = ntohl (pir_msg->pluginlen); | ||
316 | alen = ntohl (pir_msg->addrlen); | ||
317 | 309 | ||
318 | if (size != sizeof (struct PeerIterateResponseMessage) + tlen + alen) | 310 | /** |
311 | * Generic error handler, called with the appropriate error code and | ||
312 | * the same closure specified at the creation of the message queue. | ||
313 | * Not every message queue implementation supports an error handler. | ||
314 | * | ||
315 | * @param cls closure with the `struct GNUNET_TRANSPORT_PeerMonitoringContext *` | ||
316 | * @param error error code | ||
317 | */ | ||
318 | static void | ||
319 | mq_error_handler (void *cls, | ||
320 | enum GNUNET_MQ_Error error) | ||
321 | { | ||
322 | struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls; | ||
323 | |||
324 | if (pal_ctx->one_shot) | ||
319 | { | 325 | { |
320 | GNUNET_break (0); | 326 | /* Disconnect */ |
321 | if (pal_ctx->one_shot) | 327 | pal_ctx->cb (pal_ctx->cb_cls, |
322 | { | 328 | NULL, |
323 | pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL, | 329 | NULL, |
324 | GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS); | 330 | GNUNET_TRANSPORT_PS_NOT_CONNECTED, |
325 | GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx); | 331 | GNUNET_TIME_UNIT_ZERO_ABS); |
326 | } | 332 | GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx); |
327 | else | ||
328 | { | ||
329 | reconnect_peer_ctx (pal_ctx); | ||
330 | } | ||
331 | return; | 333 | return; |
332 | } | 334 | } |
335 | reconnect_peer_ctx (pal_ctx); | ||
336 | } | ||
333 | 337 | ||
334 | if ( (0 == tlen) && (0 == alen) ) | ||
335 | { | ||
336 | /* No address available */ | ||
337 | pal_ctx->cb (pal_ctx->cb_cls, &pir_msg->peer, NULL, | ||
338 | ntohl(pir_msg->state), | ||
339 | GNUNET_TIME_absolute_ntoh (pir_msg->state_timeout)); | ||
340 | } | ||
341 | else | ||
342 | { | ||
343 | if (0 == tlen) | ||
344 | { | ||
345 | GNUNET_break (0); /* This must not happen: address without plugin */ | ||
346 | return; | ||
347 | } | ||
348 | addr = (const char *) &pir_msg[1]; | ||
349 | transport_name = &addr[alen]; | ||
350 | |||
351 | if (transport_name[tlen - 1] != '\0') | ||
352 | { | ||
353 | /* Corrupt plugin name */ | ||
354 | GNUNET_break (0); | ||
355 | if (pal_ctx->one_shot) | ||
356 | { | ||
357 | pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL, | ||
358 | GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS); | ||
359 | GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx); | ||
360 | } | ||
361 | else | ||
362 | { | ||
363 | reconnect_peer_ctx (pal_ctx); | ||
364 | } | ||
365 | return; | ||
366 | } | ||
367 | |||
368 | /* notify client */ | ||
369 | address = GNUNET_HELLO_address_allocate (&pir_msg->peer, | ||
370 | transport_name, addr, alen, ntohl(pir_msg->local_address_info)); | ||
371 | pal_ctx->cb (pal_ctx->cb_cls, &pir_msg->peer, address, | ||
372 | ntohl(pir_msg->state), | ||
373 | GNUNET_TIME_absolute_ntoh (pir_msg->state_timeout)); | ||
374 | GNUNET_HELLO_address_free (address); | ||
375 | 338 | ||
376 | } | 339 | /** |
340 | * Task run to re-establish the connection. | ||
341 | * | ||
342 | * @param cls our `struct GNUNET_TRANSPORT_PeerMonitoringContext *` | ||
343 | */ | ||
344 | static void | ||
345 | do_peer_connect (void *cls) | ||
346 | { | ||
347 | GNUNET_MQ_hd_var_size (response, | ||
348 | GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE, | ||
349 | struct PeerIterateResponseMessage); | ||
350 | GNUNET_MQ_hd_fixed_size (response_end, | ||
351 | GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE_END, | ||
352 | struct GNUNET_MessageHeader); | ||
353 | struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls; | ||
354 | struct GNUNET_MQ_MessageHandler handlers[] = { | ||
355 | make_response_handler (pal_ctx), | ||
356 | make_response_end_handler (pal_ctx), | ||
357 | GNUNET_MQ_handler_end () | ||
358 | }; | ||
359 | struct PeerMonitorMessage *msg; | ||
360 | struct GNUNET_MQ_Envelope *env; | ||
377 | 361 | ||
378 | /* expect more replies */ | 362 | pal_ctx->reconnect_task = NULL; |
379 | GNUNET_CLIENT_receive (pal_ctx->client, &peer_response_processor, | 363 | pal_ctx->mq = GNUNET_CLIENT_connecT (pal_ctx->cfg, |
380 | pal_ctx, | 364 | "transport", |
381 | GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout)); | 365 | handlers, |
366 | &mq_error_handler, | ||
367 | pal_ctx); | ||
368 | if (NULL == pal_ctx->mq) | ||
369 | return; | ||
370 | env = GNUNET_MQ_msg (msg, | ||
371 | GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST); | ||
372 | msg->one_shot = htonl (pal_ctx->one_shot); | ||
373 | msg->peer = pal_ctx->peer; | ||
374 | GNUNET_MQ_send (pal_ctx->mq, | ||
375 | env); | ||
382 | } | 376 | } |
383 | 377 | ||
384 | 378 | ||
@@ -405,7 +399,6 @@ peer_response_processor (void *cls, | |||
405 | * NULL for all peers | 399 | * NULL for all peers |
406 | * @param one_shot #GNUNET_YES to return the current state and then end (with NULL+NULL), | 400 | * @param one_shot #GNUNET_YES to return the current state and then end (with NULL+NULL), |
407 | * #GNUNET_NO to monitor peers continuously | 401 | * #GNUNET_NO to monitor peers continuously |
408 | * @param timeout how long is the lookup allowed to take at most | ||
409 | * @param peer_callback function to call with the results | 402 | * @param peer_callback function to call with the results |
410 | * @param peer_callback_cls closure for @a peer_address_callback | 403 | * @param peer_callback_cls closure for @a peer_address_callback |
411 | */ | 404 | */ |
@@ -413,29 +406,24 @@ struct GNUNET_TRANSPORT_PeerMonitoringContext * | |||
413 | GNUNET_TRANSPORT_monitor_peers (const struct GNUNET_CONFIGURATION_Handle *cfg, | 406 | GNUNET_TRANSPORT_monitor_peers (const struct GNUNET_CONFIGURATION_Handle *cfg, |
414 | const struct GNUNET_PeerIdentity *peer, | 407 | const struct GNUNET_PeerIdentity *peer, |
415 | int one_shot, | 408 | int one_shot, |
416 | struct GNUNET_TIME_Relative timeout, | ||
417 | GNUNET_TRANSPORT_PeerIterateCallback peer_callback, | 409 | GNUNET_TRANSPORT_PeerIterateCallback peer_callback, |
418 | void *peer_callback_cls) | 410 | void *peer_callback_cls) |
419 | { | 411 | { |
420 | struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx; | 412 | struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx |
421 | struct GNUNET_CLIENT_Connection *client; | 413 | = GNUNET_new (struct GNUNET_TRANSPORT_PeerMonitoringContext); |
422 | 414 | ||
423 | client = GNUNET_CLIENT_connect ("transport", cfg); | ||
424 | if (NULL == client) | ||
425 | return NULL; | ||
426 | if (GNUNET_YES != one_shot) | ||
427 | timeout = GNUNET_TIME_UNIT_FOREVER_REL; | ||
428 | pal_ctx = GNUNET_new (struct GNUNET_TRANSPORT_PeerMonitoringContext); | ||
429 | pal_ctx->cb = peer_callback; | 415 | pal_ctx->cb = peer_callback; |
430 | pal_ctx->cb_cls = peer_callback_cls; | 416 | pal_ctx->cb_cls = peer_callback_cls; |
431 | pal_ctx->cfg = cfg; | 417 | pal_ctx->cfg = cfg; |
432 | pal_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); | ||
433 | if (NULL != peer) | 418 | if (NULL != peer) |
434 | pal_ctx->peer = *peer; | 419 | pal_ctx->peer = *peer; |
435 | pal_ctx->one_shot = one_shot; | 420 | pal_ctx->one_shot = one_shot; |
436 | pal_ctx->client = client; | 421 | do_peer_connect (pal_ctx); |
437 | send_peer_mon_request (pal_ctx); | 422 | if (NULL == pal_ctx->mq) |
438 | 423 | { | |
424 | GNUNET_free (pal_ctx); | ||
425 | return NULL; | ||
426 | } | ||
439 | return pal_ctx; | 427 | return pal_ctx; |
440 | } | 428 | } |
441 | 429 | ||
@@ -448,10 +436,10 @@ GNUNET_TRANSPORT_monitor_peers (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
448 | void | 436 | void |
449 | GNUNET_TRANSPORT_monitor_peers_cancel (struct GNUNET_TRANSPORT_PeerMonitoringContext *pic) | 437 | GNUNET_TRANSPORT_monitor_peers_cancel (struct GNUNET_TRANSPORT_PeerMonitoringContext *pic) |
450 | { | 438 | { |
451 | if (NULL != pic->client) | 439 | if (NULL != pic->mq) |
452 | { | 440 | { |
453 | GNUNET_CLIENT_disconnect (pic->client); | 441 | GNUNET_MQ_destroy (pic->mq); |
454 | pic->client = NULL; | 442 | pic->mq = NULL; |
455 | } | 443 | } |
456 | if (NULL != pic->reconnect_task) | 444 | if (NULL != pic->reconnect_task) |
457 | { | 445 | { |