aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/Makefile.am1
-rw-r--r--src/transport/gnunet-service-transport.c33
-rw-r--r--src/transport/gnunet-service-transport_ats.c248
-rw-r--r--src/transport/gnunet-service-transport_ats.h58
-rw-r--r--src/transport/gnunet-service-transport_clients.c3
-rw-r--r--src/transport/gnunet-service-transport_manipulation.c667
-rw-r--r--src/transport/gnunet-service-transport_manipulation.h39
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c49
-rw-r--r--src/transport/gnunet-service-transport_plugins.c18
-rw-r--r--src/transport/gnunet-service-transport_validation.c29
-rw-r--r--src/transport/plugin_transport_http_client.c16
-rw-r--r--src/transport/plugin_transport_http_server.c40
-rw-r--r--src/transport/plugin_transport_tcp.c43
-rw-r--r--src/transport/plugin_transport_udp.c26
-rw-r--r--src/transport/plugin_transport_udp_broadcasting.c13
-rw-r--r--src/transport/plugin_transport_unix.c19
-rw-r--r--src/transport/plugin_transport_wlan.c28
-rw-r--r--src/transport/test_plugin_transport.c10
-rw-r--r--src/transport/test_transport_api_manipulation_recv_tcp.c22
-rw-r--r--src/transport/test_transport_api_manipulation_send_tcp.c54
-rw-r--r--src/transport/transport.h26
-rw-r--r--src/transport/transport_api.c76
22 files changed, 630 insertions, 888 deletions
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index 3c479f8fe..289fcd4c0 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -169,6 +169,7 @@ libgnunettransport_la_SOURCES = \
169 transport_api_monitor_validation.c 169 transport_api_monitor_validation.c
170libgnunettransport_la_LIBADD = \ 170libgnunettransport_la_LIBADD = \
171 $(top_builddir)/src/hello/libgnunethello.la \ 171 $(top_builddir)/src/hello/libgnunethello.la \
172 $(top_builddir)/src/ats/libgnunetats.la \
172 $(top_builddir)/src/util/libgnunetutil.la \ 173 $(top_builddir)/src/util/libgnunetutil.la \
173 $(GN_LIBINTL) 174 $(GN_LIBINTL)
174libgnunettransport_la_LDFLAGS = \ 175libgnunettransport_la_LDFLAGS = \
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index 5840eec5e..efbd67619 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -743,18 +743,17 @@ plugin_env_session_start_bl_check_cont (void *cls,
743 * @param cls unused 743 * @param cls unused
744 * @param address the address 744 * @param address the address
745 * @param session the new session 745 * @param session the new session
746 * @param ats ats information 746 * @param scope network scope information
747 * @param ats_count number of @a ats information
748 */ 747 */
749static void 748static void
750plugin_env_session_start (void *cls, 749plugin_env_session_start (void *cls,
751 const struct GNUNET_HELLO_Address *address, 750 const struct GNUNET_HELLO_Address *address,
752 struct Session *session, 751 struct Session *session,
753 const struct GNUNET_ATS_Information *ats, 752 enum GNUNET_ATS_Network_Type scope)
754 uint32_t ats_count)
755{ 753{
756 struct BlacklistCheckContext *blctx; 754 struct BlacklistCheckContext *blctx;
757 struct GST_BlacklistCheck *blc; 755 struct GST_BlacklistCheck *blc;
756 struct GNUNET_ATS_Properties prop;
758 757
759 if (NULL == address) 758 if (NULL == address)
760 { 759 {
@@ -767,9 +766,8 @@ plugin_env_session_start (void *cls,
767 return; 766 return;
768 } 767 }
769 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 768 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
770 "Notification from plugin `%s' about new session %p from peer `%s' address `%s'\n", 769 "Notification from plugin `%s' about new session from peer `%s' address `%s'\n",
771 address->transport_name, 770 address->transport_name,
772 session,
773 GNUNET_i2s (&address->peer), 771 GNUNET_i2s (&address->peer),
774 GST_plugins_a2s (address)); 772 GST_plugins_a2s (address));
775 if (GNUNET_YES == 773 if (GNUNET_YES ==
@@ -779,22 +777,12 @@ plugin_env_session_start (void *cls,
779 /* inbound is always new, but outbound MAY already be known, but 777 /* inbound is always new, but outbound MAY already be known, but
780 for example for UNIX, we have symmetric connections and thus we 778 for example for UNIX, we have symmetric connections and thus we
781 may not know the address yet; add if necessary! */ 779 may not know the address yet; add if necessary! */
780 /* FIXME: maybe change API here so we just pass scope? */
781 memset (&prop, 0, sizeof (prop));
782 prop.scope = scope;
782 GST_ats_add_inbound_address (address, 783 GST_ats_add_inbound_address (address,
783 session, 784 session,
784 ats, 785 &prop);
785 ats_count);
786 }
787 else
788 {
789 if (GNUNET_YES ==
790 GST_ats_is_known (address,
791 session))
792 {
793 GST_ats_update_metrics (address,
794 session,
795 ats,
796 ats_count);
797 }
798 } 786 }
799 /* Do blacklist check if communication with this peer is allowed */ 787 /* Do blacklist check if communication with this peer is allowed */
800 blctx = GNUNET_new (struct BlacklistCheckContext); 788 blctx = GNUNET_new (struct BlacklistCheckContext);
@@ -1034,7 +1022,7 @@ run (void *cls,
1034 &ats_request_address_change, 1022 &ats_request_address_change,
1035 NULL); 1023 NULL);
1036 GST_ats_init (); 1024 GST_ats_init ();
1037 GST_manipulation_init (GST_cfg); 1025 GST_manipulation_init ();
1038 GST_plugins_load (&GST_manipulation_recv, 1026 GST_plugins_load (&GST_manipulation_recv,
1039 &plugin_env_address_change_notification, 1027 &plugin_env_address_change_notification,
1040 &plugin_env_session_start, 1028 &plugin_env_session_start,
@@ -1053,7 +1041,8 @@ run (void *cls,
1053 * @return 0 ok, 1 on error 1041 * @return 0 ok, 1 on error
1054 */ 1042 */
1055int 1043int
1056main (int argc, char * const *argv) 1044main (int argc,
1045 char * const *argv)
1057{ 1046{
1058 return 1047 return
1059 (GNUNET_OK 1048 (GNUNET_OK
diff --git a/src/transport/gnunet-service-transport_ats.c b/src/transport/gnunet-service-transport_ats.c
index 613f35ec2..3976ae3d9 100644
--- a/src/transport/gnunet-service-transport_ats.c
+++ b/src/transport/gnunet-service-transport_ats.c
@@ -29,6 +29,8 @@
29#include "gnunet-service-transport_plugins.h" 29#include "gnunet-service-transport_plugins.h"
30#include "gnunet_ats_service.h" 30#include "gnunet_ats_service.h"
31 31
32#define LOG(kind,...) GNUNET_log_from(kind, "transport-ats", __VA_ARGS__)
33
32 34
33/** 35/**
34 * Information we track for each address known to ATS. 36 * Information we track for each address known to ATS.
@@ -52,6 +54,11 @@ struct AddressInfo
52 struct GNUNET_ATS_AddressRecord *ar; 54 struct GNUNET_ATS_AddressRecord *ar;
53 55
54 /** 56 /**
57 * Performance properties of this address.
58 */
59 struct GNUNET_ATS_Properties properties;
60
61 /**
55 * Time until when this address is blocked and should thus not be 62 * Time until when this address is blocked and should thus not be
56 * made available to ATS (@e ar should be NULL until this time). 63 * made available to ATS (@e ar should be NULL until this time).
57 * Used when transport determines that for some reason it 64 * Used when transport determines that for some reason it
@@ -256,16 +263,15 @@ unblock_address (void *cls,
256 struct AddressInfo *ai = cls; 263 struct AddressInfo *ai = cls;
257 264
258 ai->unblock_task = NULL; 265 ai->unblock_task = NULL;
259 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 266 LOG (GNUNET_ERROR_TYPE_DEBUG,
260 "Unblocking address %s of peer %s\n", 267 "Unblocking address %s of peer %s\n",
261 GST_plugins_a2s (ai->address), 268 GST_plugins_a2s (ai->address),
262 GNUNET_i2s (&ai->address->peer)); 269 GNUNET_i2s (&ai->address->peer));
263 ai->ar = GNUNET_ATS_address_add (GST_ats, 270 ai->ar = GNUNET_ATS_address_add (GST_ats,
264 ai->address, 271 ai->address,
265 ai->session, 272 ai->session,
266 NULL, 0); 273 &ai->properties);
267 GNUNET_break (NULL != ai->ar); 274 GNUNET_break (NULL != ai->ar);
268 /* FIXME: should pass ATS information here! */
269} 275}
270 276
271 277
@@ -299,15 +305,15 @@ GST_ats_block_address (const struct GNUNET_HELLO_Address *address,
299 if (GNUNET_YES == 305 if (GNUNET_YES ==
300 GNUNET_HELLO_address_check_option (address, 306 GNUNET_HELLO_address_check_option (address,
301 GNUNET_HELLO_ADDRESS_INFO_INBOUND)) 307 GNUNET_HELLO_ADDRESS_INFO_INBOUND))
302 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 308 LOG (GNUNET_ERROR_TYPE_DEBUG,
303 "Removing address %s of peer %s from use (inbound died)\n", 309 "Removing address %s of peer %s from use (inbound died)\n",
304 GST_plugins_a2s (address), 310 GST_plugins_a2s (address),
305 GNUNET_i2s (&address->peer)); 311 GNUNET_i2s (&address->peer));
306 else 312 else
307 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 313 LOG (GNUNET_ERROR_TYPE_DEBUG,
308 "Blocking address %s of peer %s from use for a while\n", 314 "Blocking address %s of peer %s from use for a while\n",
309 GST_plugins_a2s (address), 315 GST_plugins_a2s (address),
310 GNUNET_i2s (&address->peer)); 316 GNUNET_i2s (&address->peer));
311 /* destroy session and address */ 317 /* destroy session and address */
312 if ( (NULL == session) || 318 if ( (NULL == session) ||
313 (GNUNET_NO == 319 (GNUNET_NO ==
@@ -332,20 +338,15 @@ GST_ats_block_address (const struct GNUNET_HELLO_Address *address,
332 * 338 *
333 * @param address the address 339 * @param address the address
334 * @param session the session 340 * @param session the session
335 * @param ats ats information 341 * @param prop performance information
336 * @param ats_count number of @a ats information
337 */ 342 */
338void 343void
339GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address, 344GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address,
340 struct Session *session, 345 struct Session *session,
341 const struct GNUNET_ATS_Information *ats, 346 const struct GNUNET_ATS_Properties *prop)
342 uint32_t ats_count)
343{ 347{
344 struct GNUNET_TRANSPORT_PluginFunctions *papi;
345 struct GNUNET_ATS_Information ats2[ats_count + 1];
346 struct GNUNET_ATS_AddressRecord *ar; 348 struct GNUNET_ATS_AddressRecord *ar;
347 struct AddressInfo *ai; 349 struct AddressInfo *ai;
348 uint32_t net;
349 350
350 /* valid new address, let ATS know! */ 351 /* valid new address, let ATS know! */
351 if (NULL == address->transport_name) 352 if (NULL == address->transport_name)
@@ -365,40 +366,24 @@ GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address,
365 GNUNET_break (0); 366 GNUNET_break (0);
366 return; 367 return;
367 } 368 }
368 papi = GST_plugins_find (address->transport_name); 369 GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope);
369 GNUNET_assert (NULL != papi); 370 LOG (GNUNET_ERROR_TYPE_DEBUG,
370 net = papi->get_network (papi->cls, session); 371 "Notifying ATS about peer `%s''s new inbound address `%s' session %p in network %s\n",
371 if (GNUNET_ATS_NET_UNSPECIFIED == net) 372 GNUNET_i2s (&address->peer),
372 { 373 (0 == address->address_length)
373 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 374 ? "<inbound>"
374 _("Could not obtain a valid network for `%s' %s (%s)\n"), 375 : GST_plugins_a2s (address),
375 GNUNET_i2s (&address->peer), 376 session,
376 GST_plugins_a2s (address), 377 GNUNET_ATS_print_network_type (prop->scope));
377 address->transport_name);
378 return;
379 }
380 ats2[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
381 ats2[0].value = htonl (net);
382 memcpy (&ats2[1],
383 ats,
384 sizeof(struct GNUNET_ATS_Information) * ats_count);
385 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
386 "Notifying ATS about peer `%s''s new inbound address `%s' session %p in network %s\n",
387 GNUNET_i2s (&address->peer),
388 (0 == address->address_length)
389 ? "<inbound>"
390 : GST_plugins_a2s (address),
391 session,
392 GNUNET_ATS_print_network_type (net));
393 ar = GNUNET_ATS_address_add (GST_ats, 378 ar = GNUNET_ATS_address_add (GST_ats,
394 address, 379 address,
395 session, 380 session,
396 (NULL != session) ? ats2 : ats, 381 prop);
397 (NULL != session) ? ats_count + 1 : ats_count);
398 GNUNET_break (NULL != ar); 382 GNUNET_break (NULL != ar);
399 ai = GNUNET_new (struct AddressInfo); 383 ai = GNUNET_new (struct AddressInfo);
400 ai->address = GNUNET_HELLO_address_copy (address); 384 ai->address = GNUNET_HELLO_address_copy (address);
401 ai->session = session; 385 ai->session = session;
386 ai->properties = *prop;
402 ai->ar = ar; 387 ai->ar = ar;
403 (void) GNUNET_CONTAINER_multipeermap_put (p2a, 388 (void) GNUNET_CONTAINER_multipeermap_put (p2a,
404 &ai->address->peer, 389 &ai->address->peer,
@@ -413,13 +398,11 @@ GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address,
413 * located in. The address must NOT be inbound and must be new to ATS. 398 * located in. The address must NOT be inbound and must be new to ATS.
414 * 399 *
415 * @param address the address 400 * @param address the address
416 * @param ats ats information 401 * @param prop performance information
417 * @param ats_count number of @a ats information
418 */ 402 */
419void 403void
420GST_ats_add_address (const struct GNUNET_HELLO_Address *address, 404GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
421 const struct GNUNET_ATS_Information *ats, 405 const struct GNUNET_ATS_Properties *prop)
422 uint32_t ats_count)
423{ 406{
424 struct GNUNET_ATS_AddressRecord *ar; 407 struct GNUNET_ATS_AddressRecord *ar;
425 struct AddressInfo *ai; 408 struct AddressInfo *ai;
@@ -435,21 +418,21 @@ GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
435 GNUNET_HELLO_ADDRESS_INFO_INBOUND)); 418 GNUNET_HELLO_ADDRESS_INFO_INBOUND));
436 ai = find_ai_no_session (address); 419 ai = find_ai_no_session (address);
437 GNUNET_assert (NULL == ai); 420 GNUNET_assert (NULL == ai);
438 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 421 LOG (GNUNET_ERROR_TYPE_INFO,
439 "Notifying ATS about peer `%s''s new address `%s'\n", 422 "Notifying ATS about peer `%s''s new address `%s'\n",
440 GNUNET_i2s (&address->peer), 423 GNUNET_i2s (&address->peer),
441 (0 == address->address_length) 424 (0 == address->address_length)
442 ? "<inbound>" 425 ? "<inbound>"
443 : GST_plugins_a2s (address)); 426 : GST_plugins_a2s (address));
444 ar = GNUNET_ATS_address_add (GST_ats, 427 ar = GNUNET_ATS_address_add (GST_ats,
445 address, 428 address,
446 NULL, 429 NULL,
447 ats, 430 prop);
448 ats_count);
449 GNUNET_break (NULL != ar); 431 GNUNET_break (NULL != ar);
450 ai = GNUNET_new (struct AddressInfo); 432 ai = GNUNET_new (struct AddressInfo);
451 ai->address = GNUNET_HELLO_address_copy (address); 433 ai->address = GNUNET_HELLO_address_copy (address);
452 ai->ar = ar; 434 ai->ar = ar;
435 ai->properties = *prop;
453 (void) GNUNET_CONTAINER_multipeermap_put (p2a, 436 (void) GNUNET_CONTAINER_multipeermap_put (p2a,
454 &ai->address->peer, 437 &ai->address->peer,
455 ai, 438 ai,
@@ -484,11 +467,9 @@ GST_ats_new_session (const struct GNUNET_HELLO_Address *address,
484 } 467 }
485 GNUNET_break (NULL == ai->session); 468 GNUNET_break (NULL == ai->session);
486 ai->session = session; 469 ai->session = session;
487 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 470 LOG (GNUNET_ERROR_TYPE_DEBUG,
488 "transport-ats", 471 "Telling ATS about new session for peer %s\n",
489 "Telling ATS about new session %p for peer %s\n", 472 GNUNET_i2s (&address->peer));
490 session,
491 GNUNET_i2s (&address->peer));
492 if (NULL != ai->ar) 473 if (NULL != ai->ar)
493 GNUNET_ATS_address_add_session (ai->ar, 474 GNUNET_ATS_address_add_session (ai->ar,
494 session); 475 session);
@@ -528,11 +509,10 @@ GST_ats_del_session (const struct GNUNET_HELLO_Address *address,
528 } 509 }
529 GNUNET_assert (session == ai->session); 510 GNUNET_assert (session == ai->session);
530 ai->session = NULL; 511 ai->session = NULL;
531 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 512 LOG (GNUNET_ERROR_TYPE_DEBUG,
532 "transport-ats", 513 "Telling ATS to destroy session %p from peer %s\n",
533 "Telling ATS to destroy session %p from peer %s\n", 514 session,
534 session, 515 GNUNET_i2s (&address->peer));
535 GNUNET_i2s (&address->peer));
536 if (NULL == ai->ar) 516 if (NULL == ai->ar)
537 { 517 {
538 /* If ATS doesn't know about the address/session, and this 518 /* If ATS doesn't know about the address/session, and this
@@ -555,52 +535,95 @@ GST_ats_del_session (const struct GNUNET_HELLO_Address *address,
555 535
556 536
557/** 537/**
558 * Notify ATS about property changes to an address. 538 * Notify ATS about DV distance change to an address's.
559 * 539 *
560 * @param address our information about the address 540 * @param address the address
561 * @param session the session 541 * @param distance new distance value
562 * @param ats performance information
563 * @param ats_count number of elements in @a ats
564 */ 542 */
565void 543void
566GST_ats_update_metrics (const struct GNUNET_HELLO_Address *address, 544GST_ats_update_distance (const struct GNUNET_HELLO_Address *address,
567 struct Session *session, 545 uint32_t distance)
568 const struct GNUNET_ATS_Information *ats,
569 uint32_t ats_count)
570{ 546{
571 struct GNUNET_ATS_Information *ats_new;
572 struct AddressInfo *ai; 547 struct AddressInfo *ai;
573 548
574 ai = find_ai (address, session); 549 ai = find_ai_no_session (address);
575 if (NULL == ai) 550 if (NULL == ai)
576 {
577 /* We sometimes create sessions just for sending a PING,
578 and if we get metrics for those, they were never known to
579 ATS which means we end up here (however, in this
580 case, the address must be an outbound address). */
581 GNUNET_break (GNUNET_YES !=
582 GNUNET_HELLO_address_check_option (address,
583 GNUNET_HELLO_ADDRESS_INFO_INBOUND));
584 return; 551 return;
585 } 552 LOG (GNUNET_ERROR_TYPE_DEBUG,
586 /* Call to manipulation to manipulate ATS information */ 553 "Updated distance for peer `%s' to %u\n",
587 GNUNET_assert (NULL != GST_ats); 554 GNUNET_i2s (&address->peer),
588 if ((NULL == ats) || (0 == ats_count)) 555 distance);
556 ai->properties.distance = distance;
557 GST_manipulation_manipulate_metrics (address,
558 ai->session,
559 &ai->properties);
560 if (NULL != ai->ar)
561 GNUNET_ATS_address_update (ai->ar,
562 &ai->properties);
563}
564
565
566/**
567 * Notify ATS about property changes to an address's properties.
568 *
569 * @param address the address
570 * @param delay new delay value
571 */
572void
573GST_ats_update_delay (const struct GNUNET_HELLO_Address *address,
574 struct GNUNET_TIME_Relative delay)
575{
576 struct AddressInfo *ai;
577
578 ai = find_ai_no_session (address);
579 if (NULL == ai)
580 return;
581 LOG (GNUNET_ERROR_TYPE_DEBUG,
582 "Updated latency for peer `%s' to %s\n",
583 GNUNET_i2s (&address->peer),
584 GNUNET_STRINGS_relative_time_to_string (delay,
585 GNUNET_YES));
586 ai->properties.delay = delay;
587 GST_manipulation_manipulate_metrics (address,
588 ai->session,
589 &ai->properties);
590 if (NULL != ai->ar)
591 GNUNET_ATS_address_update (ai->ar,
592 &ai->properties);
593}
594
595
596/**
597 * Notify ATS about utilization changes to an address.
598 *
599 * @param address our information about the address
600 * @param bps_in new utilization inbound
601 * @param bps_out new utilization outbound
602 */
603void
604GST_ats_update_utilization (const struct GNUNET_HELLO_Address *address,
605 uint32_t bps_in,
606 uint32_t bps_out)
607{
608 struct AddressInfo *ai;
609
610 ai = find_ai_no_session (address);
611 if (NULL == ai)
589 return; 612 return;
590 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 613 LOG (GNUNET_ERROR_TYPE_DEBUG,
591 "Updating metrics for peer `%s' address %s session %p\n", 614 "Updating utilization for peer `%s' address %s: %u/%u\n",
592 GNUNET_i2s (&address->peer), 615 GNUNET_i2s (&address->peer),
593 GST_plugins_a2s (address), 616 GST_plugins_a2s (address),
594 session); 617 (unsigned int) bps_in,
595 ats_new = GST_manipulation_manipulate_metrics (address, 618 (unsigned int) bps_out);
596 session, 619 ai->properties.utilization_in = bps_in;
597 ats, 620 ai->properties.utilization_out = bps_out;
598 ats_count); 621 GST_manipulation_manipulate_metrics (address,
622 ai->session,
623 &ai->properties);
599 if (NULL != ai->ar) 624 if (NULL != ai->ar)
600 GNUNET_ATS_address_update (ai->ar, 625 GNUNET_ATS_address_update (ai->ar,
601 ats_new, 626 &ai->properties);
602 ats_count);
603 GNUNET_free_non_null (ats_new);
604} 627}
605 628
606 629
@@ -616,10 +639,10 @@ GST_ats_expire_address (const struct GNUNET_HELLO_Address *address)
616{ 639{
617 struct AddressInfo *ai; 640 struct AddressInfo *ai;
618 641
619 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 642 LOG (GNUNET_ERROR_TYPE_DEBUG,
620 "Address %s of peer %s expired\n", 643 "Address %s of peer %s expired\n",
621 GST_plugins_a2s (address), 644 GST_plugins_a2s (address),
622 GNUNET_i2s (&address->peer)); 645 GNUNET_i2s (&address->peer));
623 ai = find_ai_no_session (address); 646 ai = find_ai_no_session (address);
624 if (NULL == ai) 647 if (NULL == ai)
625 { 648 {
@@ -632,10 +655,9 @@ GST_ats_expire_address (const struct GNUNET_HELLO_Address *address)
632 ai)); 655 ai));
633 publish_p2a_stat_update (); 656 publish_p2a_stat_update ();
634 GNUNET_break (NULL == ai->session); 657 GNUNET_break (NULL == ai->session);
635 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 658 LOG (GNUNET_ERROR_TYPE_DEBUG,
636 "transport-ats", 659 "Telling ATS to destroy address from peer %s\n",
637 "Telling ATS to destroy address from peer %s\n", 660 GNUNET_i2s (&address->peer));
638 GNUNET_i2s (&address->peer));
639 if (NULL != ai->ar) 661 if (NULL != ai->ar)
640 { 662 {
641 /* We usually should not have a session here when we 663 /* We usually should not have a session here when we
diff --git a/src/transport/gnunet-service-transport_ats.h b/src/transport/gnunet-service-transport_ats.h
index f09b52375..780e66f60 100644
--- a/src/transport/gnunet-service-transport_ats.h
+++ b/src/transport/gnunet-service-transport_ats.h
@@ -78,14 +78,12 @@ GST_ats_block_address (const struct GNUNET_HELLO_Address *address,
78 * 78 *
79 * @param address the address 79 * @param address the address
80 * @param session the session 80 * @param session the session
81 * @param ats ats information 81 * @param prop performance information
82 * @param ats_count number of @a ats information
83 */ 82 */
84void 83void
85GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address, 84GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address,
86 struct Session *session, 85 struct Session *session,
87 const struct GNUNET_ATS_Information *ats, 86 const struct GNUNET_ATS_Properties *prop);
88 uint32_t ats_count);
89 87
90 88
91/** 89/**
@@ -93,13 +91,11 @@ GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address,
93 * located in. The address must NOT be inbound and must be new to ATS. 91 * located in. The address must NOT be inbound and must be new to ATS.
94 * 92 *
95 * @param address the address 93 * @param address the address
96 * @param ats ats information 94 * @param prop performance information
97 * @param ats_count number of @a ats information
98 */ 95 */
99void 96void
100GST_ats_add_address (const struct GNUNET_HELLO_Address *address, 97GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
101 const struct GNUNET_ATS_Information *ats, 98 const struct GNUNET_ATS_Properties *prop);
102 uint32_t ats_count);
103 99
104 100
105/** 101/**
@@ -115,18 +111,54 @@ GST_ats_new_session (const struct GNUNET_HELLO_Address *address,
115 111
116 112
117/** 113/**
118 * Notify ATS about property changes to an address 114 * Notify ATS about property changes to an address's properties.
115 * FIXME: we probably want to split this one up for the different
116 * updatable properties.
119 * 117 *
120 * @param address the address 118 * @param address the address
121 * @param session the session 119 * @param session the session
122 * @param ats performance information 120 * @param prop updated performance information
123 * @param ats_count number of elements in @a ats
124 */ 121 */
125void 122void
126GST_ats_update_metrics (const struct GNUNET_HELLO_Address *address, 123GST_ats_update_metrics (const struct GNUNET_HELLO_Address *address,
127 struct Session *session, 124 struct Session *session,
128 const struct GNUNET_ATS_Information *ats, 125 const struct GNUNET_ATS_Properties *prop);
129 uint32_t ats_count); 126
127
128/**
129 * Notify ATS about utilization changes to an address.
130 *
131 * @param address our information about the address
132 * @param bps_in new utilization inbound
133 * @param bps_out new utilization outbound
134 */
135void
136GST_ats_update_utilization (const struct GNUNET_HELLO_Address *address,
137 uint32_t bps_in,
138 uint32_t bps_out);
139
140
141/**
142 * Notify ATS about property changes to an address's properties.
143 *
144 * @param address the address
145 * @param session the session
146 * @param delay new delay value
147 */
148void
149GST_ats_update_delay (const struct GNUNET_HELLO_Address *address,
150 struct GNUNET_TIME_Relative delay);
151
152
153/**
154 * Notify ATS about property changes to an address's properties.
155 *
156 * @param address the address
157 * @param distance new distance value
158 */
159void
160GST_ats_update_distance (const struct GNUNET_HELLO_Address *address,
161 uint32_t distance);
130 162
131 163
132/** 164/**
diff --git a/src/transport/gnunet-service-transport_clients.c b/src/transport/gnunet-service-transport_clients.c
index 87bc0699b..0700aef0d 100644
--- a/src/transport/gnunet-service-transport_clients.c
+++ b/src/transport/gnunet-service-transport_clients.c
@@ -1515,7 +1515,8 @@ GST_clients_start (struct GNUNET_SERVER_Handle *server)
1515 GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY, 1515 GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY,
1516 sizeof (struct BlacklistMessage)}, 1516 sizeof (struct BlacklistMessage)},
1517 {&GST_manipulation_set_metric, NULL, 1517 {&GST_manipulation_set_metric, NULL,
1518 GNUNET_MESSAGE_TYPE_TRANSPORT_TRAFFIC_METRIC, 0}, 1518 GNUNET_MESSAGE_TYPE_TRANSPORT_TRAFFIC_METRIC,
1519 sizeof (struct TrafficMetricMessage) },
1519 {&clients_handle_monitor_plugins, NULL, 1520 {&clients_handle_monitor_plugins, NULL,
1520 GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PLUGIN_START, 1521 GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PLUGIN_START,
1521 sizeof (struct GNUNET_MessageHeader) }, 1522 sizeof (struct GNUNET_MessageHeader) },
diff --git a/src/transport/gnunet-service-transport_manipulation.c b/src/transport/gnunet-service-transport_manipulation.c
index f52634edc..b58ade999 100644
--- a/src/transport/gnunet-service-transport_manipulation.c
+++ b/src/transport/gnunet-service-transport_manipulation.c
@@ -34,66 +34,36 @@
34#include "gnunet-service-transport.h" 34#include "gnunet-service-transport.h"
35#include "transport.h" 35#include "transport.h"
36 36
37enum TRAFFIC_METRIC_DIRECTION
38{
39 TM_SEND = 0, TM_RECEIVE = 1, TM_BOTH = 2
40};
41
42 37
43/** 38/**
44 * Struct containing information about manipulations to a specific peer 39 * Struct containing information about manipulations to a specific peer
45 */ 40 */
46struct TM_Peer; 41struct TM_Peer
47
48/**
49 * Manipulation entry
50 */
51struct PropManipulationEntry
52{ 42{
53 /** 43 /**
54 * Next in DLL 44 * Peer ID
55 */
56 struct PropManipulationEntry *next;
57
58 /**
59 * Previous in DLL
60 */
61 struct PropManipulationEntry *prev;
62
63 /**
64 * ATS type in HBO
65 */ 45 */
66 uint32_t type; 46 struct GNUNET_PeerIdentity peer;
67 47
68 /** 48 /**
69 * Value in HBO 49 * How long to delay incoming messages for this peer.
70 */ 50 */
71 uint32_t metrics[TM_BOTH]; 51 struct GNUNET_TIME_Relative delay_in;
72 52
73};
74
75/**
76 * Struct containing information about manipulations to a specific peer
77 */
78struct TM_Peer
79{
80 /** 53 /**
81 * Peer ID 54 * How long to delay outgoing messages for this peer.
82 */ 55 */
83 struct GNUNET_PeerIdentity peer; 56 struct GNUNET_TIME_Relative delay_out;
84
85 struct PropManipulationEntry *head;
86 struct PropManipulationEntry *tail;
87 57
88 /** 58 /**
89 * Peer specific manipulation metrics 59 * Manipulated properties to use for this peer.
90 */ 60 */
91 uint32_t metrics[TM_BOTH][GNUNET_ATS_QualityPropertiesCount]; 61 struct GNUNET_ATS_Properties properties;
92 62
93 /** 63 /**
94 * Task to schedule delayed sendding 64 * Task to schedule delayed sendding
95 */ 65 */
96 struct GNUNET_SCHEDULER_Task * send_delay_task; 66 struct GNUNET_SCHEDULER_Task *send_delay_task;
97 67
98 /** 68 /**
99 * Send queue DLL head 69 * Send queue DLL head
@@ -107,19 +77,6 @@ struct TM_Peer
107}; 77};
108 78
109 79
110struct GST_ManipulationHandle
111{
112 /**
113 * Hashmap contain all peers currently manipulated
114 */
115 struct GNUNET_CONTAINER_MultiPeerMap *peers;
116
117 /**
118 * Peer containing information for general manipulation
119 */
120 struct TM_Peer general;
121};
122
123/** 80/**
124 * Entry in the delay queue for an outbound delayed message 81 * Entry in the delay queue for an outbound delayed message
125 */ 82 */
@@ -136,9 +93,10 @@ struct DelayQueueEntry
136 struct DelayQueueEntry *next; 93 struct DelayQueueEntry *next;
137 94
138 /** 95 /**
139 * Peer this entry is belonging to 96 * Peer this entry is belonging to if (NULL == tmp): enqueued in
140 * if (NULL == tmp): enqueued in generic DLL and scheduled by generic_send_delay_task 97 * generic DLL and scheduled by generic_send_delay_task else:
141 * else: enqueued in tmp->send_head and tmp->send_tail and scheduled by tmp->send_delay_task 98 * enqueued in tmp->send_head and tmp->send_tail and scheduled by
99 * tmp->send_delay_task
142 */ 100 */
143 struct TM_Peer *tmp; 101 struct TM_Peer *tmp;
144 102
@@ -178,91 +136,35 @@ struct DelayQueueEntry
178 void *cont_cls; 136 void *cont_cls;
179}; 137};
180 138
181struct GST_ManipulationHandle man_handle;
182
183/** 139/**
184 * DLL head for delayed messages based on general delay 140 * Hashmap contain all peers currently manipulated
185 */ 141 */
186struct DelayQueueEntry *generic_dqe_head; 142static struct GNUNET_CONTAINER_MultiPeerMap *peers;
187 143
188/** 144/**
189 * DLL tail for delayed messages based on general delay 145 * Inbound delay to apply to all peers.
190 */ 146 */
191struct DelayQueueEntry *generic_dqe_tail; 147static struct GNUNET_TIME_Relative delay_in;
192 148
193/** 149/**
194 * Task to schedule delayed sending based on general delay 150 * Outbound delay to apply to all peers.
195 */ 151 */
196struct GNUNET_SCHEDULER_Task * generic_send_delay_task; 152static struct GNUNET_TIME_Relative delay_out;
197
198
199static void
200set_metric(struct TM_Peer *dest, int direction, uint32_t type, uint32_t value)
201{
202 struct PropManipulationEntry *cur;
203 for (cur = dest->head; NULL != cur; cur = cur->next)
204 {
205 if (cur->type == type)
206 break;
207 }
208 if (NULL == cur)
209 {
210 cur = GNUNET_new (struct PropManipulationEntry);
211 GNUNET_CONTAINER_DLL_insert(dest->head, dest->tail, cur);
212 cur->type = type;
213 cur->metrics[TM_SEND] = UINT32_MAX;
214 cur->metrics[TM_RECEIVE] = UINT32_MAX;
215 }
216
217 switch (direction)
218 {
219 case TM_BOTH:
220 cur->metrics[TM_SEND] = value;
221 cur->metrics[TM_RECEIVE] = value;
222 break;
223 case TM_SEND:
224 cur->metrics[TM_SEND] = value;
225 break;
226 case TM_RECEIVE:
227 cur->metrics[TM_RECEIVE] = value;
228 break;
229 default:
230 break;
231 }
232}
233
234
235static uint32_t
236find_metric(struct TM_Peer *dest, uint32_t type, int direction)
237{
238 struct PropManipulationEntry *cur;
239
240 for (cur = dest->head; NULL != cur; cur = cur->next)
241 {
242 if (cur->type == type)
243 return cur->metrics[direction];
244
245 }
246 return UINT32_MAX;
247}
248 153
154/**
155 * DLL head for delayed messages based on general delay
156 */
157static struct DelayQueueEntry *generic_dqe_head;
249 158
250/** 159/**
251 * Clean up metrics for a peer 160 * DLL tail for delayed messages based on general delay
252 */ 161 */
253static void 162static struct DelayQueueEntry *generic_dqe_tail;
254free_metric(struct TM_Peer *dest)
255{
256 struct PropManipulationEntry *cur;
257 struct PropManipulationEntry *next;
258 163
259 for (cur = dest->head; NULL != cur; cur = next) 164/**
260 { 165 * Task to schedule delayed sending based on general delay
261 next = cur->next; 166 */
262 GNUNET_CONTAINER_DLL_remove(dest->head, dest->tail, cur); 167static struct GNUNET_SCHEDULER_Task *generic_send_delay_task;
263 GNUNET_free(cur);
264 }
265}
266 168
267 169
268/** 170/**
@@ -273,134 +175,106 @@ free_metric(struct TM_Peer *dest)
273 * @param message containing information 175 * @param message containing information
274 */ 176 */
275void 177void
276GST_manipulation_set_metric(void *cls, struct GNUNET_SERVER_Client *client, 178GST_manipulation_set_metric (void *cls,
277 const struct GNUNET_MessageHeader *message) 179 struct GNUNET_SERVER_Client *client,
180 const struct GNUNET_MessageHeader *message)
278{ 181{
279 struct TrafficMetricMessage *tm = (struct TrafficMetricMessage *) message; 182 const struct TrafficMetricMessage *tm;
280 struct GNUNET_PeerIdentity dummy; 183 static struct GNUNET_PeerIdentity zero;
281 struct GNUNET_ATS_Information *ats;
282 struct TM_Peer *tmp; 184 struct TM_Peer *tmp;
283 uint32_t type;
284 uint32_t value;
285 uint16_t direction;
286 int c;
287 int c2;
288
289 if (0 == ntohs(tm->ats_count))
290 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
291
292 direction = TM_BOTH;
293 switch (ntohs(tm->direction))
294 {
295 case 1:
296 direction = TM_SEND;
297 break;
298 case 2:
299 direction = TM_RECEIVE;
300 break;
301 case 3:
302 direction = TM_BOTH;
303 break;
304 default:
305 break;
306 }
307
308 memset(&dummy, '\0', sizeof(struct GNUNET_PeerIdentity));
309 if (0 == memcmp(&tm->peer, &dummy, sizeof(struct GNUNET_PeerIdentity)))
310 {
311 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
312 "Received traffic metrics for all peers \n");
313
314 ats = (struct GNUNET_ATS_Information *) &tm[1];
315 for (c = 0; c < ntohs(tm->ats_count); c++)
316 {
317 type = htonl(ats[c].type);
318 value = htonl(ats[c].value);
319 set_metric(&man_handle.general, direction, type, value);
320 }
321 return;
322 }
323
324 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
325 "Received traffic metrics for peer `%s'\n", GNUNET_i2s(&tm->peer));
326
327 if (NULL
328 == (tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, &tm->peer)))
329 {
330 tmp = GNUNET_new (struct TM_Peer);
331 tmp->peer = (tm->peer);
332 for (c = 0; c < TM_BOTH; c++)
333 {
334 for (c2 = 0; c2 < GNUNET_ATS_QualityPropertiesCount; c2++)
335 {
336 tmp->metrics[c][c2] = UINT32_MAX;
337 }
338 }
339 GNUNET_CONTAINER_multipeermap_put(man_handle.peers, &tm->peer, tmp,
340 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
341 }
342 185
343 ats = (struct GNUNET_ATS_Information *) &tm[1]; 186 tm = (const struct TrafficMetricMessage *) message;
344 for (c = 0; c < ntohs(tm->ats_count); c++) 187 if (0 == memcmp (&tm->peer,
345 { 188 &zero,
346 type = htonl(ats[c].type); 189 sizeof(struct GNUNET_PeerIdentity)))
347 value = htonl(ats[c].value); 190 {
348 set_metric(tmp, direction, type, value); 191 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
349 } 192 "Received traffic metrics for all peers\n");
350 193 delay_in = GNUNET_TIME_relative_ntoh (tm->delay_in);
351 GNUNET_SERVER_receive_done(client, GNUNET_OK); 194 delay_out = GNUNET_TIME_relative_ntoh (tm->delay_out);
195 GNUNET_SERVER_receive_done (client,
196 GNUNET_OK);
197 return;
198 }
199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
200 "Received traffic metrics for peer `%s'\n",
201 GNUNET_i2s(&tm->peer));
202 if (NULL ==
203 (tmp = GNUNET_CONTAINER_multipeermap_get (peers,
204 &tm->peer)))
205 {
206 tmp = GNUNET_new (struct TM_Peer);
207 tmp->peer = tm->peer;
208 GNUNET_CONTAINER_multipeermap_put (peers,
209 &tm->peer,
210 tmp,
211 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
212 }
213 GNUNET_ATS_properties_ntoh (&tmp->properties,
214 &tm->properties);
215 tmp->delay_in = GNUNET_TIME_relative_ntoh (tm->delay_in);
216 tmp->delay_out = GNUNET_TIME_relative_ntoh (tm->delay_out);
217 GNUNET_SERVER_receive_done (client,
218 GNUNET_OK);
352} 219}
353 220
354 221
222/**
223 * We have delayed transmission, now it is time to send the
224 * message.
225 *
226 * @param cls the `struct DelayQueueEntry` to transmit
227 * @param tc unused
228 */
355static void 229static void
356send_delayed(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 230send_delayed (void *cls,
231 const struct GNUNET_SCHEDULER_TaskContext *tc)
357{ 232{
358 struct DelayQueueEntry *dqe = cls; 233 struct DelayQueueEntry *dqe = cls;
359 struct DelayQueueEntry *next; 234 struct DelayQueueEntry *next;
360 struct TM_Peer *tmp = dqe->tmp; 235 struct TM_Peer *tmp = dqe->tmp;
361 struct GNUNET_TIME_Relative delay; 236 struct GNUNET_TIME_Relative delay;
362 237
238 GNUNET_break (GNUNET_YES ==
239 GST_neighbours_test_connected (&dqe->id));
363 if (NULL != tmp) 240 if (NULL != tmp)
241 {
242 tmp->send_delay_task = NULL;
243 GNUNET_CONTAINER_DLL_remove (tmp->send_head,
244 tmp->send_tail,
245 dqe);
246 next = tmp->send_head;
247 if (NULL != next)
364 { 248 {
365 GNUNET_break (GNUNET_YES == 249 /* More delayed messages */
366 GST_neighbours_test_connected (&dqe->id)); 250 delay = GNUNET_TIME_absolute_get_remaining(next->sent_at);
367 tmp->send_delay_task = NULL; 251 tmp->send_delay_task = GNUNET_SCHEDULER_add_delayed(delay,
368 GNUNET_CONTAINER_DLL_remove (tmp->send_head, 252 &send_delayed, next);
369 tmp->send_tail,
370 dqe);
371 GST_neighbours_send (&dqe->id,
372 dqe->msg,
373 dqe->msg_size,
374 dqe->timeout,
375 dqe->cont,
376 dqe->cont_cls);
377
378 next = tmp->send_head;
379 if (NULL != next)
380 {
381 /* More delayed messages */
382 delay = GNUNET_TIME_absolute_get_remaining(next->sent_at);
383 tmp->send_delay_task = GNUNET_SCHEDULER_add_delayed(delay,
384 &send_delayed, next);
385 }
386 } 253 }
254 }
387 else 255 else
256 {
257 /* Remove from generic queue */
258 generic_send_delay_task = NULL;
259 GNUNET_CONTAINER_DLL_remove (generic_dqe_head,
260 generic_dqe_tail,
261 dqe);
262 next = generic_dqe_head;
263 if (NULL != next)
388 { 264 {
389 /* Remove from generic queue */ 265 /* More delayed messages */
390 GNUNET_break(GNUNET_YES == GST_neighbours_test_connected (&dqe->id)); 266 delay = GNUNET_TIME_absolute_get_remaining(next->sent_at);
391 generic_send_delay_task = NULL; 267 generic_send_delay_task = GNUNET_SCHEDULER_add_delayed (delay,
392 GNUNET_CONTAINER_DLL_remove(generic_dqe_head, generic_dqe_tail, dqe); 268 &send_delayed,
393 GST_neighbours_send(&dqe->id, dqe->msg, dqe->msg_size, dqe->timeout, 269 next);
394 dqe->cont, dqe->cont_cls);
395 next = generic_dqe_head;
396 if (NULL != next)
397 {
398 /* More delayed messages */
399 delay = GNUNET_TIME_absolute_get_remaining(next->sent_at);
400 generic_send_delay_task = GNUNET_SCHEDULER_add_delayed(delay,
401 &send_delayed, next);
402 }
403 } 270 }
271 }
272 GST_neighbours_send (&dqe->id,
273 dqe->msg,
274 dqe->msg_size,
275 dqe->timeout,
276 dqe->cont,
277 dqe->cont_cls);
404 GNUNET_free(dqe); 278 GNUNET_free(dqe);
405} 279}
406 280
@@ -427,41 +301,14 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target,
427 struct TM_Peer *tmp; 301 struct TM_Peer *tmp;
428 struct DelayQueueEntry *dqe; 302 struct DelayQueueEntry *dqe;
429 struct GNUNET_TIME_Relative delay; 303 struct GNUNET_TIME_Relative delay;
430 int do_delay;
431 304
432 do_delay = GNUNET_NO;
433 if (NULL != (tmp = 305 if (NULL != (tmp =
434 GNUNET_CONTAINER_multipeermap_get (man_handle.peers, 306 GNUNET_CONTAINER_multipeermap_get (peers,
435 target))) 307 target)))
436 { 308 delay = tmp->delay_out;
437 GNUNET_break (GNUNET_YES == 309 else
438 GST_neighbours_test_connected(target)); 310 delay = delay_out;
439 /* check for peer-specific delay */ 311 if (0 == delay.rel_value_us)
440 if (UINT32_MAX !=
441 find_metric (tmp,
442 GNUNET_ATS_QUALITY_NET_DELAY,
443 TM_SEND))
444 {
445 /* We have a delay */
446 delay.rel_value_us = find_metric(tmp, GNUNET_ATS_QUALITY_NET_DELAY,
447 TM_SEND);
448 do_delay = GNUNET_YES;
449 }
450 }
451 else if (UINT32_MAX !=
452 find_metric(&man_handle.general,
453 GNUNET_ATS_QUALITY_NET_DELAY,
454 TM_SEND))
455 {
456 GNUNET_break (GNUNET_YES ==
457 GST_neighbours_test_connected (target));
458 /* We have a delay */
459 delay.rel_value_us = find_metric (&man_handle.general,
460 GNUNET_ATS_QUALITY_NET_DELAY,
461 TM_SEND);
462 do_delay = GNUNET_YES;
463 }
464 if (GNUNET_NO == do_delay)
465 { 312 {
466 /* Normal sending */ 313 /* Normal sending */
467 GST_neighbours_send (target, 314 GST_neighbours_send (target,
@@ -516,46 +363,22 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target,
516 * Function that will be called to manipulate ATS information according to 363 * Function that will be called to manipulate ATS information according to
517 * current manipulation settings 364 * current manipulation settings
518 * 365 *
519 * @param peer the peer
520 * @param address binary address 366 * @param address binary address
521 * @param session the session 367 * @param session the session
522 * @param ats the ats information 368 * @param prop[IN|OUT] metrics to modify
523 * @param ats_count the number of ats information
524 */ 369 */
525struct GNUNET_ATS_Information * 370void
526GST_manipulation_manipulate_metrics (const struct GNUNET_HELLO_Address *address, 371GST_manipulation_manipulate_metrics (const struct GNUNET_HELLO_Address *address,
527 struct Session *session, 372 struct Session *session,
528 const struct GNUNET_ATS_Information *ats, 373 struct GNUNET_ATS_Properties *prop)
529 uint32_t ats_count)
530{ 374{
531 const struct GNUNET_PeerIdentity *peer = &address->peer; 375 const struct GNUNET_PeerIdentity *peer = &address->peer;
532 struct GNUNET_ATS_Information *ats_new;
533 struct TM_Peer *tmp; 376 struct TM_Peer *tmp;
534 uint32_t m_tmp; 377
535 uint32_t g_tmp; 378 tmp = GNUNET_CONTAINER_multipeermap_get (peers,
536 uint32_t d; 379 peer);
537 380 if (NULL != tmp)
538 if (0 == ats_count) 381 *prop = tmp->properties;
539 return NULL;
540 ats_new = GNUNET_malloc (sizeof (struct GNUNET_ATS_Information) * ats_count);
541 tmp = GNUNET_CONTAINER_multipeermap_get (man_handle.peers, peer);
542 for (d = 0; d < ats_count; d++)
543 {
544 ats_new[d] = ats[d];
545 m_tmp = UINT32_MAX;
546 if (NULL != tmp)
547 m_tmp = find_metric (tmp, ntohl(ats[d].type),
548 TM_RECEIVE);
549 g_tmp = find_metric (&man_handle.general,
550 ntohl(ats[d].type),
551 TM_RECEIVE);
552
553 if (UINT32_MAX != g_tmp)
554 ats_new[d].value = htonl(g_tmp);
555 if (UINT32_MAX != m_tmp)
556 ats_new[d].value = htonl(m_tmp);
557 }
558 return ats_new;
559} 382}
560 383
561 384
@@ -576,32 +399,22 @@ GST_manipulation_recv (void *cls,
576 const struct GNUNET_MessageHeader *message) 399 const struct GNUNET_MessageHeader *message)
577{ 400{
578 struct TM_Peer *tmp; 401 struct TM_Peer *tmp;
579 uint32_t p_recv_delay;
580 uint32_t g_recv_delay;
581 struct GNUNET_TIME_Relative quota_delay; 402 struct GNUNET_TIME_Relative quota_delay;
582 struct GNUNET_TIME_Relative m_delay; 403 struct GNUNET_TIME_Relative m_delay;
583 404
584 g_recv_delay = find_metric(&man_handle.general, GNUNET_ATS_QUALITY_NET_DELAY, 405 if (NULL !=
585 TM_RECEIVE); 406 (tmp = GNUNET_CONTAINER_multipeermap_get (peers,
586 if ((g_recv_delay >= GNUNET_TIME_UNIT_ZERO.rel_value_us) 407 &address->peer)))
587 && (UINT32_MAX != g_recv_delay)) 408 m_delay = tmp->delay_in;
588 m_delay.rel_value_us = g_recv_delay; /* Global delay */
589 else 409 else
590 m_delay = GNUNET_TIME_UNIT_ZERO; 410 m_delay = delay_in;
591 411
592 if (NULL != (tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, &address->peer))) 412 quota_delay = GST_receive_callback (cls,
593 { 413 address,
594 /* Manipulate receive delay */ 414 session,
595 p_recv_delay = find_metric(tmp, GNUNET_ATS_QUALITY_NET_DELAY, TM_RECEIVE); 415 message);
596 if (UINT32_MAX != p_recv_delay) 416 m_delay = GNUNET_TIME_relative_max (m_delay,
597 m_delay.rel_value_us = p_recv_delay; /* Peer specific delay */ 417 quota_delay);
598 }
599
600 quota_delay = GST_receive_callback(cls, address, session, message);
601
602 if (quota_delay.rel_value_us > m_delay.rel_value_us)
603 m_delay = quota_delay;
604
605 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 418 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
606 "Delaying next receive for peer `%s' for %s\n", 419 "Delaying next receive for peer `%s' for %s\n",
607 GNUNET_i2s (&address->peer), 420 GNUNET_i2s (&address->peer),
@@ -613,63 +426,110 @@ GST_manipulation_recv (void *cls,
613 426
614/** 427/**
615 * Initialize traffic manipulation 428 * Initialize traffic manipulation
616 *
617 * @param GST_cfg configuration handle
618 */ 429 */
619void 430void
620GST_manipulation_init(const struct GNUNET_CONFIGURATION_Handle *GST_cfg) 431GST_manipulation_init ()
621{ 432{
622 unsigned long long tmp;
623 struct GNUNET_TIME_Relative delay; 433 struct GNUNET_TIME_Relative delay;
624 434
625 if ( (GNUNET_OK == 435 if ( (GNUNET_OK ==
626 GNUNET_CONFIGURATION_get_value_number(GST_cfg, 436 GNUNET_CONFIGURATION_get_value_time (GST_cfg,
627 "transport", 437 "transport",
628 "MANIPULATE_DISTANCE_IN", 438 "MANIPULATE_DELAY_IN",
629 &tmp)) && 439 &delay)) &&
630 (tmp > 0) ) 440 (delay.rel_value_us > 0) )
631 { 441 {
632 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 442 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
633 "Setting inbound distance_in to %llu\n", 443 "Delaying inbound traffic for %s\n",
634 (unsigned long long) tmp); 444 GNUNET_STRINGS_relative_time_to_string (delay,
635 set_metric (&man_handle.general, 445 GNUNET_YES));
636 TM_RECEIVE, 446 delay_in = delay;
637 GNUNET_ATS_QUALITY_NET_DISTANCE,
638 tmp);
639 } 447 }
448 if ( (GNUNET_OK ==
449 GNUNET_CONFIGURATION_get_value_time (GST_cfg,
450 "transport",
451 "MANIPULATE_DELAY_OUT",
452 &delay)) &&
453 (delay.rel_value_us > 0) )
454 {
455 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
456 "Delaying outbound traffic for %s\n",
457 GNUNET_STRINGS_relative_time_to_string (delay,
458 GNUNET_YES));
459 delay_out = delay;
460 }
461 peers = GNUNET_CONTAINER_multipeermap_create (4,
462 GNUNET_NO);
463}
640 464
641 if ((GNUNET_OK
642 == GNUNET_CONFIGURATION_get_value_number(GST_cfg, "transport",
643 "MANIPULATE_DISTANCE_OUT", &tmp)) && (tmp > 0))
644 {
645 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
646 "Setting outbound distance_in to %llu\n", (unsigned long long) tmp);
647 set_metric(&man_handle.general, TM_SEND, GNUNET_ATS_QUALITY_NET_DISTANCE,
648 tmp);
649 }
650 465
651 if ((GNUNET_OK 466/**
652 == GNUNET_CONFIGURATION_get_value_time(GST_cfg, "transport", 467 * Notify manipulation about disconnect so it can discard queued messages
653 "MANIPULATE_DELAY_IN", &delay)) && (delay.rel_value_us > 0)) 468 *
469 * @param peer the disconnecting peer
470 */
471void
472GST_manipulation_peer_disconnect (const struct GNUNET_PeerIdentity *peer)
473{
474 struct TM_Peer *tmp;
475 struct DelayQueueEntry *dqe;
476 struct DelayQueueEntry *next;
477
478 tmp = GNUNET_CONTAINER_multipeermap_get (peers,
479 peer);
480 if (NULL != tmp)
481 {
482 while (NULL != (dqe = tmp->send_head))
654 { 483 {
655 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 484 GNUNET_CONTAINER_DLL_remove (tmp->send_head,
656 "Delaying inbound traffic for %s\n", GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES)); 485 tmp->send_tail,
657 set_metric(&man_handle.general, TM_RECEIVE, GNUNET_ATS_QUALITY_NET_DELAY, 486 dqe);
658 delay.rel_value_us); 487 if (NULL != dqe->cont)
488 dqe->cont (dqe->cont_cls,
489 GNUNET_SYSERR,
490 dqe->msg_size,
491 0);
492 GNUNET_free(dqe);
659 } 493 }
660 if ((GNUNET_OK 494 }
661 == GNUNET_CONFIGURATION_get_value_time(GST_cfg, "transport", 495 next = generic_dqe_head;
662 "MANIPULATE_DELAY_OUT", &delay)) && (delay.rel_value_us > 0)) 496 while (NULL != (dqe = next))
497 {
498 next = dqe->next;
499 if (0 == memcmp(peer, &dqe->id, sizeof(dqe->id)))
663 { 500 {
664 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 501 GNUNET_CONTAINER_DLL_remove (generic_dqe_head,
665 "Delaying outbound traffic for %s\n", GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES)); 502 generic_dqe_tail,
666 set_metric(&man_handle.general, TM_SEND, GNUNET_ATS_QUALITY_NET_DELAY, 503 dqe);
667 delay.rel_value_us); 504 if (NULL != dqe->cont)
505 dqe->cont (dqe->cont_cls,
506 GNUNET_SYSERR,
507 dqe->msg_size,
508 0);
509 GNUNET_free(dqe);
668 } 510 }
669 man_handle.peers = GNUNET_CONTAINER_multipeermap_create(10, GNUNET_NO); 511 }
512 if (NULL != generic_send_delay_task)
513 {
514 GNUNET_SCHEDULER_cancel (generic_send_delay_task);
515 generic_send_delay_task = NULL;
516 if (NULL != generic_dqe_head)
517 generic_send_delay_task
518 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining(generic_dqe_head->sent_at),
519 &send_delayed,
520 generic_dqe_head);
521 }
670} 522}
671 523
672 524
525/**
526 * Free manipulation information about a peer.
527 *
528 * @param cls NULL
529 * @param key peer the info is about
530 * @param value a `struct TM_Peer` to free
531 * @return #GNUNET_OK (continue to iterate)
532 */
673static int 533static int
674free_tmps (void *cls, 534free_tmps (void *cls,
675 const struct GNUNET_PeerIdentity *key, 535 const struct GNUNET_PeerIdentity *key,
@@ -678,13 +538,10 @@ free_tmps (void *cls,
678 struct TM_Peer *tmp = value; 538 struct TM_Peer *tmp = value;
679 struct DelayQueueEntry *dqe; 539 struct DelayQueueEntry *dqe;
680 540
681 if (NULL == tmp)
682 return GNUNET_OK;
683 GNUNET_break (GNUNET_YES == 541 GNUNET_break (GNUNET_YES ==
684 GNUNET_CONTAINER_multipeermap_remove (man_handle.peers, 542 GNUNET_CONTAINER_multipeermap_remove (peers,
685 key, 543 key,
686 value)); 544 value));
687 free_metric (tmp);
688 while (NULL != (dqe = tmp->send_head)) 545 while (NULL != (dqe = tmp->send_head))
689 { 546 {
690 GNUNET_CONTAINER_DLL_remove (tmp->send_head, 547 GNUNET_CONTAINER_DLL_remove (tmp->send_head,
@@ -699,89 +556,27 @@ free_tmps (void *cls,
699 } 556 }
700 if (NULL != tmp->send_delay_task) 557 if (NULL != tmp->send_delay_task)
701 { 558 {
702 GNUNET_SCHEDULER_cancel(tmp->send_delay_task); 559 GNUNET_SCHEDULER_cancel (tmp->send_delay_task);
703 tmp->send_delay_task = NULL; 560 tmp->send_delay_task = NULL;
704 } 561 }
705 GNUNET_free(tmp); 562 GNUNET_free (tmp);
706 return GNUNET_OK; 563 return GNUNET_OK;
707} 564}
708 565
709 566
710/** 567/**
711 * Notify manipulation about disconnect so it can discard queued messages
712 *
713 * @param peer the disconnecting peer
714 */
715void
716GST_manipulation_peer_disconnect (const struct GNUNET_PeerIdentity *peer)
717{
718 struct TM_Peer *tmp;
719 struct DelayQueueEntry *dqe;
720 struct DelayQueueEntry *next;
721
722 if (NULL != (tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, peer)))
723 {
724 while (NULL != (dqe = tmp->send_head))
725 {
726 GNUNET_CONTAINER_DLL_remove (tmp->send_head,
727 tmp->send_tail,
728 dqe);
729 if (NULL != dqe->cont)
730 dqe->cont (dqe->cont_cls,
731 GNUNET_SYSERR,
732 dqe->msg_size,
733 0);
734 GNUNET_free(dqe);
735 }
736 }
737 else if (UINT32_MAX != find_metric (&man_handle.general,
738 GNUNET_ATS_QUALITY_NET_DELAY,
739 TM_SEND))
740 {
741 next = generic_dqe_head;
742 while (NULL != (dqe = next))
743 {
744 next = dqe->next;
745 if (0 == memcmp(peer, &dqe->id, sizeof(dqe->id)))
746 {
747 GNUNET_CONTAINER_DLL_remove (generic_dqe_head,
748 generic_dqe_tail,
749 dqe);
750 if (NULL != dqe->cont)
751 dqe->cont (dqe->cont_cls,
752 GNUNET_SYSERR,
753 dqe->msg_size,
754 0);
755 GNUNET_free(dqe);
756 }
757 }
758 if (NULL != generic_send_delay_task)
759 {
760 GNUNET_SCHEDULER_cancel (generic_send_delay_task);
761 generic_send_delay_task = NULL;
762 if (NULL != generic_dqe_head)
763 generic_send_delay_task
764 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining(generic_dqe_head->sent_at),
765 &send_delayed,
766 generic_dqe_head);
767 }
768 }
769}
770
771
772/**
773 * Stop traffic manipulation 568 * Stop traffic manipulation
774 */ 569 */
775void 570void
776GST_manipulation_stop() 571GST_manipulation_stop ()
777{ 572{
778 struct DelayQueueEntry *cur; 573 struct DelayQueueEntry *cur;
779 574
780 GNUNET_CONTAINER_multipeermap_iterate (man_handle.peers, 575 GNUNET_CONTAINER_multipeermap_iterate (peers,
781 &free_tmps, 576 &free_tmps,
782 NULL); 577 NULL);
783 GNUNET_CONTAINER_multipeermap_destroy (man_handle.peers); 578 GNUNET_CONTAINER_multipeermap_destroy (peers);
784 579 peers = NULL;
785 while (NULL != (cur = generic_dqe_head)) 580 while (NULL != (cur = generic_dqe_head))
786 { 581 {
787 GNUNET_CONTAINER_DLL_remove (generic_dqe_head, 582 GNUNET_CONTAINER_DLL_remove (generic_dqe_head,
@@ -799,8 +594,6 @@ GST_manipulation_stop()
799 GNUNET_SCHEDULER_cancel (generic_send_delay_task); 594 GNUNET_SCHEDULER_cancel (generic_send_delay_task);
800 generic_send_delay_task = NULL; 595 generic_send_delay_task = NULL;
801 } 596 }
802 free_metric (&man_handle.general);
803 man_handle.peers = NULL;
804} 597}
805 598
806/* end of file gnunet-service-transport_manipulation.c */ 599/* end of file gnunet-service-transport_manipulation.c */
diff --git a/src/transport/gnunet-service-transport_manipulation.h b/src/transport/gnunet-service-transport_manipulation.h
index 8a3ab9849..1f87de249 100644
--- a/src/transport/gnunet-service-transport_manipulation.h
+++ b/src/transport/gnunet-service-transport_manipulation.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2010,2011 Christian Grothoff (and other contributing authors) 3 Copyright (C) 2010-2015 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -20,7 +20,8 @@
20 20
21/** 21/**
22 * @file transport/gnunet-service-transport_neighbours.h 22 * @file transport/gnunet-service-transport_neighbours.h
23 * @brief neighbour management API 23 * @brief neighbour manipulation API, allows manipulation of
24 * performance metrics (delay and towards ATS)
24 * @author Christian Grothoff 25 * @author Christian Grothoff
25 */ 26 */
26#ifndef GNUNET_SERVICE_TRANSPORT_MANIPULATION_H 27#ifndef GNUNET_SERVICE_TRANSPORT_MANIPULATION_H
@@ -44,10 +45,11 @@
44 * @param client client sending message 45 * @param client client sending message
45 * @param message containing information 46 * @param message containing information
46 */ 47 */
47
48void 48void
49GST_manipulation_set_metric (void *cls, struct GNUNET_SERVER_Client *client, 49GST_manipulation_set_metric (void *cls,
50 const struct GNUNET_MessageHeader *message); 50 struct GNUNET_SERVER_Client *client,
51 const struct GNUNET_MessageHeader *message);
52
51 53
52/** 54/**
53 * Adapter function between transport's send function and transport plugins 55 * Adapter function between transport's send function and transport plugins
@@ -61,9 +63,12 @@ GST_manipulation_set_metric (void *cls, struct GNUNET_SERVER_Client *client,
61 */ 63 */
62void 64void
63GST_manipulation_send (const struct GNUNET_PeerIdentity *target, 65GST_manipulation_send (const struct GNUNET_PeerIdentity *target,
64 const void *msg, size_t msg_size, 66 const void *msg,
65 struct GNUNET_TIME_Relative timeout, 67 size_t msg_size,
66 GST_NeighbourSendContinuation cont, void *cont_cls); 68 struct GNUNET_TIME_Relative timeout,
69 GST_NeighbourSendContinuation cont,
70 void *cont_cls);
71
67 72
68/** 73/**
69 * Adapter function between transport plugins and transport receive function 74 * Adapter function between transport plugins and transport receive function
@@ -86,18 +91,14 @@ GST_manipulation_recv (void *cls,
86 * Function that will be called to manipulate ATS information according to 91 * Function that will be called to manipulate ATS information according to
87 * current manipulation settings 92 * current manipulation settings
88 * 93 *
89 * @param peer the peer
90 * @param address binary address 94 * @param address binary address
91 * @param session the session 95 * @param session the session
92 * @param ats the ats information 96 * @param prop[IN|OUT] metrics to modify
93 * @param ats_count the number of ats information
94 * @return modified @a ats information
95 */ 97 */
96struct GNUNET_ATS_Information * 98void
97GST_manipulation_manipulate_metrics (const struct GNUNET_HELLO_Address *address, 99GST_manipulation_manipulate_metrics (const struct GNUNET_HELLO_Address *address,
98 struct Session *session, 100 struct Session *session,
99 const struct GNUNET_ATS_Information *ats, 101 struct GNUNET_ATS_Properties *prop);
100 uint32_t ats_count);
101 102
102 103
103/** 104/**
@@ -108,19 +109,19 @@ GST_manipulation_manipulate_metrics (const struct GNUNET_HELLO_Address *address,
108void 109void
109GST_manipulation_peer_disconnect (const struct GNUNET_PeerIdentity *peer); 110GST_manipulation_peer_disconnect (const struct GNUNET_PeerIdentity *peer);
110 111
112
111/** 113/**
112 * Initialize traffic manipulation 114 * Initialize traffic manipulation
113 *
114 * @param GST_cfg configuration handle
115 */ 115 */
116void 116void
117GST_manipulation_init (const struct GNUNET_CONFIGURATION_Handle *GST_cfg); 117GST_manipulation_init (void);
118
118 119
119/** 120/**
120 * Stop traffic manipulation 121 * Stop traffic manipulation
121 */ 122 */
122void 123void
123GST_manipulation_stop (); 124GST_manipulation_stop (void);
124 125
125#endif 126#endif
126/* end of file gnunet-service-transport_neighbours.h */ 127/* end of file gnunet-service-transport_neighbours.h */
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c
index 5cfb5ed6d..623712efa 100644
--- a/src/transport/gnunet-service-transport_neighbours.c
+++ b/src/transport/gnunet-service-transport_neighbours.c
@@ -1481,7 +1481,6 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
1481 struct NeighbourMapEntry *n; 1481 struct NeighbourMapEntry *n;
1482 const struct SessionKeepAliveMessage *msg; 1482 const struct SessionKeepAliveMessage *msg;
1483 struct GNUNET_TRANSPORT_PluginFunctions *papi; 1483 struct GNUNET_TRANSPORT_PluginFunctions *papi;
1484 struct GNUNET_ATS_Information ats;
1485 struct GNUNET_TIME_Relative latency; 1484 struct GNUNET_TIME_Relative latency;
1486 1485
1487 if (sizeof (struct SessionKeepAliveMessage) != ntohs (m->size)) 1486 if (sizeof (struct SessionKeepAliveMessage) != ntohs (m->size))
@@ -1524,8 +1523,9 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
1524 else 1523 else
1525 { 1524 {
1526 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1525 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1527 "Received keep alive response from peer `%s' for session %p\n", 1526 "Received keep alive response from peer `%s' for session %p\n",
1528 GNUNET_i2s (&n->id), n->primary_address.session); 1527 GNUNET_i2s (&n->id),
1528 n->primary_address.session);
1529 1529
1530 } 1530 }
1531 1531
@@ -1533,9 +1533,12 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
1533 if (NULL != (papi = GST_plugins_find (n->primary_address.address->transport_name))) 1533 if (NULL != (papi = GST_plugins_find (n->primary_address.address->transport_name)))
1534 { 1534 {
1535 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1535 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1536 "Updating session for peer `%s' for session %p\n", 1536 "Updating session for peer `%s' for session %p\n",
1537 GNUNET_i2s (&n->id), n->primary_address.session); 1537 GNUNET_i2s (&n->id),
1538 papi->update_session_timeout (papi->cls, &n->id, n->primary_address.session); 1538 n->primary_address.session);
1539 papi->update_session_timeout (papi->cls,
1540 &n->id,
1541 n->primary_address.session);
1539 } 1542 }
1540 else 1543 else
1541 { 1544 {
@@ -1554,15 +1557,8 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
1554 GNUNET_i2s (&n->id), 1557 GNUNET_i2s (&n->id),
1555 GNUNET_STRINGS_relative_time_to_string (latency, 1558 GNUNET_STRINGS_relative_time_to_string (latency,
1556 GNUNET_YES)); 1559 GNUNET_YES));
1557 /* append latency */ 1560 GST_ats_update_delay (n->primary_address.address,
1558 ats.type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); 1561 GNUNET_TIME_relative_divide (latency, 2));
1559 ats.value = htonl ( (latency.rel_value_us > UINT32_MAX)
1560 ? UINT32_MAX
1561 : (uint32_t) latency.rel_value_us );
1562 GST_ats_update_metrics (n->primary_address.address,
1563 n->primary_address.session,
1564 &ats,
1565 1);
1566} 1562}
1567 1563
1568 1564
@@ -1579,8 +1575,9 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
1579 * @return how long to wait before reading more from this sender 1575 * @return how long to wait before reading more from this sender
1580 */ 1576 */
1581struct GNUNET_TIME_Relative 1577struct GNUNET_TIME_Relative
1582GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity 1578GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity *sender,
1583 *sender, ssize_t size, int *do_forward) 1579 ssize_t size,
1580 int *do_forward)
1584{ 1581{
1585 struct NeighbourMapEntry *n; 1582 struct NeighbourMapEntry *n;
1586 struct GNUNET_TIME_Relative ret; 1583 struct GNUNET_TIME_Relative ret;
@@ -2824,7 +2821,6 @@ send_utilization_data (void *cls,
2824 void *value) 2821 void *value)
2825{ 2822{
2826 struct NeighbourMapEntry *n = value; 2823 struct NeighbourMapEntry *n = value;
2827 struct GNUNET_ATS_Information atsi[2];
2828 uint32_t bps_in; 2824 uint32_t bps_in;
2829 uint32_t bps_out; 2825 uint32_t bps_out;
2830 struct GNUNET_TIME_Relative delta; 2826 struct GNUNET_TIME_Relative delta;
@@ -2846,14 +2842,9 @@ send_utilization_data (void *cls,
2846 GNUNET_i2s (key), 2842 GNUNET_i2s (key),
2847 bps_in, 2843 bps_in,
2848 bps_out); 2844 bps_out);
2849 atsi[0].type = htonl (GNUNET_ATS_UTILIZATION_OUT); 2845 GST_ats_update_utilization (n->primary_address.address,
2850 atsi[0].value = htonl (bps_out); 2846 bps_in,
2851 atsi[1].type = htonl (GNUNET_ATS_UTILIZATION_IN); 2847 bps_out);
2852 atsi[1].value = htonl (bps_in);
2853 GST_ats_update_metrics (n->primary_address.address,
2854 n->primary_address.session,
2855 atsi,
2856 2);
2857 n->util_total_bytes_recv = 0; 2848 n->util_total_bytes_recv = 0;
2858 n->util_total_bytes_sent = 0; 2849 n->util_total_bytes_sent = 0;
2859 n->last_util_transmission = GNUNET_TIME_absolute_get (); 2850 n->last_util_transmission = GNUNET_TIME_absolute_get ();
@@ -3426,9 +3417,9 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message,
3426 return GNUNET_SYSERR; 3417 return GNUNET_SYSERR;
3427 } 3418 }
3428 GNUNET_STATISTICS_update (GST_stats, 3419 GNUNET_STATISTICS_update (GST_stats,
3429 gettext_noop 3420 gettext_noop ("# ACK messages received"),
3430 ("# ACK messages received"), 3421 1,
3431 1, GNUNET_NO); 3422 GNUNET_NO);
3432 if (NULL == (n = lookup_neighbour (&address->peer))) 3423 if (NULL == (n = lookup_neighbour (&address->peer)))
3433 { 3424 {
3434 GNUNET_break_op (0); 3425 GNUNET_break_op (0);
diff --git a/src/transport/gnunet-service-transport_plugins.c b/src/transport/gnunet-service-transport_plugins.c
index 1571cee71..cbfa50afd 100644
--- a/src/transport/gnunet-service-transport_plugins.c
+++ b/src/transport/gnunet-service-transport_plugins.c
@@ -85,19 +85,15 @@ static struct TransportPlugin *plugins_tail;
85 * @param cls closure 85 * @param cls closure
86 * @param address address to update metrics for 86 * @param address address to update metrics for
87 * @param session the session 87 * @param session the session
88 * @param ats the ats information to update 88 * @param distance new distance
89 * @param ats_count the number of @a ats elements
90 */ 89 */
91static void 90static void
92plugin_env_update_metrics (void *cls, 91plugin_env_update_distance (void *cls,
93 const struct GNUNET_HELLO_Address *address, 92 const struct GNUNET_HELLO_Address *address,
94 struct Session *session, 93 uint32_t distance)
95 const struct GNUNET_ATS_Information *ats,
96 uint32_t ats_count)
97{ 94{
98 GST_ats_update_metrics (address, 95 GST_ats_update_distance (address,
99 session, 96 distance);
100 ats, ats_count);
101} 97}
102 98
103 99
@@ -191,7 +187,7 @@ GST_plugins_load (GNUNET_TRANSPORT_PluginReceiveCallback recv_cb,
191 plug->env.session_start = session_start_cb; 187 plug->env.session_start = session_start_cb;
192 plug->env.session_end = session_end_cb; 188 plug->env.session_end = session_end_cb;
193 plug->env.get_address_type = &plugin_env_address_to_type; 189 plug->env.get_address_type = &plugin_env_address_to_type;
194 plug->env.update_address_metrics = &plugin_env_update_metrics; 190 plug->env.update_address_distance = &plugin_env_update_distance;
195 plug->env.max_connections = tneigh; 191 plug->env.max_connections = tneigh;
196 plug->env.stats = GST_stats; 192 plug->env.stats = GST_stats;
197 GNUNET_CONTAINER_DLL_insert (plugins_head, 193 GNUNET_CONTAINER_DLL_insert (plugins_head,
diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c
index d8966f1a4..b6b323bd0 100644
--- a/src/transport/gnunet-service-transport_validation.c
+++ b/src/transport/gnunet-service-transport_validation.c
@@ -804,7 +804,7 @@ add_valid_address (void *cls,
804 const struct GNUNET_HELLO_Message *hello = cls; 804 const struct GNUNET_HELLO_Message *hello = cls;
805 struct ValidationEntry *ve; 805 struct ValidationEntry *ve;
806 struct GNUNET_PeerIdentity pid; 806 struct GNUNET_PeerIdentity pid;
807 struct GNUNET_ATS_Information ats; 807 struct GNUNET_ATS_Properties prop;
808 808
809 if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us) 809 if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us)
810 return GNUNET_OK; /* expired */ 810 return GNUNET_OK; /* expired */
@@ -832,13 +832,13 @@ add_valid_address (void *cls,
832 ve->revalidation_task = GNUNET_SCHEDULER_add_now (&revalidate_address, ve); 832 ve->revalidation_task = GNUNET_SCHEDULER_add_now (&revalidate_address, ve);
833 } 833 }
834 validation_entry_changed (ve, GNUNET_TRANSPORT_VS_UPDATE); 834 validation_entry_changed (ve, GNUNET_TRANSPORT_VS_UPDATE);
835 835 memset (&prop, 0, sizeof (prop));
836 ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); 836 prop.scope = ve->network;
837 ats.value = htonl (ve->network); 837 prop.delay = GNUNET_TIME_relative_divide (ve->latency, 2);
838 if (GNUNET_YES != ve->known_to_ats) 838 if (GNUNET_YES != ve->known_to_ats)
839 { 839 {
840 ve->known_to_ats = GNUNET_YES; 840 ve->known_to_ats = GNUNET_YES;
841 GST_ats_add_address (address, &ats, 1); 841 GST_ats_add_address (address, &prop);
842 } 842 }
843 return GNUNET_OK; 843 return GNUNET_OK;
844} 844}
@@ -1465,23 +1465,20 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender,
1465 ve->pong_sig_valid_until = GNUNET_TIME_absolute_ntoh (pong->expiration); 1465 ve->pong_sig_valid_until = GNUNET_TIME_absolute_ntoh (pong->expiration);
1466 ve->latency = GNUNET_TIME_absolute_get_duration (ve->send_time); 1466 ve->latency = GNUNET_TIME_absolute_get_duration (ve->send_time);
1467 { 1467 {
1468 struct GNUNET_ATS_Information ats[2];
1469
1470 ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY);
1471 ats[0].value = htonl ((uint32_t) ve->latency.rel_value_us);
1472 ats[1].type = htonl (GNUNET_ATS_NETWORK_TYPE);
1473 ats[1].value = htonl ((uint32_t) ve->network);
1474 if (GNUNET_YES == ve->known_to_ats) 1468 if (GNUNET_YES == ve->known_to_ats)
1475 { 1469 {
1476 GST_ats_update_metrics (ve->address, 1470 GST_ats_update_delay (ve->address,
1477 NULL, 1471 GNUNET_TIME_relative_divide (ve->latency, 2));
1478 ats,
1479 2);
1480 } 1472 }
1481 else 1473 else
1482 { 1474 {
1475 struct GNUNET_ATS_Properties prop;
1476
1477 memset (&prop, 0, sizeof (prop));
1478 prop.scope = ve->network;
1479 prop.delay = GNUNET_TIME_relative_divide (ve->latency, 2);
1483 ve->known_to_ats = GNUNET_YES; 1480 ve->known_to_ats = GNUNET_YES;
1484 GST_ats_add_address (ve->address, ats, 2); 1481 GST_ats_add_address (ve->address, &prop);
1485 } 1482 }
1486 } 1483 }
1487 if (validations_running > 0) 1484 if (validations_running > 0)
diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c
index 6e994d467..165045a8a 100644
--- a/src/transport/plugin_transport_http_client.c
+++ b/src/transport/plugin_transport_http_client.c
@@ -264,7 +264,7 @@ struct Session
264 /** 264 /**
265 * ATS network type. 265 * ATS network type.
266 */ 266 */
267 enum GNUNET_ATS_Network_Type ats_address_network_type; 267 enum GNUNET_ATS_Network_Type scope;
268}; 268};
269 269
270 270
@@ -1169,23 +1169,13 @@ client_receive_mst_cb (void *cls,
1169 struct Session *s = cls; 1169 struct Session *s = cls;
1170 struct HTTP_Client_Plugin *plugin; 1170 struct HTTP_Client_Plugin *plugin;
1171 struct GNUNET_TIME_Relative delay; 1171 struct GNUNET_TIME_Relative delay;
1172 struct GNUNET_ATS_Information atsi;
1173 char *stat_txt; 1172 char *stat_txt;
1174 1173
1175 plugin = s->plugin; 1174 plugin = s->plugin;
1176 GNUNET_break (s->ats_address_network_type != GNUNET_ATS_NET_UNSPECIFIED);
1177 atsi.type = htonl (GNUNET_ATS_NETWORK_TYPE);
1178 atsi.value = htonl (s->ats_address_network_type);
1179
1180 delay = s->plugin->env->receive (plugin->env->cls, 1175 delay = s->plugin->env->receive (plugin->env->cls,
1181 s->address, 1176 s->address,
1182 s, 1177 s,
1183 message); 1178 message);
1184 plugin->env->update_address_metrics (plugin->env->cls,
1185 s->address,
1186 s,
1187 &atsi, 1);
1188
1189 GNUNET_asprintf (&stat_txt, 1179 GNUNET_asprintf (&stat_txt,
1190 "# bytes received via %s_client", 1180 "# bytes received via %s_client",
1191 plugin->protocol); 1181 plugin->protocol);
@@ -1943,7 +1933,7 @@ static enum GNUNET_ATS_Network_Type
1943http_client_plugin_get_network (void *cls, 1933http_client_plugin_get_network (void *cls,
1944 struct Session *session) 1934 struct Session *session)
1945{ 1935{
1946 return session->ats_address_network_type; 1936 return session->scope;
1947} 1937}
1948 1938
1949 1939
@@ -2057,7 +2047,7 @@ http_client_plugin_get_session (void *cls,
2057 s = GNUNET_new (struct Session); 2047 s = GNUNET_new (struct Session);
2058 s->plugin = plugin; 2048 s->plugin = plugin;
2059 s->address = GNUNET_HELLO_address_copy (address); 2049 s->address = GNUNET_HELLO_address_copy (address);
2060 s->ats_address_network_type = net_type; 2050 s->scope = net_type;
2061 2051
2062 s->put.state = H_NOT_CONNECTED; 2052 s->put.state = H_NOT_CONNECTED;
2063 s->timeout = GNUNET_TIME_relative_to_absolute (HTTP_CLIENT_SESSION_TIMEOUT); 2053 s->timeout = GNUNET_TIME_relative_to_absolute (HTTP_CLIENT_SESSION_TIMEOUT);
diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c
index 9d956b29d..9d34ef291 100644
--- a/src/transport/plugin_transport_http_server.c
+++ b/src/transport/plugin_transport_http_server.c
@@ -255,9 +255,9 @@ struct Session
255 uint32_t tag; 255 uint32_t tag;
256 256
257 /** 257 /**
258 * ATS network type in NBO 258 * ATS network type.
259 */ 259 */
260 uint32_t ats_address_network_type; 260 enum GNUNET_ATS_Network_Type scope;
261 261
262 /** 262 /**
263 * #GNUNET_YES if this session is known to the service. 263 * #GNUNET_YES if this session is known to the service.
@@ -1363,13 +1363,13 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1363 struct ServerRequest *sc = NULL; 1363 struct ServerRequest *sc = NULL;
1364 const union MHD_ConnectionInfo *conn_info; 1364 const union MHD_ConnectionInfo *conn_info;
1365 struct HttpAddress *addr; 1365 struct HttpAddress *addr;
1366 struct GNUNET_ATS_Information ats;
1367 struct GNUNET_PeerIdentity target; 1366 struct GNUNET_PeerIdentity target;
1368 size_t addr_len; 1367 size_t addr_len;
1369 struct SessionTagContext stc; 1368 struct SessionTagContext stc;
1370 uint32_t options; 1369 uint32_t options;
1371 int direction = GNUNET_SYSERR; 1370 int direction = GNUNET_SYSERR;
1372 unsigned int to; 1371 unsigned int to;
1372 enum GNUNET_ATS_Network_Type scope;
1373 1373
1374 conn_info = MHD_get_connection_info (mhd_connection, 1374 conn_info = MHD_get_connection_info (mhd_connection,
1375 MHD_CONNECTION_INFO_CLIENT_ADDRESS); 1375 MHD_CONNECTION_INFO_CLIENT_ADDRESS);
@@ -1424,36 +1424,32 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1424 conn_info->client_addr, 1424 conn_info->client_addr,
1425 sizeof (struct sockaddr_in)); 1425 sizeof (struct sockaddr_in));
1426 addr_len = http_common_address_get_size (addr); 1426 addr_len = http_common_address_get_size (addr);
1427 ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); 1427 scope = plugin->env->get_address_type (plugin->env->cls,
1428 ats.value = htonl (plugin->env->get_address_type (plugin->env->cls, 1428 conn_info->client_addr,
1429 conn_info->client_addr, 1429 sizeof (struct sockaddr_in));
1430 sizeof (struct sockaddr_in)));
1431 break; 1430 break;
1432 case (AF_INET6): 1431 case (AF_INET6):
1433 addr = http_common_address_from_socket (plugin->protocol, 1432 addr = http_common_address_from_socket (plugin->protocol,
1434 conn_info->client_addr, 1433 conn_info->client_addr,
1435 sizeof (struct sockaddr_in6)); 1434 sizeof (struct sockaddr_in6));
1436 addr_len = http_common_address_get_size (addr); 1435 addr_len = http_common_address_get_size (addr);
1437 ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); 1436 scope = plugin->env->get_address_type (plugin->env->cls,
1438 ats.value = htonl (plugin->env->get_address_type (plugin->env->cls, 1437 conn_info->client_addr,
1439 conn_info->client_addr, 1438 sizeof (struct sockaddr_in6));
1440 sizeof (struct sockaddr_in6)));
1441 break; 1439 break;
1442 default: 1440 default:
1443 /* external host name */ 1441 /* external host name */
1444 ats.type = htonl (GNUNET_ATS_NETWORK_TYPE);
1445 ats.value = htonl (GNUNET_ATS_NET_WAN);
1446 return NULL; 1442 return NULL;
1447 } 1443 }
1448 s = GNUNET_new (struct Session); 1444 s = GNUNET_new (struct Session);
1449 s->target = target; 1445 s->target = target;
1450 s->plugin = plugin; 1446 s->plugin = plugin;
1447 s->scope = scope;
1451 s->address = GNUNET_HELLO_address_allocate (&s->target, 1448 s->address = GNUNET_HELLO_address_allocate (&s->target,
1452 PLUGIN_NAME, 1449 PLUGIN_NAME,
1453 addr, 1450 addr,
1454 addr_len, 1451 addr_len,
1455 GNUNET_HELLO_ADDRESS_INFO_INBOUND); 1452 GNUNET_HELLO_ADDRESS_INFO_INBOUND);
1456 s->ats_address_network_type = ats.value;
1457 s->next_receive = GNUNET_TIME_UNIT_ZERO_ABS; 1453 s->next_receive = GNUNET_TIME_UNIT_ZERO_ABS;
1458 s->tag = stc.tag; 1454 s->tag = stc.tag;
1459 s->timeout = GNUNET_TIME_relative_to_absolute (HTTP_SERVER_SESSION_TIMEOUT); 1455 s->timeout = GNUNET_TIME_relative_to_absolute (HTTP_SERVER_SESSION_TIMEOUT);
@@ -1526,7 +1522,7 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1526 plugin->env->session_start (plugin->env->cls, 1522 plugin->env->session_start (plugin->env->cls,
1527 s->address, 1523 s->address,
1528 s, 1524 s,
1529 NULL, 0); 1525 s->scope);
1530 } 1526 }
1531 1527
1532 if ( (NULL == s->server_recv) || 1528 if ( (NULL == s->server_recv) ||
@@ -1659,23 +1655,16 @@ server_receive_mst_cb (void *cls,
1659{ 1655{
1660 struct Session *s = cls; 1656 struct Session *s = cls;
1661 struct HTTP_Server_Plugin *plugin = s->plugin; 1657 struct HTTP_Server_Plugin *plugin = s->plugin;
1662 struct GNUNET_ATS_Information atsi;
1663 struct GNUNET_TIME_Relative delay; 1658 struct GNUNET_TIME_Relative delay;
1664 char *stat_txt; 1659 char *stat_txt;
1665 1660
1666 atsi.type = htonl (GNUNET_ATS_NETWORK_TYPE);
1667 atsi.value = s->ats_address_network_type;
1668 GNUNET_break (s->ats_address_network_type !=
1669 ntohl (GNUNET_ATS_NET_UNSPECIFIED));
1670
1671 if (GNUNET_NO == s->known_to_service) 1661 if (GNUNET_NO == s->known_to_service)
1672 { 1662 {
1673 s->known_to_service = GNUNET_YES; 1663 s->known_to_service = GNUNET_YES;
1674 plugin->env->session_start (plugin->env->cls, 1664 plugin->env->session_start (plugin->env->cls,
1675 s->address, 1665 s->address,
1676 s, 1666 s,
1677 NULL, 1667 s->scope);
1678 0);
1679 notify_session_monitor (plugin, 1668 notify_session_monitor (plugin,
1680 s, 1669 s,
1681 GNUNET_TRANSPORT_SS_UP); 1670 GNUNET_TRANSPORT_SS_UP);
@@ -1684,9 +1673,6 @@ server_receive_mst_cb (void *cls,
1684 s->address, 1673 s->address,
1685 s, 1674 s,
1686 message); 1675 message);
1687 plugin->env->update_address_metrics (plugin->env->cls,
1688 s->address, s,
1689 &atsi, 1);
1690 GNUNET_asprintf (&stat_txt, 1676 GNUNET_asprintf (&stat_txt,
1691 "# bytes received via %s_server", 1677 "# bytes received via %s_server",
1692 plugin->protocol); 1678 plugin->protocol);
@@ -3287,7 +3273,7 @@ static enum GNUNET_ATS_Network_Type
3287http_server_plugin_get_network (void *cls, 3273http_server_plugin_get_network (void *cls,
3288 struct Session *session) 3274 struct Session *session)
3289{ 3275{
3290 return ntohl (session->ats_address_network_type); 3276 return session->scope;
3291} 3277}
3292 3278
3293 3279
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c
index 5396d5247..19ce855d8 100644
--- a/src/transport/plugin_transport_tcp.c
+++ b/src/transport/plugin_transport_tcp.c
@@ -331,6 +331,11 @@ struct Session
331 unsigned int msgs_in_queue; 331 unsigned int msgs_in_queue;
332 332
333 /** 333 /**
334 * Network type of the address.
335 */
336 enum GNUNET_ATS_Network_Type scope;
337
338 /**
334 * Are we still expecting the welcome message? (#GNUNET_YES/#GNUNET_NO) 339 * Are we still expecting the welcome message? (#GNUNET_YES/#GNUNET_NO)
335 */ 340 */
336 int expecting_welcome; 341 int expecting_welcome;
@@ -340,12 +345,9 @@ struct Session
340 */ 345 */
341 int is_nat; 346 int is_nat;
342 347
343 /**
344 * ATS network type in NBO
345 */
346 enum GNUNET_ATS_Network_Type ats_address_network_type;
347}; 348};
348 349
350
349/** 351/**
350 * Encapsulation of all of the state of the plugin. 352 * Encapsulation of all of the state of the plugin.
351 */ 353 */
@@ -1011,7 +1013,7 @@ create_session (struct Plugin *plugin,
1011 session->address = GNUNET_HELLO_address_copy (address); 1013 session->address = GNUNET_HELLO_address_copy (address);
1012 session->target = address->peer; 1014 session->target = address->peer;
1013 session->expecting_welcome = GNUNET_YES; 1015 session->expecting_welcome = GNUNET_YES;
1014 session->ats_address_network_type = GNUNET_ATS_NET_UNSPECIFIED; 1016 session->scope = GNUNET_ATS_NET_UNSPECIFIED;
1015 pm = GNUNET_malloc (sizeof (struct PendingMessage) + 1017 pm = GNUNET_malloc (sizeof (struct PendingMessage) +
1016 sizeof (struct WelcomeMessage)); 1018 sizeof (struct WelcomeMessage));
1017 pm->msg = (const char *) &pm[1]; 1019 pm->msg = (const char *) &pm[1];
@@ -1627,7 +1629,7 @@ tcp_plugin_get_session (void *cls,
1627 } 1629 }
1628 1630
1629 net_type = plugin->env->get_address_type (plugin->env->cls, sb, sbs); 1631 net_type = plugin->env->get_address_type (plugin->env->cls, sb, sbs);
1630 1632 GNUNET_break (net_type != GNUNET_ATS_NET_UNSPECIFIED);
1631 1633
1632 if ((is_natd == GNUNET_YES) && (addrlen == sizeof(struct IPv6TcpAddress))) 1634 if ((is_natd == GNUNET_YES) && (addrlen == sizeof(struct IPv6TcpAddress)))
1633 { 1635 {
@@ -1661,8 +1663,7 @@ tcp_plugin_get_session (void *cls,
1661 address, 1663 address,
1662 NULL, 1664 NULL,
1663 GNUNET_YES); 1665 GNUNET_YES);
1664 session->ats_address_network_type = net_type; 1666 session->scope = net_type;
1665 GNUNET_break (session->ats_address_network_type != GNUNET_ATS_NET_UNSPECIFIED);
1666 session->nat_connection_timeout = GNUNET_SCHEDULER_add_delayed (NAT_TIMEOUT, 1667 session->nat_connection_timeout = GNUNET_SCHEDULER_add_delayed (NAT_TIMEOUT,
1667 &nat_connect_timeout, 1668 &nat_connect_timeout,
1668 session); 1669 session);
@@ -1759,9 +1760,9 @@ tcp_plugin_get_session (void *cls,
1759 address, 1760 address,
1760 GNUNET_SERVER_connect_socket (plugin->server, sa), 1761 GNUNET_SERVER_connect_socket (plugin->server, sa),
1761 GNUNET_NO); 1762 GNUNET_NO);
1762 session->ats_address_network_type = net_type; 1763 session->scope = net_type;
1763 GNUNET_break (session->ats_address_network_type != GNUNET_ATS_NET_UNSPECIFIED); 1764 GNUNET_SERVER_client_set_user_context (session->client,
1764 GNUNET_SERVER_client_set_user_context(session->client, session); 1765 session);
1765 GNUNET_CONTAINER_multipeermap_put (plugin->sessionmap, 1766 GNUNET_CONTAINER_multipeermap_put (plugin->sessionmap,
1766 &session->target, 1767 &session->target,
1767 session, 1768 session,
@@ -2253,6 +2254,7 @@ handle_tcp_nat_probe (void *cls,
2253 GNUNET_SERVER_receive_done (client, GNUNET_OK); 2254 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2254} 2255}
2255 2256
2257
2256/** 2258/**
2257 * We've received a welcome from this peer via TCP. Possibly create a 2259 * We've received a welcome from this peer via TCP. Possibly create a
2258 * fresh client record and send back our welcome. 2260 * fresh client record and send back our welcome.
@@ -2276,8 +2278,6 @@ handle_tcp_welcome (void *cls,
2276 struct IPv6TcpAddress t6; 2278 struct IPv6TcpAddress t6;
2277 const struct sockaddr_in *s4; 2279 const struct sockaddr_in *s4;
2278 const struct sockaddr_in6 *s6; 2280 const struct sockaddr_in6 *s6;
2279 struct GNUNET_ATS_Information ats;
2280
2281 2281
2282 if (0 == memcmp (&wm->clientIdentity, 2282 if (0 == memcmp (&wm->clientIdentity,
2283 plugin->env->my_identity, 2283 plugin->env->my_identity,
@@ -2369,12 +2369,10 @@ handle_tcp_welcome (void *cls,
2369 client, 2369 client,
2370 GNUNET_NO); 2370 GNUNET_NO);
2371 GNUNET_HELLO_address_free (address); 2371 GNUNET_HELLO_address_free (address);
2372 session->ats_address_network_type 2372 session->scope
2373 = plugin->env->get_address_type (plugin->env->cls, 2373 = plugin->env->get_address_type (plugin->env->cls,
2374 vaddr, 2374 vaddr,
2375 alen); 2375 alen);
2376 ats.type = htonl (GNUNET_ATS_NETWORK_TYPE);
2377 ats.value = htonl (session->ats_address_network_type);
2378 LOG (GNUNET_ERROR_TYPE_DEBUG, 2376 LOG (GNUNET_ERROR_TYPE_DEBUG,
2379 "Creating new%s session %p for peer `%s' client %p \n", 2377 "Creating new%s session %p for peer `%s' client %p \n",
2380 GNUNET_HELLO_address_check_option (session->address, 2378 GNUNET_HELLO_address_check_option (session->address,
@@ -2395,7 +2393,7 @@ handle_tcp_welcome (void *cls,
2395 plugin->env->session_start (plugin->env->cls, 2393 plugin->env->session_start (plugin->env->cls,
2396 session->address, 2394 session->address,
2397 session, 2395 session,
2398 &ats, 1); 2396 session->scope);
2399 notify_session_monitor (plugin, 2397 notify_session_monitor (plugin,
2400 session, 2398 session,
2401 GNUNET_TRANSPORT_SS_INIT); 2399 GNUNET_TRANSPORT_SS_INIT);
@@ -2443,7 +2441,6 @@ handle_tcp_data (void *cls,
2443 struct Session *session; 2441 struct Session *session;
2444 struct GNUNET_TIME_Relative delay; 2442 struct GNUNET_TIME_Relative delay;
2445 uint16_t type; 2443 uint16_t type;
2446 struct GNUNET_ATS_Information distance;
2447 2444
2448 type = ntohs (message->type); 2445 type = ntohs (message->type);
2449 if ( (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME == type) || 2446 if ( (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME == type) ||
@@ -2507,10 +2504,6 @@ handle_tcp_data (void *cls,
2507 ntohs (message->size), 2504 ntohs (message->size),
2508 GNUNET_NO); 2505 GNUNET_NO);
2509 2506
2510 distance.type = htonl (GNUNET_ATS_NETWORK_TYPE);
2511 distance.value = htonl ((uint32_t) session->ats_address_network_type);
2512 GNUNET_break (session->ats_address_network_type != GNUNET_ATS_NET_UNSPECIFIED);
2513
2514 GNUNET_assert (GNUNET_CONTAINER_multipeermap_contains_value (plugin->sessionmap, 2507 GNUNET_assert (GNUNET_CONTAINER_multipeermap_contains_value (plugin->sessionmap,
2515 &session->target, 2508 &session->target,
2516 session)); 2509 session));
@@ -2518,10 +2511,6 @@ handle_tcp_data (void *cls,
2518 session->address, 2511 session->address,
2519 session, 2512 session,
2520 message); 2513 message);
2521 plugin->env->update_address_metrics (plugin->env->cls,
2522 session->address,
2523 session,
2524 &distance, 1);
2525 reschedule_session_timeout (session); 2514 reschedule_session_timeout (session);
2526 if (0 == delay.rel_value_us) 2515 if (0 == delay.rel_value_us)
2527 { 2516 {
@@ -2680,7 +2669,7 @@ static enum GNUNET_ATS_Network_Type
2680tcp_plugin_get_network (void *cls, 2669tcp_plugin_get_network (void *cls,
2681 struct Session *session) 2670 struct Session *session)
2682{ 2671{
2683 return session->ats_address_network_type; 2672 return session->scope;
2684} 2673}
2685 2674
2686 2675
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index f185c8738..477efc0a1 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -173,12 +173,6 @@ struct Session
173 struct GNUNET_TIME_Relative last_expected_msg_delay; 173 struct GNUNET_TIME_Relative last_expected_msg_delay;
174 174
175 /** 175 /**
176 * Address metrics (as set by the "update_address_metrics" by
177 * the environment).
178 */
179 struct GNUNET_ATS_Information ats;
180
181 /**
182 * Our own address. 176 * Our own address.
183 */ 177 */
184 struct GNUNET_HELLO_Address *address; 178 struct GNUNET_HELLO_Address *address;
@@ -202,6 +196,11 @@ struct Session
202 unsigned int rc; 196 unsigned int rc;
203 197
204 /** 198 /**
199 * Network type of the address.
200 */
201 enum GNUNET_ATS_Network_Type scope;
202
203 /**
205 * Is this session about to be destroyed (sometimes we cannot 204 * Is this session about to be destroyed (sometimes we cannot
206 * destroy a session immediately as below us on the stack 205 * destroy a session immediately as below us on the stack
207 * there might be code that still uses it; in this case, 206 * there might be code that still uses it; in this case,
@@ -1595,7 +1594,7 @@ static enum GNUNET_ATS_Network_Type
1595udp_get_network (void *cls, 1594udp_get_network (void *cls,
1596 struct Session *session) 1595 struct Session *session)
1597{ 1596{
1598 return ntohl (session->ats.value); 1597 return session->scope;
1599} 1598}
1600 1599
1601 1600
@@ -1742,11 +1741,8 @@ udp_plugin_create_session (void *cls,
1742 struct Session *s; 1741 struct Session *s;
1743 1742
1744 s = create_session (plugin, address); 1743 s = create_session (plugin, address);
1745 s->ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); 1744 s->scope = network_type;
1746 s->ats.value = htonl (network_type);
1747 1745
1748 if (NULL == s)
1749 return NULL; /* protocol not supported or address invalid */
1750 LOG (GNUNET_ERROR_TYPE_DEBUG, 1746 LOG (GNUNET_ERROR_TYPE_DEBUG,
1751 "Creating new session %p for peer `%s' address `%s'\n", 1747 "Creating new session %p for peer `%s' address `%s'\n",
1752 s, 1748 s,
@@ -2213,16 +2209,11 @@ process_inbound_tokenized_messages (void *cls,
2213 if (GNUNET_YES == si->session->in_destroy) 2209 if (GNUNET_YES == si->session->in_destroy)
2214 return GNUNET_OK; 2210 return GNUNET_OK;
2215 /* setup ATS */ 2211 /* setup ATS */
2216 GNUNET_break (ntohl (si->session->ats.value) != GNUNET_ATS_NET_UNSPECIFIED);
2217 reschedule_session_timeout (si->session); 2212 reschedule_session_timeout (si->session);
2218 delay = plugin->env->receive (plugin->env->cls, 2213 delay = plugin->env->receive (plugin->env->cls,
2219 si->session->address, 2214 si->session->address,
2220 si->session, 2215 si->session,
2221 hdr); 2216 hdr);
2222 plugin->env->update_address_metrics (plugin->env->cls,
2223 si->session->address,
2224 si->session,
2225 &si->session->ats, 1);
2226 si->session->flow_delay_for_other_peer = delay; 2217 si->session->flow_delay_for_other_peer = delay;
2227 return GNUNET_OK; 2218 return GNUNET_OK;
2228} 2219}
@@ -2274,8 +2265,7 @@ process_udp_message (struct Plugin *plugin,
2274 plugin->env->session_start (plugin->env->cls, 2265 plugin->env->session_start (plugin->env->cls,
2275 address, 2266 address,
2276 s, 2267 s,
2277 NULL, 2268 s->scope);
2278 0);
2279 notify_session_monitor (s->plugin, 2269 notify_session_monitor (s->plugin,
2280 s, 2270 s,
2281 GNUNET_TRANSPORT_SS_INIT); 2271 GNUNET_TRANSPORT_SS_INIT);
diff --git a/src/transport/plugin_transport_udp_broadcasting.c b/src/transport/plugin_transport_udp_broadcasting.c
index 413c79564..e7b7cdc23 100644
--- a/src/transport/plugin_transport_udp_broadcasting.c
+++ b/src/transport/plugin_transport_udp_broadcasting.c
@@ -142,7 +142,6 @@ broadcast_mst_cb (void *cls,
142 struct GNUNET_HELLO_Address *address; 142 struct GNUNET_HELLO_Address *address;
143 const struct GNUNET_MessageHeader *hello; 143 const struct GNUNET_MessageHeader *hello;
144 const struct UDP_Beacon_Message *msg; 144 const struct UDP_Beacon_Message *msg;
145 struct GNUNET_ATS_Information atsi;
146 145
147 msg = (const struct UDP_Beacon_Message *) message; 146 msg = (const struct UDP_Beacon_Message *) message;
148 147
@@ -156,13 +155,6 @@ broadcast_mst_cb (void *cls,
156 udp_address_to_string (NULL, 155 udp_address_to_string (NULL,
157 mc->udp_addr, 156 mc->udp_addr,
158 mc->udp_addr_len)); 157 mc->udp_addr_len));
159
160 /* setup ATS */
161 atsi.type = htonl (GNUNET_ATS_NETWORK_TYPE);
162 atsi.value = htonl (mc->ats_address_network_type);
163 GNUNET_break (ntohl(mc->ats_address_network_type) !=
164 GNUNET_ATS_NET_UNSPECIFIED);
165
166 hello = (struct GNUNET_MessageHeader *) &msg[1]; 158 hello = (struct GNUNET_MessageHeader *) &msg[1];
167 address = GNUNET_HELLO_address_allocate (&msg->sender, 159 address = GNUNET_HELLO_address_allocate (&msg->sender,
168 PLUGIN_NAME, 160 PLUGIN_NAME,
@@ -173,11 +165,6 @@ broadcast_mst_cb (void *cls,
173 address, 165 address,
174 NULL, 166 NULL,
175 hello); 167 hello);
176 plugin->env->update_address_metrics (plugin->env->cls,
177 address,
178 NULL,
179 &atsi,
180 1);
181 GNUNET_HELLO_address_free (address); 168 GNUNET_HELLO_address_free (address);
182 GNUNET_STATISTICS_update (plugin->env->stats, 169 GNUNET_STATISTICS_update (plugin->env->stats,
183 _("# Multicast HELLO beacons received via UDP"), 170 _("# Multicast HELLO beacons received via UDP"),
diff --git a/src/transport/plugin_transport_unix.c b/src/transport/plugin_transport_unix.c
index 160aaddaf..ddb5f747c 100644
--- a/src/transport/plugin_transport_unix.c
+++ b/src/transport/plugin_transport_unix.c
@@ -318,11 +318,6 @@ struct Plugin
318 uint32_t myoptions; 318 uint32_t myoptions;
319 319
320 /** 320 /**
321 * ATS network
322 */
323 struct GNUNET_ATS_Information ats_network;
324
325 /**
326 * Are we using an abstract UNIX domain socket? 321 * Are we using an abstract UNIX domain socket?
327 */ 322 */
328 int is_abstract; 323 int is_abstract;
@@ -947,12 +942,12 @@ static void
947unix_demultiplexer (struct Plugin *plugin, 942unix_demultiplexer (struct Plugin *plugin,
948 struct GNUNET_PeerIdentity *sender, 943 struct GNUNET_PeerIdentity *sender,
949 const struct GNUNET_MessageHeader *currhdr, 944 const struct GNUNET_MessageHeader *currhdr,
950 const struct UnixAddress *ua, size_t ua_len) 945 const struct UnixAddress *ua,
946 size_t ua_len)
951{ 947{
952 struct Session *session; 948 struct Session *session;
953 struct GNUNET_HELLO_Address *address; 949 struct GNUNET_HELLO_Address *address;
954 950
955 GNUNET_break (ntohl(plugin->ats_network.value) != GNUNET_ATS_NET_UNSPECIFIED);
956 GNUNET_assert (ua_len >= sizeof (struct UnixAddress)); 951 GNUNET_assert (ua_len >= sizeof (struct UnixAddress));
957 LOG (GNUNET_ERROR_TYPE_DEBUG, 952 LOG (GNUNET_ERROR_TYPE_DEBUG,
958 "Received message from %s\n", 953 "Received message from %s\n",
@@ -975,7 +970,7 @@ unix_demultiplexer (struct Plugin *plugin,
975 plugin->env->session_start (NULL, 970 plugin->env->session_start (NULL,
976 session->address, 971 session->address,
977 session, 972 session,
978 &plugin->ats_network, 1); 973 GNUNET_ATS_NET_LOOPBACK);
979 } 974 }
980 else 975 else
981 { 976 {
@@ -986,10 +981,6 @@ unix_demultiplexer (struct Plugin *plugin,
986 session->address, 981 session->address,
987 session, 982 session,
988 currhdr); 983 currhdr);
989 plugin->env->update_address_metrics (plugin->env->cls,
990 session->address,
991 session,
992 &plugin->ats_network, 1);
993} 984}
994 985
995 986
@@ -1387,10 +1378,6 @@ unix_transport_server_start (void *cls)
1387 plugin->unix_socket_path[0] = '@'; 1378 plugin->unix_socket_path[0] = '@';
1388 un->sun_path[0] = '\0'; 1379 un->sun_path[0] = '\0';
1389 } 1380 }
1390 plugin->ats_network.type = htonl (GNUNET_ATS_NETWORK_TYPE);
1391 plugin->ats_network.value = htonl (plugin->env->get_address_type (plugin->env->cls,
1392 (const struct sockaddr *) un,
1393 un_len));
1394 plugin->unix_sock.desc = 1381 plugin->unix_sock.desc =
1395 GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 0); 1382 GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 0);
1396 if (NULL == plugin->unix_sock.desc) 1383 if (NULL == plugin->unix_sock.desc)
diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c
index 42b7d8669..c0e629b83 100644
--- a/src/transport/plugin_transport_wlan.c
+++ b/src/transport/plugin_transport_wlan.c
@@ -98,6 +98,15 @@
98#define WLAN_MTU 1430 98#define WLAN_MTU 1430
99 99
100 100
101/**
102 * Which network scope do we belong to?
103 */
104#if BUILD_WLAN
105static const enum GNUNET_ATS_Network_Type scope = GNUNET_ATS_NET_WLAN;
106#else
107static const enum GNUNET_ATS_Network_Type scope = GNUNET_ATS_NET_BT;
108#endif
109
101 110
102/** 111/**
103 * Maximum number of messages in defragmentation queue per MAC 112 * Maximum number of messages in defragmentation queue per MAC
@@ -1428,19 +1437,12 @@ process_data (void *cls,
1428 struct Plugin *plugin = cls; 1437 struct Plugin *plugin = cls;
1429 struct GNUNET_HELLO_Address *address; 1438 struct GNUNET_HELLO_Address *address;
1430 struct MacAndSession *mas = client; 1439 struct MacAndSession *mas = client;
1431 struct GNUNET_ATS_Information ats;
1432 struct FragmentMessage *fm; 1440 struct FragmentMessage *fm;
1433 struct GNUNET_PeerIdentity tmpsource; 1441 struct GNUNET_PeerIdentity tmpsource;
1434 const struct WlanHeader *wlanheader; 1442 const struct WlanHeader *wlanheader;
1435 int ret; 1443 int ret;
1436 uint16_t msize; 1444 uint16_t msize;
1437 1445
1438 ats.type = htonl (GNUNET_ATS_NETWORK_TYPE);
1439#if BUILD_WLAN
1440 ats.value = htonl (GNUNET_ATS_NET_WLAN);
1441#else
1442 ats.value = htonl (GNUNET_ATS_NET_BT);
1443#endif
1444 msize = ntohs (hdr->size); 1446 msize = ntohs (hdr->size);
1445 1447
1446 GNUNET_STATISTICS_update (plugin->env->stats, 1448 GNUNET_STATISTICS_update (plugin->env->stats,
@@ -1489,16 +1491,12 @@ process_data (void *cls,
1489 plugin->env->session_start (plugin->env->cls, 1491 plugin->env->session_start (plugin->env->cls,
1490 address, 1492 address,
1491 mas->session, 1493 mas->session,
1492 &ats, 1); 1494 scope);
1493 } 1495 }
1494 plugin->env->receive (plugin->env->cls, 1496 plugin->env->receive (plugin->env->cls,
1495 address, 1497 address,
1496 mas->session, 1498 mas->session,
1497 hdr); 1499 hdr);
1498 plugin->env->update_address_metrics (plugin->env->cls,
1499 address,
1500 mas->session,
1501 &ats, 1);
1502 GNUNET_HELLO_address_free (address); 1500 GNUNET_HELLO_address_free (address);
1503 break; 1501 break;
1504 case GNUNET_MESSAGE_TYPE_FRAGMENT: 1502 case GNUNET_MESSAGE_TYPE_FRAGMENT:
@@ -1615,7 +1613,7 @@ process_data (void *cls,
1615 plugin->env->session_start (plugin->env->cls, 1613 plugin->env->session_start (plugin->env->cls,
1616 address, 1614 address,
1617 mas->session, 1615 mas->session,
1618 NULL, 0); 1616 scope);
1619 LOG (GNUNET_ERROR_TYPE_DEBUG, 1617 LOG (GNUNET_ERROR_TYPE_DEBUG,
1620 "Notifying transport about peer `%s''s new session %p \n", 1618 "Notifying transport about peer `%s''s new session %p \n",
1621 GNUNET_i2s (&wlanheader->sender), 1619 GNUNET_i2s (&wlanheader->sender),
@@ -1654,10 +1652,6 @@ process_data (void *cls,
1654 mas->session->address, 1652 mas->session->address,
1655 mas->session, 1653 mas->session,
1656 hdr); 1654 hdr);
1657 plugin->env->update_address_metrics (plugin->env->cls,
1658 mas->session->address,
1659 mas->session,
1660 &ats, 1);
1661 break; 1655 break;
1662 } 1656 }
1663 return GNUNET_OK; 1657 return GNUNET_OK;
diff --git a/src/transport/test_plugin_transport.c b/src/transport/test_plugin_transport.c
index 1bd0a2dcd..df7c7b23f 100644
--- a/src/transport/test_plugin_transport.c
+++ b/src/transport/test_plugin_transport.c
@@ -522,11 +522,9 @@ env_session_end (void *cls,
522 522
523 523
524static void 524static void
525env_update_metrics (void *cls, 525env_update_distance (void *cls,
526 const struct GNUNET_HELLO_Address *address, 526 const struct GNUNET_HELLO_Address *address,
527 struct Session *session, 527 uint32_t distance)
528 const struct GNUNET_ATS_Information *ats,
529 uint32_t ats_count)
530{ 528{
531} 529}
532 530
@@ -542,7 +540,7 @@ setup_plugin_environment ()
542 env.receive = &env_receive; 540 env.receive = &env_receive;
543 env.notify_address = &env_notify_address; 541 env.notify_address = &env_notify_address;
544 env.get_address_type = &env_get_address_type; 542 env.get_address_type = &env_get_address_type;
545 env.update_address_metrics = &env_update_metrics; 543 env.update_address_distance = &env_update_distance;
546 env.get_our_hello = &env_get_our_hello; 544 env.get_our_hello = &env_get_our_hello;
547 env.session_end = &env_session_end; 545 env.session_end = &env_session_end;
548} 546}
diff --git a/src/transport/test_transport_api_manipulation_recv_tcp.c b/src/transport/test_transport_api_manipulation_recv_tcp.c
index 7aaa9caee..ffb725efd 100644
--- a/src/transport/test_transport_api_manipulation_recv_tcp.c
+++ b/src/transport/test_transport_api_manipulation_recv_tcp.c
@@ -197,21 +197,25 @@ notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
197 197
198 if (messages_recv <= 1) 198 if (messages_recv <= 1)
199 { 199 {
200 /* Received non-delayed message */ 200 /* Received non-delayed message */
201 dur_normal = GNUNET_TIME_absolute_get_duration(start_normal); 201 dur_normal = GNUNET_TIME_absolute_get_duration(start_normal);
202 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 202 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
203 "Received non-delayed message %u after %s\n", 203 "Received non-delayed message %u after %s\n",
204 messages_recv, 204 messages_recv,
205 GNUNET_STRINGS_relative_time_to_string (dur_normal, 205 GNUNET_STRINGS_relative_time_to_string (dur_normal,
206 GNUNET_YES)); 206 GNUNET_YES));
207 207
208 struct GNUNET_ATS_Information ats[2]; 208 struct GNUNET_ATS_Properties prop;
209 ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); 209 struct GNUNET_TIME_Relative delay;
210 ats[0].value = htonl (1000 * 1000LL); 210
211 ats[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); 211 delay.rel_value_us = 1000 * 1000LL;
212 ats[1].value = htonl (10); 212 memset (&prop, 0, sizeof (prop));
213 213 prop.distance = 10;
214 GNUNET_TRANSPORT_set_traffic_metric (p1->th, &p2->id, GNUNET_YES, GNUNET_NO, ats, 2); 214 GNUNET_TRANSPORT_set_traffic_metric (p1->th,
215 &p2->id,
216 &prop,
217 delay,
218 GNUNET_TIME_UNIT_ZERO);
215 send_task = GNUNET_SCHEDULER_add_now (&sendtask, NULL); 219 send_task = GNUNET_SCHEDULER_add_now (&sendtask, NULL);
216 } 220 }
217 if (2 == messages_recv) 221 if (2 == messages_recv)
diff --git a/src/transport/test_transport_api_manipulation_send_tcp.c b/src/transport/test_transport_api_manipulation_send_tcp.c
index 90d0ef994..3043dc037 100644
--- a/src/transport/test_transport_api_manipulation_send_tcp.c
+++ b/src/transport/test_transport_api_manipulation_send_tcp.c
@@ -272,35 +272,46 @@ notify_ready (void *cls, size_t size, void *buf)
272 272
273 273
274static void 274static void
275sendtask (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 275sendtask (void *cls,
276 const struct GNUNET_SCHEDULER_TaskContext *tc)
276{ 277{
277 struct GNUNET_ATS_Information ats[1]; 278 struct GNUNET_TIME_Relative delay;
278 send_task = NULL; 279 struct GNUNET_ATS_Properties prop;
279 280
281 send_task = NULL;
280 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 282 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
281 return; 283 return;
282 char *receiver_s = GNUNET_strdup (GNUNET_i2s (&p1->id)); 284 char *receiver_s = GNUNET_strdup (GNUNET_i2s (&p1->id));
283 285
284 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 286 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
285 "Sending message from peer %u (`%4s') -> peer %u (`%s') !\n", 287 "Sending message from peer %u (`%4s') -> peer %u (`%s') !\n",
286 p2->no, GNUNET_i2s (&p2->id), p1->no, receiver_s); 288 p2->no,
289 GNUNET_i2s (&p2->id),
290 p1->no,
291 receiver_s);
287 GNUNET_free (receiver_s); 292 GNUNET_free (receiver_s);
288 293
289 294
290 if (0 == messages_recv) 295 if (0 == messages_recv)
291 { 296 {
292 start_normal = GNUNET_TIME_absolute_get(); 297 start_normal = GNUNET_TIME_absolute_get ();
293 } 298 }
294 if (1 == messages_recv) 299 if (1 == messages_recv)
295 { 300 {
296 ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); 301 memset (&prop, 0, sizeof (prop));
297 ats[0].value = htonl (1000LL * 1000LL); 302 delay.rel_value_us = 1000LL * 1000LL;
298 GNUNET_TRANSPORT_set_traffic_metric (p2->th, &p1->id, GNUNET_NO, GNUNET_YES, ats, 1); 303 GNUNET_TRANSPORT_set_traffic_metric (p2->th,
299 ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); 304 &p1->id,
300 ats[0].value = htonl (10); 305 &prop,
301 GNUNET_TRANSPORT_set_traffic_metric (p1->th, &p2->id, GNUNET_YES, GNUNET_YES, ats, 1); 306 GNUNET_TIME_UNIT_ZERO,
302 307 delay);
303 start_delayed = GNUNET_TIME_absolute_get(); 308 prop.distance = 10;
309 GNUNET_TRANSPORT_set_traffic_metric (p1->th,
310 &p2->id,
311 &prop,
312 delay,
313 delay);
314 start_delayed = GNUNET_TIME_absolute_get();
304 } 315 }
305 316
306 s_sending = GNUNET_YES; 317 s_sending = GNUNET_YES;
@@ -358,7 +369,8 @@ testing_connect_cb (struct PeerContext *p1, struct PeerContext *p2, void *cls)
358 cc = NULL; 369 cc = NULL;
359 char *p1_c = GNUNET_strdup (GNUNET_i2s (&p1->id)); 370 char *p1_c = GNUNET_strdup (GNUNET_i2s (&p1->id));
360 371
361 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peers connected: %u (%s) <-> %u (%s)\n", 372 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
373 "Peers connected: %u (%s) <-> %u (%s)\n",
362 p1->no, p1_c, p2->no, GNUNET_i2s (&p2->id)); 374 p1->no, p1_c, p2->no, GNUNET_i2s (&p2->id));
363 GNUNET_free (p1_c); 375 GNUNET_free (p1_c);
364 376
@@ -386,16 +398,8 @@ start_cb (struct PeerContext *p, void *cls)
386 "Test tries to connect peer %u (`%s') -> peer %u (`%s')\n", 398 "Test tries to connect peer %u (`%s') -> peer %u (`%s')\n",
387 p1->no, sender_c, p2->no, GNUNET_i2s (&p2->id)); 399 p1->no, sender_c, p2->no, GNUNET_i2s (&p2->id));
388 GNUNET_free (sender_c); 400 GNUNET_free (sender_c);
389 /* 401 cc = GNUNET_TRANSPORT_TESTING_connect_peers (tth, p1, p2,
390 struct GNUNET_ATS_Information ats[2]; 402 &testing_connect_cb,
391 ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY);
392 ats[0].value = htonl (1000);
393 ats[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
394 ats[1].value = htonl (10);
395
396 GNUNET_TRANSPORT_set_traffic_metric (p1->th, &p2->id, TM_RECEIVE, ats, 2);
397*/
398 cc = GNUNET_TRANSPORT_TESTING_connect_peers (tth, p1, p2, &testing_connect_cb,
399 NULL); 403 NULL);
400 404
401} 405}
@@ -485,4 +489,4 @@ main (int argc, char *argv[])
485 return ret; 489 return ret;
486} 490}
487 491
488/* end of test_transport_api.c */ 492/* end of test_transport_api_manipulation_send_tcp.c */
diff --git a/src/transport/transport.h b/src/transport/transport.h
index 9ee672d3a..15cf936f7 100644
--- a/src/transport/transport.h
+++ b/src/transport/transport.h
@@ -468,7 +468,7 @@ struct ValidationMonitorMessage
468 /** 468 /**
469 * One shot call or continous replies? 469 * One shot call or continous replies?
470 */ 470 */
471 uint32_t one_shot; 471 uint32_t one_shot GNUNET_PACKED;
472 472
473 /** 473 /**
474 * The identity of the peer to look up. 474 * The identity of the peer to look up.
@@ -492,7 +492,7 @@ struct PeerMonitorMessage
492 /** 492 /**
493 * One shot call or continous replies? 493 * One shot call or continous replies?
494 */ 494 */
495 uint32_t one_shot; 495 uint32_t one_shot GNUNET_PACKED;
496 496
497 /** 497 /**
498 * The identity of the peer to look up. 498 * The identity of the peer to look up.
@@ -514,19 +514,29 @@ struct TrafficMetricMessage
514 struct GNUNET_MessageHeader header; 514 struct GNUNET_MessageHeader header;
515 515
516 /** 516 /**
517 * SEND, RECEIVE or BOTH? 517 * Always zero.
518 */ 518 */
519 uint16_t direction; 519 uint32_t reserved GNUNET_PACKED;
520 520
521 /** 521 /**
522 * Traffic metrics count 522 * The identity of the peer to look up.
523 */ 523 */
524 uint16_t ats_count; 524 struct GNUNET_PeerIdentity peer;
525 525
526 /** 526 /**
527 * The identity of the peer to look up. 527 * Fake properties to generate.
528 */ 528 */
529 struct GNUNET_PeerIdentity peer; 529 struct GNUNET_ATS_PropertiesNBO properties;
530
531 /**
532 * Fake delay to add on inbound traffic.
533 */
534 struct GNUNET_TIME_RelativeNBO delay_in;
535
536 /**
537 * Fake delay to add on outbound traffic.
538 */
539 struct GNUNET_TIME_RelativeNBO delay_out;
530}; 540};
531 541
532 542
diff --git a/src/transport/transport_api.c b/src/transport/transport_api.c
index d672b4d46..6e47b269b 100644
--- a/src/transport/transport_api.c
+++ b/src/transport/transport_api.c
@@ -1054,7 +1054,8 @@ schedule_transmission (struct GNUNET_TRANSPORT_Handle *h)
1054 * @return a `struct GNUNET_TRANSPORT_TransmitHandle` 1054 * @return a `struct GNUNET_TRANSPORT_TransmitHandle`
1055 */ 1055 */
1056static struct GNUNET_TRANSPORT_TransmitHandle * 1056static struct GNUNET_TRANSPORT_TransmitHandle *
1057schedule_control_transmit (struct GNUNET_TRANSPORT_Handle *h, size_t size, 1057schedule_control_transmit (struct GNUNET_TRANSPORT_Handle *h,
1058 size_t size,
1058 GNUNET_TRANSPORT_TransmitReadyNotify notify, 1059 GNUNET_TRANSPORT_TransmitReadyNotify notify,
1059 void *notify_cls) 1060 void *notify_cls)
1060{ 1061{
@@ -1476,7 +1477,9 @@ send_hello (void *cls, size_t size, void *buf)
1476 * @return number of bytes copied to @a buf 1477 * @return number of bytes copied to @a buf
1477 */ 1478 */
1478static size_t 1479static size_t
1479send_metric (void *cls, size_t size, void *buf) 1480send_metric (void *cls,
1481 size_t size,
1482 void *buf)
1480{ 1483{
1481 struct TrafficMetricMessage *msg = cls; 1484 struct TrafficMetricMessage *msg = cls;
1482 uint16_t ssize; 1485 uint16_t ssize;
@@ -1484,14 +1487,12 @@ send_metric (void *cls, size_t size, void *buf)
1484 if (NULL == buf) 1487 if (NULL == buf)
1485 { 1488 {
1486 LOG (GNUNET_ERROR_TYPE_DEBUG, 1489 LOG (GNUNET_ERROR_TYPE_DEBUG,
1487 "Timeout while trying to transmit `%s' request.\n", 1490 "Timeout while trying to transmit TRAFFIC_METRIC request.\n");
1488 "TRAFFIC_METRIC");
1489 GNUNET_free (msg); 1491 GNUNET_free (msg);
1490 return 0; 1492 return 0;
1491 } 1493 }
1492 LOG (GNUNET_ERROR_TYPE_DEBUG, 1494 LOG (GNUNET_ERROR_TYPE_DEBUG,
1493 "Transmitting `%s' request.\n", 1495 "Transmitting TRAFFIC_METRIC request.\n");
1494 "TRAFFIC_METRIC");
1495 ssize = ntohs (msg->header.size); 1496 ssize = ntohs (msg->header.size);
1496 GNUNET_assert (size >= ssize); 1497 GNUNET_assert (size >= ssize);
1497 memcpy (buf, msg, ssize); 1498 memcpy (buf, msg, ssize);
@@ -1505,56 +1506,35 @@ send_metric (void *cls, size_t size, void *buf)
1505 * 1506 *
1506 * @param handle transport handle 1507 * @param handle transport handle
1507 * @param peer the peer to set the metric for 1508 * @param peer the peer to set the metric for
1508 * @param inbound set inbound direction (#GNUNET_YES or #GNUNET_NO) 1509 * @param prop the performance metrics to set
1509 * @param outbound set outbound direction (#GNUNET_YES or #GNUNET_NO) 1510 * @param delay_in inbound delay to introduce
1510 * @param ats the metric as ATS information 1511 * @param delay_out outbound delay to introduce
1511 * @param ats_count the number of metrics
1512 * 1512 *
1513 * Supported ATS values: 1513 * Note: Delay restrictions in receiving direction will be enforced
1514 * #GNUNET_ATS_QUALITY_NET_DELAY (value in ms) 1514 * with one message delay.
1515 * #GNUNET_ATS_QUALITY_NET_DISTANCE (value in count(hops))
1516 *
1517 * Example:
1518 * To enforce a delay of 10 ms for peer p1 in sending direction use:
1519 * <code>
1520 * struct GNUNET_ATS_Information ats;
1521 * ats.type = ntohl (GNUNET_ATS_QUALITY_NET_DELAY);
1522 * ats.value = ntohl (10);
1523 * GNUNET_TRANSPORT_set_traffic_metric (th, p1, TM_SEND, &ats, 1);
1524 * </code>
1525 * Note:
1526 * Delay restrictions in receiving direction will be enforced with
1527 * 1 message delay.
1528 */ 1515 */
1529void 1516void
1530GNUNET_TRANSPORT_set_traffic_metric (struct GNUNET_TRANSPORT_Handle *handle, 1517GNUNET_TRANSPORT_set_traffic_metric (struct GNUNET_TRANSPORT_Handle *handle,
1531 const struct GNUNET_PeerIdentity *peer, 1518 const struct GNUNET_PeerIdentity *peer,
1532 int inbound, 1519 const struct GNUNET_ATS_Properties *prop,
1533 int outbound, 1520 struct GNUNET_TIME_Relative delay_in,
1534 const struct GNUNET_ATS_Information *ats, 1521 struct GNUNET_TIME_Relative delay_out)
1535 size_t ats_count)
1536{ 1522{
1537 struct TrafficMetricMessage *msg; 1523 struct TrafficMetricMessage *msg;
1538 1524
1539 GNUNET_assert ((outbound == GNUNET_YES) || (outbound == GNUNET_NO)); 1525 msg = GNUNET_new (struct TrafficMetricMessage);
1540 GNUNET_assert ((inbound == GNUNET_YES) || (inbound == GNUNET_NO)); 1526 msg->header.size = htons (sizeof (struct TrafficMetricMessage));
1541 if ((GNUNET_NO == inbound) && (GNUNET_NO == outbound))
1542 return;
1543 if (0 == ats_count)
1544 return;
1545
1546 size_t len = sizeof (struct TrafficMetricMessage) +
1547 ats_count * sizeof (struct GNUNET_ATS_Information);
1548
1549 msg = GNUNET_malloc (len);
1550 msg->header.size = htons (len);
1551 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TRAFFIC_METRIC); 1527 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TRAFFIC_METRIC);
1552 msg->direction = htons (0 + outbound + 2 * inbound); 1528 msg->reserved = htonl (0);
1553 msg->ats_count = htons (ats_count); 1529 msg->peer = *peer;
1554 msg->peer = (*peer); 1530 GNUNET_ATS_properties_hton (&msg->properties,
1555 memcpy (&msg[1], ats, ats_count * sizeof (struct GNUNET_ATS_Information)); 1531 prop);
1556 schedule_control_transmit (handle, len, 1532 msg->delay_in = GNUNET_TIME_relative_hton (delay_in);
1557 &send_metric, msg); 1533 msg->delay_out = GNUNET_TIME_relative_hton (delay_out);
1534 schedule_control_transmit (handle,
1535 sizeof (struct TrafficMetricMessage),
1536 &send_metric,
1537 msg);
1558} 1538}
1559 1539
1560 1540