aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_protocols.h6
-rw-r--r--src/include/gnunet_transport_service.h2
-rw-r--r--src/transport/gnunet-service-transport_clients.c2
-rw-r--r--src/transport/gnunet-transport.c24
-rw-r--r--src/transport/test_transport_api_monitor_peers.c12
-rw-r--r--src/transport/transport_api_monitor_peers.c350
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 *
616GNUNET_TRANSPORT_monitor_peers (const struct GNUNET_CONFIGURATION_Handle *cfg, 615GNUNET_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
1966int 1973int
1967main (int argc, char * const *argv) 1974main (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 &notify_receive, &notify_connect, 450 &notify_receive, &notify_connect,
451 &notify_disconnect, &start_cb, 451 &notify_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 &notify_receive, &notify_connect, 461 &notify_receive, &notify_connect,
458 &notify_disconnect, &start_cb, 462 &notify_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 */
174static void 167static void
175peer_response_processor (void *cls, 168do_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 */
184static void 176static void
185send_peer_mon_request (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx) 177reconnect_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 */
208static void 200static void
209do_peer_connect (void *cls) 201handle_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 */
225static void 230static int
226reconnect_peer_ctx (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx) 231check_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 */
248static void 269static void
249peer_response_processor (void *cls, 270handle_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 */
318static void
319mq_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 */
344static void
345do_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 *
413GNUNET_TRANSPORT_monitor_peers (const struct GNUNET_CONFIGURATION_Handle *cfg, 406GNUNET_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,
448void 436void
449GNUNET_TRANSPORT_monitor_peers_cancel (struct GNUNET_TRANSPORT_PeerMonitoringContext *pic) 437GNUNET_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 {