2 This file is part of GNUnet.
3 (C) 2009, 2010 Christian Grothoff (and other contributing authors)
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.
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.
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.
22 * @file transport/transport_api_monitoring.c
23 * @brief montoring api for transport peer status and validation entries
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.
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.
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"
41 * Context for iterating validation entries.
43 struct GNUNET_TRANSPORT_PeerMonitoringContext
46 * Function to call with the binary address.
48 GNUNET_TRANSPORT_PeerIterateCallback cb;
56 * Connection to the service.
58 struct GNUNET_CLIENT_Connection *client;
61 * Configuration we use.
63 const struct GNUNET_CONFIGURATION_Handle *cfg;
66 * When should this operation time out?
68 struct GNUNET_TIME_Absolute timeout;
71 * Backoff for reconnect.
73 struct GNUNET_TIME_Relative backoff;
76 * Task ID for reconnect.
78 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
81 * Identity of the peer to monitor.
83 struct GNUNET_PeerIdentity peer;
86 * Was this a one-shot request?
93 * Context for the address lookup.
95 struct GNUNET_TRANSPORT_ValidationMonitoringContext
98 * Function to call with the binary address.
100 GNUNET_TRANSPORT_ValidationIterateCallback cb;
108 * Connection to the service.
110 struct GNUNET_CLIENT_Connection *client;
113 * Configuration we use.
115 const struct GNUNET_CONFIGURATION_Handle *cfg;
118 * When should this operation time out?
120 struct GNUNET_TIME_Absolute timeout;
123 * Backoff for reconnect.
125 struct GNUNET_TIME_Relative backoff;
128 * Task ID for reconnect.
130 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
133 * Identity of the peer to monitor.
135 struct GNUNET_PeerIdentity peer;
138 * Was this a one-shot request?
144 * Check if a state is defined as connected
146 * @param state the state value
147 * @return GNUNET_YES or GNUNET_NO
150 GNUNET_TRANSPORT_is_connected (enum GNUNET_TRANSPORT_PeerState state)
154 case GNUNET_TRANSPORT_PS_NOT_CONNECTED:
155 case GNUNET_TRANSPORT_PS_INIT_ATS:
156 case GNUNET_TRANSPORT_PS_INIT_BLACKLIST:
157 case GNUNET_TRANSPORT_PS_CONNECT_SENT:
158 case GNUNET_TRANSPORT_PS_CONNECT_RECV_BLACKLIST_INBOUND:
159 case GNUNET_TRANSPORT_PS_CONNECT_RECV_ATS:
160 case GNUNET_TRANSPORT_PS_CONNECT_RECV_BLACKLIST:
161 case GNUNET_TRANSPORT_PS_CONNECT_RECV_ACK:
163 case GNUNET_TRANSPORT_PS_CONNECTED:
164 case GNUNET_TRANSPORT_PS_RECONNECT_ATS:
165 case GNUNET_TRANSPORT_PS_RECONNECT_BLACKLIST:
166 case GNUNET_TRANSPORT_PS_RECONNECT_SENT:
167 case GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_BLACKLIST:
168 case GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_CONNECT_SENT:
170 case GNUNET_TRANSPORT_PS_DISCONNECT:
171 case GNUNET_TRANSPORT_PS_DISCONNECT_FINISHED:
174 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
175 "Unhandled state `%s' \n",
176 GNUNET_TRANSPORT_ps2s (state));
180 return GNUNET_SYSERR;
184 * Convert peer state to human-readable string.
186 * @param state the state value
187 * @return corresponding string
190 GNUNET_TRANSPORT_ps2s (enum GNUNET_TRANSPORT_PeerState state)
194 case GNUNET_TRANSPORT_PS_NOT_CONNECTED:
195 return "S_NOT_CONNECTED";
196 case GNUNET_TRANSPORT_PS_INIT_ATS:
198 case GNUNET_TRANSPORT_PS_INIT_BLACKLIST:
199 return "S_INIT_BLACKLIST";
200 case GNUNET_TRANSPORT_PS_CONNECT_SENT:
201 return "S_CONNECT_SENT";
202 case GNUNET_TRANSPORT_PS_CONNECT_RECV_BLACKLIST_INBOUND:
203 return "S_CONNECT_RECV_BLACKLIST_INBOUND";
204 case GNUNET_TRANSPORT_PS_CONNECT_RECV_ATS:
205 return "S_CONNECT_RECV_ATS";
206 case GNUNET_TRANSPORT_PS_CONNECT_RECV_BLACKLIST:
207 return "S_CONNECT_RECV_BLACKLIST";
208 case GNUNET_TRANSPORT_PS_CONNECT_RECV_ACK:
209 return "S_CONNECT_RECV_ACK";
210 case GNUNET_TRANSPORT_PS_CONNECTED:
211 return "S_CONNECTED";
212 case GNUNET_TRANSPORT_PS_RECONNECT_ATS:
213 return "S_RECONNECT_ATS";
214 case GNUNET_TRANSPORT_PS_RECONNECT_BLACKLIST:
215 return "S_RECONNECT_BLACKLIST";
216 case GNUNET_TRANSPORT_PS_RECONNECT_SENT:
217 return "S_RECONNECT_SENT";
218 case GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_BLACKLIST:
219 return "S_CONNECTED_SWITCHING_BLACKLIST";
220 case GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_CONNECT_SENT:
221 return "S_CONNECTED_SWITCHING_CONNECT_SENT";
222 case GNUNET_TRANSPORT_PS_DISCONNECT:
223 return "S_DISCONNECT";
224 case GNUNET_TRANSPORT_PS_DISCONNECT_FINISHED:
225 return "S_DISCONNECT_FINISHED";
233 * Convert validation state to human-readable string.
235 * @param state the state value
236 * @return corresponding string
239 GNUNET_TRANSPORT_vs2s (enum GNUNET_TRANSPORT_ValidationState state)
243 case GNUNET_TRANSPORT_VS_NEW:
245 case GNUNET_TRANSPORT_VS_REMOVE:
247 case GNUNET_TRANSPORT_VS_TIMEOUT:
249 case GNUNET_TRANSPORT_VS_UPDATE:
259 * Function called with responses from the service.
261 * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*'
262 * @param msg NULL on timeout or error, otherwise presumably a
263 * message with the human-readable address
266 peer_response_processor (void *cls, const struct GNUNET_MessageHeader *msg);
270 * Function called with responses from the service.
272 * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*'
273 * @param msg NULL on timeout or error, otherwise presumably a
274 * message with the human-readable address
277 val_response_processor (void *cls, const struct GNUNET_MessageHeader *msg);
280 * Send our subscription request to the service.
282 * @param pal_ctx our context
285 send_peer_mon_request (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx)
287 struct PeerMonitorMessage msg;
289 msg.header.size = htons (sizeof (struct PeerMonitorMessage));
290 msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST);
291 msg.one_shot = htonl (pal_ctx->one_shot);
292 msg.peer = pal_ctx->peer;
293 GNUNET_assert (GNUNET_OK ==
294 GNUNET_CLIENT_transmit_and_get_response (pal_ctx->client,
296 GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout),
298 &peer_response_processor,
303 * Send our subscription request to the service.
305 * @param pal_ctx our context
308 send_val_mon_request (struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx)
310 struct ValidationMonitorMessage msg;
312 msg.header.size = htons (sizeof (struct PeerMonitorMessage));
313 msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_REQUEST);
314 msg.one_shot = htonl (val_ctx->one_shot);
315 msg.peer = val_ctx->peer;
316 GNUNET_assert (GNUNET_OK ==
317 GNUNET_CLIENT_transmit_and_get_response (val_ctx->client,
319 GNUNET_TIME_absolute_get_remaining (val_ctx->timeout),
321 &val_response_processor,
327 * Task run to re-establish the connection.
329 * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*'
330 * @param tc scheduler context, unused
333 do_connect (void *cls,
334 const struct GNUNET_SCHEDULER_TaskContext *tc)
336 struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
338 pal_ctx->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
339 pal_ctx->client = GNUNET_CLIENT_connect ("transport", pal_ctx->cfg);
340 GNUNET_assert (NULL != pal_ctx->client);
341 send_peer_mon_request (pal_ctx);
346 * Cut the existing connection and reconnect.
348 * @param pal_ctx our context
351 reconnect_peer_ctx (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx)
353 GNUNET_assert (GNUNET_NO == pal_ctx->one_shot);
354 GNUNET_CLIENT_disconnect (pal_ctx->client);
355 pal_ctx->client = NULL;
356 pal_ctx->backoff = GNUNET_TIME_STD_BACKOFF (pal_ctx->backoff);
357 pal_ctx->reconnect_task = GNUNET_SCHEDULER_add_delayed (pal_ctx->backoff,
363 * Cut the existing connection and reconnect.
365 * @param pal_ctx our context
368 reconnect_val_ctx (struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx)
370 GNUNET_assert (GNUNET_NO == val_ctx->one_shot);
371 GNUNET_CLIENT_disconnect (val_ctx->client);
372 val_ctx->client = NULL;
373 val_ctx->backoff = GNUNET_TIME_STD_BACKOFF (val_ctx->backoff);
374 val_ctx->reconnect_task = GNUNET_SCHEDULER_add_delayed (val_ctx->backoff,
380 * Function called with responses from the service.
382 * @param cls our 'struct GNUNET_TRANSPORT_PeerMonitoringContext*'
383 * @param msg NULL on timeout or error, otherwise presumably a
384 * message with the human-readable address
387 val_response_processor (void *cls, const struct GNUNET_MessageHeader *msg)
389 struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx = cls;
390 struct ValidationIterateResponseMessage *vr_msg;
391 struct GNUNET_HELLO_Address *address;
393 const char *transport_name;
401 if (val_ctx->one_shot)
404 val_ctx->cb (val_ctx->cb_cls, NULL, NULL,
405 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
406 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_TIMEOUT);
407 GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
411 reconnect_val_ctx (val_ctx);
415 size = ntohs (msg->size);
416 GNUNET_break (ntohs (msg->type) ==
417 GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_RESPONSE);
418 if (size == sizeof (struct GNUNET_MessageHeader))
421 if (val_ctx->one_shot)
423 val_ctx->cb (val_ctx->cb_cls, NULL, NULL,
424 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
425 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
426 GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
430 reconnect_val_ctx (val_ctx);
435 if ((size < sizeof (struct ValidationIterateResponseMessage)) ||
436 (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_RESPONSE))
439 if (val_ctx->one_shot)
441 val_ctx->cb (val_ctx->cb_cls, NULL, NULL,
442 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
443 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
444 GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
448 reconnect_val_ctx (val_ctx);
453 vr_msg = (struct ValidationIterateResponseMessage *) msg;
454 tlen = ntohl (vr_msg->pluginlen);
455 alen = ntohl (vr_msg->addrlen);
457 if (size != sizeof (struct ValidationIterateResponseMessage) + tlen + alen)
460 if (val_ctx->one_shot)
462 val_ctx->cb (val_ctx->cb_cls, NULL, NULL,
463 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
464 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
465 GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
469 reconnect_val_ctx (val_ctx);
473 if ( (0 == tlen) && (0 == alen) )
476 if (val_ctx->one_shot)
478 val_ctx->cb (val_ctx->cb_cls, NULL, NULL,
479 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
480 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
481 GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
485 reconnect_val_ctx (val_ctx);
493 GNUNET_break (0); /* This must not happen: address without plugin */
496 addr = (const char *) &vr_msg[1];
497 transport_name = &addr[alen];
499 if (transport_name[tlen - 1] != '\0')
501 /* Corrupt plugin name */
503 if (val_ctx->one_shot)
505 val_ctx->cb (val_ctx->cb_cls, NULL, NULL,
506 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
507 GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
508 GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
512 reconnect_val_ctx (val_ctx);
518 address = GNUNET_HELLO_address_allocate (&vr_msg->peer,
519 transport_name, addr, alen, ntohl(vr_msg->local_address_info));
520 val_ctx->cb (val_ctx->cb_cls, &vr_msg->peer, address,
521 GNUNET_TIME_absolute_ntoh(vr_msg->last_validation),
522 GNUNET_TIME_absolute_ntoh(vr_msg->valid_until),
523 GNUNET_TIME_absolute_ntoh(vr_msg->next_validation),
524 ntohl(vr_msg->state));
525 GNUNET_HELLO_address_free (address);
527 /* expect more replies */
528 GNUNET_CLIENT_receive (val_ctx->client, &val_response_processor,
529 val_ctx, GNUNET_TIME_absolute_get_remaining (val_ctx->timeout));
534 * Function called with responses from the service.
536 * @param cls our 'struct GNUNET_TRANSPORT_PeerMonitoringContext*'
537 * @param msg NULL on timeout or error, otherwise presumably a
538 * message with the human-readable address
541 peer_response_processor (void *cls, const struct GNUNET_MessageHeader *msg)
543 struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
544 struct PeerIterateResponseMessage *pir_msg;
545 struct GNUNET_HELLO_Address *address;
547 const char *transport_name;
554 if (pal_ctx->one_shot)
557 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
558 GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
559 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
563 reconnect_peer_ctx (pal_ctx);
567 size = ntohs (msg->size);
568 GNUNET_break (ntohs (msg->type) ==
569 GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE);
570 if (size == sizeof (struct GNUNET_MessageHeader))
573 if (pal_ctx->one_shot)
575 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
576 GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
577 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
581 reconnect_peer_ctx (pal_ctx);
586 if ((size < sizeof (struct PeerIterateResponseMessage)) ||
587 (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE))
590 if (pal_ctx->one_shot)
592 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
593 GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
594 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
598 reconnect_peer_ctx (pal_ctx);
603 pir_msg = (struct PeerIterateResponseMessage *) msg;
604 tlen = ntohl (pir_msg->pluginlen);
605 alen = ntohl (pir_msg->addrlen);
607 if (size != sizeof (struct PeerIterateResponseMessage) + tlen + alen)
610 if (pal_ctx->one_shot)
612 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
613 GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
614 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
618 reconnect_peer_ctx (pal_ctx);
623 if ( (0 == tlen) && (0 == alen) )
625 /* No address available */
626 pal_ctx->cb (pal_ctx->cb_cls, &pir_msg->peer, NULL,
627 ntohl(pir_msg->state),
628 GNUNET_TIME_absolute_ntoh (pir_msg->state_timeout));
634 GNUNET_break (0); /* This must not happen: address without plugin */
637 addr = (const char *) &pir_msg[1];
638 transport_name = &addr[alen];
640 if (transport_name[tlen - 1] != '\0')
642 /* Corrupt plugin name */
644 if (pal_ctx->one_shot)
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);
652 reconnect_peer_ctx (pal_ctx);
658 address = GNUNET_HELLO_address_allocate (&pir_msg->peer,
659 transport_name, addr, alen, ntohl(pir_msg->local_address_info));
660 pal_ctx->cb (pal_ctx->cb_cls, &pir_msg->peer, address,
661 ntohl(pir_msg->state),
662 GNUNET_TIME_absolute_ntoh (pir_msg->state_timeout));
663 GNUNET_HELLO_address_free (address);
667 /* expect more replies */
668 GNUNET_CLIENT_receive (pal_ctx->client, &peer_response_processor,
670 GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout));
675 * Return information about a specific peer or all peers currently known to
676 * transport service once or in monitoring mode. To obtain information about
677 * a specific peer, a peer identity can be passed. To obtain information about
678 * all peers currently known to transport service, NULL can be passed as peer
681 * For each peer, the callback is called with information about the address used
682 * to communicate with this peer, the state this peer is currently in and the
683 * the current timeout for this state.
685 * Upon completion, the 'GNUNET_TRANSPORT_PeerIterateCallback' is called one
686 * more time with 'NULL'. After this, the operation must no longer be
687 * explicitly canceled.
689 * The #GNUNET_TRANSPORT_monitor_peers_cancel call MUST not be called in the
692 * @param cfg configuration to use
693 * @param peer a specific peer identity to obtain information for,
695 * @param one_shot GNUNET_YES to return the current state and then end (with NULL+NULL),
696 * GNUNET_NO to monitor peers continuously
697 * @param timeout how long is the lookup allowed to take at most
698 * @param peer_callback function to call with the results
699 * @param peer_callback_cls closure for peer_address_callback
701 struct GNUNET_TRANSPORT_PeerMonitoringContext *
702 GNUNET_TRANSPORT_monitor_peers (const struct GNUNET_CONFIGURATION_Handle *cfg,
703 const struct GNUNET_PeerIdentity *peer,
705 struct GNUNET_TIME_Relative timeout,
706 GNUNET_TRANSPORT_PeerIterateCallback peer_callback,
707 void *peer_callback_cls)
709 struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx;
710 struct GNUNET_CLIENT_Connection *client;
712 client = GNUNET_CLIENT_connect ("transport", cfg);
715 if (GNUNET_YES != one_shot)
716 timeout = GNUNET_TIME_UNIT_FOREVER_REL;
717 pal_ctx = GNUNET_new (struct GNUNET_TRANSPORT_PeerMonitoringContext);
718 pal_ctx->cb = peer_callback;
719 pal_ctx->cb_cls = peer_callback_cls;
721 pal_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
723 pal_ctx->peer = *peer;
724 pal_ctx->one_shot = one_shot;
725 pal_ctx->client = client;
726 send_peer_mon_request (pal_ctx);
733 * Cancel request to monitor peers
735 * @param pic handle for the request to cancel
738 GNUNET_TRANSPORT_monitor_peers_cancel (struct GNUNET_TRANSPORT_PeerMonitoringContext *pic)
740 if (NULL != pic->client)
742 GNUNET_CLIENT_disconnect (pic->client);
745 if (GNUNET_SCHEDULER_NO_TASK != pic->reconnect_task)
747 GNUNET_SCHEDULER_cancel (pic->reconnect_task);
748 pic->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
755 * Return information about pending address validation operations for a specific
758 * @param cfg configuration to use
759 * @param peer a specific peer identity to obtain validation entries for,
761 * @param one_shot GNUNET_YES to return all entries and then end (with NULL+NULL),
762 * GNUNET_NO to monitor validation entries continuously
763 * @param timeout how long is the lookup allowed to take at most
764 * @param validation_callback function to call with the results
765 * @param validation_callback_cls closure for peer_address_callback
767 struct GNUNET_TRANSPORT_ValidationMonitoringContext *
768 GNUNET_TRANSPORT_monitor_validation_entries (const struct
769 GNUNET_CONFIGURATION_Handle *cfg,
770 const struct GNUNET_PeerIdentity *peer,
772 struct GNUNET_TIME_Relative timeout,
773 GNUNET_TRANSPORT_ValidationIterateCallback validation_callback,
774 void *validation_callback_cls)
776 struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx;
777 struct GNUNET_CLIENT_Connection *client;
779 client = GNUNET_CLIENT_connect ("transport", cfg);
782 if (GNUNET_YES != one_shot)
783 timeout = GNUNET_TIME_UNIT_FOREVER_REL;
784 val_ctx = GNUNET_new (struct GNUNET_TRANSPORT_ValidationMonitoringContext);
785 val_ctx->cb = validation_callback;
786 val_ctx->cb_cls = validation_callback_cls;
788 val_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
790 val_ctx->peer = *peer;
791 val_ctx->one_shot = one_shot;
792 val_ctx->client = client;
793 send_val_mon_request (val_ctx);
800 * Return information about all current pending validation operations
802 * @param vic handle for the request to cancel
805 GNUNET_TRANSPORT_monitor_validation_entries_cancel (struct GNUNET_TRANSPORT_ValidationMonitoringContext *vic)
807 if (NULL != vic->client)
809 GNUNET_CLIENT_disconnect (vic->client);
812 if (GNUNET_SCHEDULER_NO_TASK != vic->reconnect_task)
814 GNUNET_SCHEDULER_cancel (vic->reconnect_task);
815 vic->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
821 /* end of transport_api_monitoring.c */