aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-transport_ats.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-service-transport_ats.c')
-rw-r--r--src/transport/gnunet-service-transport_ats.c772
1 files changed, 383 insertions, 389 deletions
diff --git a/src/transport/gnunet-service-transport_ats.c b/src/transport/gnunet-service-transport_ats.c
index f8756c750..555302813 100644
--- a/src/transport/gnunet-service-transport_ats.c
+++ b/src/transport/gnunet-service-transport_ats.c
@@ -11,12 +11,12 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 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/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20/** 20/**
21 * @file transport/gnunet-service-transport_ats.c 21 * @file transport/gnunet-service-transport_ats.c
22 * @brief interfacing between transport and ATS service 22 * @brief interfacing between transport and ATS service
@@ -32,15 +32,13 @@
32/** 32/**
33 * Log convenience function. 33 * Log convenience function.
34 */ 34 */
35#define LOG(kind,...) GNUNET_log_from(kind, "transport-ats", __VA_ARGS__) 35#define LOG(kind, ...) GNUNET_log_from(kind, "transport-ats", __VA_ARGS__)
36 36
37 37
38/** 38/**
39 * Information we track for each address known to ATS. 39 * Information we track for each address known to ATS.
40 */ 40 */
41struct AddressInfo 41struct AddressInfo {
42{
43
44 /** 42 /**
45 * The address (with peer identity). Must never change 43 * The address (with peer identity). Must never change
46 * while this struct is in the #p2a map. 44 * while this struct is in the #p2a map.
@@ -89,7 +87,6 @@ struct AddressInfo
89 * not yet remove it because we still have a valid session. 87 * not yet remove it because we still have a valid session.
90 */ 88 */
91 int expired; 89 int expired;
92
93}; 90};
94 91
95 92
@@ -108,9 +105,7 @@ static unsigned int num_blocked;
108/** 105/**
109 * Closure for #find_ai_cb() and #find_ai_no_session_cb(). 106 * Closure for #find_ai_cb() and #find_ai_no_session_cb().
110 */ 107 */
111struct FindClosure 108struct FindClosure {
112{
113
114 /** 109 /**
115 * Session to look for (only used if the address is inbound). 110 * Session to look for (only used if the address is inbound).
116 */ 111 */
@@ -125,7 +120,6 @@ struct FindClosure
125 * Where to store the result. 120 * Where to store the result.
126 */ 121 */
127 struct AddressInfo *ret; 122 struct AddressInfo *ret;
128
129}; 123};
130 124
131 125
@@ -135,16 +129,16 @@ struct FindClosure
135 * is changed. 129 * is changed.
136 */ 130 */
137static void 131static void
138publish_p2a_stat_update () 132publish_p2a_stat_update()
139{ 133{
140 GNUNET_STATISTICS_set (GST_stats, 134 GNUNET_STATISTICS_set(GST_stats,
141 gettext_noop ("# Addresses given to ATS"), 135 gettext_noop("# Addresses given to ATS"),
142 GNUNET_CONTAINER_multipeermap_size (p2a) - num_blocked, 136 GNUNET_CONTAINER_multipeermap_size(p2a) - num_blocked,
143 GNUNET_NO); 137 GNUNET_NO);
144 GNUNET_STATISTICS_set (GST_stats, 138 GNUNET_STATISTICS_set(GST_stats,
145 "# blocked addresses", 139 "# blocked addresses",
146 num_blocked, 140 num_blocked,
147 GNUNET_NO); 141 GNUNET_NO);
148} 142}
149 143
150 144
@@ -159,21 +153,21 @@ publish_p2a_stat_update ()
159 * @return #GNUNET_YES to continue to iterate, #GNUNET_NO if we found the value 153 * @return #GNUNET_YES to continue to iterate, #GNUNET_NO if we found the value
160 */ 154 */
161static int 155static int
162find_ai_cb (void *cls, 156find_ai_cb(void *cls,
163 const struct GNUNET_PeerIdentity *key, 157 const struct GNUNET_PeerIdentity *key,
164 void *value) 158 void *value)
165{ 159{
166 struct FindClosure *fc = cls; 160 struct FindClosure *fc = cls;
167 struct AddressInfo *ai = value; 161 struct AddressInfo *ai = value;
168 162
169 if ( (0 == 163 if ((0 ==
170 GNUNET_HELLO_address_cmp (fc->address, 164 GNUNET_HELLO_address_cmp(fc->address,
171 ai->address) ) && 165 ai->address)) &&
172 (fc->session == ai->session) ) 166 (fc->session == ai->session))
173 { 167 {
174 fc->ret = ai; 168 fc->ret = ai;
175 return GNUNET_NO; 169 return GNUNET_NO;
176 } 170 }
177 return GNUNET_YES; 171 return GNUNET_YES;
178} 172}
179 173
@@ -187,18 +181,18 @@ find_ai_cb (void *cls,
187 * @return NULL if this combination is unknown 181 * @return NULL if this combination is unknown
188 */ 182 */
189static struct AddressInfo * 183static struct AddressInfo *
190find_ai (const struct GNUNET_HELLO_Address *address, 184find_ai(const struct GNUNET_HELLO_Address *address,
191 struct GNUNET_ATS_Session *session) 185 struct GNUNET_ATS_Session *session)
192{ 186{
193 struct FindClosure fc; 187 struct FindClosure fc;
194 188
195 fc.address = address; 189 fc.address = address;
196 fc.session = session; 190 fc.session = session;
197 fc.ret = NULL; 191 fc.ret = NULL;
198 GNUNET_CONTAINER_multipeermap_get_multiple (p2a, 192 GNUNET_CONTAINER_multipeermap_get_multiple(p2a,
199 &address->peer, 193 &address->peer,
200 &find_ai_cb, 194 &find_ai_cb,
201 &fc); 195 &fc);
202 return fc.ret; 196 return fc.ret;
203} 197}
204 198
@@ -213,9 +207,9 @@ find_ai (const struct GNUNET_HELLO_Address *address,
213 * @return #GNUNET_YES to continue to iterate, #GNUNET_NO if we found the value 207 * @return #GNUNET_YES to continue to iterate, #GNUNET_NO if we found the value
214 */ 208 */
215static int 209static int
216find_ai_no_session_cb (void *cls, 210find_ai_no_session_cb(void *cls,
217 const struct GNUNET_PeerIdentity *key, 211 const struct GNUNET_PeerIdentity *key,
218 void *value) 212 void *value)
219{ 213{
220 struct FindClosure *fc = cls; 214 struct FindClosure *fc = cls;
221 struct AddressInfo *ai = value; 215 struct AddressInfo *ai = value;
@@ -223,12 +217,12 @@ find_ai_no_session_cb (void *cls,
223 if (ai->expired) 217 if (ai->expired)
224 return GNUNET_YES; /* expired do not count here */ 218 return GNUNET_YES; /* expired do not count here */
225 if (0 == 219 if (0 ==
226 GNUNET_HELLO_address_cmp (fc->address, 220 GNUNET_HELLO_address_cmp(fc->address,
227 ai->address)) 221 ai->address))
228 { 222 {
229 fc->ret = ai; 223 fc->ret = ai;
230 return GNUNET_NO; 224 return GNUNET_NO;
231 } 225 }
232 return GNUNET_YES; 226 return GNUNET_YES;
233} 227}
234 228
@@ -241,17 +235,17 @@ find_ai_no_session_cb (void *cls,
241 * @return NULL if this combination is unknown 235 * @return NULL if this combination is unknown
242 */ 236 */
243static struct AddressInfo * 237static struct AddressInfo *
244find_ai_no_session (const struct GNUNET_HELLO_Address *address) 238find_ai_no_session(const struct GNUNET_HELLO_Address *address)
245{ 239{
246 struct FindClosure fc; 240 struct FindClosure fc;
247 241
248 fc.address = address; 242 fc.address = address;
249 fc.session = NULL; 243 fc.session = NULL;
250 fc.ret = NULL; 244 fc.ret = NULL;
251 GNUNET_CONTAINER_multipeermap_get_multiple (p2a, 245 GNUNET_CONTAINER_multipeermap_get_multiple(p2a,
252 &address->peer, 246 &address->peer,
253 &find_ai_no_session_cb, 247 &find_ai_no_session_cb,
254 &fc); 248 &fc);
255 return fc.ret; 249 return fc.ret;
256} 250}
257 251
@@ -266,10 +260,10 @@ find_ai_no_session (const struct GNUNET_HELLO_Address *address)
266 * @return #GNUNET_YES if @a address is known, #GNUNET_NO if not. 260 * @return #GNUNET_YES if @a address is known, #GNUNET_NO if not.
267 */ 261 */
268int 262int
269GST_ats_is_known (const struct GNUNET_HELLO_Address *address, 263GST_ats_is_known(const struct GNUNET_HELLO_Address *address,
270 struct GNUNET_ATS_Session *session) 264 struct GNUNET_ATS_Session *session)
271{ 265{
272 return (NULL != find_ai (address, session)) ? GNUNET_YES : GNUNET_NO; 266 return (NULL != find_ai(address, session)) ? GNUNET_YES : GNUNET_NO;
273} 267}
274 268
275 269
@@ -281,11 +275,11 @@ GST_ats_is_known (const struct GNUNET_HELLO_Address *address,
281 * @return #GNUNET_YES if @a address is known, #GNUNET_NO if not. 275 * @return #GNUNET_YES if @a address is known, #GNUNET_NO if not.
282 */ 276 */
283int 277int
284GST_ats_is_known_no_session (const struct GNUNET_HELLO_Address *address) 278GST_ats_is_known_no_session(const struct GNUNET_HELLO_Address *address)
285{ 279{
286 return (NULL != find_ai_no_session (address)) 280 return (NULL != find_ai_no_session(address))
287 ? GNUNET_YES 281 ? GNUNET_YES
288 : GNUNET_NO; 282 : GNUNET_NO;
289} 283}
290 284
291 285
@@ -296,22 +290,22 @@ GST_ats_is_known_no_session (const struct GNUNET_HELLO_Address *address)
296 * @param cls the `struct AddressInfo` of the address to unblock 290 * @param cls the `struct AddressInfo` of the address to unblock
297 */ 291 */
298static void 292static void
299unblock_address (void *cls) 293unblock_address(void *cls)
300{ 294{
301 struct AddressInfo *ai = cls; 295 struct AddressInfo *ai = cls;
302 296
303 ai->unblock_task = NULL; 297 ai->unblock_task = NULL;
304 LOG (GNUNET_ERROR_TYPE_DEBUG, 298 LOG(GNUNET_ERROR_TYPE_DEBUG,
305 "Unblocking address %s of peer %s\n", 299 "Unblocking address %s of peer %s\n",
306 GST_plugins_a2s (ai->address), 300 GST_plugins_a2s(ai->address),
307 GNUNET_i2s (&ai->address->peer)); 301 GNUNET_i2s(&ai->address->peer));
308 ai->ar = GNUNET_ATS_address_add (GST_ats, 302 ai->ar = GNUNET_ATS_address_add(GST_ats,
309 ai->address, 303 ai->address,
310 ai->session, 304 ai->session,
311 &ai->properties); 305 &ai->properties);
312 GNUNET_break (NULL != ai->ar); 306 GNUNET_break(NULL != ai->ar);
313 num_blocked--; 307 num_blocked--;
314 publish_p2a_stat_update (); 308 publish_p2a_stat_update();
315} 309}
316 310
317 311
@@ -325,61 +319,61 @@ unblock_address (void *cls)
325 * @param session the session (can be NULL) 319 * @param session the session (can be NULL)
326 */ 320 */
327void 321void
328GST_ats_block_address (const struct GNUNET_HELLO_Address *address, 322GST_ats_block_address(const struct GNUNET_HELLO_Address *address,
329 struct GNUNET_ATS_Session *session) 323 struct GNUNET_ATS_Session *session)
330{ 324{
331 struct AddressInfo *ai; 325 struct AddressInfo *ai;
332 326
333 if (0 == 327 if (0 ==
334 memcmp (&GST_my_identity, 328 memcmp(&GST_my_identity,
335 &address->peer, 329 &address->peer,
336 sizeof (struct GNUNET_PeerIdentity))) 330 sizeof(struct GNUNET_PeerIdentity)))
337 return; /* our own, ignore! */ 331 return; /* our own, ignore! */
338 ai = find_ai (address, 332 ai = find_ai(address,
339 session); 333 session);
340 if (NULL == ai || NULL == ai->ar) 334 if (NULL == ai || NULL == ai->ar)
341 { 335 {
342 /* The address is already gone/blocked, this can happen during a blacklist 336 /* The address is already gone/blocked, this can happen during a blacklist
343 * callback. */ 337 * callback. */
344 return; 338 return;
345 } 339 }
346 ai->back_off = GNUNET_TIME_STD_BACKOFF (ai->back_off); 340 ai->back_off = GNUNET_TIME_STD_BACKOFF(ai->back_off);
347 if (GNUNET_YES == 341 if (GNUNET_YES ==
348 GNUNET_HELLO_address_check_option (address, 342 GNUNET_HELLO_address_check_option(address,
349 GNUNET_HELLO_ADDRESS_INFO_INBOUND)) 343 GNUNET_HELLO_ADDRESS_INFO_INBOUND))
350 LOG (GNUNET_ERROR_TYPE_DEBUG, 344 LOG(GNUNET_ERROR_TYPE_DEBUG,
351 "Removing address %s of peer %s from use (inbound died)\n", 345 "Removing address %s of peer %s from use (inbound died)\n",
352 GST_plugins_a2s (address), 346 GST_plugins_a2s(address),
353 GNUNET_i2s (&address->peer)); 347 GNUNET_i2s(&address->peer));
354 else 348 else
355 LOG (GNUNET_ERROR_TYPE_INFO, 349 LOG(GNUNET_ERROR_TYPE_INFO,
356 "Blocking address %s of peer %s from use for %s\n", 350 "Blocking address %s of peer %s from use for %s\n",
357 GST_plugins_a2s (address), 351 GST_plugins_a2s(address),
358 GNUNET_i2s (&address->peer), 352 GNUNET_i2s(&address->peer),
359 GNUNET_STRINGS_relative_time_to_string (ai->back_off, 353 GNUNET_STRINGS_relative_time_to_string(ai->back_off,
360 GNUNET_YES)); 354 GNUNET_YES));
361 /* destroy session and address */ 355 /* destroy session and address */
362 if ( (NULL == session) || 356 if ((NULL == session) ||
363 (GNUNET_NO == 357 (GNUNET_NO ==
364 GNUNET_ATS_address_del_session (ai->ar, 358 GNUNET_ATS_address_del_session(ai->ar,
365 session)) ) 359 session)))
366 { 360 {
367 GNUNET_ATS_address_destroy (ai->ar); 361 GNUNET_ATS_address_destroy(ai->ar);
368 } 362 }
369 /* "ar" has been freed, regardless how the branch 363 /* "ar" has been freed, regardless how the branch
370 above played out: it was either freed in 364 above played out: it was either freed in
371 #GNUNET_ATS_address_del_session() because it was 365 #GNUNET_ATS_address_del_session() because it was
372 incoming, or explicitly in 366 incoming, or explicitly in
373 #GNUNET_ATS_address_del_session(). */ 367 #GNUNET_ATS_address_del_session(). */
374 ai->ar = NULL; 368 ai->ar = NULL;
375 369
376 /* determine when the address should come back to life */ 370 /* determine when the address should come back to life */
377 ai->blocked = GNUNET_TIME_relative_to_absolute (ai->back_off); 371 ai->blocked = GNUNET_TIME_relative_to_absolute(ai->back_off);
378 ai->unblock_task = GNUNET_SCHEDULER_add_delayed (ai->back_off, 372 ai->unblock_task = GNUNET_SCHEDULER_add_delayed(ai->back_off,
379 &unblock_address, 373 &unblock_address,
380 ai); 374 ai);
381 num_blocked++; 375 num_blocked++;
382 publish_p2a_stat_update (); 376 publish_p2a_stat_update();
383} 377}
384 378
385 379
@@ -392,24 +386,24 @@ GST_ats_block_address (const struct GNUNET_HELLO_Address *address,
392 * @param session the session (can be NULL) 386 * @param session the session (can be NULL)
393 */ 387 */
394void 388void
395GST_ats_block_reset (const struct GNUNET_HELLO_Address *address, 389GST_ats_block_reset(const struct GNUNET_HELLO_Address *address,
396 struct GNUNET_ATS_Session *session) 390 struct GNUNET_ATS_Session *session)
397{ 391{
398 struct AddressInfo *ai; 392 struct AddressInfo *ai;
399 393
400 if (0 == 394 if (0 ==
401 memcmp (&GST_my_identity, 395 memcmp(&GST_my_identity,
402 &address->peer, 396 &address->peer,
403 sizeof (struct GNUNET_PeerIdentity))) 397 sizeof(struct GNUNET_PeerIdentity)))
404 return; /* our own, ignore! */ 398 return; /* our own, ignore! */
405 ai = find_ai (address, session); 399 ai = find_ai(address, session);
406 if (NULL == ai) 400 if (NULL == ai)
407 { 401 {
408 GNUNET_break (0); 402 GNUNET_break(0);
409 return; 403 return;
410 } 404 }
411 /* address is in successful use, so it should not be blocked right now */ 405 /* address is in successful use, so it should not be blocked right now */
412 GNUNET_break (NULL == ai->unblock_task); 406 GNUNET_break(NULL == ai->unblock_task);
413 ai->back_off = GNUNET_TIME_UNIT_ZERO; 407 ai->back_off = GNUNET_TIME_UNIT_ZERO;
414} 408}
415 409
@@ -425,60 +419,60 @@ GST_ats_block_reset (const struct GNUNET_HELLO_Address *address,
425 * @param prop performance information 419 * @param prop performance information
426 */ 420 */
427void 421void
428GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address, 422GST_ats_add_inbound_address(const struct GNUNET_HELLO_Address *address,
429 struct GNUNET_ATS_Session *session, 423 struct GNUNET_ATS_Session *session,
430 const struct GNUNET_ATS_Properties *prop) 424 const struct GNUNET_ATS_Properties *prop)
431{ 425{
432 struct GNUNET_ATS_AddressRecord *ar; 426 struct GNUNET_ATS_AddressRecord *ar;
433 struct AddressInfo *ai; 427 struct AddressInfo *ai;
434 428
435 if (0 == 429 if (0 ==
436 memcmp (&GST_my_identity, 430 memcmp(&GST_my_identity,
437 &address->peer, 431 &address->peer,
438 sizeof (struct GNUNET_PeerIdentity))) 432 sizeof(struct GNUNET_PeerIdentity)))
439 return; /* our own, ignore! */ 433 return; /* our own, ignore! */
440 434
441 /* Sanity checks for a valid inbound address */ 435 /* Sanity checks for a valid inbound address */
442 if (NULL == address->transport_name) 436 if (NULL == address->transport_name)
443 { 437 {
444 GNUNET_break(0); 438 GNUNET_break(0);
445 return; 439 return;
446 } 440 }
447 GNUNET_break (GNUNET_NT_UNSPECIFIED != prop->scope); 441 GNUNET_break(GNUNET_NT_UNSPECIFIED != prop->scope);
448 GNUNET_assert (GNUNET_YES == 442 GNUNET_assert(GNUNET_YES ==
449 GNUNET_HELLO_address_check_option (address, 443 GNUNET_HELLO_address_check_option(address,
450 GNUNET_HELLO_ADDRESS_INFO_INBOUND)); 444 GNUNET_HELLO_ADDRESS_INFO_INBOUND));
451 GNUNET_assert (NULL != session); 445 GNUNET_assert(NULL != session);
452 ai = find_ai (address, session); 446 ai = find_ai(address, session);
453 if (NULL != ai) 447 if (NULL != ai)
454 { 448 {
455 /* This should only be called for new sessions, and thus 449 /* This should only be called for new sessions, and thus
456 we should not already have the address */ 450 we should not already have the address */
457 GNUNET_break (0); 451 GNUNET_break(0);
458 return; 452 return;
459 } 453 }
460 /* Is indeed new, let's tell ATS */ 454 /* Is indeed new, let's tell ATS */
461 LOG (GNUNET_ERROR_TYPE_DEBUG, 455 LOG(GNUNET_ERROR_TYPE_DEBUG,
462 "Notifying ATS about peer `%s''s new inbound address `%s' session %p in network %s\n", 456 "Notifying ATS about peer `%s''s new inbound address `%s' session %p in network %s\n",
463 GNUNET_i2s (&address->peer), 457 GNUNET_i2s(&address->peer),
464 GST_plugins_a2s (address), 458 GST_plugins_a2s(address),
465 session, 459 session,
466 GNUNET_NT_to_string (prop->scope)); 460 GNUNET_NT_to_string(prop->scope));
467 ar = GNUNET_ATS_address_add (GST_ats, 461 ar = GNUNET_ATS_address_add(GST_ats,
468 address, 462 address,
469 session, 463 session,
470 prop); 464 prop);
471 GNUNET_assert (NULL != ar); 465 GNUNET_assert(NULL != ar);
472 ai = GNUNET_new (struct AddressInfo); 466 ai = GNUNET_new(struct AddressInfo);
473 ai->address = GNUNET_HELLO_address_copy (address); 467 ai->address = GNUNET_HELLO_address_copy(address);
474 ai->session = session; 468 ai->session = session;
475 ai->properties = *prop; 469 ai->properties = *prop;
476 ai->ar = ar; 470 ai->ar = ar;
477 (void) GNUNET_CONTAINER_multipeermap_put (p2a, 471 (void)GNUNET_CONTAINER_multipeermap_put(p2a,
478 &ai->address->peer, 472 &ai->address->peer,
479 ai, 473 ai,
480 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 474 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
481 publish_p2a_stat_update (); 475 publish_p2a_stat_update();
482} 476}
483 477
484 478
@@ -490,49 +484,49 @@ GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address,
490 * @param prop performance information 484 * @param prop performance information
491 */ 485 */
492void 486void
493GST_ats_add_address (const struct GNUNET_HELLO_Address *address, 487GST_ats_add_address(const struct GNUNET_HELLO_Address *address,
494 const struct GNUNET_ATS_Properties *prop) 488 const struct GNUNET_ATS_Properties *prop)
495{ 489{
496 struct GNUNET_ATS_AddressRecord *ar; 490 struct GNUNET_ATS_AddressRecord *ar;
497 struct AddressInfo *ai; 491 struct AddressInfo *ai;
498 492
499 if (0 == 493 if (0 ==
500 memcmp (&GST_my_identity, 494 memcmp(&GST_my_identity,
501 &address->peer, 495 &address->peer,
502 sizeof (struct GNUNET_PeerIdentity))) 496 sizeof(struct GNUNET_PeerIdentity)))
503 return; /* our own, ignore! */ 497 return; /* our own, ignore! */
504 /* validadte address */ 498 /* validadte address */
505 if (NULL == address->transport_name) 499 if (NULL == address->transport_name)
506 { 500 {
507 GNUNET_break(0); 501 GNUNET_break(0);
508 return; 502 return;
509 } 503 }
510 GNUNET_assert (GNUNET_YES != 504 GNUNET_assert(GNUNET_YES !=
511 GNUNET_HELLO_address_check_option (address, 505 GNUNET_HELLO_address_check_option(address,
512 GNUNET_HELLO_ADDRESS_INFO_INBOUND)); 506 GNUNET_HELLO_ADDRESS_INFO_INBOUND));
513 ai = find_ai_no_session (address); 507 ai = find_ai_no_session(address);
514 GNUNET_assert (NULL == ai); 508 GNUNET_assert(NULL == ai);
515 GNUNET_break (GNUNET_NT_UNSPECIFIED != prop->scope); 509 GNUNET_break(GNUNET_NT_UNSPECIFIED != prop->scope);
516 510
517 /* address seems sane, let's tell ATS */ 511 /* address seems sane, let's tell ATS */
518 LOG (GNUNET_ERROR_TYPE_INFO, 512 LOG(GNUNET_ERROR_TYPE_INFO,
519 "Notifying ATS about peer %s's new address `%s'\n", 513 "Notifying ATS about peer %s's new address `%s'\n",
520 GNUNET_i2s (&address->peer), 514 GNUNET_i2s(&address->peer),
521 GST_plugins_a2s (address)); 515 GST_plugins_a2s(address));
522 ar = GNUNET_ATS_address_add (GST_ats, 516 ar = GNUNET_ATS_address_add(GST_ats,
523 address, 517 address,
524 NULL, 518 NULL,
525 prop); 519 prop);
526 GNUNET_assert (NULL != ar); 520 GNUNET_assert(NULL != ar);
527 ai = GNUNET_new (struct AddressInfo); 521 ai = GNUNET_new(struct AddressInfo);
528 ai->address = GNUNET_HELLO_address_copy (address); 522 ai->address = GNUNET_HELLO_address_copy(address);
529 ai->ar = ar; 523 ai->ar = ar;
530 ai->properties = *prop; 524 ai->properties = *prop;
531 (void) GNUNET_CONTAINER_multipeermap_put (p2a, 525 (void)GNUNET_CONTAINER_multipeermap_put(p2a,
532 &ai->address->peer, 526 &ai->address->peer,
533 ai, 527 ai,
534 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 528 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
535 publish_p2a_stat_update (); 529 publish_p2a_stat_update();
536} 530}
537 531
538 532
@@ -546,41 +540,41 @@ GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
546 * @param session the session 540 * @param session the session
547 */ 541 */
548void 542void
549GST_ats_new_session (const struct GNUNET_HELLO_Address *address, 543GST_ats_new_session(const struct GNUNET_HELLO_Address *address,
550 struct GNUNET_ATS_Session *session) 544 struct GNUNET_ATS_Session *session)
551{ 545{
552 struct AddressInfo *ai; 546 struct AddressInfo *ai;
553 547
554 if (0 == 548 if (0 ==
555 memcmp (&GST_my_identity, 549 memcmp(&GST_my_identity,
556 &address->peer, 550 &address->peer,
557 sizeof (struct GNUNET_PeerIdentity))) 551 sizeof(struct GNUNET_PeerIdentity)))
558 return; /* our own, ignore! */ 552 return; /* our own, ignore! */
559 ai = find_ai (address, NULL); 553 ai = find_ai(address, NULL);
560 if (NULL == ai) 554 if (NULL == ai)
561 { 555 {
562 /* We may simply already be aware of the session, even if some 556 /* We may simply already be aware of the session, even if some
563 other part of the code could not tell if it just created a new 557 other part of the code could not tell if it just created a new
564 session or just got one recycled from the plugin; hence, we may 558 session or just got one recycled from the plugin; hence, we may
565 be called with "new" session even for an "old" session; in that 559 be called with "new" session even for an "old" session; in that
566 case, check that this is the case, but just ignore it. */ 560 case, check that this is the case, but just ignore it. */
567 GNUNET_assert (NULL != (find_ai (address, session))); 561 GNUNET_assert(NULL != (find_ai(address, session)));
568 return; 562 return;
569 } 563 }
570 GNUNET_assert (NULL == ai->session); 564 GNUNET_assert(NULL == ai->session);
571 ai->session = session; 565 ai->session = session;
572 LOG (GNUNET_ERROR_TYPE_DEBUG, 566 LOG(GNUNET_ERROR_TYPE_DEBUG,
573 "Telling ATS about new session for peer %s\n", 567 "Telling ATS about new session for peer %s\n",
574 GNUNET_i2s (&address->peer)); 568 GNUNET_i2s(&address->peer));
575 /* Note that the address might currently be blocked; we only 569 /* Note that the address might currently be blocked; we only
576 tell ATS about the session if the address is currently not 570 tell ATS about the session if the address is currently not
577 blocked; otherwise, ATS will be told about the session on 571 blocked; otherwise, ATS will be told about the session on
578 unblock. */ 572 unblock. */
579 if (NULL != ai->ar) 573 if (NULL != ai->ar)
580 GNUNET_ATS_address_add_session (ai->ar, 574 GNUNET_ATS_address_add_session(ai->ar,
581 session); 575 session);
582 else 576 else
583 GNUNET_assert (NULL != ai->unblock_task); 577 GNUNET_assert(NULL != ai->unblock_task);
584} 578}
585 579
586 580
@@ -590,30 +584,30 @@ GST_ats_new_session (const struct GNUNET_HELLO_Address *address,
590 * @param ai the `struct AddressInfo` 584 * @param ai the `struct AddressInfo`
591 */ 585 */
592static void 586static void
593destroy_ai (struct AddressInfo *ai) 587destroy_ai(struct AddressInfo *ai)
594{ 588{
595 GNUNET_assert (NULL == ai->session); 589 GNUNET_assert(NULL == ai->session);
596 if (NULL != ai->unblock_task) 590 if (NULL != ai->unblock_task)
597 { 591 {
598 GNUNET_SCHEDULER_cancel (ai->unblock_task); 592 GNUNET_SCHEDULER_cancel(ai->unblock_task);
599 ai->unblock_task = NULL; 593 ai->unblock_task = NULL;
600 num_blocked--; 594 num_blocked--;
601 } 595 }
602 GNUNET_assert (GNUNET_YES == 596 GNUNET_assert(GNUNET_YES ==
603 GNUNET_CONTAINER_multipeermap_remove (p2a, 597 GNUNET_CONTAINER_multipeermap_remove(p2a,
604 &ai->address->peer, 598 &ai->address->peer,
605 ai)); 599 ai));
606 LOG (GNUNET_ERROR_TYPE_DEBUG, 600 LOG(GNUNET_ERROR_TYPE_DEBUG,
607 "Telling ATS to destroy address from peer %s\n", 601 "Telling ATS to destroy address from peer %s\n",
608 GNUNET_i2s (&ai->address->peer)); 602 GNUNET_i2s(&ai->address->peer));
609 if (NULL != ai->ar) 603 if (NULL != ai->ar)
610 { 604 {
611 GNUNET_ATS_address_destroy (ai->ar); 605 GNUNET_ATS_address_destroy(ai->ar);
612 ai->ar = NULL; 606 ai->ar = NULL;
613 } 607 }
614 publish_p2a_stat_update (); 608 publish_p2a_stat_update();
615 GNUNET_HELLO_address_free (ai->address); 609 GNUNET_HELLO_address_free(ai->address);
616 GNUNET_free (ai); 610 GNUNET_free(ai);
617} 611}
618 612
619 613
@@ -629,100 +623,100 @@ destroy_ai (struct AddressInfo *ai)
629 * @param session the session 623 * @param session the session
630 */ 624 */
631void 625void
632GST_ats_del_session (const struct GNUNET_HELLO_Address *address, 626GST_ats_del_session(const struct GNUNET_HELLO_Address *address,
633 struct GNUNET_ATS_Session *session) 627 struct GNUNET_ATS_Session *session)
634{ 628{
635 struct AddressInfo *ai; 629 struct AddressInfo *ai;
636 630
637 if (0 == 631 if (0 ==
638 memcmp (&GST_my_identity, 632 memcmp(&GST_my_identity,
639 &address->peer, 633 &address->peer,
640 sizeof (struct GNUNET_PeerIdentity))) 634 sizeof(struct GNUNET_PeerIdentity)))
641 return; /* our own, ignore! */ 635 return; /* our own, ignore! */
642 if (NULL == session) 636 if (NULL == session)
643 { 637 {
644 GNUNET_break (0); 638 GNUNET_break(0);
645 return; 639 return;
646 } 640 }
647 ai = find_ai (address, 641 ai = find_ai(address,
648 session); 642 session);
649 if (NULL == ai) 643 if (NULL == ai)
650 { 644 {
651 /* We sometimes create sessions just for sending a PING, 645 /* We sometimes create sessions just for sending a PING,
652 and if those are destroyed they were never known to 646 and if those are destroyed they were never known to
653 ATS which means we end up here (however, in this 647 ATS which means we end up here (however, in this
654 case, the address must be an outbound address). */ 648 case, the address must be an outbound address). */
655 GNUNET_break (GNUNET_YES != 649 GNUNET_break(GNUNET_YES !=
656 GNUNET_HELLO_address_check_option (address, 650 GNUNET_HELLO_address_check_option(address,
657 GNUNET_HELLO_ADDRESS_INFO_INBOUND)); 651 GNUNET_HELLO_ADDRESS_INFO_INBOUND));
658 return; 652 return;
659 } 653 }
660 GNUNET_assert (session == ai->session); 654 GNUNET_assert(session == ai->session);
661 ai->session = NULL; 655 ai->session = NULL;
662 LOG (GNUNET_ERROR_TYPE_DEBUG, 656 LOG(GNUNET_ERROR_TYPE_DEBUG,
663 "Telling ATS to destroy session %p from peer %s\n", 657 "Telling ATS to destroy session %p from peer %s\n",
664 session, 658 session,
665 GNUNET_i2s (&address->peer)); 659 GNUNET_i2s(&address->peer));
666 if (GNUNET_YES == ai->expired) 660 if (GNUNET_YES == ai->expired)
667 {
668 /* last reason to keep this 'ai' around is now gone, the
669 session is dead as well, clean up */
670 if (NULL != ai->ar)
671 { 661 {
672 /* Address expired but not blocked, and thus 'ar' was still 662 /* last reason to keep this 'ai' around is now gone, the
673 live because of the session; deleting just the session 663 session is dead as well, clean up */
674 will do for an inbound session, but for an outbound we 664 if (NULL != ai->ar)
675 then also need to destroy the address with ATS. */ 665 {
676 if (GNUNET_NO == 666 /* Address expired but not blocked, and thus 'ar' was still
677 GNUNET_ATS_address_del_session (ai->ar, 667 live because of the session; deleting just the session
678 session)) 668 will do for an inbound session, but for an outbound we
679 { 669 then also need to destroy the address with ATS. */
680 GNUNET_ATS_address_destroy (ai->ar); 670 if (GNUNET_NO ==
681 } 671 GNUNET_ATS_address_del_session(ai->ar,
682 /* "ar" has been freed, regardless how the branch 672 session))
683 above played out: it was either freed in 673 {
684 #GNUNET_ATS_address_del_session() because it was 674 GNUNET_ATS_address_destroy(ai->ar);
685 incoming, or explicitly in 675 }
686 #GNUNET_ATS_address_del_session(). */ 676 /* "ar" has been freed, regardless how the branch
687 ai->ar = NULL; 677 above played out: it was either freed in
678 #GNUNET_ATS_address_del_session() because it was
679 incoming, or explicitly in
680 #GNUNET_ATS_address_del_session(). */
681 ai->ar = NULL;
682 }
683 destroy_ai(ai);
684 return;
688 } 685 }
689 destroy_ai (ai);
690 return;
691 }
692 686
693 if (NULL == ai->ar) 687 if (NULL == ai->ar)
694 {
695 /* If ATS doesn't know about the address/session, this means
696 this address was blocked. */
697 if (GNUNET_YES ==
698 GNUNET_HELLO_address_check_option (address,
699 GNUNET_HELLO_ADDRESS_INFO_INBOUND))
700 { 688 {
701 /* This was a blocked inbound session, which now lost the 689 /* If ATS doesn't know about the address/session, this means
702 session. But inbound addresses are by themselves useless, 690 this address was blocked. */
703 so we must forget about the address as well. */ 691 if (GNUNET_YES ==
704 destroy_ai (ai); 692 GNUNET_HELLO_address_check_option(address,
693 GNUNET_HELLO_ADDRESS_INFO_INBOUND))
694 {
695 /* This was a blocked inbound session, which now lost the
696 session. But inbound addresses are by themselves useless,
697 so we must forget about the address as well. */
698 destroy_ai(ai);
699 return;
700 }
701 /* Otherwise, we are done as we have set `ai->session` to NULL
702 already and ATS will simply not be told about the session when
703 the connection is unblocked and the outbound address becomes
704 available again. . */
705 return; 705 return;
706 } 706 }
707 /* Otherwise, we are done as we have set `ai->session` to NULL
708 already and ATS will simply not be told about the session when
709 the connection is unblocked and the outbound address becomes
710 available again. . */
711 return;
712 }
713 707
714 /* This is the "simple" case where ATS knows about the session and 708 /* This is the "simple" case where ATS knows about the session and
715 the address is neither blocked nor expired. Delete the session, 709 the address is neither blocked nor expired. Delete the session,
716 and if it was inbound, free the address as well. */ 710 and if it was inbound, free the address as well. */
717 if (GNUNET_YES == 711 if (GNUNET_YES ==
718 GNUNET_ATS_address_del_session (ai->ar, 712 GNUNET_ATS_address_del_session(ai->ar,
719 session)) 713 session))
720 { 714 {
721 /* This was an inbound address, the session is now gone, so we 715 /* This was an inbound address, the session is now gone, so we
722 need to also forget about the address itself. */ 716 need to also forget about the address itself. */
723 ai->ar = NULL; 717 ai->ar = NULL;
724 destroy_ai (ai); 718 destroy_ai(ai);
725 } 719 }
726} 720}
727 721
728 722
@@ -734,31 +728,31 @@ GST_ats_del_session (const struct GNUNET_HELLO_Address *address,
734 * @param distance new distance value 728 * @param distance new distance value
735 */ 729 */
736void 730void
737GST_ats_update_distance (const struct GNUNET_HELLO_Address *address, 731GST_ats_update_distance(const struct GNUNET_HELLO_Address *address,
738 uint32_t distance) 732 uint32_t distance)
739{ 733{
740 struct AddressInfo *ai; 734 struct AddressInfo *ai;
741 735
742 ai = find_ai_no_session (address); 736 ai = find_ai_no_session(address);
743 if (NULL == ai) 737 if (NULL == ai)
744 { 738 {
745 /* We do not know about this address, do nothing. */ 739 /* We do not know about this address, do nothing. */
746 return; 740 return;
747 } 741 }
748 LOG (GNUNET_ERROR_TYPE_DEBUG, 742 LOG(GNUNET_ERROR_TYPE_DEBUG,
749 "Updated distance for peer `%s' to %u\n", 743 "Updated distance for peer `%s' to %u\n",
750 GNUNET_i2s (&address->peer), 744 GNUNET_i2s(&address->peer),
751 distance); 745 distance);
752 ai->properties.distance = distance; 746 ai->properties.distance = distance;
753 /* Give manipulation its chance to change metrics */ 747 /* Give manipulation its chance to change metrics */
754 GST_manipulation_manipulate_metrics (address, 748 GST_manipulation_manipulate_metrics(address,
755 ai->session, 749 ai->session,
756 &ai->properties); 750 &ai->properties);
757 /* Address may be blocked, only give ATS if address is 751 /* Address may be blocked, only give ATS if address is
758 currently active. */ 752 currently active. */
759 if (NULL != ai->ar) 753 if (NULL != ai->ar)
760 GNUNET_ATS_address_update (ai->ar, 754 GNUNET_ATS_address_update(ai->ar,
761 &ai->properties); 755 &ai->properties);
762} 756}
763 757
764 758
@@ -770,32 +764,32 @@ GST_ats_update_distance (const struct GNUNET_HELLO_Address *address,
770 * @param delay new delay value 764 * @param delay new delay value
771 */ 765 */
772void 766void
773GST_ats_update_delay (const struct GNUNET_HELLO_Address *address, 767GST_ats_update_delay(const struct GNUNET_HELLO_Address *address,
774 struct GNUNET_TIME_Relative delay) 768 struct GNUNET_TIME_Relative delay)
775{ 769{
776 struct AddressInfo *ai; 770 struct AddressInfo *ai;
777 771
778 ai = find_ai_no_session (address); 772 ai = find_ai_no_session(address);
779 if (NULL == ai) 773 if (NULL == ai)
780 { 774 {
781 /* We do not know about this address, do nothing. */ 775 /* We do not know about this address, do nothing. */
782 return; 776 return;
783 } 777 }
784 LOG (GNUNET_ERROR_TYPE_DEBUG, 778 LOG(GNUNET_ERROR_TYPE_DEBUG,
785 "Updated latency for peer `%s' to %s\n", 779 "Updated latency for peer `%s' to %s\n",
786 GNUNET_i2s (&address->peer), 780 GNUNET_i2s(&address->peer),
787 GNUNET_STRINGS_relative_time_to_string (delay, 781 GNUNET_STRINGS_relative_time_to_string(delay,
788 GNUNET_YES)); 782 GNUNET_YES));
789 ai->properties.delay = delay; 783 ai->properties.delay = delay;
790 /* Give manipulation its chance to change metrics */ 784 /* Give manipulation its chance to change metrics */
791 GST_manipulation_manipulate_metrics (address, 785 GST_manipulation_manipulate_metrics(address,
792 ai->session, 786 ai->session,
793 &ai->properties); 787 &ai->properties);
794 /* Address may be blocked, only give ATS if address is 788 /* Address may be blocked, only give ATS if address is
795 currently active. */ 789 currently active. */
796 if (NULL != ai->ar) 790 if (NULL != ai->ar)
797 GNUNET_ATS_address_update (ai->ar, 791 GNUNET_ATS_address_update(ai->ar,
798 &ai->properties); 792 &ai->properties);
799} 793}
800 794
801 795
@@ -808,35 +802,35 @@ GST_ats_update_delay (const struct GNUNET_HELLO_Address *address,
808 * @param bps_out new utilization outbound 802 * @param bps_out new utilization outbound
809 */ 803 */
810void 804void
811GST_ats_update_utilization (const struct GNUNET_HELLO_Address *address, 805GST_ats_update_utilization(const struct GNUNET_HELLO_Address *address,
812 uint32_t bps_in, 806 uint32_t bps_in,
813 uint32_t bps_out) 807 uint32_t bps_out)
814{ 808{
815 struct AddressInfo *ai; 809 struct AddressInfo *ai;
816 810
817 ai = find_ai_no_session (address); 811 ai = find_ai_no_session(address);
818 if (NULL == ai) 812 if (NULL == ai)
819 { 813 {
820 /* We do not know about this address, do nothing. */ 814 /* We do not know about this address, do nothing. */
821 return; 815 return;
822 } 816 }
823 LOG (GNUNET_ERROR_TYPE_DEBUG, 817 LOG(GNUNET_ERROR_TYPE_DEBUG,
824 "Updating utilization for peer `%s' address %s: %u/%u\n", 818 "Updating utilization for peer `%s' address %s: %u/%u\n",
825 GNUNET_i2s (&address->peer), 819 GNUNET_i2s(&address->peer),
826 GST_plugins_a2s (address), 820 GST_plugins_a2s(address),
827 (unsigned int) bps_in, 821 (unsigned int)bps_in,
828 (unsigned int) bps_out); 822 (unsigned int)bps_out);
829 ai->properties.utilization_in = bps_in; 823 ai->properties.utilization_in = bps_in;
830 ai->properties.utilization_out = bps_out; 824 ai->properties.utilization_out = bps_out;
831 /* Give manipulation its chance to change metrics */ 825 /* Give manipulation its chance to change metrics */
832 GST_manipulation_manipulate_metrics (address, 826 GST_manipulation_manipulate_metrics(address,
833 ai->session, 827 ai->session,
834 &ai->properties); 828 &ai->properties);
835 /* Address may be blocked, only give ATS if address is 829 /* Address may be blocked, only give ATS if address is
836 currently active. */ 830 currently active. */
837 if (NULL != ai->ar) 831 if (NULL != ai->ar)
838 GNUNET_ATS_address_update (ai->ar, 832 GNUNET_ATS_address_update(ai->ar,
839 &ai->properties); 833 &ai->properties);
840} 834}
841 835
842 836
@@ -848,34 +842,34 @@ GST_ats_update_utilization (const struct GNUNET_HELLO_Address *address,
848 * @param address the address 842 * @param address the address
849 */ 843 */
850void 844void
851GST_ats_expire_address (const struct GNUNET_HELLO_Address *address) 845GST_ats_expire_address(const struct GNUNET_HELLO_Address *address)
852{ 846{
853 struct AddressInfo *ai; 847 struct AddressInfo *ai;
854 848
855 if (0 == 849 if (0 ==
856 memcmp (&GST_my_identity, 850 memcmp(&GST_my_identity,
857 &address->peer, 851 &address->peer,
858 sizeof (struct GNUNET_PeerIdentity))) 852 sizeof(struct GNUNET_PeerIdentity)))
859 return; /* our own, ignore! */ 853 return; /* our own, ignore! */
860 LOG (GNUNET_ERROR_TYPE_DEBUG, 854 LOG(GNUNET_ERROR_TYPE_DEBUG,
861 "Address %s of peer %s expired\n", 855 "Address %s of peer %s expired\n",
862 GST_plugins_a2s (address), 856 GST_plugins_a2s(address),
863 GNUNET_i2s (&address->peer)); 857 GNUNET_i2s(&address->peer));
864 ai = find_ai_no_session (address); 858 ai = find_ai_no_session(address);
865 if (NULL == ai) 859 if (NULL == ai)
866 { 860 {
867 GNUNET_assert (0); 861 GNUNET_assert(0);
868 return; 862 return;
869 } 863 }
870 if (NULL != ai->session) 864 if (NULL != ai->session)
871 { 865 {
872 /* Got an active session, just remember the expiration 866 /* Got an active session, just remember the expiration
873 and act upon it when the session goes down. */ 867 and act upon it when the session goes down. */
874 ai->expired = GNUNET_YES; 868 ai->expired = GNUNET_YES;
875 return; 869 return;
876 } 870 }
877 /* Address expired, no session, free resources */ 871 /* Address expired, no session, free resources */
878 destroy_ai (ai); 872 destroy_ai(ai);
879} 873}
880 874
881 875
@@ -883,9 +877,9 @@ GST_ats_expire_address (const struct GNUNET_HELLO_Address *address)
883 * Initialize ATS subsystem. 877 * Initialize ATS subsystem.
884 */ 878 */
885void 879void
886GST_ats_init () 880GST_ats_init()
887{ 881{
888 p2a = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_YES); 882 p2a = GNUNET_CONTAINER_multipeermap_create(4, GNUNET_YES);
889} 883}
890 884
891 885
@@ -898,13 +892,13 @@ GST_ats_init ()
898 * @return #GNUNET_OK (continue to iterate) 892 * @return #GNUNET_OK (continue to iterate)
899 */ 893 */
900static int 894static int
901destroy_ai_cb (void *cls, 895destroy_ai_cb(void *cls,
902 const struct GNUNET_PeerIdentity *key, 896 const struct GNUNET_PeerIdentity *key,
903 void *value) 897 void *value)
904{ 898{
905 struct AddressInfo *ai = value; 899 struct AddressInfo *ai = value;
906 900
907 destroy_ai (ai); 901 destroy_ai(ai);
908 return GNUNET_OK; 902 return GNUNET_OK;
909} 903}
910 904
@@ -913,13 +907,13 @@ destroy_ai_cb (void *cls,
913 * Shutdown ATS subsystem. 907 * Shutdown ATS subsystem.
914 */ 908 */
915void 909void
916GST_ats_done () 910GST_ats_done()
917{ 911{
918 GNUNET_CONTAINER_multipeermap_iterate (p2a, 912 GNUNET_CONTAINER_multipeermap_iterate(p2a,
919 &destroy_ai_cb, 913 &destroy_ai_cb,
920 NULL); 914 NULL);
921 publish_p2a_stat_update (); 915 publish_p2a_stat_update();
922 GNUNET_CONTAINER_multipeermap_destroy (p2a); 916 GNUNET_CONTAINER_multipeermap_destroy(p2a);
923 p2a = NULL; 917 p2a = NULL;
924} 918}
925 919