diff options
Diffstat (limited to 'src/ats/gnunet-service-ats_addresses.c')
-rw-r--r-- | src/ats/gnunet-service-ats_addresses.c | 715 |
1 files changed, 0 insertions, 715 deletions
diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c deleted file mode 100644 index 3cd831a39..000000000 --- a/src/ats/gnunet-service-ats_addresses.c +++ /dev/null | |||
@@ -1,715 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2011-2015 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your 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 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file ats/gnunet-service-ats_addresses.c | ||
23 | * @brief ats service address management | ||
24 | * @author Matthias Wachs | ||
25 | * @author Christian Grothoff | ||
26 | */ | ||
27 | #include "platform.h" | ||
28 | #include "gnunet-service-ats_addresses.h" | ||
29 | #include "gnunet-service-ats_performance.h" | ||
30 | #include "gnunet-service-ats_normalization.h" | ||
31 | #include "gnunet-service-ats_plugins.h" | ||
32 | |||
33 | |||
34 | /** | ||
35 | * A multihashmap to store all addresses | ||
36 | */ | ||
37 | struct GNUNET_CONTAINER_MultiPeerMap *GSA_addresses; | ||
38 | |||
39 | |||
40 | /** | ||
41 | * Update statistic on number of addresses. | ||
42 | */ | ||
43 | static void | ||
44 | update_addresses_stat () | ||
45 | { | ||
46 | GNUNET_STATISTICS_set (GSA_stats, | ||
47 | "# addresses", | ||
48 | GNUNET_CONTAINER_multipeermap_size (GSA_addresses), | ||
49 | GNUNET_NO); | ||
50 | } | ||
51 | |||
52 | |||
53 | /** | ||
54 | * Free the given address | ||
55 | * | ||
56 | * @param addr address to destroy | ||
57 | */ | ||
58 | static void | ||
59 | free_address (struct ATS_Address *addr) | ||
60 | { | ||
61 | GNUNET_assert (GNUNET_YES == | ||
62 | GNUNET_CONTAINER_multipeermap_remove (GSA_addresses, | ||
63 | &addr->peer, | ||
64 | addr)); | ||
65 | update_addresses_stat (); | ||
66 | GAS_plugin_delete_address (addr); | ||
67 | GAS_performance_notify_all_clients (&addr->peer, | ||
68 | addr->plugin, | ||
69 | addr->addr, | ||
70 | addr->addr_len, | ||
71 | GNUNET_NO, | ||
72 | NULL, | ||
73 | addr->local_address_info, | ||
74 | GNUNET_BANDWIDTH_ZERO, | ||
75 | GNUNET_BANDWIDTH_ZERO); | ||
76 | GNUNET_free (addr->plugin); | ||
77 | GNUNET_free (addr); | ||
78 | } | ||
79 | |||
80 | |||
81 | /** | ||
82 | * Initialize @a norm. Sets all historic values to undefined. | ||
83 | * | ||
84 | * @param norm normalization data to initialize | ||
85 | */ | ||
86 | static void | ||
87 | init_norm (struct GAS_NormalizationInfo *norm) | ||
88 | { | ||
89 | unsigned int c; | ||
90 | |||
91 | for (c = 0; c < GAS_normalization_queue_length; c++) | ||
92 | norm->atsi_abs[c] = UINT64_MAX; | ||
93 | } | ||
94 | |||
95 | |||
96 | /** | ||
97 | * Create a ATS_address with the given information | ||
98 | * | ||
99 | * @param peer peer | ||
100 | * @param plugin_name plugin | ||
101 | * @param plugin_addr address | ||
102 | * @param plugin_addr_len address length | ||
103 | * @param local_address_info additional local info for the address | ||
104 | * @param session_id session identifier, can never be 0 | ||
105 | * @return the ATS_Address | ||
106 | */ | ||
107 | static struct ATS_Address * | ||
108 | create_address (const struct GNUNET_PeerIdentity *peer, | ||
109 | const char *plugin_name, | ||
110 | const void *plugin_addr, | ||
111 | size_t plugin_addr_len, | ||
112 | uint32_t local_address_info, | ||
113 | uint32_t session_id) | ||
114 | { | ||
115 | struct ATS_Address *aa; | ||
116 | |||
117 | aa = GNUNET_malloc (sizeof(struct ATS_Address) + plugin_addr_len); | ||
118 | aa->peer = *peer; | ||
119 | aa->addr_len = plugin_addr_len; | ||
120 | aa->addr = &aa[1]; | ||
121 | GNUNET_memcpy (&aa[1], | ||
122 | plugin_addr, | ||
123 | plugin_addr_len); | ||
124 | aa->plugin = GNUNET_strdup (plugin_name); | ||
125 | aa->session_id = session_id; | ||
126 | aa->local_address_info = local_address_info; | ||
127 | init_norm (&aa->norm_delay); | ||
128 | init_norm (&aa->norm_distance); | ||
129 | init_norm (&aa->norm_utilization_in); | ||
130 | init_norm (&aa->norm_utilization_out); | ||
131 | return aa; | ||
132 | } | ||
133 | |||
134 | |||
135 | /** | ||
136 | * Closure for #find_address_cb() | ||
137 | */ | ||
138 | struct FindAddressContext | ||
139 | { | ||
140 | /** | ||
141 | * Session Id to look for. | ||
142 | */ | ||
143 | uint32_t session_id; | ||
144 | |||
145 | /** | ||
146 | * Where to store matching address result. | ||
147 | */ | ||
148 | struct ATS_Address *exact_address; | ||
149 | }; | ||
150 | |||
151 | |||
152 | /** | ||
153 | * Find session matching given session ID. | ||
154 | * | ||
155 | * @param cls a `struct FindAddressContext` | ||
156 | * @param key peer id | ||
157 | * @param value the address to compare with | ||
158 | * @return #GNUNET_YES to continue, #GNUNET_NO if address is found | ||
159 | */ | ||
160 | static int | ||
161 | find_address_cb (void *cls, | ||
162 | const struct GNUNET_PeerIdentity *key, | ||
163 | void *value) | ||
164 | { | ||
165 | struct FindAddressContext *fac = cls; | ||
166 | struct ATS_Address *aa = value; | ||
167 | |||
168 | if (aa->session_id == fac->session_id) | ||
169 | { | ||
170 | fac->exact_address = aa; | ||
171 | return GNUNET_NO; | ||
172 | } | ||
173 | return GNUNET_YES; | ||
174 | } | ||
175 | |||
176 | |||
177 | /** | ||
178 | * Find the exact address | ||
179 | * | ||
180 | * @param peer peer | ||
181 | * @param session_id session id, can never be 0 | ||
182 | * @return an ATS_address or NULL | ||
183 | */ | ||
184 | static struct ATS_Address * | ||
185 | find_exact_address (const struct GNUNET_PeerIdentity *peer, | ||
186 | uint32_t session_id) | ||
187 | { | ||
188 | struct FindAddressContext fac; | ||
189 | |||
190 | fac.exact_address = NULL; | ||
191 | fac.session_id = session_id; | ||
192 | GNUNET_CONTAINER_multipeermap_get_multiple (GSA_addresses, | ||
193 | peer, | ||
194 | &find_address_cb, &fac); | ||
195 | return fac.exact_address; | ||
196 | } | ||
197 | |||
198 | |||
199 | /** | ||
200 | * Add a new address for a peer. | ||
201 | * | ||
202 | * @param peer peer | ||
203 | * @param plugin_name transport plugin name | ||
204 | * @param plugin_addr plugin address | ||
205 | * @param plugin_addr_len length of the plugin address in @a plugin_addr | ||
206 | * @param local_address_info the local address for the address | ||
207 | * @param session_id session id, can be 0 | ||
208 | * @param prop performance information for this address | ||
209 | */ | ||
210 | void | ||
211 | GAS_addresses_add (const struct GNUNET_PeerIdentity *peer, | ||
212 | const char *plugin_name, | ||
213 | const void *plugin_addr, | ||
214 | size_t plugin_addr_len, | ||
215 | uint32_t local_address_info, | ||
216 | uint32_t session_id, | ||
217 | const struct GNUNET_ATS_Properties *prop) | ||
218 | { | ||
219 | struct ATS_Address *new_address; | ||
220 | |||
221 | if (NULL != find_exact_address (peer, | ||
222 | session_id)) | ||
223 | { | ||
224 | GNUNET_break (0); | ||
225 | return; | ||
226 | } | ||
227 | GNUNET_break (GNUNET_NT_UNSPECIFIED != prop->scope); | ||
228 | new_address = create_address (peer, | ||
229 | plugin_name, | ||
230 | plugin_addr, | ||
231 | plugin_addr_len, | ||
232 | local_address_info, | ||
233 | session_id); | ||
234 | /* Add a new address */ | ||
235 | new_address->properties = *prop; | ||
236 | new_address->t_added = GNUNET_TIME_absolute_get (); | ||
237 | new_address->t_last_activity = GNUNET_TIME_absolute_get (); | ||
238 | GNUNET_assert (GNUNET_OK == | ||
239 | GNUNET_CONTAINER_multipeermap_put (GSA_addresses, | ||
240 | peer, | ||
241 | new_address, | ||
242 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); | ||
243 | update_addresses_stat (); | ||
244 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
245 | "Adding new address for peer `%s' slot %u\n", | ||
246 | GNUNET_i2s (peer), | ||
247 | session_id); | ||
248 | /* Tell solver about new address */ | ||
249 | GAS_plugin_solver_lock (); | ||
250 | GAS_plugin_new_address (new_address); | ||
251 | GAS_normalization_update_property (new_address); // FIXME: needed? | ||
252 | GAS_plugin_solver_unlock (); | ||
253 | /* Notify performance clients about new address */ | ||
254 | GAS_performance_notify_all_clients (&new_address->peer, | ||
255 | new_address->plugin, | ||
256 | new_address->addr, | ||
257 | new_address->addr_len, | ||
258 | new_address->active, | ||
259 | &new_address->properties, | ||
260 | new_address->local_address_info, | ||
261 | GNUNET_BANDWIDTH_value_init ( | ||
262 | new_address->assigned_bw_out), | ||
263 | GNUNET_BANDWIDTH_value_init ( | ||
264 | new_address->assigned_bw_in)); | ||
265 | } | ||
266 | |||
267 | |||
268 | /** | ||
269 | * Update an address with new performance information for a peer. | ||
270 | * | ||
271 | * @param peer peer | ||
272 | * @param session_id session id, never 0 | ||
273 | * @param prop performance information for this address | ||
274 | */ | ||
275 | void | ||
276 | GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, | ||
277 | uint32_t session_id, | ||
278 | const struct GNUNET_ATS_Properties *prop) | ||
279 | { | ||
280 | struct ATS_Address *aa; | ||
281 | |||
282 | /* Get existing address */ | ||
283 | aa = find_exact_address (peer, | ||
284 | session_id); | ||
285 | if (NULL == aa) | ||
286 | { | ||
287 | GNUNET_break (0); | ||
288 | return; | ||
289 | } | ||
290 | if (NULL == aa->solver_information) | ||
291 | { | ||
292 | GNUNET_break (0); | ||
293 | return; | ||
294 | } | ||
295 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
296 | "Received ADDRESS_UPDATE for peer `%s' slot %u\n", | ||
297 | GNUNET_i2s (peer), | ||
298 | (unsigned int) session_id); | ||
299 | GNUNET_break (GNUNET_NT_UNSPECIFIED != prop->scope); | ||
300 | /* Update address */ | ||
301 | aa->t_last_activity = GNUNET_TIME_absolute_get (); | ||
302 | aa->properties = *prop; | ||
303 | /* Notify performance clients about updated address */ | ||
304 | GAS_performance_notify_all_clients (&aa->peer, | ||
305 | aa->plugin, | ||
306 | aa->addr, | ||
307 | aa->addr_len, | ||
308 | aa->active, | ||
309 | prop, | ||
310 | aa->local_address_info, | ||
311 | GNUNET_BANDWIDTH_value_init ( | ||
312 | aa->assigned_bw_out), | ||
313 | GNUNET_BANDWIDTH_value_init ( | ||
314 | aa->assigned_bw_in)); | ||
315 | |||
316 | GAS_normalization_update_property (aa); | ||
317 | } | ||
318 | |||
319 | |||
320 | /** | ||
321 | * Remove an address for a peer. | ||
322 | * | ||
323 | * @param peer peer | ||
324 | * @param session_id session id, can never be 0 | ||
325 | */ | ||
326 | void | ||
327 | GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer, | ||
328 | uint32_t session_id) | ||
329 | { | ||
330 | struct ATS_Address *ea; | ||
331 | |||
332 | /* Get existing address */ | ||
333 | ea = find_exact_address (peer, | ||
334 | session_id); | ||
335 | if (NULL == ea) | ||
336 | { | ||
337 | GNUNET_break (0); | ||
338 | return; | ||
339 | } | ||
340 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
341 | "Received ADDRESS_DESTROYED for peer `%s' session %u\n", | ||
342 | GNUNET_i2s (peer), | ||
343 | session_id); | ||
344 | free_address (ea); | ||
345 | } | ||
346 | |||
347 | |||
348 | /** | ||
349 | * Initialize address subsystem. The addresses subsystem manages the addresses | ||
350 | * known and current performance information. It has a solver component | ||
351 | * responsible for the resource allocation. It tells the solver about changes | ||
352 | * and receives updates when the solver changes the resource allocation. | ||
353 | */ | ||
354 | void | ||
355 | GAS_addresses_init () | ||
356 | { | ||
357 | GSA_addresses | ||
358 | = GNUNET_CONTAINER_multipeermap_create (128, | ||
359 | GNUNET_NO); | ||
360 | update_addresses_stat (); | ||
361 | } | ||
362 | |||
363 | |||
364 | /** | ||
365 | * Destroy all addresses iterator | ||
366 | * | ||
367 | * @param cls NULL | ||
368 | * @param key peer identity (unused) | ||
369 | * @param value the 'struct ATS_Address' to free | ||
370 | * @return #GNUNET_OK (continue to iterate) | ||
371 | */ | ||
372 | static int | ||
373 | destroy_all_address_it (void *cls, | ||
374 | const struct GNUNET_PeerIdentity *key, | ||
375 | void *value) | ||
376 | { | ||
377 | struct ATS_Address *aa = value; | ||
378 | |||
379 | free_address (aa); | ||
380 | return GNUNET_OK; | ||
381 | } | ||
382 | |||
383 | |||
384 | /** | ||
385 | * Remove all addresses | ||
386 | */ | ||
387 | void | ||
388 | GAS_addresses_destroy_all () | ||
389 | { | ||
390 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
391 | "Destroying all addresses\n"); | ||
392 | if (0 == | ||
393 | GNUNET_CONTAINER_multipeermap_size (GSA_addresses)) | ||
394 | return; | ||
395 | GAS_plugin_solver_lock (); | ||
396 | GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses, | ||
397 | &destroy_all_address_it, | ||
398 | NULL); | ||
399 | GAS_plugin_solver_unlock (); | ||
400 | } | ||
401 | |||
402 | |||
403 | /** | ||
404 | * Shutdown address subsystem. | ||
405 | */ | ||
406 | void | ||
407 | GAS_addresses_done () | ||
408 | { | ||
409 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
410 | "Shutting down addresses\n"); | ||
411 | GAS_plugin_solver_lock (); | ||
412 | GAS_addresses_destroy_all (); | ||
413 | GAS_plugin_solver_unlock (); | ||
414 | GNUNET_CONTAINER_multipeermap_destroy (GSA_addresses); | ||
415 | GSA_addresses = NULL; | ||
416 | } | ||
417 | |||
418 | |||
419 | /** | ||
420 | * Closure for #peerinfo_it(). | ||
421 | */ | ||
422 | struct PeerInfoIteratorContext | ||
423 | { | ||
424 | /** | ||
425 | * Function to call for each address. | ||
426 | */ | ||
427 | GNUNET_ATS_PeerInfo_Iterator it; | ||
428 | |||
429 | /** | ||
430 | * Closure for @e it. | ||
431 | */ | ||
432 | void *it_cls; | ||
433 | }; | ||
434 | |||
435 | |||
436 | /** | ||
437 | * Iterator to iterate over a peer's addresses | ||
438 | * | ||
439 | * @param cls a `struct PeerInfoIteratorContext` | ||
440 | * @param key the peer id | ||
441 | * @param value the `struct ATS_address` | ||
442 | * @return #GNUNET_OK to continue | ||
443 | */ | ||
444 | static int | ||
445 | peerinfo_it (void *cls, | ||
446 | const struct GNUNET_PeerIdentity *key, | ||
447 | void *value) | ||
448 | { | ||
449 | struct PeerInfoIteratorContext *pi_ctx = cls; | ||
450 | struct ATS_Address *addr = value; | ||
451 | |||
452 | pi_ctx->it (pi_ctx->it_cls, | ||
453 | &addr->peer, | ||
454 | addr->plugin, | ||
455 | addr->addr, | ||
456 | addr->addr_len, | ||
457 | addr->active, | ||
458 | &addr->properties, | ||
459 | addr->local_address_info, | ||
460 | GNUNET_BANDWIDTH_value_init (addr->assigned_bw_out), | ||
461 | GNUNET_BANDWIDTH_value_init (addr->assigned_bw_in)); | ||
462 | return GNUNET_OK; | ||
463 | } | ||
464 | |||
465 | |||
466 | /** | ||
467 | * Return information all peers currently known to ATS | ||
468 | * | ||
469 | * @param peer the respective peer, NULL for 'all' peers | ||
470 | * @param pi_it the iterator to call for every peer | ||
471 | * @param pi_it_cls the closure for @a pi_it | ||
472 | */ | ||
473 | void | ||
474 | GAS_addresses_get_peer_info (const struct GNUNET_PeerIdentity *peer, | ||
475 | GNUNET_ATS_PeerInfo_Iterator pi_it, | ||
476 | void *pi_it_cls) | ||
477 | { | ||
478 | struct PeerInfoIteratorContext pi_ctx; | ||
479 | |||
480 | if (NULL == pi_it) | ||
481 | { | ||
482 | /* does not make sense without callback */ | ||
483 | GNUNET_break (0); | ||
484 | return; | ||
485 | } | ||
486 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
487 | "Returning information for %s from a total of %u known addresses\n", | ||
488 | (NULL == peer) | ||
489 | ? "all peers" | ||
490 | : GNUNET_i2s (peer), | ||
491 | (unsigned int) GNUNET_CONTAINER_multipeermap_size ( | ||
492 | GSA_addresses)); | ||
493 | pi_ctx.it = pi_it; | ||
494 | pi_ctx.it_cls = pi_it_cls; | ||
495 | if (NULL == peer) | ||
496 | GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses, | ||
497 | &peerinfo_it, | ||
498 | &pi_ctx); | ||
499 | else | ||
500 | GNUNET_CONTAINER_multipeermap_get_multiple (GSA_addresses, | ||
501 | peer, | ||
502 | &peerinfo_it, &pi_ctx); | ||
503 | pi_it (pi_it_cls, | ||
504 | NULL, NULL, NULL, 0, | ||
505 | GNUNET_NO, | ||
506 | NULL, | ||
507 | GNUNET_HELLO_ADDRESS_INFO_NONE, | ||
508 | GNUNET_BANDWIDTH_ZERO, | ||
509 | GNUNET_BANDWIDTH_ZERO); | ||
510 | } | ||
511 | |||
512 | |||
513 | /** | ||
514 | * Information we need for the callbacks to return a list of addresses | ||
515 | * back to the client. | ||
516 | */ | ||
517 | struct AddressIteration | ||
518 | { | ||
519 | /** | ||
520 | * Actual handle to the client. | ||
521 | */ | ||
522 | struct GNUNET_SERVICE_Client *client; | ||
523 | |||
524 | /** | ||
525 | * Are we sending all addresses, or only those that are active? | ||
526 | */ | ||
527 | int all; | ||
528 | |||
529 | /** | ||
530 | * Which ID should be included in the response? | ||
531 | */ | ||
532 | uint32_t id; | ||
533 | }; | ||
534 | |||
535 | |||
536 | /** | ||
537 | * Send a #GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_RESPONSE with the | ||
538 | * given address details to the client identified in @a ai. | ||
539 | * | ||
540 | * @param ai our address information context (identifies the client) | ||
541 | * @param id the peer id this address is for | ||
542 | * @param plugin_name name of the plugin that supports this address | ||
543 | * @param plugin_addr address | ||
544 | * @param plugin_addr_len length of @a plugin_addr | ||
545 | * @param active #GNUNET_YES if this address is actively used | ||
546 | * @param prop performance information | ||
547 | * @param local_address_info flags for the address | ||
548 | * @param bandwidth_out current outbound bandwidth assigned to address | ||
549 | * @param bandwidth_in current inbound bandwidth assigned to address | ||
550 | */ | ||
551 | static void | ||
552 | transmit_req_addr (struct AddressIteration *ai, | ||
553 | const struct GNUNET_PeerIdentity *id, | ||
554 | const char *plugin_name, | ||
555 | const void *plugin_addr, | ||
556 | size_t plugin_addr_len, | ||
557 | int active, | ||
558 | const struct GNUNET_ATS_Properties *prop, | ||
559 | enum GNUNET_HELLO_AddressInfo local_address_info, | ||
560 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, | ||
561 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) | ||
562 | |||
563 | { | ||
564 | struct GNUNET_MQ_Envelope *env; | ||
565 | struct PeerInformationMessage *msg; | ||
566 | char *addrp; | ||
567 | size_t plugin_name_length; | ||
568 | size_t msize; | ||
569 | |||
570 | if (NULL != plugin_name) | ||
571 | plugin_name_length = strlen (plugin_name) + 1; | ||
572 | else | ||
573 | plugin_name_length = 0; | ||
574 | msize = plugin_addr_len + plugin_name_length; | ||
575 | |||
576 | GNUNET_assert (sizeof(struct PeerInformationMessage) + msize | ||
577 | < GNUNET_MAX_MESSAGE_SIZE); | ||
578 | env = GNUNET_MQ_msg_extra (msg, | ||
579 | msize, | ||
580 | GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_RESPONSE); | ||
581 | msg->id = htonl (ai->id); | ||
582 | if (NULL != id) | ||
583 | msg->peer = *id; | ||
584 | msg->address_length = htons (plugin_addr_len); | ||
585 | msg->address_active = ntohl (active); | ||
586 | msg->plugin_name_length = htons (plugin_name_length); | ||
587 | msg->bandwidth_out = bandwidth_out; | ||
588 | msg->bandwidth_in = bandwidth_in; | ||
589 | if (NULL != prop) | ||
590 | GNUNET_ATS_properties_hton (&msg->properties, | ||
591 | prop); | ||
592 | msg->address_local_info = htonl ((uint32_t) local_address_info); | ||
593 | addrp = (char *) &msg[1]; | ||
594 | GNUNET_memcpy (addrp, | ||
595 | plugin_addr, | ||
596 | plugin_addr_len); | ||
597 | if (NULL != plugin_name) | ||
598 | strcpy (&addrp[plugin_addr_len], | ||
599 | plugin_name); | ||
600 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (ai->client), | ||
601 | env); | ||
602 | } | ||
603 | |||
604 | |||
605 | /** | ||
606 | * Iterator for #GAS_addresses_get_peer_info(), called with peer-specific | ||
607 | * information to be passed back to the client. | ||
608 | * | ||
609 | * @param cls closure with our `struct AddressIteration *` | ||
610 | * @param id the peer id | ||
611 | * @param plugin_name plugin name | ||
612 | * @param plugin_addr address | ||
613 | * @param plugin_addr_len length of @a plugin_addr | ||
614 | * @param active is address actively used | ||
615 | * @param prop performance information | ||
616 | * @param local_address_info additional local info for the address | ||
617 | * @param bandwidth_out current outbound bandwidth assigned to address | ||
618 | * @param bandwidth_in current inbound bandwidth assigned to address | ||
619 | */ | ||
620 | static void | ||
621 | req_addr_peerinfo_it (void *cls, | ||
622 | const struct GNUNET_PeerIdentity *id, | ||
623 | const char *plugin_name, | ||
624 | const void *plugin_addr, | ||
625 | size_t plugin_addr_len, | ||
626 | int active, | ||
627 | const struct GNUNET_ATS_Properties *prop, | ||
628 | enum GNUNET_HELLO_AddressInfo local_address_info, | ||
629 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, | ||
630 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) | ||
631 | { | ||
632 | struct AddressIteration *ai = cls; | ||
633 | |||
634 | if ((NULL == id) && | ||
635 | (NULL == plugin_name) && | ||
636 | (NULL == plugin_addr)) | ||
637 | { | ||
638 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
639 | "Address iteration done for one peer\n"); | ||
640 | return; | ||
641 | } | ||
642 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
643 | "Callback for %s peer `%s' plugin `%s' BW out %u, BW in %u\n", | ||
644 | (active == GNUNET_YES) ? "ACTIVE" : "INACTIVE", | ||
645 | GNUNET_i2s (id), | ||
646 | plugin_name, | ||
647 | (unsigned int) ntohl (bandwidth_out.value__), | ||
648 | (unsigned int) ntohl (bandwidth_in.value__)); | ||
649 | /* Transmit result (either if address is active, or if | ||
650 | client wanted all addresses) */ | ||
651 | if ((GNUNET_YES != ai->all) && | ||
652 | (GNUNET_YES != active)) | ||
653 | return; | ||
654 | transmit_req_addr (ai, | ||
655 | id, | ||
656 | plugin_name, | ||
657 | plugin_addr, plugin_addr_len, | ||
658 | active, | ||
659 | prop, | ||
660 | local_address_info, | ||
661 | bandwidth_out, | ||
662 | bandwidth_in); | ||
663 | } | ||
664 | |||
665 | |||
666 | /** | ||
667 | * Handle 'address list request' messages from clients. | ||
668 | * | ||
669 | * @param cls client that sent the request | ||
670 | * @param alrm the request message | ||
671 | */ | ||
672 | void | ||
673 | GAS_handle_request_address_list (struct GNUNET_SERVICE_Client *client, | ||
674 | const struct AddressListRequestMessage *alrm) | ||
675 | { | ||
676 | struct AddressIteration ai; | ||
677 | struct GNUNET_PeerIdentity allzeros; | ||
678 | |||
679 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
680 | "Received ADDRESSLIST_REQUEST message\n"); | ||
681 | ai.all = ntohl (alrm->all); | ||
682 | ai.id = ntohl (alrm->id); | ||
683 | ai.client = client; | ||
684 | |||
685 | memset (&allzeros, | ||
686 | '\0', | ||
687 | sizeof(struct GNUNET_PeerIdentity)); | ||
688 | if (GNUNET_YES == GNUNET_is_zero (&alrm->peer)) | ||
689 | { | ||
690 | /* Return addresses for all peers */ | ||
691 | GAS_addresses_get_peer_info (NULL, | ||
692 | &req_addr_peerinfo_it, | ||
693 | &ai); | ||
694 | } | ||
695 | else | ||
696 | { | ||
697 | /* Return addresses for a specific peer */ | ||
698 | GAS_addresses_get_peer_info (&alrm->peer, | ||
699 | &req_addr_peerinfo_it, | ||
700 | &ai); | ||
701 | } | ||
702 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
703 | "Finished handling `%s' message\n", | ||
704 | "ADDRESSLIST_REQUEST"); | ||
705 | transmit_req_addr (&ai, | ||
706 | NULL, NULL, NULL, | ||
707 | 0, GNUNET_NO, | ||
708 | NULL, | ||
709 | GNUNET_HELLO_ADDRESS_INFO_NONE, | ||
710 | GNUNET_BANDWIDTH_ZERO, | ||
711 | GNUNET_BANDWIDTH_ZERO); | ||
712 | } | ||
713 | |||
714 | |||
715 | /* end of gnunet-service-ats_addresses.c */ | ||