aboutsummaryrefslogtreecommitdiff
path: root/src/transport/transport_api_monitoring.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2014-06-22 20:08:16 +0000
committerChristian Grothoff <christian@grothoff.org>2014-06-22 20:08:16 +0000
commiteeaa12c3dbd18925c1177cfc66f52711b612fd9e (patch)
tree012f822b6d20f324f68ea29d9fe2237a0716935e /src/transport/transport_api_monitoring.c
parent194669680385bd40ce7c84b11021b21b6ed6d295 (diff)
downloadgnunet-eeaa12c3dbd18925c1177cfc66f52711b612fd9e.tar.gz
gnunet-eeaa12c3dbd18925c1177cfc66f52711b612fd9e.zip
-split up transport_api_monitoring into monitor_peers and monitor_validation
Diffstat (limited to 'src/transport/transport_api_monitoring.c')
-rw-r--r--src/transport/transport_api_monitoring.c854
1 files changed, 0 insertions, 854 deletions
diff --git a/src/transport/transport_api_monitoring.c b/src/transport/transport_api_monitoring.c
deleted file mode 100644
index adea00278..000000000
--- a/src/transport/transport_api_monitoring.c
+++ /dev/null
@@ -1,854 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009, 2010 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file transport/transport_api_monitoring.c
23 * @brief montoring api for transport peer status and validation entries
24 *
25 * This api provides the ability to query the transport service about
26 * the status of a specific or all peers as well as address validation entries.
27 *
28 * Calls back with information about peer(s) including address used, state and
29 * state timeout for peer requests and address, address lifetime and next revalidation
30 * for validation entries.
31 */
32#include "platform.h"
33#include "gnunet_util_lib.h"
34#include "gnunet_arm_service.h"
35#include "gnunet_hello_lib.h"
36#include "gnunet_protocols.h"
37#include "gnunet_transport_service.h"
38#include "transport.h"
39
40/**
41 * Context for iterating validation entries.
42 */
43struct GNUNET_TRANSPORT_PeerMonitoringContext
44{
45 /**
46 * Function to call with the binary address.
47 */
48 GNUNET_TRANSPORT_PeerIterateCallback cb;
49
50 /**
51 * Closure for @e cb.
52 */
53 void *cb_cls;
54
55 /**
56 * Connection to the service.
57 */
58 struct GNUNET_CLIENT_Connection *client;
59
60 /**
61 * Configuration we use.
62 */
63 const struct GNUNET_CONFIGURATION_Handle *cfg;
64
65 /**
66 * When should this operation time out?
67 */
68 struct GNUNET_TIME_Absolute timeout;
69
70 /**
71 * Backoff for reconnect.
72 */
73 struct GNUNET_TIME_Relative backoff;
74
75 /**
76 * Task ID for reconnect.
77 */
78 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
79
80 /**
81 * Identity of the peer to monitor.
82 */
83 struct GNUNET_PeerIdentity peer;
84
85 /**
86 * Was this a one-shot request?
87 */
88 int one_shot;
89};
90
91
92/**
93 * Context for the address lookup.
94 */
95struct GNUNET_TRANSPORT_ValidationMonitoringContext
96{
97 /**
98 * Function to call with the binary address.
99 */
100 GNUNET_TRANSPORT_ValidationIterateCallback cb;
101
102 /**
103 * Closure for @e cb.
104 */
105 void *cb_cls;
106
107 /**
108 * Connection to the service.
109 */
110 struct GNUNET_CLIENT_Connection *client;
111
112 /**
113 * Configuration we use.
114 */
115 const struct GNUNET_CONFIGURATION_Handle *cfg;
116
117 /**
118 * When should this operation time out?
119 */
120 struct GNUNET_TIME_Absolute timeout;
121
122 /**
123 * Backoff for reconnect.
124 */
125 struct GNUNET_TIME_Relative backoff;
126
127 /**
128 * Task ID for reconnect.
129 */
130 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
131
132 /**
133 * Identity of the peer to monitor.
134 */
135 struct GNUNET_PeerIdentity peer;
136
137 /**
138 * Was this a one-shot request?
139 */
140 int one_shot;
141};
142
143
144/**
145 * Check if a state is defined as connected
146 *
147 * @param state the state value
148 * @return #GNUNET_YES or #GNUNET_NO
149 */
150int
151GNUNET_TRANSPORT_is_connected (enum GNUNET_TRANSPORT_PeerState state)
152{
153 switch (state)
154 {
155 case GNUNET_TRANSPORT_PS_NOT_CONNECTED:
156 case GNUNET_TRANSPORT_PS_INIT_ATS:
157 case GNUNET_TRANSPORT_PS_CONNECT_SENT:
158 case GNUNET_TRANSPORT_PS_CONNECT_RECV_ATS:
159 case GNUNET_TRANSPORT_PS_CONNECT_RECV_ACK:
160 return GNUNET_NO;
161 case GNUNET_TRANSPORT_PS_CONNECTED:
162 case GNUNET_TRANSPORT_PS_RECONNECT_ATS:
163 case GNUNET_TRANSPORT_PS_RECONNECT_SENT:
164 case GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_CONNECT_SENT:
165 return GNUNET_YES;
166 case GNUNET_TRANSPORT_PS_DISCONNECT:
167 case GNUNET_TRANSPORT_PS_DISCONNECT_FINISHED:
168 return GNUNET_NO;
169 default:
170 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
171 "Unhandled state `%s' \n",
172 GNUNET_TRANSPORT_ps2s (state));
173 GNUNET_break (0);
174 break;
175 }
176 return GNUNET_SYSERR;
177}
178
179
180/**
181 * Convert peer state to human-readable string.
182 *
183 * @param state the state value
184 * @return corresponding string
185 */
186const char *
187GNUNET_TRANSPORT_ps2s (enum GNUNET_TRANSPORT_PeerState state)
188{
189 switch (state)
190 {
191 case GNUNET_TRANSPORT_PS_NOT_CONNECTED:
192 return "S_NOT_CONNECTED";
193 case GNUNET_TRANSPORT_PS_INIT_ATS:
194 return "S_INIT_ATS";
195 case GNUNET_TRANSPORT_PS_CONNECT_SENT:
196 return "S_CONNECT_SENT";
197 case GNUNET_TRANSPORT_PS_CONNECT_RECV_ATS:
198 return "S_CONNECT_RECV_ATS";
199 case GNUNET_TRANSPORT_PS_CONNECT_RECV_ACK:
200 return "S_CONNECT_RECV_ACK";
201 case GNUNET_TRANSPORT_PS_CONNECTED:
202 return "S_CONNECTED";
203 case GNUNET_TRANSPORT_PS_RECONNECT_ATS:
204 return "S_RECONNECT_ATS";
205 case GNUNET_TRANSPORT_PS_RECONNECT_SENT:
206 return "S_RECONNECT_SENT";
207 case GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_CONNECT_SENT:
208 return "S_CONNECTED_SWITCHING_CONNECT_SENT";
209 case GNUNET_TRANSPORT_PS_DISCONNECT:
210 return "S_DISCONNECT";
211 case GNUNET_TRANSPORT_PS_DISCONNECT_FINISHED:
212 return "S_DISCONNECT_FINISHED";
213 default:
214 GNUNET_break (0);
215 return "UNDEFINED";
216 }
217}
218
219
220/**
221 * Convert validation state to human-readable string.
222 *
223 * @param state the state value
224 * @return corresponding string
225 */
226const char *
227GNUNET_TRANSPORT_vs2s (enum GNUNET_TRANSPORT_ValidationState state)
228{
229 switch (state)
230 {
231 case GNUNET_TRANSPORT_VS_NONE:
232 return "NONE";
233 case GNUNET_TRANSPORT_VS_NEW:
234 return "NEW";
235 case GNUNET_TRANSPORT_VS_REMOVE:
236 return "REMOVE";
237 case GNUNET_TRANSPORT_VS_TIMEOUT:
238 return "TIMEOUT";
239 case GNUNET_TRANSPORT_VS_UPDATE:
240 return "UPDATE";
241 default:
242 GNUNET_break (0);
243 return "UNDEFINED";
244 }
245}
246
247
248/**
249 * Function called with responses from the service.
250 *
251 * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*'
252 * @param msg NULL on timeout or error, otherwise presumably a
253 * message with the human-readable address
254 */
255static void
256peer_response_processor (void *cls,
257 const struct GNUNET_MessageHeader *msg);
258
259
260/**
261 * Function called with responses from the service.
262 *
263 * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*'
264 * @param msg NULL on timeout or error, otherwise presumably a
265 * message with the human-readable address
266 */
267static void
268val_response_processor (void *cls,
269 const struct GNUNET_MessageHeader *msg);
270
271
272/**
273 * Send our subscription request to the service.
274 *
275 * @param pal_ctx our context
276 */
277static void
278send_peer_mon_request (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx)
279{
280 struct PeerMonitorMessage msg;
281
282 msg.header.size = htons (sizeof (struct PeerMonitorMessage));
283 msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST);
284 msg.one_shot = htonl (pal_ctx->one_shot);
285 msg.peer = pal_ctx->peer;
286 GNUNET_assert (GNUNET_OK ==
287 GNUNET_CLIENT_transmit_and_get_response (pal_ctx->client,
288 &msg.header,
289 GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout),
290 GNUNET_YES,
291 &peer_response_processor,
292 pal_ctx));
293}
294
295
296/**
297 * Send our subscription request to the service.
298 *
299 * @param val_ctx our context
300 */
301static void
302send_val_mon_request (struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx)
303{
304 struct ValidationMonitorMessage msg;
305
306 msg.header.size = htons (sizeof (struct ValidationMonitorMessage));
307 msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_REQUEST);
308 msg.one_shot = htonl (val_ctx->one_shot);
309 msg.peer = val_ctx->peer;
310 GNUNET_assert (GNUNET_OK ==
311 GNUNET_CLIENT_transmit_and_get_response (val_ctx->client,
312 &msg.header,
313 GNUNET_TIME_absolute_get_remaining (val_ctx->timeout),
314 GNUNET_YES,
315 &val_response_processor,
316 val_ctx));
317}
318
319/**
320 * Task run to re-establish the connection.
321 *
322 * @param cls our `struct GNUNET_TRANSPORT_PeerAddressLookupContext *`
323 * @param tc scheduler context, unused
324 */
325static void
326do_peer_connect (void *cls,
327 const struct GNUNET_SCHEDULER_TaskContext *tc)
328{
329 struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
330
331 pal_ctx->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
332 pal_ctx->client = GNUNET_CLIENT_connect ("transport", pal_ctx->cfg);
333 GNUNET_assert (NULL != pal_ctx->client);
334 send_peer_mon_request (pal_ctx);
335}
336
337
338/**
339 * Cut the existing connection and reconnect.
340 *
341 * @param pal_ctx our context
342 */
343static void
344reconnect_peer_ctx (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx)
345{
346 GNUNET_assert (GNUNET_NO == pal_ctx->one_shot);
347 GNUNET_CLIENT_disconnect (pal_ctx->client);
348 pal_ctx->client = NULL;
349 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
350 GNUNET_TRANSPORT_PS_NOT_CONNECTED,
351 GNUNET_TIME_UNIT_ZERO_ABS);
352 pal_ctx->backoff = GNUNET_TIME_STD_BACKOFF (pal_ctx->backoff);
353 pal_ctx->reconnect_task = GNUNET_SCHEDULER_add_delayed (pal_ctx->backoff,
354 &do_peer_connect,
355 pal_ctx);
356}
357
358
359/**
360 * Task run to re-establish the connection.
361 *
362 * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*'
363 * @param tc scheduler context, unused
364 */
365static void
366do_val_connect (void *cls,
367 const struct GNUNET_SCHEDULER_TaskContext *tc)
368{
369 struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx = cls;
370
371 val_ctx->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
372 val_ctx->client = GNUNET_CLIENT_connect ("transport", val_ctx->cfg);
373 GNUNET_assert (NULL != val_ctx->client);
374 send_val_mon_request (val_ctx);
375}
376
377
378/**
379 * Cut the existing connection and reconnect.
380 *
381 * @param val_ctx our context
382 */
383static void
384reconnect_val_ctx (struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx)
385{
386 GNUNET_assert (GNUNET_NO == val_ctx->one_shot);
387 GNUNET_CLIENT_disconnect (val_ctx->client);
388 val_ctx->client = NULL;
389 /* notify clients about (re)connect */
390 val_ctx->cb (val_ctx->cb_cls, NULL, NULL,
391 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
392 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_TIMEOUT);
393 val_ctx->backoff = GNUNET_TIME_STD_BACKOFF (val_ctx->backoff);
394 val_ctx->reconnect_task = GNUNET_SCHEDULER_add_delayed (val_ctx->backoff,
395 &do_val_connect,
396 val_ctx);
397}
398
399
400/**
401 * Function called with responses from the service.
402 *
403 * @param cls our `struct GNUNET_TRANSPORT_PeerMonitoringContext *`
404 * @param msg NULL on timeout or error, otherwise presumably a
405 * message with the human-readable address
406 */
407static void
408val_response_processor (void *cls,
409 const struct GNUNET_MessageHeader *msg)
410{
411 struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx = cls;
412 struct ValidationIterateResponseMessage *vr_msg;
413 struct GNUNET_HELLO_Address *address;
414 const char *addr;
415 const char *transport_name;
416 size_t size;
417 size_t tlen;
418 size_t alen;
419
420 if (NULL == msg)
421 {
422 if (val_ctx->one_shot)
423 {
424 /* Disconnect */
425 val_ctx->cb (val_ctx->cb_cls, NULL, NULL,
426 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
427 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_TIMEOUT);
428 GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
429 }
430 else
431 {
432 reconnect_val_ctx (val_ctx);
433 }
434 return;
435 }
436 size = ntohs (msg->size);
437 GNUNET_break (ntohs (msg->type) ==
438 GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_RESPONSE);
439
440 if (size == sizeof (struct GNUNET_MessageHeader))
441 {
442 /* Done! */
443 if (val_ctx->one_shot)
444 {
445 val_ctx->cb (val_ctx->cb_cls, NULL, NULL,
446 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
447 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
448 GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
449 }
450 else
451 {
452 reconnect_val_ctx (val_ctx);
453 }
454 return;
455 }
456
457 if ((size < sizeof (struct ValidationIterateResponseMessage)) ||
458 (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_RESPONSE))
459 {
460 GNUNET_break (0);
461 if (val_ctx->one_shot)
462 {
463 val_ctx->cb (val_ctx->cb_cls, NULL, NULL,
464 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
465 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
466 GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
467 }
468 else
469 {
470 reconnect_val_ctx (val_ctx);
471 }
472 return;
473 }
474
475 vr_msg = (struct ValidationIterateResponseMessage *) msg;
476 tlen = ntohl (vr_msg->pluginlen);
477 alen = ntohl (vr_msg->addrlen);
478
479 if (size != sizeof (struct ValidationIterateResponseMessage) + tlen + alen)
480 {
481 GNUNET_break (0);
482 if (val_ctx->one_shot)
483 {
484 val_ctx->cb (val_ctx->cb_cls, NULL, NULL,
485 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
486 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
487 GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
488 }
489 else
490 {
491 reconnect_val_ctx (val_ctx);
492 }
493 return;
494 }
495 if ( (0 == tlen) && (0 == alen) )
496 {
497 GNUNET_break (0);
498 if (val_ctx->one_shot)
499 {
500 val_ctx->cb (val_ctx->cb_cls, NULL, NULL,
501 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
502 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
503 GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
504 }
505 else
506 {
507 reconnect_val_ctx (val_ctx);
508 }
509 return;
510 }
511 else
512 {
513 if (0 == tlen)
514 {
515 GNUNET_break (0); /* This must not happen: address without plugin */
516 return;
517 }
518 addr = (const char *) &vr_msg[1];
519 transport_name = &addr[alen];
520
521 if (transport_name[tlen - 1] != '\0')
522 {
523 /* Corrupt plugin name */
524 GNUNET_break (0);
525 if (val_ctx->one_shot)
526 {
527 val_ctx->cb (val_ctx->cb_cls,
528 NULL, NULL,
529 GNUNET_TIME_UNIT_ZERO_ABS,
530 GNUNET_TIME_UNIT_ZERO_ABS,
531 GNUNET_TIME_UNIT_ZERO_ABS,
532 GNUNET_TRANSPORT_VS_NONE);
533 GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
534 }
535 else
536 {
537 reconnect_val_ctx (val_ctx);
538 }
539 return;
540 }
541
542 /* notify client */
543 address = GNUNET_HELLO_address_allocate (&vr_msg->peer,
544 transport_name,
545 addr, alen,
546 ntohl (vr_msg->local_address_info));
547 val_ctx->cb (val_ctx->cb_cls,
548 &vr_msg->peer,
549 address,
550 GNUNET_TIME_absolute_ntoh (vr_msg->last_validation),
551 GNUNET_TIME_absolute_ntoh (vr_msg->valid_until),
552 GNUNET_TIME_absolute_ntoh (vr_msg->next_validation),
553 ntohl(vr_msg->state));
554 GNUNET_HELLO_address_free (address);
555 }
556 /* expect more replies */
557 GNUNET_CLIENT_receive (val_ctx->client,
558 &val_response_processor,
559 val_ctx,
560 GNUNET_TIME_absolute_get_remaining (val_ctx->timeout));
561}
562
563
564/**
565 * Function called with responses from the service.
566 *
567 * @param cls our `struct GNUNET_TRANSPORT_PeerMonitoringContext *`
568 * @param msg NULL on timeout or error, otherwise presumably a
569 * message with the human-readable address
570 */
571static void
572peer_response_processor (void *cls,
573 const struct GNUNET_MessageHeader *msg)
574{
575 struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
576 struct PeerIterateResponseMessage *pir_msg;
577 struct GNUNET_HELLO_Address *address;
578 const char *addr;
579 const char *transport_name;
580 uint16_t size;
581 size_t alen;
582 size_t tlen;
583
584 if (NULL == msg)
585 {
586 if (pal_ctx->one_shot)
587 {
588 /* Disconnect */
589 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
590 GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
591 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
592 }
593 else
594 {
595 reconnect_peer_ctx (pal_ctx);
596 }
597 return;
598 }
599 size = ntohs (msg->size);
600 GNUNET_break (ntohs (msg->type) ==
601 GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE);
602 if (size == sizeof (struct GNUNET_MessageHeader))
603 {
604 /* Done! */
605 if (pal_ctx->one_shot)
606 {
607 /* iteration finished */
608 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
609 GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
610 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
611 }
612 else
613 {
614 reconnect_peer_ctx (pal_ctx);
615 }
616 return;
617 }
618
619 if ((size < sizeof (struct PeerIterateResponseMessage)) ||
620 (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE))
621 {
622 GNUNET_break (0);
623 if (pal_ctx->one_shot)
624 {
625 /* iteration finished (with error) */
626 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
627 GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
628 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
629 }
630 else
631 {
632 reconnect_peer_ctx (pal_ctx);
633 }
634 return;
635 }
636
637 pir_msg = (struct PeerIterateResponseMessage *) msg;
638 tlen = ntohl (pir_msg->pluginlen);
639 alen = ntohl (pir_msg->addrlen);
640
641 if (size != sizeof (struct PeerIterateResponseMessage) + tlen + alen)
642 {
643 GNUNET_break (0);
644 if (pal_ctx->one_shot)
645 {
646 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
647 GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
648 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
649 }
650 else
651 {
652 reconnect_peer_ctx (pal_ctx);
653 }
654 return;
655 }
656
657 if ( (0 == tlen) && (0 == alen) )
658 {
659 /* No address available */
660 pal_ctx->cb (pal_ctx->cb_cls, &pir_msg->peer, NULL,
661 ntohl(pir_msg->state),
662 GNUNET_TIME_absolute_ntoh (pir_msg->state_timeout));
663 }
664 else
665 {
666 if (0 == tlen)
667 {
668 GNUNET_break (0); /* This must not happen: address without plugin */
669 return;
670 }
671 addr = (const char *) &pir_msg[1];
672 transport_name = &addr[alen];
673
674 if (transport_name[tlen - 1] != '\0')
675 {
676 /* Corrupt plugin name */
677 GNUNET_break (0);
678 if (pal_ctx->one_shot)
679 {
680 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
681 GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
682 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
683 }
684 else
685 {
686 reconnect_peer_ctx (pal_ctx);
687 }
688 return;
689 }
690
691 /* notify client */
692 address = GNUNET_HELLO_address_allocate (&pir_msg->peer,
693 transport_name, addr, alen, ntohl(pir_msg->local_address_info));
694 pal_ctx->cb (pal_ctx->cb_cls, &pir_msg->peer, address,
695 ntohl(pir_msg->state),
696 GNUNET_TIME_absolute_ntoh (pir_msg->state_timeout));
697 GNUNET_HELLO_address_free (address);
698
699 }
700
701 /* expect more replies */
702 GNUNET_CLIENT_receive (pal_ctx->client, &peer_response_processor,
703 pal_ctx,
704 GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout));
705}
706
707
708/**
709 * Return information about a specific peer or all peers currently known to
710 * transport service once or in monitoring mode. To obtain information about
711 * a specific peer, a peer identity can be passed. To obtain information about
712 * all peers currently known to transport service, NULL can be passed as peer
713 * identity.
714 *
715 * For each peer, the callback is called with information about the address used
716 * to communicate with this peer, the state this peer is currently in and the
717 * the current timeout for this state.
718 *
719 * Upon completion, the 'GNUNET_TRANSPORT_PeerIterateCallback' is called one
720 * more time with 'NULL'. After this, the operation must no longer be
721 * explicitly canceled.
722 *
723 * The #GNUNET_TRANSPORT_monitor_peers_cancel call MUST not be called in the
724 * the peer_callback!
725 *
726 * @param cfg configuration to use
727 * @param peer a specific peer identity to obtain information for,
728 * NULL for all peers
729 * @param one_shot #GNUNET_YES to return the current state and then end (with NULL+NULL),
730 * #GNUNET_NO to monitor peers continuously
731 * @param timeout how long is the lookup allowed to take at most
732 * @param peer_callback function to call with the results
733 * @param peer_callback_cls closure for @a peer_address_callback
734 */
735struct GNUNET_TRANSPORT_PeerMonitoringContext *
736GNUNET_TRANSPORT_monitor_peers (const struct GNUNET_CONFIGURATION_Handle *cfg,
737 const struct GNUNET_PeerIdentity *peer,
738 int one_shot,
739 struct GNUNET_TIME_Relative timeout,
740 GNUNET_TRANSPORT_PeerIterateCallback peer_callback,
741 void *peer_callback_cls)
742{
743 struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx;
744 struct GNUNET_CLIENT_Connection *client;
745
746 client = GNUNET_CLIENT_connect ("transport", cfg);
747 if (client == NULL)
748 return NULL;
749 if (GNUNET_YES != one_shot)
750 timeout = GNUNET_TIME_UNIT_FOREVER_REL;
751 pal_ctx = GNUNET_new (struct GNUNET_TRANSPORT_PeerMonitoringContext);
752 pal_ctx->cb = peer_callback;
753 pal_ctx->cb_cls = peer_callback_cls;
754 pal_ctx->cfg = cfg;
755 pal_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
756 if (NULL != peer)
757 pal_ctx->peer = *peer;
758 pal_ctx->one_shot = one_shot;
759 pal_ctx->client = client;
760 send_peer_mon_request (pal_ctx);
761
762 return pal_ctx;
763}
764
765
766/**
767 * Cancel request to monitor peers
768 *
769 * @param pic handle for the request to cancel
770 */
771void
772GNUNET_TRANSPORT_monitor_peers_cancel (struct GNUNET_TRANSPORT_PeerMonitoringContext *pic)
773{
774 if (NULL != pic->client)
775 {
776 GNUNET_CLIENT_disconnect (pic->client);
777 pic->client = NULL;
778 }
779 if (GNUNET_SCHEDULER_NO_TASK != pic->reconnect_task)
780 {
781 GNUNET_SCHEDULER_cancel (pic->reconnect_task);
782 pic->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
783 }
784 GNUNET_free (pic);
785}
786
787
788/**
789 * Return information about pending address validation operations for a specific
790 * or all peers
791 *
792 * @param cfg configuration to use
793 * @param peer a specific peer identity to obtain validation entries for,
794 * NULL for all peers
795 * @param one_shot #GNUNET_YES to return all entries and then end (with NULL+NULL),
796 * #GNUNET_NO to monitor validation entries continuously
797 * @param timeout how long is the lookup allowed to take at most
798 * @param validation_callback function to call with the results
799 * @param validation_callback_cls closure for peer_address_callback
800 */
801struct GNUNET_TRANSPORT_ValidationMonitoringContext *
802GNUNET_TRANSPORT_monitor_validation_entries (const struct GNUNET_CONFIGURATION_Handle *cfg,
803 const struct GNUNET_PeerIdentity *peer,
804 int one_shot,
805 struct GNUNET_TIME_Relative timeout,
806 GNUNET_TRANSPORT_ValidationIterateCallback validation_callback,
807 void *validation_callback_cls)
808{
809 struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx;
810 struct GNUNET_CLIENT_Connection *client;
811
812 client = GNUNET_CLIENT_connect ("transport", cfg);
813 if (client == NULL)
814 return NULL;
815 if (GNUNET_YES != one_shot)
816 timeout = GNUNET_TIME_UNIT_FOREVER_REL;
817 val_ctx = GNUNET_new (struct GNUNET_TRANSPORT_ValidationMonitoringContext);
818 val_ctx->cb = validation_callback;
819 val_ctx->cb_cls = validation_callback_cls;
820 val_ctx->cfg = cfg;
821 val_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
822 if (NULL != peer)
823 val_ctx->peer = *peer;
824 val_ctx->one_shot = one_shot;
825 val_ctx->client = client;
826 send_val_mon_request (val_ctx);
827
828 return val_ctx;
829}
830
831
832/**
833 * Return information about all current pending validation operations
834 *
835 * @param vic handle for the request to cancel
836 */
837void
838GNUNET_TRANSPORT_monitor_validation_entries_cancel (struct GNUNET_TRANSPORT_ValidationMonitoringContext *vic)
839{
840 if (NULL != vic->client)
841 {
842 GNUNET_CLIENT_disconnect (vic->client);
843 vic->client = NULL;
844 }
845 if (GNUNET_SCHEDULER_NO_TASK != vic->reconnect_task)
846 {
847 GNUNET_SCHEDULER_cancel (vic->reconnect_task);
848 vic->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
849 }
850 GNUNET_free (vic);
851}
852
853
854/* end of transport_api_monitoring.c */