aboutsummaryrefslogtreecommitdiff
path: root/src/transport/transport_api_address_lookup.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2014-01-07 16:00:27 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2014-01-07 16:00:27 +0000
commitcfa7d229b27b9c387351c9bf3c8a9eb7994de13a (patch)
tree4fc0eba5eb000ed230d110cd79b5fe2933d11e97 /src/transport/transport_api_address_lookup.c
parentf4c6b450aa848628fb07d0a9ede9465a81090691 (diff)
downloadgnunet-cfa7d229b27b9c387351c9bf3c8a9eb7994de13a.tar.gz
gnunet-cfa7d229b27b9c387351c9bf3c8a9eb7994de13a.zip
new monitoring API
Diffstat (limited to 'src/transport/transport_api_address_lookup.c')
-rw-r--r--src/transport/transport_api_address_lookup.c364
1 files changed, 0 insertions, 364 deletions
diff --git a/src/transport/transport_api_address_lookup.c b/src/transport/transport_api_address_lookup.c
deleted file mode 100644
index d547b8ed8..000000000
--- a/src/transport/transport_api_address_lookup.c
+++ /dev/null
@@ -1,364 +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_address_lookup.c
23 * @brief given a peer id, get all known addresses from transport service
24 *
25 * This api provides the ability to query the transport service about
26 * the status of connections to a specific peer. Calls back with a
27 * pretty printed string of the address, as formatted by the appropriate
28 * transport plugin, and whether or not the address given is currently
29 * in the 'connected' state (according to the transport service).
30 */
31#include "platform.h"
32#include "gnunet_util_lib.h"
33#include "gnunet_arm_service.h"
34#include "gnunet_hello_lib.h"
35#include "gnunet_protocols.h"
36#include "gnunet_transport_service.h"
37#include "transport.h"
38
39/**
40 * Context for the address lookup.
41 */
42struct GNUNET_TRANSPORT_PeerIterateContext
43{
44 /**
45 * Function to call with the binary address.
46 */
47 GNUNET_TRANSPORT_PeerIterateCallback cb;
48
49 /**
50 * Closure for cb.
51 */
52 void *cb_cls;
53
54 /**
55 * Connection to the service.
56 */
57 struct GNUNET_CLIENT_Connection *client;
58
59 /**
60 * Configuration we use.
61 */
62 const struct GNUNET_CONFIGURATION_Handle *cfg;
63
64 /**
65 * When should this operation time out?
66 */
67 struct GNUNET_TIME_Absolute timeout;
68
69 /**
70 * Backoff for reconnect.
71 */
72 struct GNUNET_TIME_Relative backoff;
73
74 /**
75 * Task ID for reconnect.
76 */
77 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
78
79 /**
80 * Identity of the peer to monitor.
81 */
82 struct GNUNET_PeerIdentity peer;
83
84 /**
85 * Was this a one-shot request?
86 */
87 int one_shot;
88};
89
90
91/**
92 * Function called with responses from the service.
93 *
94 * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*'
95 * @param msg NULL on timeout or error, otherwise presumably a
96 * message with the human-readable address
97 */
98static void
99peer_address_response_processor (void *cls,
100 const struct GNUNET_MessageHeader *msg);
101
102
103/**
104 * Send our subscription request to the service.
105 *
106 * @param pal_ctx our context
107 */
108static void
109send_request (struct GNUNET_TRANSPORT_PeerIterateContext *pal_ctx)
110{
111 struct AddressIterateMessage msg;
112
113 msg.header.size = htons (sizeof (struct AddressIterateMessage));
114 msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE);
115 msg.one_shot = htonl (pal_ctx->one_shot);
116 msg.timeout = GNUNET_TIME_absolute_hton (pal_ctx->timeout);
117 msg.peer = pal_ctx->peer;
118 GNUNET_assert (GNUNET_OK ==
119 GNUNET_CLIENT_transmit_and_get_response (pal_ctx->client,
120 &msg.header,
121 GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout),
122 GNUNET_YES,
123 &peer_address_response_processor,
124 pal_ctx));
125}
126
127/**
128 * Task run to re-establish the connection.
129 *
130 * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*'
131 * @param tc scheduler context, unused
132 */
133static void
134do_connect (void *cls,
135 const struct GNUNET_SCHEDULER_TaskContext *tc)
136{
137 struct GNUNET_TRANSPORT_PeerIterateContext *pal_ctx = cls;
138
139 pal_ctx->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
140 pal_ctx->client = GNUNET_CLIENT_connect ("transport", pal_ctx->cfg);
141 GNUNET_assert (NULL != pal_ctx->client);
142 send_request (pal_ctx);
143}
144
145
146/**
147 * Cut the existing connection and reconnect.
148 *
149 * @param pal_ctx our context
150 */
151static void
152reconnect (struct GNUNET_TRANSPORT_PeerIterateContext *pal_ctx)
153{
154 GNUNET_assert (GNUNET_NO == pal_ctx->one_shot);
155 GNUNET_CLIENT_disconnect (pal_ctx->client);
156 pal_ctx->client = NULL;
157 pal_ctx->backoff = GNUNET_TIME_STD_BACKOFF (pal_ctx->backoff);
158 pal_ctx->reconnect_task = GNUNET_SCHEDULER_add_delayed (pal_ctx->backoff,
159 &do_connect,
160 pal_ctx);
161}
162
163
164/**
165 * Function called with responses from the service.
166 *
167 * @param cls our 'struct GNUNET_TRANSPORT_PeerAddressLookupContext*'
168 * @param msg NULL on timeout or error, otherwise presumably a
169 * message with the human-readable address
170 */
171static void
172peer_address_response_processor (void *cls,
173 const struct GNUNET_MessageHeader *msg)
174{
175 struct GNUNET_TRANSPORT_PeerIterateContext *pal_ctx = cls;
176 struct AddressIterateResponseMessage *air_msg;
177 struct GNUNET_HELLO_Address *address;
178 const char *addr;
179 const char *transport_name;
180 uint16_t size;
181 size_t alen;
182 size_t tlen;
183
184 if (msg == NULL)
185 {
186 if (pal_ctx->one_shot)
187 {
188 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL);
189 GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pal_ctx);
190 }
191 else
192 {
193 reconnect (pal_ctx);
194 }
195 return;
196 }
197 size = ntohs (msg->size);
198 GNUNET_break (ntohs (msg->type) ==
199 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE);
200 if (size == sizeof (struct GNUNET_MessageHeader))
201 {
202 /* done! */
203 if (pal_ctx->one_shot)
204 {
205 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL);
206 GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pal_ctx);
207 }
208 else
209 {
210 reconnect (pal_ctx);
211 }
212 return;
213 }
214
215 if ((size < sizeof (struct AddressIterateResponseMessage)) ||
216 (ntohs (msg->type) !=
217 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE))
218 {
219 GNUNET_break (0);
220 if (pal_ctx->one_shot)
221 {
222 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL);
223 GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pal_ctx);
224 }
225 else
226 {
227 reconnect (pal_ctx);
228 }
229 return;
230 }
231
232 air_msg = (struct AddressIterateResponseMessage *) msg;
233 tlen = ntohl (air_msg->pluginlen);
234 alen = ntohl (air_msg->addrlen);
235
236 if (size != sizeof (struct AddressIterateResponseMessage) + tlen + alen)
237 {
238 GNUNET_break (0);
239 if (pal_ctx->one_shot)
240 {
241 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL);
242 GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pal_ctx);
243 }
244 else
245 {
246 reconnect (pal_ctx);
247 }
248 return;
249 }
250
251 if (alen == 0 && tlen == 0)
252 {
253 pal_ctx->cb (pal_ctx->cb_cls, &air_msg->peer, NULL);
254 }
255 else
256 {
257 addr = (const char *) &air_msg[1];
258 transport_name = &addr[alen];
259
260 if (transport_name[tlen - 1] != '\0')
261 {
262 GNUNET_break (0);
263 if (pal_ctx->one_shot)
264 {
265 pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL);
266 GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pal_ctx);
267 }
268 else
269 {
270 reconnect (pal_ctx);
271 }
272 return;
273 }
274
275 /* notify client */
276 address =
277 GNUNET_HELLO_address_allocate (&air_msg->peer, transport_name, addr,
278 alen);
279 pal_ctx->cb (pal_ctx->cb_cls, &air_msg->peer, address);
280 GNUNET_HELLO_address_free (address);
281 }
282
283 /* expect more replies */
284 GNUNET_CLIENT_receive (pal_ctx->client, &peer_address_response_processor,
285 pal_ctx,
286 GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout));
287}
288
289
290/**
291 * Return all the known addresses for a specific peer or all peers.
292 * Returns continuously all address if one_shot is set to GNUNET_NO
293 *
294 * CHANGE: Returns the address(es) that we are currently using for this
295 * peer. Upon completion, the 'AddressLookUpCallback' is called one more
296 * time with 'NULL' for the address and the peer. After this, the operation must no
297 * longer be explicitly canceled.
298 *
299 * @param cfg configuration to use
300 * @param peer peer identity to look up the addresses of, CHANGE: allow NULL for all (connected) peers
301 * @param one_shot GNUNET_YES to return the current state and then end (with NULL+NULL),
302 * GNUNET_NO to monitor the set of addresses used (continuously, must be explicitly canceled)
303 * @param timeout how long is the lookup allowed to take at most (irrelevant if one_shot is set to GNUNET_NO)
304 * @param peer_address_callback function to call with the results
305 * @param peer_address_callback_cls closure for peer_address_callback
306 */
307struct GNUNET_TRANSPORT_PeerIterateContext *
308GNUNET_TRANSPORT_peer_get_active_addresses (const struct
309 GNUNET_CONFIGURATION_Handle *cfg,
310 const struct GNUNET_PeerIdentity
311 *peer, int one_shot,
312 struct GNUNET_TIME_Relative timeout,
313 GNUNET_TRANSPORT_PeerIterateCallback
314 peer_address_callback,
315 void *peer_address_callback_cls)
316{
317 struct GNUNET_TRANSPORT_PeerIterateContext *pal_ctx;
318 struct GNUNET_CLIENT_Connection *client;
319
320 client = GNUNET_CLIENT_connect ("transport", cfg);
321 if (client == NULL)
322 return NULL;
323 if (GNUNET_YES != one_shot)
324 timeout = GNUNET_TIME_UNIT_FOREVER_REL;
325 pal_ctx = GNUNET_new (struct GNUNET_TRANSPORT_PeerIterateContext);
326 pal_ctx->cb = peer_address_callback;
327 pal_ctx->cb_cls = peer_address_callback_cls;
328 pal_ctx->cfg = cfg;
329 pal_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
330 if (NULL != peer)
331 pal_ctx->peer = *peer;
332 pal_ctx->one_shot = one_shot;
333 pal_ctx->client = client;
334 send_request (pal_ctx);
335
336 return pal_ctx;
337}
338
339
340/**
341 * Cancel request for address conversion.
342 *
343 * @param alc handle for the request to cancel
344 */
345void
346GNUNET_TRANSPORT_peer_get_active_addresses_cancel (struct
347 GNUNET_TRANSPORT_PeerIterateContext
348 *alc)
349{
350 if (NULL != alc->client)
351 {
352 GNUNET_CLIENT_disconnect (alc->client);
353 alc->client = NULL;
354 }
355 if (GNUNET_SCHEDULER_NO_TASK != alc->reconnect_task)
356 {
357 GNUNET_SCHEDULER_cancel (alc->reconnect_task);
358 alc->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
359 }
360 GNUNET_free (alc);
361}
362
363
364/* end of transport_api_peer_address_lookup.c */