diff options
author | Christian Grothoff <christian@grothoff.org> | 2014-06-22 20:08:16 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2014-06-22 20:08:16 +0000 |
commit | eeaa12c3dbd18925c1177cfc66f52711b612fd9e (patch) | |
tree | 012f822b6d20f324f68ea29d9fe2237a0716935e /src/transport/transport_api_monitoring.c | |
parent | 194669680385bd40ce7c84b11021b21b6ed6d295 (diff) | |
download | gnunet-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.c | 854 |
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 | */ | ||
43 | struct 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 | */ | ||
95 | struct 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 | */ | ||
150 | int | ||
151 | GNUNET_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 | */ | ||
186 | const char * | ||
187 | GNUNET_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 | */ | ||
226 | const char * | ||
227 | GNUNET_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 | */ | ||
255 | static void | ||
256 | peer_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 | */ | ||
267 | static void | ||
268 | val_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 | */ | ||
277 | static void | ||
278 | send_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 | */ | ||
301 | static void | ||
302 | send_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 | */ | ||
325 | static void | ||
326 | do_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 | */ | ||
343 | static void | ||
344 | reconnect_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 | */ | ||
365 | static void | ||
366 | do_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 | */ | ||
383 | static void | ||
384 | reconnect_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 | */ | ||
407 | static void | ||
408 | val_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 | */ | ||
571 | static void | ||
572 | peer_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 | */ | ||
735 | struct GNUNET_TRANSPORT_PeerMonitoringContext * | ||
736 | GNUNET_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 | */ | ||
771 | void | ||
772 | GNUNET_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 | */ | ||
801 | struct GNUNET_TRANSPORT_ValidationMonitoringContext * | ||
802 | GNUNET_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 | */ | ||
837 | void | ||
838 | GNUNET_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 */ | ||