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_montoring.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?
146 * Function called with responses from the service.
148 * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*'
149 * @param msg NULL on timeout or error, otherwise presumably a
150 * message with the human-readable address
153 peer_address_response_processor (void *cls,
154 const struct GNUNET_MessageHeader *msg);
158 * Send our subscription request to the service.
160 * @param pal_ctx our context
163 send_request (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx)
165 struct PeerIterateMessage msg;
167 msg.header.size = htons (sizeof (struct PeerIterateMessage));
168 msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE);
169 msg.one_shot = htonl (pal_ctx->one_shot);
170 msg.timeout = GNUNET_TIME_absolute_hton (pal_ctx->timeout);
171 msg.peer = pal_ctx->peer;
172 GNUNET_assert (GNUNET_OK ==
173 GNUNET_CLIENT_transmit_and_get_response (pal_ctx->client,
175 GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout),
177 &peer_address_response_processor,
182 * Task run to re-establish the connection.
184 * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*'
185 * @param tc scheduler context, unused
188 do_connect (void *cls,
189 const struct GNUNET_SCHEDULER_TaskContext *tc)
191 struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
193 pal_ctx->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
194 pal_ctx->client = GNUNET_CLIENT_connect ("transport", pal_ctx->cfg);
195 GNUNET_assert (NULL != pal_ctx->client);
196 send_request (pal_ctx);
201 * Cut the existing connection and reconnect.
203 * @param pal_ctx our context
206 reconnect (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx)
208 GNUNET_assert (GNUNET_NO == pal_ctx->one_shot);
209 GNUNET_CLIENT_disconnect (pal_ctx->client);
210 pal_ctx->client = NULL;
211 pal_ctx->backoff = GNUNET_TIME_STD_BACKOFF (pal_ctx->backoff);
212 pal_ctx->reconnect_task = GNUNET_SCHEDULER_add_delayed (pal_ctx->backoff,
219 * Function called with responses from the service.
221 * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*'
222 * @param msg NULL on timeout or error, otherwise presumably a
223 * message with the human-readable address
226 peer_address_response_processor (void *cls,
227 const struct GNUNET_MessageHeader *msg)
229 struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
230 struct PeerIterateResponseMessage *air_msg;
231 struct GNUNET_HELLO_Address *address;
233 const char *transport_name;
240 if (pal_ctx->one_shot)
242 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
243 S_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
244 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
252 size = ntohs (msg->size);
253 GNUNET_break (ntohs (msg->type) ==
254 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE);
255 if (size == sizeof (struct GNUNET_MessageHeader))
258 if (pal_ctx->one_shot)
260 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
261 S_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
262 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
271 if ((size < sizeof (struct PeerIterateResponseMessage)) ||
272 (ntohs (msg->type) !=
273 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE))
276 if (pal_ctx->one_shot)
278 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
279 S_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
280 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
289 air_msg = (struct PeerIterateResponseMessage *) msg;
290 tlen = ntohl (air_msg->pluginlen);
291 alen = ntohl (air_msg->addrlen);
293 if (size != sizeof (struct PeerIterateResponseMessage) + tlen + alen)
296 if (pal_ctx->one_shot)
298 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
299 S_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
300 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
309 if (alen == 0 && tlen == 0)
311 pal_ctx->cb (pal_ctx->cb_cls, &air_msg->peer, NULL,
312 S_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
316 addr = (const char *) &air_msg[1];
317 transport_name = &addr[alen];
319 if (transport_name[tlen - 1] != '\0')
322 if (pal_ctx->one_shot)
324 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
325 S_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
326 GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
336 address = GNUNET_HELLO_address_allocate (&air_msg->peer,
337 transport_name, addr, alen);
338 pal_ctx->cb (pal_ctx->cb_cls, &air_msg->peer, address,
339 ntohl(air_msg->state),
340 GNUNET_TIME_absolute_ntoh (air_msg->state_timeout));
341 GNUNET_HELLO_address_free (address);
344 /* expect more replies */
345 GNUNET_CLIENT_receive (pal_ctx->client, &peer_address_response_processor,
347 GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout));
352 * Return all the known addresses for a specific peer or all peers.
353 * Returns continuously all address if one_shot is set to GNUNET_NO
355 * CHANGE: Returns the address(es) that we are currently using for this
356 * peer. Upon completion, the 'AddressLookUpCallback' is called one more
357 * time with 'NULL' for the address and the peer. After this, the operation must no
358 * longer be explicitly canceled.
360 * @param cfg configuration to use
361 * @param peer peer identity to look up the addresses of, CHANGE: allow NULL for all (connected) peers
362 * @param one_shot GNUNET_YES to return the current state and then end (with NULL+NULL),
363 * GNUNET_NO to monitor the set of addresses used (continuously, must be explicitly canceled)
364 * @param timeout how long is the lookup allowed to take at most (irrelevant if one_shot is set to GNUNET_NO)
365 * @param peer_address_callback function to call with the results
366 * @param peer_address_callback_cls closure for peer_address_callback
368 struct GNUNET_TRANSPORT_PeerMonitoringContext *
369 GNUNET_TRANSPORT_monitor_peers (const struct GNUNET_CONFIGURATION_Handle *cfg,
370 const struct GNUNET_PeerIdentity *peer,
372 struct GNUNET_TIME_Relative timeout,
373 GNUNET_TRANSPORT_PeerIterateCallback peer_address_callback,
374 void *peer_address_callback_cls)
376 struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx;
377 struct GNUNET_CLIENT_Connection *client;
379 client = GNUNET_CLIENT_connect ("transport", cfg);
382 if (GNUNET_YES != one_shot)
383 timeout = GNUNET_TIME_UNIT_FOREVER_REL;
384 pal_ctx = GNUNET_new (struct GNUNET_TRANSPORT_PeerMonitoringContext);
385 pal_ctx->cb = peer_address_callback;
386 pal_ctx->cb_cls = peer_address_callback_cls;
388 pal_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
390 pal_ctx->peer = *peer;
391 pal_ctx->one_shot = one_shot;
392 pal_ctx->client = client;
393 send_request (pal_ctx);
400 * Cancel request for address conversion.
402 * @param alc handle for the request to cancel
405 GNUNET_TRANSPORT_monitor_peers_cancel (
406 struct GNUNET_TRANSPORT_PeerMonitoringContext *alc)
408 if (NULL != alc->client)
410 GNUNET_CLIENT_disconnect (alc->client);
413 if (GNUNET_SCHEDULER_NO_TASK != alc->reconnect_task)
415 GNUNET_SCHEDULER_cancel (alc->reconnect_task);
416 alc->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
423 * Return information about a peer's or all current pending validation operations
425 * @param cfg configuration to use
426 * @param peer a specific peer identity to obtain validation entries for,
428 * @param one_shot GNUNET_YES to return all entries and then end (with NULL+NULL),
429 * GNUNET_NO to monitor validation entries continuously
430 * @param timeout how long is the lookup allowed to take at most
431 * @param peer_address_callback function to call with the results
432 * @param peer_address_callback_cls closure for peer_address_callback
434 struct GNUNET_TRANSPORT_ValidationMonitoringContext *
435 GNUNET_TRANSPORT_monitor_validation_entries (const struct
436 GNUNET_CONFIGURATION_Handle *cfg,
437 const struct GNUNET_PeerIdentity *peer,
439 struct GNUNET_TIME_Relative timeout,
440 GNUNET_TRANSPORT_ValidationIterateCallback validation_callback,
441 void *validation_callback_cls)
443 /* Not implemented */
449 * Return information about all current pending validation operations
451 * @param vic handle for the request to cancel
454 GNUNET_TRANSPORT_monitor_validation_entries_cancel (struct GNUNET_TRANSPORT_ValidationMonitoringContext *vic)
456 /* Not implemented */
460 /* end of transport_api_montoring.c */