aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-02-10 23:24:01 +0000
committerChristian Grothoff <christian@grothoff.org>2015-02-10 23:24:01 +0000
commit1c323bd4cbb388a9e7515a1f733a3062bf093aee (patch)
tree7cc525d79149d44840b9f7a0040aaf3e69ecd665
parentaedaaed687db1ff20b447378f01ad7306921450c (diff)
downloadgnunet-1c323bd4cbb388a9e7515a1f733a3062bf093aee.tar.gz
gnunet-1c323bd4cbb388a9e7515a1f733a3062bf093aee.zip
fixing #3657 (replace ATS_Information with struct), but WIHTOUT fixing ATS testcases yet
-rw-r--r--src/Makefile.am3
-rw-r--r--src/ats-tests/ats-testing-preferences.c6
-rw-r--r--src/ats-tests/ats-testing.h6
-rw-r--r--src/ats-tool/gnunet-ats.c141
-rw-r--r--src/ats/Makefile.am34
-rw-r--r--src/ats/ats.h54
-rw-r--r--src/ats/ats_api_performance.c58
-rw-r--r--src/ats/ats_api_scanner.c52
-rw-r--r--src/ats/ats_api_scheduling.c77
-rw-r--r--src/ats/gnunet-ats-solver-eval.c40
-rw-r--r--src/ats/gnunet-ats-solver-eval.h6
-rw-r--r--src/ats/gnunet-service-ats.c3
-rw-r--r--src/ats/gnunet-service-ats_addresses.c465
-rw-r--r--src/ats/gnunet-service-ats_addresses.h43
-rw-r--r--src/ats/gnunet-service-ats_normalization.c299
-rw-r--r--src/ats/gnunet-service-ats_normalization.h8
-rw-r--r--src/ats/gnunet-service-ats_performance.c39
-rw-r--r--src/ats/gnunet-service-ats_performance.h6
-rw-r--r--src/ats/gnunet-service-ats_plugins.c24
-rw-r--r--src/ats/gnunet-service-ats_plugins.h11
-rw-r--r--src/ats/gnunet-service-ats_preferences.c20
-rw-r--r--src/ats/gnunet-service-ats_scheduling.c53
-rw-r--r--src/ats/plugin_ats_mlp.c230
-rw-r--r--src/ats/plugin_ats_proportional.c45
-rw-r--r--src/ats/plugin_ats_ril.c50
-rw-r--r--src/ats/test_ats_api_common.h7
-rw-r--r--src/dv/gnunet-service-dv.c52
-rw-r--r--src/dv/plugin_transport_dv.c59
-rw-r--r--src/fs/gnunet-service-fs.c36
-rw-r--r--src/fs/gnunet-service-fs_cp.c9
-rw-r--r--src/fs/gnunet-service-fs_cp.h5
-rw-r--r--src/include/gnunet_ats_plugin.h14
-rw-r--r--src/include/gnunet_ats_service.h205
-rw-r--r--src/include/gnunet_transport_plugin.h28
-rw-r--r--src/include/gnunet_transport_service.h31
-rw-r--r--src/testbed/gnunet-daemon-latency-logger.c22
-rw-r--r--src/testbed/gnunet-daemon-testbed-underlay.c18
-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
59 files changed, 1363 insertions, 2414 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 83648ded2..cdfd5f307 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -67,7 +67,6 @@ SUBDIRS = \
67 peerinfo-tool \ 67 peerinfo-tool \
68 core \ 68 core \
69 $(TESTBED) \ 69 $(TESTBED) \
70 ats-tests \
71 nse \ 70 nse \
72 dht \ 71 dht \
73 hostlist \ 72 hostlist \
@@ -91,3 +90,5 @@ SUBDIRS = \
91 pt \ 90 pt \
92 integration-tests \ 91 integration-tests \
93 $(EXP_DIR) 92 $(EXP_DIR)
93
94# ats-tests
diff --git a/src/ats-tests/ats-testing-preferences.c b/src/ats-tests/ats-testing-preferences.c
index 99dbdb0f9..e5f32d6b1 100644
--- a/src/ats-tests/ats-testing-preferences.c
+++ b/src/ats-tests/ats-testing-preferences.c
@@ -106,7 +106,10 @@ set_pref_task (void *cls,
106 GNUNET_ATS_print_preference_type (p->pg->kind), pref_value); 106 GNUNET_ATS_print_preference_type (p->pg->kind), pref_value);
107 107
108 GNUNET_ATS_performance_change_preference(p->me->ats_perf_handle, 108 GNUNET_ATS_performance_change_preference(p->me->ats_perf_handle,
109 &p->dest->id, p->pg->kind, pref_value, GNUNET_ATS_PREFERENCE_END); 109 &p->dest->id,
110 p->pg->kind,
111 pref_value,
112 GNUNET_ATS_PREFERENCE_END);
110 113
111 switch (p->pg->kind) { 114 switch (p->pg->kind) {
112 case GNUNET_ATS_PREFERENCE_BANDWIDTH: 115 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
@@ -241,4 +244,3 @@ GNUNET_ATS_TEST_generate_preferences_stop_all ()
241} 244}
242 245
243/* end of file ats-testing-preferences.c */ 246/* end of file ats-testing-preferences.c */
244
diff --git a/src/ats-tests/ats-testing.h b/src/ats-tests/ats-testing.h
index 7b1633c28..a2e61c0d6 100644
--- a/src/ats-tests/ats-testing.h
+++ b/src/ats-tests/ats-testing.h
@@ -84,8 +84,7 @@ typedef void (*GNUNET_ATS_TEST_TopologySetupDoneCallback) (void *cls,
84 * @param address_active is address active 84 * @param address_active is address active
85 * @param bandwidth_out bandwidth outbound 85 * @param bandwidth_out bandwidth outbound
86 * @param bandwidth_in bandwidth inbound 86 * @param bandwidth_in bandwidth inbound
87 * @param ats ats information 87 * @param prop performance information
88 * @param ats_count number of ats inforation
89 */ 88 */
90typedef void 89typedef void
91(*GNUNET_ATS_TEST_LogRequest) (void *cls, 90(*GNUNET_ATS_TEST_LogRequest) (void *cls,
@@ -93,8 +92,7 @@ typedef void
93 int address_active, 92 int address_active,
94 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 93 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
95 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 94 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
96 const struct GNUNET_ATS_Information *ats, 95 const struct GNUNET_ATS_Properties *prop);
97 uint32_t ats_count);
98 96
99/** 97/**
100 * Information we track for a peer in the testbed. 98 * Information we track for a peer in the testbed.
diff --git a/src/ats-tool/gnunet-ats.c b/src/ats-tool/gnunet-ats.c
index 612eb20ff..2d19df737 100644
--- a/src/ats-tool/gnunet-ats.c
+++ b/src/ats-tool/gnunet-ats.c
@@ -84,8 +84,6 @@ static char *opt_type_str;
84 */ 84 */
85static unsigned int opt_pref_value; 85static unsigned int opt_pref_value;
86 86
87
88
89/** 87/**
90 * Final status code. 88 * Final status code.
91 */ 89 */
@@ -124,7 +122,7 @@ static struct GNUNET_CONFIGURATION_Handle *cfg;
124/** 122/**
125 * Shutdown task 123 * Shutdown task
126 */ 124 */
127static struct GNUNET_SCHEDULER_Task * shutdown_task; 125static struct GNUNET_SCHEDULER_Task *shutdown_task;
128 126
129/** 127/**
130 * Hashmap to store addresses 128 * Hashmap to store addresses
@@ -161,14 +159,9 @@ struct PendingResolutions
161 struct GNUNET_TRANSPORT_AddressToStringContext *tats_ctx; 159 struct GNUNET_TRANSPORT_AddressToStringContext *tats_ctx;
162 160
163 /** 161 /**
164 * Array of performance data. 162 * Performance data.
165 */ 163 */
166 struct GNUNET_ATS_Information *ats; 164 struct GNUNET_ATS_Properties properties;
167
168 /**
169 * Length of the @e ats array.
170 */
171 uint32_t ats_count;
172 165
173 /** 166 /**
174 * Amount of outbound bandwidth assigned by ATS. 167 * Amount of outbound bandwidth assigned by ATS.
@@ -325,20 +318,15 @@ transport_addr_to_str_cb (void *cls,
325 int res) 318 int res)
326{ 319{
327 struct PendingResolutions *pr = cls; 320 struct PendingResolutions *pr = cls;
328 char *ats_str;
329 char *ats_tmp;
330 char *ats_prop_value;
331 unsigned int c;
332 uint32_t ats_type;
333 uint32_t ats_value;
334 uint32_t network;
335 321
336 if (NULL == address) 322 if (NULL == address)
337 { 323 {
338 /* We're done */ 324 /* We're done */
339 GNUNET_CONTAINER_DLL_remove(head, tail, pr); 325 GNUNET_CONTAINER_DLL_remove (head,
340 GNUNET_free(pr->address); 326 tail,
341 GNUNET_free(pr); 327 pr);
328 GNUNET_free (pr->address);
329 GNUNET_free (pr);
342 stat_pending--; 330 stat_pending--;
343 331
344 if ((GNUNET_YES == stat_receive_done) && (0 == stat_pending)) 332 if ((GNUNET_YES == stat_receive_done) && (0 == stat_pending))
@@ -374,64 +362,15 @@ transport_addr_to_str_cb (void *cls,
374 return; 362 return;
375 } 363 }
376 364
377 ats_str = GNUNET_strdup (pr->active ? _("active ") : _("inactive "));
378 network = GNUNET_ATS_NET_UNSPECIFIED;
379 for (c = 0; c < pr->ats_count; c++)
380 {
381 ats_tmp = ats_str;
382
383 ats_type = ntohl (pr->ats[c].type);
384 ats_value = ntohl (pr->ats[c].value);
385
386 if (ats_type > GNUNET_ATS_PropertyCount)
387 {
388 FPRINTF (stderr,
389 "Invalid ATS property type %u %u for address %s\n",
390 ats_type,
391 pr->ats[c].type,
392 address);
393 continue;
394 }
395
396 switch (ats_type)
397 {
398 case GNUNET_ATS_NETWORK_TYPE:
399 if (ats_value > GNUNET_ATS_NetworkTypeCount)
400 {
401 GNUNET_break(0);
402 continue;
403 }
404 network = ats_value;
405 GNUNET_asprintf (&ats_prop_value,
406 "%s",
407 GNUNET_ATS_print_network_type (ats_value));
408 break;
409 default:
410 GNUNET_asprintf (&ats_prop_value, "%u", ats_value);
411 break;
412 }
413 if ((opt_verbose) && (ats_type < GNUNET_ATS_PropertyCount))
414 {
415 GNUNET_asprintf (&ats_str,
416 "%s%s=%s, ",
417 ats_tmp,
418 GNUNET_ATS_print_property_type (ats_type),
419 ats_prop_value);
420 GNUNET_free(ats_tmp);
421 }
422 GNUNET_free(ats_prop_value);
423 }
424
425 FPRINTF (stderr, 365 FPRINTF (stderr,
426 _("Peer `%s' plugin `%s', address `%s', `%s' bw out: %u Bytes/s, bw in %u Bytes/s, %s\n"), 366 _("Peer `%s' plugin `%s', address `%s', `%s' bw out: %u Bytes/s, bw in %u Bytes/s, %s\n"),
427 GNUNET_i2s (&pr->address->peer), 367 GNUNET_i2s (&pr->address->peer),
428 pr->address->transport_name, 368 pr->address->transport_name,
429 address, 369 address,
430 GNUNET_ATS_print_network_type (network), 370 GNUNET_ATS_print_network_type (pr->properties.scope),
431 ntohl (pr->bandwidth_out.value__), 371 ntohl (pr->bandwidth_out.value__),
432 ntohl (pr->bandwidth_in.value__), 372 ntohl (pr->bandwidth_in.value__),
433 ats_str); 373 pr->active ? _("active ") : _("inactive "));
434 GNUNET_free (ats_str);
435} 374}
436 375
437 376
@@ -489,8 +428,7 @@ find_address_it (void *cls,
489 * #GNUNET_SYSERR if this address is no longer available for ATS 428 * #GNUNET_SYSERR if this address is no longer available for ATS
490 * @param bandwidth_out assigned outbound bandwidth for the connection 429 * @param bandwidth_out assigned outbound bandwidth for the connection
491 * @param bandwidth_in assigned inbound bandwidth for the connection 430 * @param bandwidth_in assigned inbound bandwidth for the connection
492 * @param ats performance data for the address (as far as known) 431 * @param prop performance data for the address (as far as known)
493 * @param ats_count number of performance records in @a ats
494 */ 432 */
495static void 433static void
496ats_perf_mon_cb (void *cls, 434ats_perf_mon_cb (void *cls,
@@ -498,8 +436,7 @@ ats_perf_mon_cb (void *cls,
498 int active, 436 int active,
499 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 437 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
500 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 438 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
501 const struct GNUNET_ATS_Information *ats, 439 const struct GNUNET_ATS_Properties *prop)
502 uint32_t ats_count)
503{ 440{
504 struct PendingResolutions *pr; 441 struct PendingResolutions *pr;
505 struct PendingResolutions *cur; 442 struct PendingResolutions *cur;
@@ -517,7 +454,6 @@ ats_perf_mon_cb (void *cls,
517 GNUNET_HELLO_address_free (cur->address); 454 GNUNET_HELLO_address_free (cur->address);
518 GNUNET_free (cur); 455 GNUNET_free (cur);
519 } 456 }
520
521 GNUNET_CONTAINER_multipeermap_iterate (addresses, 457 GNUNET_CONTAINER_multipeermap_iterate (addresses,
522 &free_addr_it, 458 &free_addr_it,
523 NULL); 459 NULL);
@@ -530,15 +466,19 @@ ats_perf_mon_cb (void *cls,
530 466
531 actx.src = address; 467 actx.src = address;
532 actx.res = NULL; 468 actx.res = NULL;
533 GNUNET_CONTAINER_multipeermap_get_multiple (addresses, &address->peer, 469 GNUNET_CONTAINER_multipeermap_get_multiple (addresses,
534 &find_address_it, &actx); 470 &address->peer,
471 &find_address_it,
472 &actx);
535 if (NULL == actx.res) 473 if (NULL == actx.res)
536 { 474 {
537 GNUNET_break (0); 475 GNUNET_break (0);
538 return; 476 return;
539 } 477 }
540 GNUNET_break( 478 GNUNET_break(GNUNET_OK ==
541 GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (addresses, &address->peer, actx.res)); 479 GNUNET_CONTAINER_multipeermap_remove (addresses,
480 &address->peer,
481 actx.res));
542 FPRINTF (stderr, 482 FPRINTF (stderr,
543 _("Removed address of peer `%s' with plugin `%s'\n"), 483 _("Removed address of peer `%s' with plugin `%s'\n"),
544 GNUNET_i2s (&address->peer), 484 GNUNET_i2s (&address->peer),
@@ -554,8 +494,10 @@ ats_perf_mon_cb (void *cls,
554 494
555 actx.src = address; 495 actx.src = address;
556 actx.res = NULL; 496 actx.res = NULL;
557 GNUNET_CONTAINER_multipeermap_get_multiple (addresses, &address->peer, 497 GNUNET_CONTAINER_multipeermap_get_multiple (addresses,
558 &find_address_it, &actx); 498 &address->peer,
499 &find_address_it,
500 &actx);
559 if ((NULL != actx.res)) 501 if ((NULL != actx.res))
560 { 502 {
561 if ((bandwidth_in.value__ == actx.res->bandwidth_in.value__) && 503 if ((bandwidth_in.value__ == actx.res->bandwidth_in.value__) &&
@@ -578,18 +520,15 @@ ats_perf_mon_cb (void *cls,
578 a->bandwidth_in = bandwidth_in; 520 a->bandwidth_in = bandwidth_in;
579 a->bandwidth_out = bandwidth_out; 521 a->bandwidth_out = bandwidth_out;
580 a->active = active; 522 a->active = active;
581 GNUNET_CONTAINER_multipeermap_put (addresses, &address->peer, a, 523 GNUNET_CONTAINER_multipeermap_put (addresses,
582 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 524 &address->peer,
525 a,
526 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
583 } 527 }
584 } 528 }
585 529
586 pr = GNUNET_malloc (sizeof (struct PendingResolutions) + 530 pr = GNUNET_new (struct PendingResolutions);
587 ats_count * sizeof (struct GNUNET_ATS_Information)); 531 pr->properties = *prop;
588
589 pr->ats_count = ats_count;
590 pr->ats = (struct GNUNET_ATS_Information *) &pr[1];
591 if (ats_count > 0)
592 memcpy (pr->ats, ats, ats_count * sizeof(struct GNUNET_ATS_Information));
593 pr->address = GNUNET_HELLO_address_copy (address); 532 pr->address = GNUNET_HELLO_address_copy (address);
594 pr->bandwidth_in = bandwidth_in; 533 pr->bandwidth_in = bandwidth_in;
595 pr->bandwidth_out = bandwidth_out; 534 pr->bandwidth_out = bandwidth_out;
@@ -614,8 +553,7 @@ ats_perf_mon_cb (void *cls,
614 to a peer 553 to a peer
615 * @param bandwidth_out assigned outbound bandwidth for the connection 554 * @param bandwidth_out assigned outbound bandwidth for the connection
616 * @param bandwidth_in assigned inbound bandwidth for the connection 555 * @param bandwidth_in assigned inbound bandwidth for the connection
617 * @param ats performance data for the address (as far as known) 556 * @param prop performance data for the address (as far as known)
618 * @param ats_count number of performance records in @a ats
619 */ 557 */
620static void 558static void
621ats_perf_cb (void *cls, 559ats_perf_cb (void *cls,
@@ -623,8 +561,7 @@ ats_perf_cb (void *cls,
623 int active, 561 int active,
624 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 562 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
625 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 563 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
626 const struct GNUNET_ATS_Information *ats, 564 const struct GNUNET_ATS_Properties *prop)
627 uint32_t ats_count)
628{ 565{
629 struct PendingResolutions *pr; 566 struct PendingResolutions *pr;
630 567
@@ -643,13 +580,8 @@ ats_perf_cb (void *cls,
643 return; 580 return;
644 } 581 }
645 582
646 pr = GNUNET_malloc (sizeof (struct PendingResolutions) + 583 pr = GNUNET_new (struct PendingResolutions);
647 ats_count * sizeof (struct GNUNET_ATS_Information)); 584 pr->properties = *prop;
648
649 pr->ats_count = ats_count;
650 pr->ats = (struct GNUNET_ATS_Information *) &pr[1];
651 if (ats_count > 0)
652 memcpy (pr->ats, ats, ats_count * sizeof(struct GNUNET_ATS_Information));
653 pr->address = GNUNET_HELLO_address_copy (address); 585 pr->address = GNUNET_HELLO_address_copy (address);
654 pr->bandwidth_in = bandwidth_in; 586 pr->bandwidth_in = bandwidth_in;
655 pr->bandwidth_out = bandwidth_out; 587 pr->bandwidth_out = bandwidth_out;
@@ -921,7 +853,10 @@ testservice_ats (void *cls,
921 "%s", 853 "%s",
922 _("Cannot connect to ATS service, exiting...\n")); 854 _("Cannot connect to ATS service, exiting...\n"));
923 855
924 GNUNET_ATS_performance_change_preference (ph, &pid, type, (double) opt_pref_value, 856 GNUNET_ATS_performance_change_preference (ph,
857 &pid,
858 type,
859 (double) opt_pref_value,
925 GNUNET_ATS_PREFERENCE_END); 860 GNUNET_ATS_PREFERENCE_END);
926 861
927 shutdown_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, 862 shutdown_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am
index 4491b08a2..2a14ae73f 100644
--- a/src/ats/Makefile.am
+++ b/src/ats/Makefile.am
@@ -18,8 +18,8 @@ if USE_COVERAGE
18 AM_CFLAGS = -fprofile-arcs -ftest-coverage 18 AM_CFLAGS = -fprofile-arcs -ftest-coverage
19endif 19endif
20 20
21noinst_PROGRAMS = \ 21#noinst_PROGRAMS = \
22 gnunet-ats-solver-eval 22# gnunet-ats-solver-eval
23 23
24if HAVE_LIBGLPK 24if HAVE_LIBGLPK
25 GN_LIBGLPK = -lglpk 25 GN_LIBGLPK = -lglpk
@@ -42,21 +42,21 @@ plugin_LTLIBRARIES = \
42 $(GN_MLP_LIB) \ 42 $(GN_MLP_LIB) \
43 libgnunet_plugin_ats_ril.la 43 libgnunet_plugin_ats_ril.la
44 44
45gnunet_ats_solver_eval_SOURCES = \ 45#gnunet_ats_solver_eval_SOURCES = \
46 gnunet-ats-solver-eval.c gnunet-ats-solver-eval.h \ 46# gnunet-ats-solver-eval.c gnunet-ats-solver-eval.h \
47 gnunet-service-ats_addresses.c gnunet-service-ats_addresses.h \ 47# gnunet-service-ats_addresses.c gnunet-service-ats_addresses.h \
48 gnunet-service-ats_plugins.c gnunet-service-ats_plugins.h \ 48# gnunet-service-ats_plugins.c gnunet-service-ats_plugins.h \
49 gnunet-service-ats_connectivity.c gnunet-service-ats_connectivity.h \ 49# gnunet-service-ats_connectivity.c gnunet-service-ats_connectivity.h \
50 gnunet-service-ats_feedback.c gnunet-service-ats_feedback.h \ 50# gnunet-service-ats_feedback.c gnunet-service-ats_feedback.h \
51 gnunet-service-ats_performance.c gnunet-service-ats_performance.h \ 51# gnunet-service-ats_performance.c gnunet-service-ats_performance.h \
52 gnunet-service-ats_reservations.c gnunet-service-ats_reservations.h \ 52# gnunet-service-ats_reservations.c gnunet-service-ats_reservations.h \
53 gnunet-service-ats_scheduling.c gnunet-service-ats_scheduling.h \ 53# gnunet-service-ats_scheduling.c gnunet-service-ats_scheduling.h \
54 gnunet-service-ats_normalization.c 54# gnunet-service-ats_normalization.c
55gnunet_ats_solver_eval_LDADD = \ 55#gnunet_ats_solver_eval_LDADD = \
56 $(top_builddir)/src/util/libgnunetutil.la \ 56# $(top_builddir)/src/util/libgnunetutil.la \
57 libgnunetats.la \ 57# libgnunetats.la \
58 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 58# $(top_builddir)/src/statistics/libgnunetstatistics.la \
59 $(LTLIBINTL) 59# $(LTLIBINTL)
60 60
61libgnunetats_la_SOURCES = \ 61libgnunetats_la_SOURCES = \
62 ats_api_connectivity.c \ 62 ats_api_connectivity.c \
diff --git a/src/ats/ats.h b/src/ats/ats.h
index d5d5d6c3f..7e411fb98 100644
--- a/src/ats/ats.h
+++ b/src/ats/ats.h
@@ -27,6 +27,8 @@
27#define ATS_H 27#define ATS_H
28 28
29#include "gnunet_util_lib.h" 29#include "gnunet_util_lib.h"
30#include "gnunet_ats_service.h"
31
30 32
31/** 33/**
32 * Flag used to indicate which type of client is connecting 34 * Flag used to indicate which type of client is connecting
@@ -115,16 +117,6 @@ struct AddressAddMessage
115 struct GNUNET_MessageHeader header; 117 struct GNUNET_MessageHeader header;
116 118
117 /** 119 /**
118 * Length of the `struct GNUNET_ATS_Information` array that follows this struct.
119 */
120 uint32_t ats_count GNUNET_PACKED;
121
122 /**
123 * Identity of the peer that this address is for.
124 */
125 struct GNUNET_PeerIdentity peer;
126
127 /**
128 * Number of bytes in the address that follows this struct. 120 * Number of bytes in the address that follows this struct.
129 */ 121 */
130 uint16_t address_length GNUNET_PACKED; 122 uint16_t address_length GNUNET_PACKED;
@@ -135,6 +127,11 @@ struct AddressAddMessage
135 uint16_t plugin_name_length GNUNET_PACKED; 127 uint16_t plugin_name_length GNUNET_PACKED;
136 128
137 /** 129 /**
130 * Identity of the peer that this address is for.
131 */
132 struct GNUNET_PeerIdentity peer;
133
134 /**
138 * Internal number this client will henceforth use to 135 * Internal number this client will henceforth use to
139 * refer to this address. 136 * refer to this address.
140 */ 137 */
@@ -146,8 +143,12 @@ struct AddressAddMessage
146 */ 143 */
147 uint32_t address_local_info GNUNET_PACKED; 144 uint32_t address_local_info GNUNET_PACKED;
148 145
146 /**
147 * Performance properties of the address.
148 */
149 struct GNUNET_ATS_PropertiesNBO properties;
150
149 /* followed by: 151 /* followed by:
150 * - struct GNUNET_ATS_Information [ats_count];
151 * - char address[address_length] 152 * - char address[address_length]
152 * - char plugin_name[plugin_name_length] (including '\0'-termination). 153 * - char plugin_name[plugin_name_length] (including '\0'-termination).
153 */ 154 */
@@ -167,9 +168,9 @@ struct AddressUpdateMessage
167 struct GNUNET_MessageHeader header; 168 struct GNUNET_MessageHeader header;
168 169
169 /** 170 /**
170 * Length of the `struct GNUNET_ATS_Information` array that follows. 171 * Internal number this client uses to refer to this address.
171 */ 172 */
172 uint32_t ats_count GNUNET_PACKED; 173 uint32_t session_id GNUNET_PACKED;
173 174
174 /** 175 /**
175 * Which peer is this about? (Technically redundant, as the 176 * Which peer is this about? (Technically redundant, as the
@@ -179,13 +180,9 @@ struct AddressUpdateMessage
179 struct GNUNET_PeerIdentity peer; 180 struct GNUNET_PeerIdentity peer;
180 181
181 /** 182 /**
182 * Internal number this client uses to refer to this address. 183 * Performance properties of the address.
183 */
184 uint32_t session_id GNUNET_PACKED;
185
186 /* followed by:
187 * - struct GNUNET_ATS_Information [ats_count];
188 */ 184 */
185 struct GNUNET_ATS_PropertiesNBO properties;
189 186
190}; 187};
191 188
@@ -294,17 +291,12 @@ struct PeerInformationMessage
294 /** 291 /**
295 * 292 *
296 */ 293 */
297 uint32_t ats_count GNUNET_PACKED; 294 uint16_t address_length GNUNET_PACKED;
298
299 /**
300 *
301 */
302 uint32_t address_active GNUNET_PACKED;
303 295
304 /** 296 /**
305 * 297 *
306 */ 298 */
307 uint32_t id GNUNET_PACKED; 299 uint16_t plugin_name_length GNUNET_PACKED;
308 300
309 /** 301 /**
310 * 302 *
@@ -314,12 +306,12 @@ struct PeerInformationMessage
314 /** 306 /**
315 * 307 *
316 */ 308 */
317 uint16_t address_length GNUNET_PACKED; 309 uint32_t address_active GNUNET_PACKED;
318 310
319 /** 311 /**
320 * 312 *
321 */ 313 */
322 uint16_t plugin_name_length GNUNET_PACKED; 314 uint32_t id GNUNET_PACKED;
323 315
324 /** 316 /**
325 * 317 *
@@ -331,8 +323,12 @@ struct PeerInformationMessage
331 */ 323 */
332 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in; 324 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in;
333 325
326 /**
327 * Performance properties of the address.
328 */
329 struct GNUNET_ATS_PropertiesNBO properties;
330
334 /* followed by: 331 /* followed by:
335 * - struct GNUNET_ATS_Information [ats_count];
336 * - char address[address_length] 332 * - char address[address_length]
337 * - char plugin_name[plugin_name_length] (including '\0'-termination). 333 * - char plugin_name[plugin_name_length] (including '\0'-termination).
338 */ 334 */
diff --git a/src/ats/ats_api_performance.c b/src/ats/ats_api_performance.c
index 51980f079..aaaaee089 100644
--- a/src/ats/ats_api_performance.c
+++ b/src/ats/ats_api_performance.c
@@ -364,35 +364,27 @@ process_pi_message (struct GNUNET_ATS_PerformanceHandle *ph,
364 const struct GNUNET_MessageHeader *msg) 364 const struct GNUNET_MessageHeader *msg)
365{ 365{
366 const struct PeerInformationMessage *pi; 366 const struct PeerInformationMessage *pi;
367 const struct GNUNET_ATS_Information *atsi;
368 const char *plugin_address; 367 const char *plugin_address;
369 const char *plugin_name; 368 const char *plugin_name;
370 struct GNUNET_HELLO_Address address; 369 struct GNUNET_HELLO_Address address;
371 uint16_t plugin_address_length; 370 uint16_t plugin_address_length;
372 uint16_t plugin_name_length; 371 uint16_t plugin_name_length;
373 uint32_t ats_count;
374 int addr_active; 372 int addr_active;
373 struct GNUNET_ATS_Properties prop;
375 374
376 if (ntohs (msg->size) < sizeof(struct PeerInformationMessage)) 375 if (ntohs (msg->size) < sizeof(struct PeerInformationMessage))
377 { 376 {
378 GNUNET_break(0); 377 GNUNET_break(0);
379 return GNUNET_SYSERR; 378 return GNUNET_SYSERR;
380 } 379 }
381
382 pi = (const struct PeerInformationMessage *) msg; 380 pi = (const struct PeerInformationMessage *) msg;
383 ats_count = ntohl (pi->ats_count);
384 plugin_address_length = ntohs (pi->address_length); 381 plugin_address_length = ntohs (pi->address_length);
385 plugin_name_length = ntohs (pi->plugin_name_length); 382 plugin_name_length = ntohs (pi->plugin_name_length);
386 addr_active = (int) ntohl (pi->address_active); 383 addr_active = (int) ntohl (pi->address_active);
387 atsi = (const struct GNUNET_ATS_Information *) &pi[1]; 384 plugin_address = (const char *) &pi[1];
388 plugin_address = (const char *) &atsi[ats_count];
389 plugin_name = &plugin_address[plugin_address_length]; 385 plugin_name = &plugin_address[plugin_address_length];
390 if ((plugin_address_length + plugin_name_length 386 if ((plugin_address_length + plugin_name_length
391 + ats_count * sizeof(struct GNUNET_ATS_Information)
392 + sizeof(struct PeerInformationMessage) != ntohs (msg->size)) 387 + sizeof(struct PeerInformationMessage) != ntohs (msg->size))
393 || (ats_count
394 > GNUNET_SERVER_MAX_MESSAGE_SIZE
395 / sizeof(struct GNUNET_ATS_Information))
396 || (plugin_name[plugin_name_length - 1] != '\0')) 388 || (plugin_name[plugin_name_length - 1] != '\0'))
397 { 389 {
398 GNUNET_break(0); 390 GNUNET_break(0);
@@ -401,6 +393,8 @@ process_pi_message (struct GNUNET_ATS_PerformanceHandle *ph,
401 393
402 if (NULL != ph->addr_info_cb) 394 if (NULL != ph->addr_info_cb)
403 { 395 {
396 GNUNET_ATS_properties_ntoh (&prop,
397 &pi->properties);
404 address.peer = pi->peer; 398 address.peer = pi->peer;
405 address.address = plugin_address; 399 address.address = plugin_address;
406 address.address_length = plugin_address_length; 400 address.address_length = plugin_address_length;
@@ -410,7 +404,7 @@ process_pi_message (struct GNUNET_ATS_PerformanceHandle *ph,
410 addr_active, 404 addr_active,
411 pi->bandwidth_out, 405 pi->bandwidth_out,
412 pi->bandwidth_in, 406 pi->bandwidth_in,
413 atsi, ats_count); 407 &prop);
414 } 408 }
415 return GNUNET_OK; 409 return GNUNET_OK;
416} 410}
@@ -488,15 +482,14 @@ process_ar_message (struct GNUNET_ATS_PerformanceHandle *ph,
488 const struct PeerInformationMessage *pi; 482 const struct PeerInformationMessage *pi;
489 struct GNUNET_ATS_AddressListHandle *alh; 483 struct GNUNET_ATS_AddressListHandle *alh;
490 struct GNUNET_ATS_AddressListHandle *next; 484 struct GNUNET_ATS_AddressListHandle *next;
491 const struct GNUNET_ATS_Information *atsi;
492 const char *plugin_address; 485 const char *plugin_address;
493 const char *plugin_name; 486 const char *plugin_name;
494 struct GNUNET_HELLO_Address address; 487 struct GNUNET_HELLO_Address address;
495 struct GNUNET_PeerIdentity allzeros; 488 struct GNUNET_PeerIdentity allzeros;
496 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_zero; 489 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_zero;
490 struct GNUNET_ATS_Properties prop;
497 uint16_t plugin_address_length; 491 uint16_t plugin_address_length;
498 uint16_t plugin_name_length; 492 uint16_t plugin_name_length;
499 uint32_t ats_count;
500 uint32_t active; 493 uint32_t active;
501 uint32_t id; 494 uint32_t id;
502 495
@@ -507,18 +500,13 @@ process_ar_message (struct GNUNET_ATS_PerformanceHandle *ph,
507 } 500 }
508 pi = (const struct PeerInformationMessage *) msg; 501 pi = (const struct PeerInformationMessage *) msg;
509 id = ntohl (pi->id); 502 id = ntohl (pi->id);
510 ats_count = ntohl (pi->ats_count);
511 active = ntohl (pi->address_active); 503 active = ntohl (pi->address_active);
512 plugin_address_length = ntohs (pi->address_length); 504 plugin_address_length = ntohs (pi->address_length);
513 plugin_name_length = ntohs (pi->plugin_name_length); 505 plugin_name_length = ntohs (pi->plugin_name_length);
514 atsi = (const struct GNUNET_ATS_Information *) &pi[1]; 506 plugin_address = (const char *) &pi[1];
515 plugin_address = (const char *) &atsi[ats_count];
516 plugin_name = &plugin_address[plugin_address_length]; 507 plugin_name = &plugin_address[plugin_address_length];
517 if ( (plugin_address_length + plugin_name_length 508 if ( (plugin_address_length + plugin_name_length
518 + ats_count * sizeof(struct GNUNET_ATS_Information)
519 + sizeof (struct PeerInformationMessage) != ntohs (msg->size)) || 509 + sizeof (struct PeerInformationMessage) != ntohs (msg->size)) ||
520 (ats_count > GNUNET_SERVER_MAX_MESSAGE_SIZE
521 / sizeof(struct GNUNET_ATS_Information)) ||
522 (plugin_name[plugin_name_length - 1] != '\0') ) 510 (plugin_name[plugin_name_length - 1] != '\0') )
523 { 511 {
524 GNUNET_break(0); 512 GNUNET_break(0);
@@ -545,8 +533,7 @@ process_ar_message (struct GNUNET_ATS_PerformanceHandle *ph,
545 memset (&allzeros, '\0', sizeof (allzeros)); 533 memset (&allzeros, '\0', sizeof (allzeros));
546 if ( (0 == memcmp (&allzeros, &pi->peer, sizeof(allzeros))) && 534 if ( (0 == memcmp (&allzeros, &pi->peer, sizeof(allzeros))) &&
547 (0 == plugin_name_length) && 535 (0 == plugin_name_length) &&
548 (0 == plugin_address_length) && 536 (0 == plugin_address_length) )
549 (0 == ats_count) )
550 { 537 {
551 /* Done */ 538 /* Done */
552 LOG (GNUNET_ERROR_TYPE_DEBUG, 539 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -561,7 +548,7 @@ process_ar_message (struct GNUNET_ATS_PerformanceHandle *ph,
561 GNUNET_NO, 548 GNUNET_NO,
562 bandwidth_zero, 549 bandwidth_zero,
563 bandwidth_zero, 550 bandwidth_zero,
564 NULL, 0); 551 NULL);
565 GNUNET_free (alh); 552 GNUNET_free (alh);
566 return GNUNET_OK; 553 return GNUNET_OK;
567 } 554 }
@@ -573,12 +560,16 @@ process_ar_message (struct GNUNET_ATS_PerformanceHandle *ph,
573 if ( ( (GNUNET_YES == alh->all_addresses) || 560 if ( ( (GNUNET_YES == alh->all_addresses) ||
574 (GNUNET_YES == active) ) && 561 (GNUNET_YES == active) ) &&
575 (NULL != alh->cb) ) 562 (NULL != alh->cb) )
563 {
564 GNUNET_ATS_properties_ntoh (&prop,
565 &pi->properties);
576 alh->cb (ph->addr_info_cb_cls, 566 alh->cb (ph->addr_info_cb_cls,
577 &address, 567 &address,
578 active, 568 active,
579 pi->bandwidth_out, 569 pi->bandwidth_out,
580 pi->bandwidth_in, 570 pi->bandwidth_in,
581 atsi, ats_count); 571 &prop);
572 }
582 return GNUNET_OK; 573 return GNUNET_OK;
583} 574}
584 575
@@ -641,7 +632,7 @@ process_ats_message (void *cls,
641 GNUNET_NO, 632 GNUNET_NO,
642 GNUNET_BANDWIDTH_value_init (0), 633 GNUNET_BANDWIDTH_value_init (0),
643 GNUNET_BANDWIDTH_value_init (0), 634 GNUNET_BANDWIDTH_value_init (0),
644 NULL, 0); 635 NULL);
645 } 636 }
646 ph->backoff = GNUNET_TIME_STD_BACKOFF (ph->backoff); 637 ph->backoff = GNUNET_TIME_STD_BACKOFF (ph->backoff);
647 ph->task = GNUNET_SCHEDULER_add_delayed (ph->backoff, 638 ph->task = GNUNET_SCHEDULER_add_delayed (ph->backoff,
@@ -917,8 +908,9 @@ GNUNET_ATS_performance_list_addresses_cancel (struct GNUNET_ATS_AddressListHandl
917const char * 908const char *
918GNUNET_ATS_print_preference_type (uint32_t type) 909GNUNET_ATS_print_preference_type (uint32_t type)
919{ 910{
920 char *prefs[GNUNET_ATS_PreferenceCount] = GNUNET_ATS_PreferenceTypeString; 911 const char *prefs[] = GNUNET_ATS_PreferenceTypeString;
921 if (type < GNUNET_ATS_PreferenceCount) 912
913 if (type < GNUNET_ATS_PREFERENCE_END)
922 return prefs[type]; 914 return prefs[type];
923 return NULL; 915 return NULL;
924} 916}
@@ -930,7 +922,7 @@ GNUNET_ATS_print_preference_type (uint32_t type)
930 * 922 *
931 * @param ph performance handle 923 * @param ph performance handle
932 * @param peer identifies the peer 924 * @param peer identifies the peer
933 * @param ... 0-terminated specification of the desired changes 925 * @param ... #GNUNET_ATS_PREFERENCE_END-terminated specification of the desired changes
934 */ 926 */
935void 927void
936GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *ph, 928GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *ph,
@@ -946,20 +938,18 @@ GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *p
946 938
947 count = 0; 939 count = 0;
948 va_start(ap, peer); 940 va_start(ap, peer);
949 while (GNUNET_ATS_PREFERENCE_END != (kind = 941 while (GNUNET_ATS_PREFERENCE_END !=
950 va_arg (ap, enum GNUNET_ATS_PreferenceKind) )) 942 (kind = va_arg (ap, enum GNUNET_ATS_PreferenceKind) ))
951 { 943 {
952 switch (kind) 944 switch (kind)
953 { 945 {
954 case GNUNET_ATS_PREFERENCE_BANDWIDTH: 946 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
955 count++; 947 count++;
956 (void) va_arg (ap, double); 948 (void) va_arg (ap, double);
957
958 break; 949 break;
959 case GNUNET_ATS_PREFERENCE_LATENCY: 950 case GNUNET_ATS_PREFERENCE_LATENCY:
960 count++; 951 count++;
961 (void) va_arg (ap, double); 952 (void) va_arg (ap, double);
962
963 break; 953 break;
964 default: 954 default:
965 GNUNET_assert(0); 955 GNUNET_assert(0);
@@ -1012,7 +1002,7 @@ GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *p
1012 * @param ph performance handle 1002 * @param ph performance handle
1013 * @param scope the time interval this valid for: [now - scope .. now] 1003 * @param scope the time interval this valid for: [now - scope .. now]
1014 * @param peer identifies the peer 1004 * @param peer identifies the peer
1015 * @param ... 0-terminated specification of the desired changes 1005 * @param ... #GNUNET_ATS_PREFERENCE_END-terminated specification of the desired changes
1016 */ 1006 */
1017void 1007void
1018GNUNET_ATS_performance_give_feedback (struct GNUNET_ATS_PerformanceHandle *ph, 1008GNUNET_ATS_performance_give_feedback (struct GNUNET_ATS_PerformanceHandle *ph,
@@ -1029,8 +1019,8 @@ GNUNET_ATS_performance_give_feedback (struct GNUNET_ATS_PerformanceHandle *ph,
1029 1019
1030 count = 0; 1020 count = 0;
1031 va_start(ap, scope); 1021 va_start(ap, scope);
1032 while (GNUNET_ATS_PREFERENCE_END != (kind = 1022 while (GNUNET_ATS_PREFERENCE_END !=
1033 va_arg (ap, enum GNUNET_ATS_PreferenceKind) )) 1023 (kind = va_arg (ap, enum GNUNET_ATS_PreferenceKind) ))
1034 { 1024 {
1035 switch (kind) 1025 switch (kind)
1036 { 1026 {
diff --git a/src/ats/ats_api_scanner.c b/src/ats/ats_api_scanner.c
index 64c02acf6..f9c30770e 100644
--- a/src/ats/ats_api_scanner.c
+++ b/src/ats/ats_api_scanner.c
@@ -62,32 +62,38 @@ GNUNET_ATS_print_network_type (enum GNUNET_ATS_Network_Type net)
62 62
63 63
64/** 64/**
65 * Convert a ATS property to a string 65 * Convert ATS properties from host to network byte order.
66 * 66 *
67 * @param type the property type 67 * @param nbo[OUT] value written
68 * @return a string or NULL if invalid 68 * @param hbo value read
69 */ 69 */
70const char * 70void
71GNUNET_ATS_print_property_type (enum GNUNET_ATS_Property type) 71GNUNET_ATS_properties_hton (struct GNUNET_ATS_PropertiesNBO *nbo,
72 const struct GNUNET_ATS_Properties *hbo)
72{ 73{
73 switch (type) 74 nbo->utilization_out = htonl (hbo->utilization_out);
74 { 75 nbo->utilization_in = htonl (hbo->utilization_in);
75 case GNUNET_ATS_ARRAY_TERMINATOR: 76 nbo->scope = htonl ((uint32_t) hbo->scope);
76 return "TERMINATOR"; 77 nbo->distance = htonl (hbo->distance);
77 case GNUNET_ATS_UTILIZATION_OUT: 78 nbo->delay = GNUNET_TIME_relative_hton (hbo->delay);
78 return "UTILIZATION_UP"; 79}
79 case GNUNET_ATS_UTILIZATION_IN: 80
80 return "UTILIZATION_DOWN"; 81
81 case GNUNET_ATS_NETWORK_TYPE: 82/**
82 return "NETWORK_TYPE"; 83 * Convert ATS properties from network to host byte order.
83 case GNUNET_ATS_QUALITY_NET_DELAY: 84 *
84 return "DELAY"; 85 * @param hbo[OUT] value written
85 case GNUNET_ATS_QUALITY_NET_DISTANCE: 86 * @param nbo value read
86 return "DISTANCE"; 87 */
87 default: 88void
88 GNUNET_break (0); 89GNUNET_ATS_properties_ntoh (struct GNUNET_ATS_Properties *hbo,
89 return NULL; 90 const struct GNUNET_ATS_PropertiesNBO *nbo)
90 } 91{
92 hbo->utilization_out = ntohl (nbo->utilization_out);
93 hbo->utilization_in = ntohl (nbo->utilization_in);
94 hbo->scope = ntohl ((uint32_t) nbo->scope);
95 hbo->distance = ntohl (nbo->distance);
96 hbo->delay = GNUNET_TIME_relative_ntoh (nbo->delay);
91} 97}
92 98
93 99
diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c
index ed82dd2ad..f02e4a9e7 100644
--- a/src/ats/ats_api_scheduling.c
+++ b/src/ats/ats_api_scheduling.c
@@ -73,14 +73,9 @@ struct GNUNET_ATS_AddressRecord
73 struct Session *session; 73 struct Session *session;
74 74
75 /** 75 /**
76 * Array with performance data about the address. 76 * Performance data about the address.
77 */ 77 */
78 struct GNUNET_ATS_Information *ats; 78 struct GNUNET_ATS_PropertiesNBO properties;
79
80 /**
81 * Number of entries in @e ats.
82 */
83 uint32_t ats_count;
84 79
85 /** 80 /**
86 * Which slot (index) in the session array does 81 * Which slot (index) in the session array does
@@ -487,7 +482,6 @@ send_add_address_message (struct GNUNET_ATS_SchedulingHandle *sh,
487{ 482{
488 struct GNUNET_MQ_Envelope *ev; 483 struct GNUNET_MQ_Envelope *ev;
489 struct AddressAddMessage *m; 484 struct AddressAddMessage *m;
490 struct GNUNET_ATS_Information *am;
491 char *pm; 485 char *pm;
492 size_t namelen; 486 size_t namelen;
493 size_t msize; 487 size_t msize;
@@ -497,16 +491,14 @@ send_add_address_message (struct GNUNET_ATS_SchedulingHandle *sh,
497 namelen = (NULL == ar->address->transport_name) 491 namelen = (NULL == ar->address->transport_name)
498 ? 0 492 ? 0
499 : strlen (ar->address->transport_name) + 1; 493 : strlen (ar->address->transport_name) + 1;
500 msize = ar->address->address_length + 494 msize = ar->address->address_length + namelen;
501 ar->ats_count * sizeof (struct GNUNET_ATS_Information) + namelen;
502
503 ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD); 495 ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD);
504 m->ats_count = htonl (ar->ats_count);
505 m->peer = ar->address->peer; 496 m->peer = ar->address->peer;
506 m->address_length = htons (ar->address->address_length); 497 m->address_length = htons (ar->address->address_length);
507 m->address_local_info = htonl ((uint32_t) ar->address->local_info); 498 m->address_local_info = htonl ((uint32_t) ar->address->local_info);
508 m->plugin_name_length = htons (namelen); 499 m->plugin_name_length = htons (namelen);
509 m->session_id = htonl (ar->slot); 500 m->session_id = htonl (ar->slot);
501 m->properties = ar->properties;
510 502
511 LOG (GNUNET_ERROR_TYPE_DEBUG, 503 LOG (GNUNET_ERROR_TYPE_DEBUG,
512 "Adding address for peer `%s', plugin `%s', session %p slot %u\n", 504 "Adding address for peer `%s', plugin `%s', session %p slot %u\n",
@@ -514,11 +506,7 @@ send_add_address_message (struct GNUNET_ATS_SchedulingHandle *sh,
514 ar->address->transport_name, 506 ar->address->transport_name,
515 ar->session, 507 ar->session,
516 ar->slot); 508 ar->slot);
517 am = (struct GNUNET_ATS_Information *) &m[1]; 509 pm = (char *) &m[1];
518 memcpy (am,
519 ar->ats,
520 ar->ats_count * sizeof (struct GNUNET_ATS_Information));
521 pm = (char *) &am[ar->ats_count];
522 memcpy (pm, 510 memcpy (pm,
523 ar->address->address, 511 ar->address->address,
524 ar->address->address_length); 512 ar->address->address_length);
@@ -675,8 +663,7 @@ GNUNET_ATS_session_known (struct GNUNET_ATS_SchedulingHandle *sh,
675 * @param sh handle 663 * @param sh handle
676 * @param address the address 664 * @param address the address
677 * @param session session handle, can be NULL 665 * @param session session handle, can be NULL
678 * @param ats performance data for the address 666 * @param prop performance data for the address
679 * @param ats_count number of performance records in @a ats
680 * @return handle to the address representation inside ATS, NULL 667 * @return handle to the address representation inside ATS, NULL
681 * on error (i.e. ATS knows this exact address already) 668 * on error (i.e. ATS knows this exact address already)
682 */ 669 */
@@ -684,8 +671,7 @@ struct GNUNET_ATS_AddressRecord *
684GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, 671GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
685 const struct GNUNET_HELLO_Address *address, 672 const struct GNUNET_HELLO_Address *address,
686 struct Session *session, 673 struct Session *session,
687 const struct GNUNET_ATS_Information *ats, 674 const struct GNUNET_ATS_Properties *prop)
688 uint32_t ats_count)
689{ 675{
690 struct GNUNET_ATS_AddressRecord *ar; 676 struct GNUNET_ATS_AddressRecord *ar;
691 size_t namelen; 677 size_t namelen;
@@ -701,13 +687,10 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
701 namelen = (NULL == address->transport_name) 687 namelen = (NULL == address->transport_name)
702 ? 0 688 ? 0
703 : strlen (address->transport_name) + 1; 689 : strlen (address->transport_name) + 1;
704 msize = address->address_length + 690 msize = address->address_length + namelen;
705 ats_count * sizeof (struct GNUNET_ATS_Information) + namelen;
706 if ((msize + sizeof (struct AddressUpdateMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || 691 if ((msize + sizeof (struct AddressUpdateMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
707 (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || 692 (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
708 (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || 693 (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) )
709 (ats_count >=
710 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information)))
711 { 694 {
712 /* address too large for us, this should not happen */ 695 /* address too large for us, this should not happen */
713 GNUNET_break (0); 696 GNUNET_break (0);
@@ -729,12 +712,8 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
729 ar->slot = s; 712 ar->slot = s;
730 ar->session = session; 713 ar->session = session;
731 ar->address = GNUNET_HELLO_address_copy (address); 714 ar->address = GNUNET_HELLO_address_copy (address);
732 GNUNET_array_grow (ar->ats, 715 GNUNET_ATS_properties_hton (&ar->properties,
733 ar->ats_count, 716 prop);
734 ats_count);
735 memcpy (ar->ats,
736 ats,
737 ats_count * sizeof (struct GNUNET_ATS_Information));
738 sh->session_array[s] = ar; 717 sh->session_array[s] = ar;
739 send_add_address_message (sh, ar); 718 send_add_address_message (sh, ar);
740 return ar; 719 return ar;
@@ -793,19 +772,15 @@ GNUNET_ATS_address_del_session (struct GNUNET_ATS_AddressRecord *ar,
793 * for later use). Update bandwidth assignments. 772 * for later use). Update bandwidth assignments.
794 * 773 *
795 * @param ar address record to update information for 774 * @param ar address record to update information for
796 * @param ats performance data for the address 775 * @param prop performance data for the address
797 * @param ats_count number of performance records in @a ats
798 */ 776 */
799void 777void
800GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar, 778GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar,
801 const struct GNUNET_ATS_Information *ats, 779 const struct GNUNET_ATS_Properties *prop)
802 uint32_t ats_count)
803{ 780{
804 struct GNUNET_ATS_SchedulingHandle *sh = ar->sh; 781 struct GNUNET_ATS_SchedulingHandle *sh = ar->sh;
805 struct GNUNET_MQ_Envelope *ev; 782 struct GNUNET_MQ_Envelope *ev;
806 struct AddressUpdateMessage *m; 783 struct AddressUpdateMessage *m;
807 struct GNUNET_ATS_Information *am;
808 size_t msize;
809 784
810 LOG (GNUNET_ERROR_TYPE_DEBUG, 785 LOG (GNUNET_ERROR_TYPE_DEBUG,
811 "Updating address for peer `%s', plugin `%s', session %p slot %u\n", 786 "Updating address for peer `%s', plugin `%s', session %p slot %u\n",
@@ -813,25 +788,16 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar,
813 ar->address->transport_name, 788 ar->address->transport_name,
814 ar->session, 789 ar->session,
815 ar->slot); 790 ar->slot);
816 GNUNET_array_grow (ar->ats, 791 GNUNET_ATS_properties_hton (&ar->properties,
817 ar->ats_count, 792 prop);
818 ats_count);
819 memcpy (ar->ats,
820 ats,
821 ats_count * sizeof (struct GNUNET_ATS_Information));
822
823 if (NULL == sh->mq) 793 if (NULL == sh->mq)
824 return; /* disconnected, skip for now */ 794 return; /* disconnected, skip for now */
825 msize = ar->ats_count * sizeof (struct GNUNET_ATS_Information); 795 ev = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE);
826 ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE);
827 m->ats_count = htonl (ar->ats_count);
828 m->peer = ar->address->peer;
829 m->session_id = htonl (ar->slot); 796 m->session_id = htonl (ar->slot);
830 am = (struct GNUNET_ATS_Information *) &m[1]; 797 m->peer = ar->address->peer;
831 memcpy (am, 798 m->properties = ar->properties;
832 ar->ats, 799 GNUNET_MQ_send (sh->mq,
833 ar->ats_count * sizeof (struct GNUNET_ATS_Information)); 800 ev);
834 GNUNET_MQ_send (sh->mq, ev);
835} 801}
836 802
837 803
@@ -857,9 +823,6 @@ GNUNET_ATS_address_destroy (struct GNUNET_ATS_AddressRecord *ar)
857 GNUNET_break (NULL == ar->session); 823 GNUNET_break (NULL == ar->session);
858 ar->session = NULL; 824 ar->session = NULL;
859 ar->in_destroy = GNUNET_YES; 825 ar->in_destroy = GNUNET_YES;
860 GNUNET_array_grow (ar->ats,
861 ar->ats_count,
862 0);
863 if (NULL == sh->mq) 826 if (NULL == sh->mq)
864 return; 827 return;
865 ev = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED); 828 ev = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED);
diff --git a/src/ats/gnunet-ats-solver-eval.c b/src/ats/gnunet-ats-solver-eval.c
index 8cf4b115b..5645e81c5 100644
--- a/src/ats/gnunet-ats-solver-eval.c
+++ b/src/ats/gnunet-ats-solver-eval.c
@@ -166,7 +166,8 @@ GNUNET_ATS_solver_logging_now (struct LoggingHandle *l)
166 /* Store logging data here */ 166 /* Store logging data here */
167 for (cur = peer_head; NULL != cur; cur = cur->next) 167 for (cur = peer_head; NULL != cur; cur = cur->next)
168 { 168 {
169 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Logging peer id %llu\n", cur->id); 169 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
170 "Logging peer id %llu\n", cur->id);
170 171
171 log_p = GNUNET_new (struct LoggingPeer); 172 log_p = GNUNET_new (struct LoggingPeer);
172 log_p->id = cur->id; 173 log_p->id = cur->id;
@@ -176,16 +177,18 @@ GNUNET_ATS_solver_logging_now (struct LoggingHandle *l)
176 { 177 {
177 log_p->pref_abs[c] = cur->pref_abs[c]; 178 log_p->pref_abs[c] = cur->pref_abs[c];
178 log_p->pref_norm[c] = cur->pref_norm[c]; 179 log_p->pref_norm[c] = cur->pref_norm[c];
179 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t %s = %.2f %.2f [abs/rel]\n", 180 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
180 GNUNET_ATS_print_preference_type(c), 181 "\t %s = %.2f %.2f [abs/rel]\n",
181 log_p->pref_abs[c], log_p->pref_norm[c]); 182 GNUNET_ATS_print_preference_type(c),
183 log_p->pref_abs[c], log_p->pref_norm[c]);
182 } 184 }
183 GNUNET_CONTAINER_DLL_insert_tail(lts->head, lts->tail, log_p); 185 GNUNET_CONTAINER_DLL_insert_tail(lts->head, lts->tail, log_p);
184 186
185 for (cur_addr = cur->addr_head; NULL != cur_addr; cur_addr = cur_addr->next) 187 for (cur_addr = cur->addr_head; NULL != cur_addr; cur_addr = cur_addr->next)
186 { 188 {
187 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Logging peer id %llu address %llu \n", 189 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
188 cur->id, cur_addr->aid); 190 "Logging peer id %llu address %llu\n",
191 cur->id, cur_addr->aid);
189 log_a = GNUNET_new (struct LoggingAddress); 192 log_a = GNUNET_new (struct LoggingAddress);
190 log_a->aid = cur_addr->aid; 193 log_a->aid = cur_addr->aid;
191 log_a->active = cur_addr->ats_addr->active; 194 log_a->active = cur_addr->ats_addr->active;
@@ -196,9 +199,11 @@ GNUNET_ATS_solver_logging_now (struct LoggingHandle *l)
196 { 199 {
197 log_a->prop_abs[c] = cur_addr->prop_abs[c]; 200 log_a->prop_abs[c] = cur_addr->prop_abs[c];
198 log_a->prop_norm[c] = cur_addr->prop_norm[c]; 201 log_a->prop_norm[c] = cur_addr->prop_norm[c];
199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t %s = %.2f %.2f [abs/rel]\n", 202 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
200 GNUNET_ATS_print_property_type(c), 203 "\t %s = %.2f %.2f [abs/rel]\n",
201 log_a->prop_abs[c], log_a->prop_norm[c]); 204 GNUNET_ATS_print_property_type(c),
205 log_a->prop_abs[c],
206 log_a->prop_norm[c]);
202 } 207 }
203 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t Active = %i\n", log_a->active); 208 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t Active = %i\n", log_a->active);
204 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t BW in = %llu\n", log_a->assigned_bw_in); 209 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\t BW in = %llu\n", log_a->assigned_bw_in);
@@ -209,16 +214,17 @@ GNUNET_ATS_solver_logging_now (struct LoggingHandle *l)
209 } 214 }
210} 215}
211 216
217
212static void 218static void
213logging_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 219logging_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
214{ 220{
215 struct LoggingHandle *l = cls; 221 struct LoggingHandle *l = cls;
216 l->logging_task = NULL;
217 222
223 l->logging_task = NULL;
218 GNUNET_ATS_solver_logging_now (l); 224 GNUNET_ATS_solver_logging_now (l);
219 225 l->logging_task = GNUNET_SCHEDULER_add_delayed (l->log_freq,
220 l->logging_task = GNUNET_SCHEDULER_add_delayed (l->log_freq, &logging_task, l); 226 &logging_task,
221 227 l);
222} 228}
223 229
224struct LoggingHandle * 230struct LoggingHandle *
@@ -395,7 +401,9 @@ GNUNET_ATS_solver_logging_write_to_disk (struct LoggingHandle *l, int add_time_s
395 GNUNET_ATS_print_property_type(c), 401 GNUNET_ATS_print_property_type(c),
396 log_a->prop_abs[c], log_a->prop_norm[c]);*/ 402 log_a->prop_abs[c], log_a->prop_norm[c]);*/
397 GNUNET_asprintf(&propstring_tmp,"%s%.3f;%.3f;", 403 GNUNET_asprintf(&propstring_tmp,"%s%.3f;%.3f;",
398 propstring, log_a->prop_abs[c], log_a->prop_norm[c]); 404 propstring,
405 log_a->prop_abs[c],
406 log_a->prop_norm[c]);
399 GNUNET_free (propstring); 407 GNUNET_free (propstring);
400 propstring = GNUNET_strdup(propstring_tmp); 408 propstring = GNUNET_strdup(propstring_tmp);
401 GNUNET_free (propstring_tmp); 409 GNUNET_free (propstring_tmp);
@@ -519,10 +527,10 @@ GNUNET_ATS_solver_logging_free (struct LoggingHandle *l)
519/** 527/**
520 * Property Generators 528 * Property Generators
521 */ 529 */
522
523static struct PropertyGenerator *prop_gen_head; 530static struct PropertyGenerator *prop_gen_head;
524static struct PropertyGenerator *prop_gen_tail; 531static struct PropertyGenerator *prop_gen_tail;
525 532
533
526static double 534static double
527get_property (struct PropertyGenerator *pg) 535get_property (struct PropertyGenerator *pg)
528{ 536{
@@ -3001,7 +3009,7 @@ get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id)
3001 } 3009 }
3002 else 3010 else
3003 return GAS_preference_get_by_peer (NULL, 3011 return GAS_preference_get_by_peer (NULL,
3004 id); 3012 id);
3005} 3013}
3006 3014
3007 3015
diff --git a/src/ats/gnunet-ats-solver-eval.h b/src/ats/gnunet-ats-solver-eval.h
index bc5083e34..44ccfe081 100644
--- a/src/ats/gnunet-ats-solver-eval.h
+++ b/src/ats/gnunet-ats-solver-eval.h
@@ -120,8 +120,8 @@ struct LoggingPeer
120 120
121 long long unsigned int id; 121 long long unsigned int id;
122 struct GNUNET_PeerIdentity peer_id; 122 struct GNUNET_PeerIdentity peer_id;
123 double pref_abs[GNUNET_ATS_PreferenceCount]; 123 double pref_abs[GNUNET_ATS_PREFERENCE_END];
124 double pref_norm[GNUNET_ATS_PreferenceCount]; 124 double pref_norm[GNUNET_ATS_PREFERENCE_END];
125 int is_requested; 125 int is_requested;
126 126
127 struct LoggingAddress *addr_head; 127 struct LoggingAddress *addr_head;
@@ -215,7 +215,7 @@ struct GNUNET_ATS_TEST_Operation
215 enum OperationType type; 215 enum OperationType type;
216 enum GeneratorType gen_type; 216 enum GeneratorType gen_type;
217 enum GNUNET_ATS_PreferenceKind pref_type; 217 enum GNUNET_ATS_PreferenceKind pref_type;
218 enum GNUNET_ATS_Property prop_type; 218 // enum GNUNET_ATS_Property prop_type;
219}; 219};
220 220
221struct Episode 221struct Episode
diff --git a/src/ats/gnunet-service-ats.c b/src/ats/gnunet-service-ats.c
index 716bd6332..8570b57b6 100644
--- a/src/ats/gnunet-service-ats.c
+++ b/src/ats/gnunet-service-ats.c
@@ -177,7 +177,8 @@ run (void *cls,
177 {&GAS_handle_address_add, NULL, 177 {&GAS_handle_address_add, NULL,
178 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD, 0}, 178 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD, 0},
179 {&GAS_handle_address_update, NULL, 179 {&GAS_handle_address_update, NULL,
180 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE, 0}, 180 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE,
181 sizeof (struct AddressUpdateMessage) },
181 {&GAS_handle_address_destroyed, NULL, 182 {&GAS_handle_address_destroyed, NULL,
182 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED, 183 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED,
183 sizeof (struct AddressDestroyedMessage) }, 184 sizeof (struct AddressDestroyedMessage) },
diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c
index c4d7f2da9..17f030a6c 100644
--- a/src/ats/gnunet-service-ats_addresses.c
+++ b/src/ats/gnunet-service-ats_addresses.c
@@ -32,186 +32,6 @@
32 32
33 33
34/** 34/**
35 * NOTE: Do not change this documentation. This documentation is based on
36 * gnunet.org:/vcs/fsnsg/2014-p2p-ats.git/tech-doku/ats-tech-guide.tex
37 * use build_txt.sh to generate plaintext output
38 *
39 * 1 ATS addresses : ATS address management
40 *
41 * This ATS addresses ("addresses") component manages the addresses known to
42 * ATS service and suggests addresses to transport service when it is
43 * interested in address suggestion for a peer. ATS addresses also
44 * instantiates the bandwidth assignment mechanism (solver), notifies it
45 * about changes to addresses and forwards changes to bandwidth assignments
46 * to transport, depending if transport is interested in this change.
47 *
48 * 1.1 Input data
49 *
50 * 1.1.1 Addresses
51 *
52 * Addresses are added by specifying peer ID, plugin, address, address length
53 * and session, if available. ATS information can be specified if available.
54 *
55 * 1.1.2 Networks
56 *
57 * ATS specifies a fix set of networks an address can belong to. For each
58 * network an inbound and outbound quota will be specified. The available
59 * networks and addtional helper varaibles are defined in
60 * gnunet_ats_service.h. At the moment 5 networks are defined:
61 * * GNUNET_ATS_NET_UNSPECIFIED
62 * * GNUNET_ATS_NET_LOOPBACK
63 * * GNUNET_ATS_NET_LAN
64 * * GNUNET_ATS_NET_WAN
65 * * GNUNET_ATS_NET_WLAN
66 *
67 * The total number of networks defined is stored in
68 * GNUNET_ATS_NetworkTypeCount GNUNET_ATS_NetworkType can be used array
69 * initializer for an int array, while GNUNET_ATS_NetworkType is an
70 * initializer for a char array containing a string description of all
71 * networks
72 *
73 * 1.1.3 Quotas
74 *
75 * An inbound and outbound quota for each of the networks mentioned in 1.1.2
76 * is loaded from ats configuration during initialization. This quota defines
77 * to total amount of inbound and outbound traffic allowed for a specific
78 * network. The configuration values used are in section ats:
79 * * "NETWORK"_QUOTA_IN = <value>
80 * * "NETWORK"_QUOTA_IN = <value>
81 *
82 * You can specify quotas by setting the <value> to a:
83 * * unrestricted: unlimited
84 * * number of bytes: e.g. 10240
85 * * fancy value: e.g. 64 Kib
86 *
87 * unlimited is defined as GNUNET_ATS_MaxBandwidthString and equivalent to
88 * the value GNUNET_ATS_MaxBandwidth Important predefined values for quotas
89 * are:
90 * * GNUNET_ATS_DefaultBandwidth: 65536
91 * * GNUNET_ATS_MaxBandwidth: UINT32_MAX
92 * * GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT: 1024
93 *
94 * Details of loading quotas and default values will be described on
95 *
96 * 1.1.4 Preference values
97 *
98 * 1.2 Data structures used
99 *
100 * Addresse uses struct ATS_Address for each address. The structs are stored
101 * in a linked list and provides a pointer void *solver_information for the
102 * solver to store address specific information. It provides the int values
103 * active which is set to GNUNET_YES if the address is select for transport
104 * use and used, representing that transport service is actively using this
105 * address. Address information are stored in peer, addr, addr_len, plugin.
106 *
107 * 1.3 Initialization
108 *
109 * During initialization a hashmap to store addresses is created. The quotas
110 * for all networks defined for ATS are loaded from configuration. For each
111 * network first the logic will check if the string
112 * GNUNET_ATS_MaxBandwidthString is configured, if not it will try to convert
113 * the configured value as a fancy size and if this fails it will try to use
114 * it as a value_number. If no configuration value is found it will assign
115 * GNUNET_ATS_DefaultBandwidth. The most important step is to load the
116 * configured solver using configuration "[ats]:MODE". Current solvers are
117 * MODE_PROPORTIONAL, MODE_MLP. Interaction is done using a solver API
118 *
119 * 1.4 Solver API
120 *
121 * Solver functions:
122 * * s_init: init the solver with required information
123 * * s_add: add a new address
124 * * s_update: update ATS values or session for an address
125 * * s_get: get prefered address for a peer
126 * * s_del: delete an address
127 * * s_pref: change preference value for a peer
128 * * s_done: shutdown solver
129 *
130 * Callbacks: addresses provides a bandwidth_changed_cb callback to the
131 * solver which is called when bandwidth assigned to peer has changed
132 *
133 * 1.5 Shutdown
134 *
135 * During shutdown all addresses are freed and the solver told to shutdown
136 *
137 * 1.6 Addresses and sessions
138 *
139 * Addresses consist of the address itself and a numerical session. When a
140 * new address without a session is added it has no session, so it gets
141 * session 0 assigned. When an address with a session is added and an address
142 * object with session 0 is found, this object is updated with the session
143 * otherwise a new address object with this session assigned is created.
144 *
145 * 1.6.1 Terminology
146 *
147 * Addresses a1,a2 with session s1, s2 are "exact" if:
148 * (a1 == a2)&&(s1 == s2)
149 * Addresses a1,a2 with session s1, s2 are "equivalent" if:
150 * (a1 == a2)&&((s1 == s2)||(s1 == 0)||(s2 == 0)
151 *
152 * 1.7 Address management
153 *
154 * Transport service notifies ATS about changes to the addresses known to
155 * him.
156 *
157 * 1.7.1 Adding an address
158 *
159 * When transport learns a new address it tells ATS and ATS is telling
160 * addresses about it using GAS_address_add. If not known to addresses it
161 * creates a new address object and calls solver's s_add. ATS information are
162 * deserialized and solver is notified about the session and ATS information
163 * using s_update.
164 *
165 * 1.7.2 Updating an address
166 *
167 * Addresses does an lookup up for the existing address with the given
168 * session. If disassembles included ATS information and notifies the solver
169 * using s_update about the update.
170 *
171 * 1.7.3 Deleting an address
172 *
173 * Addresses does an lookup for the exact address and session and if removes
174 * this address. If session != 0 the session is set to 0 and the address is
175 * kept. If session == 0, the addresses is removed.
176 *
177 * 1.7.4 Requesting an address suggestion
178 *
179 * The address client issues a request address message to be notified about
180 * address suggestions for a specific peer. Addresses asks the solver with
181 * s_get. If no address is available, it will not send a response, otherwise
182 * it will respond with the choosen address.
183 *
184 * 1.7.5 Address suggestions
185 *
186 * Addresses will notify the client automatically on any bandwidth_changed_cb
187 * by the solver if a address suggestion request is pending. If no address is
188 * available it will not respond at all If the client is not interested
189 * anymore, it has to cancel the address suggestion request.
190 *
191 * 1.7.6 Address lifecycle
192 *
193 * * (add address)
194 * * (updated address)
195 * * (delete address)
196 *
197 * 1.8 Bandwidth assignment
198 *
199 * The addresses are used to perform resource allocation operations. ATS
200 * addresses takes care of instantiating the solver configured and notifies
201 * the respective solver about address changes and receives changes to the
202 * bandwidth assignment from the solver. The current bandwidth assignment is
203 * sent to transport. The specific solvers will be described in the specific
204 * section.
205 *
206 * 1.9 Changing peer preferences
207 *
208 * The bandwidth assigned to a peer can be influenced by setting a preference
209 * for a peer. The prefernce will be given to to the solver with s_pref which
210 * has to take care of the preference value
211 */
212
213
214/**
215 * A multihashmap to store all addresses 35 * A multihashmap to store all addresses
216 */ 36 */
217struct GNUNET_CONTAINER_MultiPeerMap *GSA_addresses; 37struct GNUNET_CONTAINER_MultiPeerMap *GSA_addresses;
@@ -231,124 +51,6 @@ update_addresses_stat ()
231 51
232 52
233/** 53/**
234 * Disassemble ATS information and update performance information in address
235 *
236 * Updates existing information and adds new information
237 *
238 * @param dest destination address
239 * @param update source ATS information
240 * @param update_count number of ATS information in @a update
241 * @param delta_dest ats performance information which were updated
242 * including previous value
243 * @param delta_count number of ATS information in the @a delta_dest
244 * @return #GNUNET_YES if address was address updated, GNUNET_NO otherwise
245 */
246static unsigned int
247disassemble_ats_information (struct ATS_Address *dest,
248 const struct GNUNET_ATS_Information *update,
249 uint32_t update_count,
250 struct GNUNET_ATS_Information **delta_dest,
251 uint32_t *delta_count)
252{
253 int c1;
254 int c2;
255 int found;
256 int change;
257 struct GNUNET_ATS_Information add_atsi[update_count];
258 struct GNUNET_ATS_Information delta_atsi[update_count];
259 struct GNUNET_ATS_Information *tmp_atsi;
260 uint32_t add_atsi_count;
261 uint32_t delta_atsi_count;
262
263 change = GNUNET_NO;
264 add_atsi_count = 0;
265 delta_atsi_count = 0;
266
267 if (0 == update_count)
268 return GNUNET_NO;
269
270 if (NULL == dest->atsi)
271 {
272 /* Create performance information */
273 dest->atsi =
274 GNUNET_malloc (update_count * sizeof (struct GNUNET_ATS_Information));
275 dest->atsi_count = update_count;
276 memcpy (dest->atsi,
277 update,
278 update_count * sizeof(struct GNUNET_ATS_Information));
279 *delta_dest =
280 GNUNET_malloc (update_count * sizeof (struct GNUNET_ATS_Information));
281 for (c1 = 0; c1 < update_count; c1++)
282 {
283 (*delta_dest)[c1].type = update[c1].type;
284 (*delta_dest)[c1].value = htonl (GNUNET_ATS_VALUE_UNDEFINED);
285 }
286 (*delta_count) = update_count;
287 return GNUNET_YES;
288 }
289
290 for (c1 = 0; c1 < update_count; c1++)
291 {
292 /* Update existing performance information */
293 found = GNUNET_NO;
294 for (c2 = 0; c2 < dest->atsi_count; c2++)
295 {
296 if (update[c1].type == dest->atsi[c2].type)
297 {
298 if (update[c1].value != dest->atsi[c2].value)
299 {
300 /* Save previous value in delta */
301 delta_atsi[delta_atsi_count] = dest->atsi[c2];
302 delta_atsi_count++;
303 /* Set new value */
304 dest->atsi[c2].value = update[c1].value;
305 change = GNUNET_YES;
306 }
307 found = GNUNET_YES;
308 break;
309 }
310 }
311 if (GNUNET_NO == found)
312 {
313 add_atsi[add_atsi_count] = update[c1];
314 add_atsi_count++;
315 delta_atsi[delta_atsi_count].type = update[c1].type;
316 delta_atsi[delta_atsi_count].value = htonl (GNUNET_ATS_VALUE_UNDEFINED);
317 delta_atsi_count++;
318 }
319 }
320
321 if (add_atsi_count > 0)
322 {
323 /* Extend ats performance information */
324
325 tmp_atsi = GNUNET_malloc ((dest->atsi_count + add_atsi_count) *
326 (sizeof (struct GNUNET_ATS_Information)));
327 memcpy (tmp_atsi, dest->atsi,
328 dest->atsi_count * sizeof(struct GNUNET_ATS_Information));
329 memcpy (&tmp_atsi[dest->atsi_count], add_atsi,
330 add_atsi_count * sizeof(struct GNUNET_ATS_Information));
331 GNUNET_free (dest->atsi);
332 dest->atsi = tmp_atsi;
333 dest->atsi_count = dest->atsi_count + add_atsi_count;
334 change = GNUNET_YES;
335 }
336
337 if (delta_atsi_count > 0)
338 {
339 /* Copy delta */
340 (*delta_dest) =
341 GNUNET_malloc (delta_atsi_count * sizeof (struct GNUNET_ATS_Information));
342 memcpy ((*delta_dest), delta_atsi,
343 delta_atsi_count * sizeof(struct GNUNET_ATS_Information));
344 (*delta_count) = delta_atsi_count;
345 }
346
347 return change;
348}
349
350
351/**
352 * Free the given address 54 * Free the given address
353 * 55 *
354 * @param addr address to destroy 56 * @param addr address to destroy
@@ -366,16 +68,30 @@ free_address (struct ATS_Address *addr)
366 addr->addr, 68 addr->addr,
367 addr->addr_len, 69 addr->addr_len,
368 GNUNET_NO, 70 GNUNET_NO,
369 NULL, 0, 71 NULL,
370 GNUNET_BANDWIDTH_ZERO, 72 GNUNET_BANDWIDTH_ZERO,
371 GNUNET_BANDWIDTH_ZERO); 73 GNUNET_BANDWIDTH_ZERO);
372 GNUNET_free (addr->plugin); 74 GNUNET_free (addr->plugin);
373 GNUNET_free_non_null (addr->atsi);
374 GNUNET_free (addr); 75 GNUNET_free (addr);
375} 76}
376 77
377 78
378/** 79/**
80 * Initialize @a norm. Sets all historic values to undefined.
81 *
82 * @param norm normalization data to initialize
83 */
84static void
85init_norm (struct GAS_NormalizationInfo *norm)
86{
87 unsigned int c;
88
89 for (c = 0; c < GAS_normalization_queue_length; c++)
90 norm->atsi_abs[c] = UINT64_MAX;
91}
92
93
94/**
379 * Create a ATS_address with the given information 95 * Create a ATS_address with the given information
380 * 96 *
381 * @param peer peer 97 * @param peer peer
@@ -395,8 +111,6 @@ create_address (const struct GNUNET_PeerIdentity *peer,
395 uint32_t session_id) 111 uint32_t session_id)
396{ 112{
397 struct ATS_Address *aa; 113 struct ATS_Address *aa;
398 unsigned int c1;
399 unsigned int c2;
400 114
401 aa = GNUNET_malloc (sizeof (struct ATS_Address) + plugin_addr_len); 115 aa = GNUNET_malloc (sizeof (struct ATS_Address) + plugin_addr_len);
402 aa->peer = *peer; 116 aa->peer = *peer;
@@ -408,14 +122,10 @@ create_address (const struct GNUNET_PeerIdentity *peer,
408 aa->plugin = GNUNET_strdup (plugin_name); 122 aa->plugin = GNUNET_strdup (plugin_name);
409 aa->session_id = session_id; 123 aa->session_id = session_id;
410 aa->local_address_info = local_address_info; 124 aa->local_address_info = local_address_info;
411 125 init_norm (&aa->norm_delay);
412 for (c1 = 0; c1 < GNUNET_ATS_QualityPropertiesCount; c1++) 126 init_norm (&aa->norm_distance);
413 { 127 init_norm (&aa->norm_utilization_in);
414 aa->atsin[c1].avg_queue_index = 0; 128 init_norm (&aa->norm_utilization_out);
415 aa->atsin[c1].norm = DEFAULT_REL_QUALITY;
416 for (c2 = 0; c2 < GAS_normalization_queue_length; c2++)
417 aa->atsin[c1].atsi_abs[c2] = GNUNET_ATS_VALUE_UNDEFINED;
418 }
419 return aa; 129 return aa;
420} 130}
421 131
@@ -486,31 +196,6 @@ find_exact_address (const struct GNUNET_PeerIdentity *peer,
486 196
487 197
488/** 198/**
489 * Extract an ATS performance info from an address
490 *
491 * @param address the address
492 * @param type the type to extract in HBO
493 * @return the value in HBO or #GNUNET_ATS_VALUE_UNDEFINED in HBO if value does not exist
494 */
495static int
496get_performance_info (struct ATS_Address *address,
497 uint32_t type)
498{
499 uint32_t c1;
500
501 if ((NULL == address->atsi) || (0 == address->atsi_count))
502 return GNUNET_ATS_VALUE_UNDEFINED;
503
504 for (c1 = 0; c1 < address->atsi_count; c1++)
505 {
506 if (ntohl (address->atsi[c1].type) == type)
507 return ntohl (address->atsi[c1].value);
508 }
509 return GNUNET_ATS_VALUE_UNDEFINED;
510}
511
512
513/**
514 * Add a new address for a peer. 199 * Add a new address for a peer.
515 * 200 *
516 * @param peer peer 201 * @param peer peer
@@ -519,8 +204,7 @@ get_performance_info (struct ATS_Address *address,
519 * @param plugin_addr_len length of the plugin address in @a plugin_addr 204 * @param plugin_addr_len length of the plugin address in @a plugin_addr
520 * @param local_address_info the local address for the address 205 * @param local_address_info the local address for the address
521 * @param session_id session id, can be 0 206 * @param session_id session id, can be 0
522 * @param atsi performance information for this address 207 * @param prop performance information for this address
523 * @param atsi_count number of performance information contained in @a atsi
524 */ 208 */
525void 209void
526GAS_addresses_add (const struct GNUNET_PeerIdentity *peer, 210GAS_addresses_add (const struct GNUNET_PeerIdentity *peer,
@@ -529,15 +213,12 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer,
529 size_t plugin_addr_len, 213 size_t plugin_addr_len,
530 uint32_t local_address_info, 214 uint32_t local_address_info,
531 uint32_t session_id, 215 uint32_t session_id,
532 const struct GNUNET_ATS_Information *atsi, 216 const struct GNUNET_ATS_Properties *prop)
533 uint32_t atsi_count)
534{ 217{
535 struct ATS_Address *new_address; 218 struct ATS_Address *new_address;
536 struct GNUNET_ATS_Information *atsi_delta;
537 uint32_t atsi_delta_count;
538 uint32_t addr_net;
539 219
540 if (NULL != find_exact_address (peer, session_id)) 220 if (NULL != find_exact_address (peer,
221 session_id))
541 { 222 {
542 GNUNET_break (0); 223 GNUNET_break (0);
543 return; 224 return;
@@ -548,17 +229,8 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer,
548 plugin_addr_len, 229 plugin_addr_len,
549 local_address_info, 230 local_address_info,
550 session_id); 231 session_id);
551 atsi_delta = NULL;
552 disassemble_ats_information (new_address,
553 atsi, atsi_count,
554 &atsi_delta,
555 &atsi_delta_count);
556 GNUNET_free_non_null (atsi_delta);
557 addr_net = get_performance_info (new_address, GNUNET_ATS_NETWORK_TYPE);
558 if (GNUNET_ATS_VALUE_UNDEFINED == addr_net)
559 addr_net = GNUNET_ATS_NET_UNSPECIFIED;
560
561 /* Add a new address */ 232 /* Add a new address */
233 new_address->properties = *prop;
562 new_address->t_added = GNUNET_TIME_absolute_get(); 234 new_address->t_added = GNUNET_TIME_absolute_get();
563 new_address->t_last_activity = GNUNET_TIME_absolute_get(); 235 new_address->t_last_activity = GNUNET_TIME_absolute_get();
564 GNUNET_assert(GNUNET_OK == 236 GNUNET_assert(GNUNET_OK ==
@@ -573,11 +245,8 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer,
573 session_id); 245 session_id);
574 /* Tell solver about new address */ 246 /* Tell solver about new address */
575 GAS_plugin_solver_lock (); 247 GAS_plugin_solver_lock ();
576 GAS_plugin_new_address (new_address, 248 GAS_plugin_new_address (new_address);
577 addr_net); 249 GAS_normalization_update_property (new_address); // FIXME: needed?
578 GAS_normalization_update_property (new_address,
579 atsi,
580 atsi_count);
581 GAS_plugin_solver_unlock (); 250 GAS_plugin_solver_unlock ();
582 /* Notify performance clients about new address */ 251 /* Notify performance clients about new address */
583 GAS_performance_notify_all_clients (&new_address->peer, 252 GAS_performance_notify_all_clients (&new_address->peer,
@@ -585,8 +254,7 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer,
585 new_address->addr, 254 new_address->addr,
586 new_address->addr_len, 255 new_address->addr_len,
587 new_address->active, 256 new_address->active,
588 new_address->atsi, 257 &new_address->properties,
589 new_address->atsi_count,
590 GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_out), 258 GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_out),
591 GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_in)); 259 GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_in));
592} 260}
@@ -597,18 +265,14 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer,
597 * 265 *
598 * @param peer peer 266 * @param peer peer
599 * @param session_id session id, never 0 267 * @param session_id session id, never 0
600 * @param atsi performance information for this address 268 * @param prop performance information for this address
601 * @param atsi_count number of performance information contained in @a atsi
602 */ 269 */
603void 270void
604GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, 271GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
605 uint32_t session_id, 272 uint32_t session_id,
606 const struct GNUNET_ATS_Information *atsi, 273 const struct GNUNET_ATS_Properties *prop)
607 uint32_t atsi_count)
608{ 274{
609 struct ATS_Address *aa; 275 struct ATS_Address *aa;
610 struct GNUNET_ATS_Information *atsi_delta;
611 uint32_t atsi_delta_count;
612 276
613 /* Get existing address */ 277 /* Get existing address */
614 aa = find_exact_address (peer, 278 aa = find_exact_address (peer,
@@ -630,30 +294,18 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
630 294
631 /* Update address */ 295 /* Update address */
632 aa->t_last_activity = GNUNET_TIME_absolute_get(); 296 aa->t_last_activity = GNUNET_TIME_absolute_get();
633 atsi_delta = NULL; 297 aa->properties = *prop;
634 atsi_delta_count = 0; 298 /* Notify performance clients about updated address */
635 if (GNUNET_YES == 299 GAS_performance_notify_all_clients (&aa->peer,
636 disassemble_ats_information (aa, atsi, 300 aa->plugin,
637 atsi_count, 301 aa->addr,
638 &atsi_delta, 302 aa->addr_len,
639 &atsi_delta_count)) 303 aa->active,
640 { 304 prop,
641 /* Notify performance clients about updated address */ 305 GNUNET_BANDWIDTH_value_init (aa->assigned_bw_out),
642 GAS_performance_notify_all_clients (&aa->peer, 306 GNUNET_BANDWIDTH_value_init (aa->assigned_bw_in));
643 aa->plugin, 307
644 aa->addr, 308 GAS_normalization_update_property (aa);
645 aa->addr_len,
646 aa->active,
647 aa->atsi,
648 aa->atsi_count,
649 GNUNET_BANDWIDTH_value_init (aa->assigned_bw_out),
650 GNUNET_BANDWIDTH_value_init (aa->assigned_bw_in));
651
652 GAS_normalization_update_property (aa,
653 atsi,
654 atsi_count);
655 }
656 GNUNET_free_non_null (atsi_delta);
657} 309}
658 310
659 311
@@ -793,7 +445,7 @@ peerinfo_it (void *cls,
793 addr->addr, 445 addr->addr,
794 addr->addr_len, 446 addr->addr_len,
795 addr->active, 447 addr->active,
796 addr->atsi, addr->atsi_count, 448 &addr->properties,
797 GNUNET_BANDWIDTH_value_init (addr->assigned_bw_out), 449 GNUNET_BANDWIDTH_value_init (addr->assigned_bw_out),
798 GNUNET_BANDWIDTH_value_init (addr->assigned_bw_in)); 450 GNUNET_BANDWIDTH_value_init (addr->assigned_bw_in));
799 return GNUNET_OK; 451 return GNUNET_OK;
@@ -839,7 +491,7 @@ GAS_addresses_get_peer_info (const struct GNUNET_PeerIdentity *peer,
839 pi_it (pi_it_cls, 491 pi_it (pi_it_cls,
840 NULL, NULL, NULL, 0, 492 NULL, NULL, NULL, 0,
841 GNUNET_NO, 493 GNUNET_NO,
842 NULL, 0, 494 NULL,
843 GNUNET_BANDWIDTH_ZERO, 495 GNUNET_BANDWIDTH_ZERO,
844 GNUNET_BANDWIDTH_ZERO); 496 GNUNET_BANDWIDTH_ZERO);
845} 497}
@@ -879,8 +531,7 @@ struct AddressIteration
879 * @param plugin_addr address 531 * @param plugin_addr address
880 * @param plugin_addr_len length of @a plugin_addr 532 * @param plugin_addr_len length of @a plugin_addr
881 * @param active #GNUNET_YES if this address is actively used 533 * @param active #GNUNET_YES if this address is actively used
882 * @param atsi ats performance information 534 * @param prop performance information
883 * @param atsi_count number of ats performance elements in @a atsi
884 * @param bandwidth_out current outbound bandwidth assigned to address 535 * @param bandwidth_out current outbound bandwidth assigned to address
885 * @param bandwidth_in current inbound bandwidth assigned to address 536 * @param bandwidth_in current inbound bandwidth assigned to address
886 */ 537 */
@@ -891,13 +542,11 @@ transmit_req_addr (struct AddressIteration *ai,
891 const void *plugin_addr, 542 const void *plugin_addr,
892 size_t plugin_addr_len, 543 size_t plugin_addr_len,
893 int active, 544 int active,
894 const struct GNUNET_ATS_Information *atsi, 545 const struct GNUNET_ATS_Properties *prop,
895 uint32_t atsi_count,
896 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 546 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
897 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) 547 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
898 548
899{ 549{
900 struct GNUNET_ATS_Information *atsp;
901 struct PeerInformationMessage *msg; 550 struct PeerInformationMessage *msg;
902 char *addrp; 551 char *addrp;
903 size_t plugin_name_length; 552 size_t plugin_name_length;
@@ -909,18 +558,13 @@ transmit_req_addr (struct AddressIteration *ai,
909 else 558 else
910 plugin_name_length = 0; 559 plugin_name_length = 0;
911 msize = sizeof (struct PeerInformationMessage) + 560 msize = sizeof (struct PeerInformationMessage) +
912 atsi_count * sizeof (struct GNUNET_ATS_Information) +
913 plugin_addr_len + plugin_name_length; 561 plugin_addr_len + plugin_name_length;
914 char buf[msize] GNUNET_ALIGN; 562 char buf[msize] GNUNET_ALIGN;
915 563
916 GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE); 564 GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE);
917 GNUNET_assert (atsi_count <
918 GNUNET_SERVER_MAX_MESSAGE_SIZE /
919 sizeof (struct GNUNET_ATS_Information));
920 msg = (struct PeerInformationMessage *) buf; 565 msg = (struct PeerInformationMessage *) buf;
921 msg->header.size = htons (msize); 566 msg->header.size = htons (msize);
922 msg->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_RESPONSE); 567 msg->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_RESPONSE);
923 msg->ats_count = htonl (atsi_count);
924 msg->id = htonl (ai->id); 568 msg->id = htonl (ai->id);
925 if (NULL != id) 569 if (NULL != id)
926 msg->peer = *id; 570 msg->peer = *id;
@@ -931,9 +575,9 @@ transmit_req_addr (struct AddressIteration *ai,
931 msg->plugin_name_length = htons (plugin_name_length); 575 msg->plugin_name_length = htons (plugin_name_length);
932 msg->bandwidth_out = bandwidth_out; 576 msg->bandwidth_out = bandwidth_out;
933 msg->bandwidth_in = bandwidth_in; 577 msg->bandwidth_in = bandwidth_in;
934 atsp = (struct GNUNET_ATS_Information *) &msg[1]; 578 GNUNET_ATS_properties_hton (&msg->properties,
935 memcpy (atsp, atsi, sizeof (struct GNUNET_ATS_Information) * atsi_count); 579 prop);
936 addrp = (char *) &atsp[atsi_count]; 580 addrp = (char *) &msg[1];
937 if (NULL != plugin_addr) 581 if (NULL != plugin_addr)
938 memcpy (addrp, plugin_addr, plugin_addr_len); 582 memcpy (addrp, plugin_addr, plugin_addr_len);
939 if (NULL != plugin_name) 583 if (NULL != plugin_name)
@@ -962,8 +606,7 @@ transmit_req_addr (struct AddressIteration *ai,
962 * @param plugin_addr address 606 * @param plugin_addr address
963 * @param plugin_addr_len length of @a plugin_addr 607 * @param plugin_addr_len length of @a plugin_addr
964 * @param active is address actively used 608 * @param active is address actively used
965 * @param atsi ats performance information 609 * @param prop performance information
966 * @param atsi_count number of ats performance elements in @a atsi
967 * @param bandwidth_out current outbound bandwidth assigned to address 610 * @param bandwidth_out current outbound bandwidth assigned to address
968 * @param bandwidth_in current inbound bandwidth assigned to address 611 * @param bandwidth_in current inbound bandwidth assigned to address
969 */ 612 */
@@ -974,8 +617,7 @@ req_addr_peerinfo_it (void *cls,
974 const void *plugin_addr, 617 const void *plugin_addr,
975 size_t plugin_addr_len, 618 size_t plugin_addr_len,
976 int active, 619 int active,
977 const struct GNUNET_ATS_Information *atsi, 620 const struct GNUNET_ATS_Properties *prop,
978 uint32_t atsi_count,
979 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 621 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
980 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) 622 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
981{ 623{
@@ -1006,8 +648,7 @@ req_addr_peerinfo_it (void *cls,
1006 plugin_name, 648 plugin_name,
1007 plugin_addr, plugin_addr_len, 649 plugin_addr, plugin_addr_len,
1008 active, 650 active,
1009 atsi, 651 prop,
1010 atsi_count,
1011 bandwidth_out, 652 bandwidth_out,
1012 bandwidth_in); 653 bandwidth_in);
1013} 654}
@@ -1061,7 +702,7 @@ GAS_handle_request_address_list (void *cls,
1061 transmit_req_addr (&ai, 702 transmit_req_addr (&ai,
1062 NULL, NULL, NULL, 703 NULL, NULL, NULL,
1063 0, GNUNET_NO, 704 0, GNUNET_NO,
1064 NULL, 0, 705 NULL,
1065 GNUNET_BANDWIDTH_ZERO, 706 GNUNET_BANDWIDTH_ZERO,
1066 GNUNET_BANDWIDTH_ZERO); 707 GNUNET_BANDWIDTH_ZERO);
1067 GNUNET_SERVER_receive_done (client, 708 GNUNET_SERVER_receive_done (client,
diff --git a/src/ats/gnunet-service-ats_addresses.h b/src/ats/gnunet-service-ats_addresses.h
index 2be8277e1..072a3d078 100644
--- a/src/ats/gnunet-service-ats_addresses.h
+++ b/src/ats/gnunet-service-ats_addresses.h
@@ -235,12 +235,12 @@ struct GAS_NormalizationInfo
235 /** 235 /**
236 * Averaging queue 236 * Averaging queue
237 */ 237 */
238 uint32_t atsi_abs[GAS_normalization_queue_length]; 238 uint64_t atsi_abs[GAS_normalization_queue_length];
239 239
240 /** 240 /**
241 * Averaged ATSI values from queue 241 * Averaged ATSI values from queue
242 */ 242 */
243 uint32_t avg; 243 uint64_t avg;
244 244
245 /** 245 /**
246 * Normalized values from queue to a range of values [1.0...2.0] 246 * Normalized values from queue to a range of values [1.0...2.0]
@@ -277,7 +277,7 @@ struct ATS_Address
277 /** 277 /**
278 * ATS performance information for this address 278 * ATS performance information for this address
279 */ 279 */
280 struct GNUNET_ATS_Information *atsi; 280 struct GNUNET_ATS_Properties properties;
281 281
282 /** 282 /**
283 * Time when address had last activity (update, in uses) 283 * Time when address had last activity (update, in uses)
@@ -336,10 +336,25 @@ struct ATS_Address
336 int active; 336 int active;
337 337
338 /** 338 /**
339 * Normalized ATS performance information for this address 339 * Normalized delay information for this address.
340 * Each entry can be accessed using the GNUNET_ATS_QualityProperties avg_queue_index
341 */ 340 */
342 struct GAS_NormalizationInfo atsin[GNUNET_ATS_QualityPropertiesCount]; 341 struct GAS_NormalizationInfo norm_delay;
342
343 /**
344 * Normalized distance information for this address.
345 */
346 struct GAS_NormalizationInfo norm_distance;
347
348 /**
349 * Normalized utilization inbound for this address.
350 */
351 struct GAS_NormalizationInfo norm_utilization_in;
352
353 /**
354 * Normalized utilization outbound for this address.
355 */
356 struct GAS_NormalizationInfo norm_utilization_out;
357
343}; 358};
344 359
345 360
@@ -375,8 +390,7 @@ GAS_addresses_done (void);
375 * @param plugin_addr_len length of the @a plugin_addr 390 * @param plugin_addr_len length of the @a plugin_addr
376 * @param local_address_info the local address for the address 391 * @param local_address_info the local address for the address
377 * @param session_id session id, can never be 0. 392 * @param session_id session id, can never be 0.
378 * @param atsi performance information for this address 393 * @param prop performance information for this address
379 * @param atsi_count number of performance information contained in @a atsi
380 */ 394 */
381void 395void
382GAS_addresses_add (const struct GNUNET_PeerIdentity *peer, 396GAS_addresses_add (const struct GNUNET_PeerIdentity *peer,
@@ -385,8 +399,7 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer,
385 size_t plugin_addr_len, 399 size_t plugin_addr_len,
386 uint32_t local_address_info, 400 uint32_t local_address_info,
387 uint32_t session_id, 401 uint32_t session_id,
388 const struct GNUNET_ATS_Information *atsi, 402 const struct GNUNET_ATS_Properties *prop);
389 uint32_t atsi_count);
390 403
391 404
392/** 405/**
@@ -394,14 +407,12 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer,
394 * 407 *
395 * @param peer peer 408 * @param peer peer
396 * @param session_id session id, can never be 0 409 * @param session_id session id, can never be 0
397 * @param atsi performance information for this address 410 * @param prop performance information for this address
398 * @param atsi_count number of performance information contained in @a atsi
399 */ 411 */
400void 412void
401GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, 413GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
402 uint32_t session_id, 414 uint32_t session_id,
403 const struct GNUNET_ATS_Information *atsi, 415 const struct GNUNET_ATS_Properties *prop);
404 uint32_t atsi_count);
405 416
406 417
407/** 418/**
@@ -432,7 +443,6 @@ GAS_addresses_destroy_all (void);
432 * @param plugin_addr_len length of @a plugin_addr 443 * @param plugin_addr_len length of @a plugin_addr
433 * @param address_active is address actively used 444 * @param address_active is address actively used
434 * @param atsi ats performance information 445 * @param atsi ats performance information
435 * @param atsi_count number of ats performance elements in @a atsi
436 * @param bandwidth_out current outbound bandwidth assigned to address 446 * @param bandwidth_out current outbound bandwidth assigned to address
437 * @param bandwidth_in current inbound bandwidth assigned to address 447 * @param bandwidth_in current inbound bandwidth assigned to address
438 */ 448 */
@@ -443,8 +453,7 @@ typedef void
443 const void *plugin_addr, 453 const void *plugin_addr,
444 size_t plugin_addr_len, 454 size_t plugin_addr_len,
445 const int address_active, 455 const int address_active,
446 const struct GNUNET_ATS_Information *atsi, 456 const struct GNUNET_ATS_Properties *prop,
447 uint32_t atsi_count,
448 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 457 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
449 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in); 458 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in);
450 459
diff --git a/src/ats/gnunet-service-ats_normalization.c b/src/ats/gnunet-service-ats_normalization.c
index 936f8ca34..c10e5070f 100644
--- a/src/ats/gnunet-service-ats_normalization.c
+++ b/src/ats/gnunet-service-ats_normalization.c
@@ -37,103 +37,65 @@
37/** 37/**
38 * Range information for normalization of quality properties. 38 * Range information for normalization of quality properties.
39 */ 39 */
40struct Property 40struct PropertyRange
41{ 41{
42 /** 42 /**
43 * Index into the properties array.
44 */
45 uint32_t prop_type;
46
47 /**
48 * Corresponding enum value of the respective quality property.
49 */
50 enum GNUNET_ATS_Property atsi_type;
51
52 /**
53 * Minimum value we see for this property across all addresses. 43 * Minimum value we see for this property across all addresses.
54 */ 44 */
55 uint32_t min; 45 struct GNUNET_ATS_Properties min;
56 46
57 /** 47 /**
58 * Maximum value we see for this property across all addresses. 48 * Maximum value we see for this property across all addresses.
59 */ 49 */
60 uint32_t max; 50 struct GNUNET_ATS_Properties max;
61}; 51};
62 52
63 53
64/** 54/**
65 * Range information for all quality properties we see. 55 * Range information for all quality properties we see.
66 */ 56 */
67static struct Property properties[GNUNET_ATS_QualityPropertiesCount]; 57static struct PropertyRange property_range;
68
69 58
70 59
71/** 60/**
72 * Add the value from @a atsi to the running average of the 61 * Add the value from @a atsi to the running average of the
73 * given @a ni quality property. 62 * given @a ni quality property.
74 * 63 *
64 * @param current_val the updated value
75 * @param ni normalization information to update 65 * @param ni normalization information to update
76 * @param atsi the ats information
77 */ 66 */
78static void 67static void
79property_average (struct GAS_NormalizationInfo *ni, 68update_avg (uint64_t current_val,
80 const struct GNUNET_ATS_Information *atsi) 69 struct GAS_NormalizationInfo *ni)
81{ 70{
82 uint32_t current_val; 71 double sum;
83 uint32_t res;
84 uint64_t sum;
85 uint32_t count; 72 uint32_t count;
86 unsigned int c1; 73 unsigned int c1;
87 74
88 current_val = ntohl (atsi->value);
89 GNUNET_assert (GNUNET_ATS_VALUE_UNDEFINED != current_val);
90 ni->atsi_abs[ni->avg_queue_index++] = current_val; 75 ni->atsi_abs[ni->avg_queue_index++] = current_val;
91 if (GAS_normalization_queue_length == ni->avg_queue_index) 76 if (GAS_normalization_queue_length == ni->avg_queue_index)
92 ni->avg_queue_index = 0; 77 ni->avg_queue_index = 0;
93 count = 0; 78 count = 0;
94 sum = 0; 79 sum = 0.0;
95 for (c1 = 0; c1 < GAS_normalization_queue_length; c1++) 80 for (c1 = 0; c1 < GAS_normalization_queue_length; c1++)
96 { 81 {
97 if (GNUNET_ATS_VALUE_UNDEFINED != ni->atsi_abs[c1]) 82 if (UINT64_MAX != ni->atsi_abs[c1])
98 { 83 {
99 count++; 84 count++;
100 sum += ni->atsi_abs[c1]; 85 sum += (double) ni->atsi_abs[c1];
101 } 86 }
102 } 87 }
103 GNUNET_assert (0 != count); 88 GNUNET_assert (0 != count);
104 res = sum / count; 89 ni->avg = sum / count;
105 ni->avg = res;
106} 90}
107 91
108 92
109/** 93/**
110 * Closure for #find_min_max_it().
111 */
112struct FindMinMaxCtx
113{
114 /**
115 * Property we are looking for.
116 */
117 struct Property *p;
118
119 /**
120 * Set to mimimum value observed.
121 */
122 uint32_t min;
123
124 /**
125 * Set to maximum value observed.
126 */
127 uint32_t max;
128};
129
130
131/**
132 * Function called for all addresses and peers to find the minimum and 94 * Function called for all addresses and peers to find the minimum and
133 * maximum (averaged) values for a given quality property. Given 95 * maximum (averaged) values for a given quality property. Given
134 * those, we can then calculate the normalized score. 96 * those, we can then calculate the normalized score.
135 * 97 *
136 * @param cls the `struct FindMinMaxCtx` 98 * @param cls the `struct PropertyRange`
137 * @param h which peer are we looking at (ignored) 99 * @param h which peer are we looking at (ignored)
138 * @param k the address for that peer 100 * @param k the address for that peer
139 * @return #GNUNET_OK (continue to iterate) 101 * @return #GNUNET_OK (continue to iterate)
@@ -143,23 +105,55 @@ find_min_max_it (void *cls,
143 const struct GNUNET_PeerIdentity *h, 105 const struct GNUNET_PeerIdentity *h,
144 void *k) 106 void *k)
145{ 107{
146 struct FindMinMaxCtx *find_res = cls; 108 struct PropertyRange *pr = cls;
147 const struct ATS_Address *a = k; 109 const struct ATS_Address *a = k;
148 110
149 find_res->max = GNUNET_MAX (find_res->max, 111 pr->max.utilization_out = GNUNET_MAX (pr->max.utilization_out,
150 a->atsin[find_res->p->prop_type].avg); 112 a->properties.utilization_out);
151 find_res->min = GNUNET_MIN (find_res->min, 113 pr->max.utilization_in = GNUNET_MAX (pr->max.utilization_in,
152 a->atsin[find_res->p->prop_type].avg); 114 a->properties.utilization_in);
115 pr->max.distance = GNUNET_MAX (pr->max.distance,
116 a->properties.distance);
117 pr->max.delay = GNUNET_TIME_relative_max (pr->max.delay,
118 a->properties.delay);
119 pr->min.utilization_out = GNUNET_MIN (pr->min.utilization_out,
120 a->properties.utilization_out);
121 pr->min.utilization_in = GNUNET_MIN (pr->min.utilization_in,
122 a->properties.utilization_in);
123 pr->min.distance = GNUNET_MIN (pr->min.distance,
124 a->properties.distance);
125 pr->min.delay = GNUNET_TIME_relative_min (pr->min.delay,
126 a->properties.delay);
153 return GNUNET_OK; 127 return GNUNET_OK;
154} 128}
155 129
156 130
157/** 131/**
132 * Compute the normalized value from the given @a ni range
133 * data and the average value.
134 *
135 * @param min minimum value
136 * @param max maximum value
137 * @param ni normalization information to update
138 */
139static void
140update_norm (uint64_t min,
141 uint64_t max,
142 struct GAS_NormalizationInfo *ni)
143{
144 /* max - 2 * min + avg_value / (max - min) */
145 if (min < max)
146 ni->norm = DEFAULT_REL_QUALITY + (ni->avg - min) / (double) (max - min);
147 else
148 ni->norm = DEFAULT_REL_QUALITY;
149}
150
151
152/**
158 * Normalize the property value for a given address based 153 * Normalize the property value for a given address based
159 * on the range we know that property value has globally. 154 * on the range we know that property values have globally.
160 * 155 *
161 * @param cls the `struct Property` with details on the 156 * @param cls NULL
162 * property and its global range
163 * @param key which peer are we looking at (ignored) 157 * @param key which peer are we looking at (ignored)
164 * @param value the address for that peer, from where we get 158 * @param value the address for that peer, from where we get
165 * the original value and where we write the 159 * the original value and where we write the
@@ -171,33 +165,20 @@ normalize_address (void *cls,
171 const struct GNUNET_PeerIdentity *key, 165 const struct GNUNET_PeerIdentity *key,
172 void *value) 166 void *value)
173{ 167{
174 struct Property *p = cls;
175 struct ATS_Address *address = value; 168 struct ATS_Address *address = value;
176 double delta;
177 double update;
178 uint32_t avg_value;
179
180 avg_value = address->atsin[p->prop_type].avg;
181 delta = p->max - p->min;
182 /* max - 2 * min + avg_value / (max - min) */
183 if (delta > DBL_EPSILON)
184 update = DEFAULT_REL_QUALITY + (avg_value - p->min) / delta;
185 else
186 update = DEFAULT_REL_QUALITY;
187 169
188 if (update == address->atsin[p->prop_type].norm) 170 update_norm (property_range.min.delay.rel_value_us,
189 return GNUNET_OK; 171 property_range.max.delay.rel_value_us,
190 address->atsin[p->prop_type].norm = update; 172 &address->norm_delay);
191 173 update_norm (property_range.min.distance,
192 LOG (GNUNET_ERROR_TYPE_DEBUG, 174 property_range.max.distance,
193 "Normalize `%s' address %p's '%s' with value %u to range [%u..%u] = %.3f\n", 175 &address->norm_distance);
194 GNUNET_i2s (&address->peer), 176 update_norm (property_range.min.utilization_in,
195 address, 177 property_range.max.utilization_in,
196 GNUNET_ATS_print_property_type (p->atsi_type), 178 &address->norm_utilization_in);
197 address->atsin[p->prop_type].avg, 179 update_norm (property_range.min.utilization_out,
198 p->min, 180 property_range.max.utilization_out,
199 p->max, 181 &address->norm_utilization_out);
200 address->atsin[p->prop_type].norm);
201 return GNUNET_OK; 182 return GNUNET_OK;
202} 183}
203 184
@@ -205,8 +186,7 @@ normalize_address (void *cls,
205/** 186/**
206 * Notify about change in normalized property. 187 * Notify about change in normalized property.
207 * 188 *
208 * @param cls the `struct Property` with details on the 189 * @param cls NULL
209 * property and its global range
210 * @param key which peer are we looking at (ignored) 190 * @param key which peer are we looking at (ignored)
211 * @param value the address for that peer 191 * @param value the address for that peer
212 * @return #GNUNET_OK (continue to iterate) 192 * @return #GNUNET_OK (continue to iterate)
@@ -216,104 +196,84 @@ notify_change (void *cls,
216 const struct GNUNET_PeerIdentity *key, 196 const struct GNUNET_PeerIdentity *key,
217 void *value) 197 void *value)
218{ 198{
219 struct Property *p = cls;
220 struct ATS_Address *address = value; 199 struct ATS_Address *address = value;
221 200
222 GAS_plugin_notify_property_changed (address, 201 GAS_plugin_notify_property_changed (address);
223 p->atsi_type,
224 address->atsin[p->prop_type].norm);
225 return GNUNET_OK; 202 return GNUNET_OK;
226} 203}
227 204
228 205
229/** 206/**
207 * Initialize property range to the values corresponding
208 * to an empty set.
209 *
210 * @param pr range to initialize
211 */
212static void
213init_range (struct PropertyRange *pr)
214{
215 memset (pr, 0, sizeof (struct PropertyRange));
216 pr->min.utilization_out = UINT32_MAX;
217 pr->min.utilization_in = UINT32_MAX;
218 pr->min.distance = UINT32_MAX;
219 pr->min.delay = GNUNET_TIME_UNIT_FOREVER_REL;
220}
221
222
223/**
230 * Update and normalize atsi performance information 224 * Update and normalize atsi performance information
231 * 225 *
232 * @param address the address to update 226 * @param address the address to update
233 * @param atsi the array of performance information
234 * @param atsi_count the number of atsi information in the array
235 */ 227 */
236void 228void
237GAS_normalization_update_property (struct ATS_Address *address, 229GAS_normalization_update_property (struct ATS_Address *address)
238 const struct GNUNET_ATS_Information *atsi,
239 uint32_t atsi_count)
240{ 230{
241 unsigned int c1; 231 const struct GNUNET_ATS_Properties *prop = &address->properties;
242 unsigned int c2; 232 struct PropertyRange range;
243 uint32_t current_type;
244 uint32_t old;
245 struct FindMinMaxCtx find_ctx;
246 int range_changed; 233 int range_changed;
247 234
248 LOG (GNUNET_ERROR_TYPE_DEBUG, 235 LOG (GNUNET_ERROR_TYPE_DEBUG,
249 "Updating %u elements for peer `%s'\n", 236 "Updating properties for peer `%s'\n",
250 atsi_count,
251 GNUNET_i2s (&address->peer)); 237 GNUNET_i2s (&address->peer));
252 GAS_plugin_solver_lock (); 238 GAS_plugin_solver_lock ();
253 for (c1 = 0; c1 < atsi_count; c1++) 239 update_avg (prop->delay.rel_value_us,
240 &address->norm_delay);
241 update_avg (prop->distance,
242 &address->norm_distance);
243 update_avg (prop->utilization_in,
244 &address->norm_utilization_in);
245 update_avg (prop->utilization_in,
246 &address->norm_utilization_out);
247
248 init_range (&range);
249 GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses,
250 &find_min_max_it,
251 &range);
252 if (0 != memcmp (&range,
253 &property_range,
254 sizeof (struct PropertyRange)))
254 { 255 {
255 current_type = ntohl (atsi[c1].type); 256 /* limits changed, (re)normalize all addresses */
256 257 property_range = range;
257 for (c2 = 0; c2 < GNUNET_ATS_QualityPropertiesCount; c2++) 258 range_changed = GNUNET_YES;
258 if (current_type == properties[c2].atsi_type)
259 break;
260 if (GNUNET_ATS_QualityPropertiesCount == c2)
261 {
262 /* Not a quality property, continue with next element */
263 continue;
264 }
265 /* Calculate running average */
266 old = address->atsin[c2].avg;
267 property_average (&address->atsin[c2],
268 &atsi[c1]);
269 if (old == address->atsin[c2].avg)
270 continue; /* no change */
271 range_changed = GNUNET_NO;
272 if ( (old == properties[c2].min) ||
273 (old == properties[c2].max) ||
274 (address->atsin[c2].avg < properties[c2].min) ||
275 (address->atsin[c2].avg > properties[c2].max) )
276 {
277 /* need to re-calculate min/max range, as it may have changed */
278 find_ctx.p = &properties[c2];
279 find_ctx.max = 0;
280 find_ctx.min = UINT32_MAX;
281 if (0 ==
282 GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses,
283 &find_min_max_it,
284 &find_ctx))
285 {
286 GNUNET_break(0);
287 continue;
288 }
289 if ( (find_ctx.min != properties[c2].min) ||
290 (find_ctx.max != properties[c2].max) )
291 {
292 properties[c2].min = find_ctx.min;
293 properties[c2].max = find_ctx.max;
294 /* limits changed, (re)normalize all addresses */
295 range_changed = GNUNET_YES;
296 }
297 }
298 if (GNUNET_YES == range_changed)
299 GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses,
300 &normalize_address,
301 &properties[c2]);
302 else
303 normalize_address (&properties[c2],
304 &address->peer,
305 address);
306 /* after all peers have been updated, notify about changes */
307 if (GNUNET_YES == range_changed)
308 GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses,
309 &notify_change,
310 &properties[c2]);
311 else
312 notify_change (&properties[c2],
313 &address->peer,
314 address);
315
316 } 259 }
260 if (GNUNET_YES == range_changed)
261 GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses,
262 &normalize_address,
263 NULL);
264 else
265 normalize_address (NULL,
266 &address->peer,
267 address);
268 /* after all peers have been updated, notify about changes */
269 if (GNUNET_YES == range_changed)
270 GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses,
271 &notify_change,
272 NULL);
273 else
274 notify_change (NULL,
275 &address->peer,
276 address);
317 GAS_plugin_solver_unlock (); 277 GAS_plugin_solver_unlock ();
318} 278}
319 279
@@ -324,16 +284,7 @@ GAS_normalization_update_property (struct ATS_Address *address,
324void 284void
325GAS_normalization_start () 285GAS_normalization_start ()
326{ 286{
327 unsigned int c1; 287 init_range (&property_range);
328 const unsigned int existing_properties[] = GNUNET_ATS_QualityProperties;
329
330 for (c1 = 0; c1 < GNUNET_ATS_QualityPropertiesCount; c1++)
331 {
332 properties[c1].prop_type = c1;
333 properties[c1].atsi_type = existing_properties[c1];
334 properties[c1].min = UINT32_MAX;
335 properties[c1].max = 0;
336 }
337} 288}
338 289
339 290
diff --git a/src/ats/gnunet-service-ats_normalization.h b/src/ats/gnunet-service-ats_normalization.h
index 2ce9d726f..2a9f68b60 100644
--- a/src/ats/gnunet-service-ats_normalization.h
+++ b/src/ats/gnunet-service-ats_normalization.h
@@ -35,16 +35,12 @@
35 35
36 36
37/** 37/**
38 * Update and normalize a @a atsi performance information 38 * Update and normalize a @a prop performance information
39 * 39 *
40 * @param address the address to update 40 * @param address the address to update
41 * @param atsi the array of performance information
42 * @param atsi_count the number of atsi information in the array
43 */ 41 */
44void 42void
45GAS_normalization_update_property (struct ATS_Address *address, 43GAS_normalization_update_property (struct ATS_Address *address);
46 const struct GNUNET_ATS_Information *atsi,
47 uint32_t atsi_count);
48 44
49 45
50/** 46/**
diff --git a/src/ats/gnunet-service-ats_performance.c b/src/ats/gnunet-service-ats_performance.c
index 0f17f0bec..c3d9e78eb 100644
--- a/src/ats/gnunet-service-ats_performance.c
+++ b/src/ats/gnunet-service-ats_performance.c
@@ -54,8 +54,7 @@ static struct GNUNET_SERVER_NotificationContext *nc_pic;
54 * to maintain a connection to a peer; 54 * to maintain a connection to a peer;
55 * #GNUNET_NO if the address is not actively used; 55 * #GNUNET_NO if the address is not actively used;
56 * #GNUNET_SYSERR if this address is no longer available for ATS 56 * #GNUNET_SYSERR if this address is no longer available for ATS
57 * @param atsi performance data for the address 57 * @param prop performance data for the address
58 * @param atsi_count number of performance records in @a atsi
59 * @param bandwidth_out assigned outbound bandwidth 58 * @param bandwidth_out assigned outbound bandwidth
60 * @param bandwidth_in assigned inbound bandwidth 59 * @param bandwidth_in assigned inbound bandwidth
61 */ 60 */
@@ -66,40 +65,34 @@ notify_client (struct GNUNET_SERVER_Client *client,
66 const void *plugin_addr, 65 const void *plugin_addr,
67 size_t plugin_addr_len, 66 size_t plugin_addr_len,
68 int active, 67 int active,
69 const struct GNUNET_ATS_Information *atsi, 68 const struct GNUNET_ATS_Properties *prop,
70 uint32_t atsi_count,
71 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 69 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
72 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) 70 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
73{ 71{
74 struct PeerInformationMessage *msg; 72 struct PeerInformationMessage *msg;
75 size_t plugin_name_length = strlen (plugin_name) + 1; 73 size_t plugin_name_length = strlen (plugin_name) + 1;
76 size_t msize = 74 size_t msize =
77 sizeof (struct PeerInformationMessage) + 75 sizeof (struct PeerInformationMessage) +
78 atsi_count * sizeof (struct GNUNET_ATS_Information) + plugin_addr_len + 76 plugin_addr_len +
79 plugin_name_length; 77 plugin_name_length;
80 char buf[msize] GNUNET_ALIGN; 78 char buf[msize] GNUNET_ALIGN;
81 struct GNUNET_ATS_Information *atsp;
82 struct GNUNET_SERVER_NotificationContext *nc; 79 struct GNUNET_SERVER_NotificationContext *nc;
83 char *addrp; 80 char *addrp;
84 81
85 GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE); 82 GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE);
86 GNUNET_assert (atsi_count <
87 GNUNET_SERVER_MAX_MESSAGE_SIZE /
88 sizeof (struct GNUNET_ATS_Information));
89 msg = (struct PeerInformationMessage *) buf; 83 msg = (struct PeerInformationMessage *) buf;
90 msg->header.size = htons (msize); 84 msg->header.size = htons (msize);
91 msg->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_PEER_INFORMATION); 85 msg->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_PEER_INFORMATION);
92 msg->id = htonl (0); 86 msg->id = htonl (0);
93 msg->ats_count = htonl (atsi_count);
94 msg->peer = *peer; 87 msg->peer = *peer;
95 msg->address_length = htons (plugin_addr_len); 88 msg->address_length = htons (plugin_addr_len);
96 msg->address_active = ntohl ((uint32_t) active); 89 msg->address_active = ntohl ((uint32_t) active);
97 msg->plugin_name_length = htons (plugin_name_length); 90 msg->plugin_name_length = htons (plugin_name_length);
98 msg->bandwidth_out = bandwidth_out; 91 msg->bandwidth_out = bandwidth_out;
99 msg->bandwidth_in = bandwidth_in; 92 msg->bandwidth_in = bandwidth_in;
100 atsp = (struct GNUNET_ATS_Information *) &msg[1]; 93 GNUNET_ATS_properties_hton (&msg->properties,
101 memcpy (atsp, atsi, sizeof (struct GNUNET_ATS_Information) * atsi_count); 94 prop);
102 addrp = (char *) &atsp[atsi_count]; 95 addrp = (char *) &msg[1];
103 memcpy (addrp, plugin_addr, plugin_addr_len); 96 memcpy (addrp, plugin_addr, plugin_addr_len);
104 strcpy (&addrp[plugin_addr_len], plugin_name); 97 strcpy (&addrp[plugin_addr_len], plugin_name);
105 if (NULL == client) 98 if (NULL == client)
@@ -137,8 +130,7 @@ notify_client (struct GNUNET_SERVER_Client *client,
137 * to maintain a connection to a peer; 130 * to maintain a connection to a peer;
138 * #GNUNET_NO if the address is not actively used; 131 * #GNUNET_NO if the address is not actively used;
139 * #GNUNET_SYSERR if this address is no longer available for ATS 132 * #GNUNET_SYSERR if this address is no longer available for ATS
140 * @param atsi performance data for the address 133 * @param prop performance data for the address
141 * @param atsi_count number of performance records in @a atsi
142 * @param bandwidth_out assigned outbound bandwidth 134 * @param bandwidth_out assigned outbound bandwidth
143 * @param bandwidth_in assigned inbound bandwidth 135 * @param bandwidth_in assigned inbound bandwidth
144 */ 136 */
@@ -148,8 +140,7 @@ GAS_performance_notify_all_clients (const struct GNUNET_PeerIdentity *peer,
148 const void *plugin_addr, 140 const void *plugin_addr,
149 size_t plugin_addr_len, 141 size_t plugin_addr_len,
150 int active, 142 int active,
151 const struct GNUNET_ATS_Information *atsi, 143 const struct GNUNET_ATS_Properties *prop,
152 uint32_t atsi_count,
153 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 144 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
154 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) 145 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
155{ 146{
@@ -159,7 +150,7 @@ GAS_performance_notify_all_clients (const struct GNUNET_PeerIdentity *peer,
159 plugin_addr, 150 plugin_addr,
160 plugin_addr_len, 151 plugin_addr_len,
161 active, 152 active,
162 atsi, atsi_count, 153 prop,
163 bandwidth_out, 154 bandwidth_out,
164 bandwidth_in); 155 bandwidth_in);
165 GNUNET_STATISTICS_update (GSA_stats, 156 GNUNET_STATISTICS_update (GSA_stats,
@@ -178,8 +169,7 @@ GAS_performance_notify_all_clients (const struct GNUNET_PeerIdentity *peer,
178 * @param plugin_addr address 169 * @param plugin_addr address
179 * @param plugin_addr_len length of @a plugin_addr 170 * @param plugin_addr_len length of @a plugin_addr
180 * @param active is address actively used 171 * @param active is address actively used
181 * @param atsi ats performance information 172 * @param prop performance information
182 * @param atsi_count number of ats performance elements in @a atsi
183 * @param bandwidth_out current outbound bandwidth assigned to address 173 * @param bandwidth_out current outbound bandwidth assigned to address
184 * @param bandwidth_in current inbound bandwidth assigned to address 174 * @param bandwidth_in current inbound bandwidth assigned to address
185 */ 175 */
@@ -190,8 +180,7 @@ peerinfo_it (void *cls,
190 const void *plugin_addr, 180 const void *plugin_addr,
191 size_t plugin_addr_len, 181 size_t plugin_addr_len,
192 int active, 182 int active,
193 const struct GNUNET_ATS_Information *atsi, 183 const struct GNUNET_ATS_Properties *prop,
194 uint32_t atsi_count,
195 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 184 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
196 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) 185 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
197{ 186{
@@ -211,7 +200,7 @@ peerinfo_it (void *cls,
211 plugin_addr, 200 plugin_addr,
212 plugin_addr_len, 201 plugin_addr_len,
213 active, 202 active,
214 atsi, atsi_count, 203 prop,
215 bandwidth_out, 204 bandwidth_out,
216 bandwidth_in); 205 bandwidth_in);
217} 206}
diff --git a/src/ats/gnunet-service-ats_performance.h b/src/ats/gnunet-service-ats_performance.h
index 87712552f..abdeb975f 100644
--- a/src/ats/gnunet-service-ats_performance.h
+++ b/src/ats/gnunet-service-ats_performance.h
@@ -44,8 +44,7 @@
44 * to maintain a connection to a peer; 44 * to maintain a connection to a peer;
45 * #GNUNET_NO if the address is not actively used; 45 * #GNUNET_NO if the address is not actively used;
46 * #GNUNET_SYSERR if this address is no longer available for ATS 46 * #GNUNET_SYSERR if this address is no longer available for ATS
47 * @param atsi performance data for the address 47 * @param prop performance data for the address
48 * @param atsi_count number of performance records in @a atsi
49 * @param bandwidth_out assigned outbound bandwidth 48 * @param bandwidth_out assigned outbound bandwidth
50 * @param bandwidth_in assigned inbound bandwidth 49 * @param bandwidth_in assigned inbound bandwidth
51 */ 50 */
@@ -55,8 +54,7 @@ GAS_performance_notify_all_clients (const struct GNUNET_PeerIdentity *peer,
55 const void *plugin_addr, 54 const void *plugin_addr,
56 size_t plugin_addr_len, 55 size_t plugin_addr_len,
57 int active, 56 int active,
58 const struct GNUNET_ATS_Information *atsi, 57 const struct GNUNET_ATS_Properties *prop,
59 uint32_t atsi_count,
60 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 58 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
61 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in); 59 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in);
62 60
diff --git a/src/ats/gnunet-service-ats_plugins.c b/src/ats/gnunet-service-ats_plugins.c
index fbc047a33..b0bbb910b 100644
--- a/src/ats/gnunet-service-ats_plugins.c
+++ b/src/ats/gnunet-service-ats_plugins.c
@@ -70,22 +70,15 @@ GAS_plugin_notify_preference_changed (const struct GNUNET_PeerIdentity *peer,
70 70
71 71
72/** 72/**
73 * The relative value for a property changed 73 * The relative value for a property changed.
74 * 74 *
75 * @param address the peer 75 * @param address the peer for which a property changed
76 * @param type the ATS type
77 * @param prop_rel the new relative preference value
78 */ 76 */
79void 77void
80GAS_plugin_notify_property_changed (struct ATS_Address *address, 78GAS_plugin_notify_property_changed (struct ATS_Address *address)
81 enum GNUNET_ATS_Property type,
82 double prop_rel)
83{ 79{
84 sf->s_address_update_property (sf->cls, 80 sf->s_address_update_property (sf->cls,
85 address, 81 address);
86 type,
87 0,
88 prop_rel);
89} 82}
90 83
91 84
@@ -221,8 +214,7 @@ bandwidth_changed_cb (void *cls,
221 address->addr, 214 address->addr,
222 address->addr_len, 215 address->addr_len,
223 address->active, 216 address->active,
224 address->atsi, 217 &address->properties,
225 address->atsi_count,
226 GNUNET_BANDWIDTH_value_init (address->assigned_bw_out), 218 GNUNET_BANDWIDTH_value_init (address->assigned_bw_out),
227 GNUNET_BANDWIDTH_value_init (address->assigned_bw_in)); 219 GNUNET_BANDWIDTH_value_init (address->assigned_bw_in));
228 220
@@ -481,15 +473,13 @@ GAS_plugin_done ()
481 * for talking to the respective peer. 473 * for talking to the respective peer.
482 * 474 *
483 * @param new_address the new address 475 * @param new_address the new address
484 * @param addr_net network scope the address is in
485 */ 476 */
486void 477void
487GAS_plugin_new_address (struct ATS_Address *new_address, 478GAS_plugin_new_address (struct ATS_Address *new_address)
488 enum GNUNET_ATS_Network_Type addr_net)
489{ 479{
490 sf->s_add (sf->cls, 480 sf->s_add (sf->cls,
491 new_address, 481 new_address,
492 addr_net); 482 new_address->properties.scope); /* FIXME: remove 3rd arg here! */
493} 483}
494 484
495 485
diff --git a/src/ats/gnunet-service-ats_plugins.h b/src/ats/gnunet-service-ats_plugins.h
index 7d76f6431..66eafa4c8 100644
--- a/src/ats/gnunet-service-ats_plugins.h
+++ b/src/ats/gnunet-service-ats_plugins.h
@@ -65,16 +65,12 @@ GAS_plugin_notify_preference_changed (const struct GNUNET_PeerIdentity *peer,
65 65
66 66
67/** 67/**
68 * The relative value for a property changed 68 * The relative value for a property changed.
69 * 69 *
70 * @param address the peer 70 * @param address the peer
71 * @param type the ATS type
72 * @param prop_rel the new relative property value
73 */ 71 */
74void 72void
75GAS_plugin_notify_property_changed (struct ATS_Address *address, 73GAS_plugin_notify_property_changed (struct ATS_Address *address);
76 enum GNUNET_ATS_Property type,
77 double prop_rel);
78 74
79 75
80/** 76/**
@@ -85,8 +81,7 @@ GAS_plugin_notify_property_changed (struct ATS_Address *address,
85 * @param addr_net network scope the address is in 81 * @param addr_net network scope the address is in
86 */ 82 */
87void 83void
88GAS_plugin_new_address (struct ATS_Address *new_address, 84GAS_plugin_new_address (struct ATS_Address *new_address);
89 enum GNUNET_ATS_Network_Type addr_net);
90 85
91 86
92/** 87/**
diff --git a/src/ats/gnunet-service-ats_preferences.c b/src/ats/gnunet-service-ats_preferences.c
index 3be6d3525..8c0b13ab0 100644
--- a/src/ats/gnunet-service-ats_preferences.c
+++ b/src/ats/gnunet-service-ats_preferences.c
@@ -62,7 +62,7 @@ struct PeerRelative
62 * Array of relative preference values, to be indexed by 62 * Array of relative preference values, to be indexed by
63 * an `enum GNUNET_ATS_PreferenceKind`. 63 * an `enum GNUNET_ATS_PreferenceKind`.
64 */ 64 */
65 double f_rel[GNUNET_ATS_PreferenceCount]; 65 double f_rel[GNUNET_ATS_PREFERENCE_END];
66 66
67 /** 67 /**
68 * Number of clients that are expressing a preference for 68 * Number of clients that are expressing a preference for
@@ -99,14 +99,14 @@ struct PreferencePeer
99 * Absolute preference values for all preference types 99 * Absolute preference values for all preference types
100 * as expressed by this client for this peer. 100 * as expressed by this client for this peer.
101 */ 101 */
102 double f_abs[GNUNET_ATS_PreferenceCount]; 102 double f_abs[GNUNET_ATS_PREFERENCE_END];
103 103
104 /** 104 /**
105 * Relative preference values for all preference types, 105 * Relative preference values for all preference types,
106 * normalized in [0..1] based on how the respective 106 * normalized in [0..1] based on how the respective
107 * client scored other peers. 107 * client scored other peers.
108 */ 108 */
109 double f_rel[GNUNET_ATS_PreferenceCount]; 109 double f_rel[GNUNET_ATS_PREFERENCE_END];
110 110
111}; 111};
112 112
@@ -144,7 +144,7 @@ struct PreferenceClient
144 * Array of sums of absolute preferences for all 144 * Array of sums of absolute preferences for all
145 * peers as expressed by this client. 145 * peers as expressed by this client.
146 */ 146 */
147 double f_abs_sum[GNUNET_ATS_PreferenceCount]; 147 double f_abs_sum[GNUNET_ATS_PREFERENCE_END];
148 148
149}; 149};
150 150
@@ -353,7 +353,7 @@ age_values (void *cls,
353 int dead; 353 int dead;
354 354
355 dead = GNUNET_YES; 355 dead = GNUNET_YES;
356 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) 356 for (i = 0; i < GNUNET_ATS_PREFERENCE_END; i++)
357 { 357 {
358 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 358 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
359 "Aging preference for peer `%s'\n", 359 "Aging preference for peer `%s'\n",
@@ -563,7 +563,7 @@ update_preference (struct GNUNET_SERVER_Client *client,
563 struct PeerRelative *r_cur; 563 struct PeerRelative *r_cur;
564 unsigned int i; 564 unsigned int i;
565 565
566 if (kind >= GNUNET_ATS_PreferenceCount) 566 if (kind >= GNUNET_ATS_PREFERENCE_END)
567 { 567 {
568 GNUNET_break(0); 568 GNUNET_break(0);
569 return; 569 return;
@@ -584,7 +584,7 @@ update_preference (struct GNUNET_SERVER_Client *client,
584 c_cur = GNUNET_new (struct PreferenceClient); 584 c_cur = GNUNET_new (struct PreferenceClient);
585 c_cur->peer2pref = GNUNET_CONTAINER_multipeermap_create (16, 585 c_cur->peer2pref = GNUNET_CONTAINER_multipeermap_create (16,
586 GNUNET_NO); 586 GNUNET_NO);
587 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) 587 for (i = 0; i < GNUNET_ATS_PREFERENCE_END; i++)
588 c_cur->f_abs_sum[i] = DEFAULT_ABS_PREFERENCE; 588 c_cur->f_abs_sum[i] = DEFAULT_ABS_PREFERENCE;
589 GNUNET_CONTAINER_DLL_insert (pc_head, 589 GNUNET_CONTAINER_DLL_insert (pc_head,
590 pc_tail, 590 pc_tail,
@@ -598,7 +598,7 @@ update_preference (struct GNUNET_SERVER_Client *client,
598 { 598 {
599 /* Create struct for peer */ 599 /* Create struct for peer */
600 r_cur = GNUNET_new (struct PeerRelative); 600 r_cur = GNUNET_new (struct PeerRelative);
601 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) 601 for (i = 0; i < GNUNET_ATS_PREFERENCE_END; i++)
602 r_cur->f_rel[i] = DEFAULT_REL_PREFERENCE; 602 r_cur->f_rel[i] = DEFAULT_REL_PREFERENCE;
603 GNUNET_assert (GNUNET_OK == 603 GNUNET_assert (GNUNET_OK ==
604 GNUNET_CONTAINER_multipeermap_put (preference_peers, 604 GNUNET_CONTAINER_multipeermap_put (preference_peers,
@@ -614,7 +614,7 @@ update_preference (struct GNUNET_SERVER_Client *client,
614 { 614 {
615 /* Not found: create new peer entry */ 615 /* Not found: create new peer entry */
616 p_cur = GNUNET_new (struct PreferencePeer); 616 p_cur = GNUNET_new (struct PreferencePeer);
617 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) 617 for (i = 0; i < GNUNET_ATS_PREFERENCE_END; i++)
618 { 618 {
619 /* Default value per peer absolute preference for a preference*/ 619 /* Default value per peer absolute preference for a preference*/
620 p_cur->f_abs[i] = DEFAULT_ABS_PREFERENCE; 620 p_cur->f_abs[i] = DEFAULT_ABS_PREFERENCE;
@@ -710,7 +710,7 @@ GAS_preference_init ()
710 710
711 preference_peers = GNUNET_CONTAINER_multipeermap_create (16, 711 preference_peers = GNUNET_CONTAINER_multipeermap_create (16,
712 GNUNET_NO); 712 GNUNET_NO);
713 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) 713 for (i = 0; i < GNUNET_ATS_PREFERENCE_END; i++)
714 defvalues.f_rel[i] = DEFAULT_REL_PREFERENCE; 714 defvalues.f_rel[i] = DEFAULT_REL_PREFERENCE;
715} 715}
716 716
diff --git a/src/ats/gnunet-service-ats_scheduling.c b/src/ats/gnunet-service-ats_scheduling.c
index 74b83bf45..c5539897b 100644
--- a/src/ats/gnunet-service-ats_scheduling.c
+++ b/src/ats/gnunet-service-ats_scheduling.c
@@ -135,13 +135,12 @@ GAS_handle_address_add (void *cls,
135 const struct GNUNET_MessageHeader *message) 135 const struct GNUNET_MessageHeader *message)
136{ 136{
137 const struct AddressAddMessage *m; 137 const struct AddressAddMessage *m;
138 const struct GNUNET_ATS_Information *atsi;
139 const char *address; 138 const char *address;
140 const char *plugin_name; 139 const char *plugin_name;
141 uint16_t address_length; 140 uint16_t address_length;
142 uint16_t plugin_name_length; 141 uint16_t plugin_name_length;
143 uint32_t ats_count;
144 uint16_t size; 142 uint16_t size;
143 struct GNUNET_ATS_Properties prop;
145 144
146 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 145 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
147 "Received `%s' message\n", 146 "Received `%s' message\n",
@@ -154,38 +153,38 @@ GAS_handle_address_add (void *cls,
154 return; 153 return;
155 } 154 }
156 m = (const struct AddressAddMessage *) message; 155 m = (const struct AddressAddMessage *) message;
157 ats_count = ntohl (m->ats_count);
158 address_length = ntohs (m->address_length); 156 address_length = ntohs (m->address_length);
159 plugin_name_length = ntohs (m->plugin_name_length); 157 plugin_name_length = ntohs (m->plugin_name_length);
160 atsi = (const struct GNUNET_ATS_Information *) &m[1]; 158 address = (const char *) &m[1];
161 address = (const char *) &atsi[ats_count];
162 if (plugin_name_length != 0) 159 if (plugin_name_length != 0)
163 plugin_name = &address[address_length]; 160 plugin_name = &address[address_length];
164 else 161 else
165 plugin_name = ""; 162 plugin_name = "";
166 163
167 if ((address_length + plugin_name_length + 164 if ((address_length + plugin_name_length +
168 ats_count * sizeof (struct GNUNET_ATS_Information) +
169 sizeof (struct AddressAddMessage) != ntohs (message->size)) || 165 sizeof (struct AddressAddMessage) != ntohs (message->size)) ||
170 (ats_count > 166 ( (plugin_name_length > 0) &&
171 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information)) || 167 (plugin_name[plugin_name_length - 1] != '\0') ) )
172 ((plugin_name_length > 0) && (plugin_name[plugin_name_length - 1] != '\0')))
173 { 168 {
174 GNUNET_break (0); 169 GNUNET_break (0);
175 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 170 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
176 return; 171 return;
177 } 172 }
178 GNUNET_STATISTICS_update (GSA_stats, 173 GNUNET_STATISTICS_update (GSA_stats,
179 "# addresses created", 1, 174 "# addresses created",
175 1,
180 GNUNET_NO); 176 GNUNET_NO);
177 GNUNET_ATS_properties_ntoh (&prop,
178 &m->properties);
181 GAS_addresses_add (&m->peer, 179 GAS_addresses_add (&m->peer,
182 plugin_name, 180 plugin_name,
183 address, 181 address,
184 address_length, 182 address_length,
185 ntohl (m->address_local_info), 183 ntohl (m->address_local_info),
186 ntohl (m->session_id), 184 ntohl (m->session_id),
187 atsi, ats_count); 185 &prop);
188 GNUNET_SERVER_receive_done (client, GNUNET_OK); 186 GNUNET_SERVER_receive_done (client,
187 GNUNET_OK);
189} 188}
190 189
191 190
@@ -202,38 +201,20 @@ GAS_handle_address_update (void *cls,
202 const struct GNUNET_MessageHeader *message) 201 const struct GNUNET_MessageHeader *message)
203{ 202{
204 const struct AddressUpdateMessage *m; 203 const struct AddressUpdateMessage *m;
205 const struct GNUNET_ATS_Information *atsi; 204 struct GNUNET_ATS_Properties prop;
206 uint32_t ats_count;
207 uint16_t size;
208 205
209 size = ntohs (message->size);
210 if (size < sizeof (struct AddressUpdateMessage))
211 {
212 GNUNET_break (0);
213 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
214 return;
215 }
216 m = (const struct AddressUpdateMessage *) message; 206 m = (const struct AddressUpdateMessage *) message;
217 ats_count = ntohl (m->ats_count);
218 atsi = (const struct GNUNET_ATS_Information *) &m[1];
219
220 if ((ats_count * sizeof (struct GNUNET_ATS_Information) +
221 sizeof (struct AddressUpdateMessage) != ntohs (message->size)) ||
222 (ats_count >
223 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information)))
224 {
225 GNUNET_break (0);
226 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
227 return;
228 }
229 GNUNET_STATISTICS_update (GSA_stats, 207 GNUNET_STATISTICS_update (GSA_stats,
230 "# address updates received", 208 "# address updates received",
231 1, 209 1,
232 GNUNET_NO); 210 GNUNET_NO);
211 GNUNET_ATS_properties_ntoh (&prop,
212 &m->properties);
233 GAS_addresses_update (&m->peer, 213 GAS_addresses_update (&m->peer,
234 ntohl (m->session_id), 214 ntohl (m->session_id),
235 atsi, ats_count); 215 &prop);
236 GNUNET_SERVER_receive_done (client, GNUNET_OK); 216 GNUNET_SERVER_receive_done (client,
217 GNUNET_OK);
237} 218}
238 219
239 220
diff --git a/src/ats/plugin_ats_mlp.c b/src/ats/plugin_ats_mlp.c
index b97261d46..7d402044f 100644
--- a/src/ats/plugin_ats_mlp.c
+++ b/src/ats/plugin_ats_mlp.c
@@ -62,6 +62,29 @@ enum MLP_Output_Format
62}; 62};
63 63
64 64
65enum QualityMetrics
66{
67 RQ_QUALITY_METRIC_DELAY = 0,
68 RQ_QUALITY_METRIC_DISTANCE = 1,
69 RQ_QUALITY_METRIC_COUNT = 2
70};
71
72
73static const char *
74print_quality_type (enum QualityMetrics qm)
75{
76 switch (qm){
77 case RQ_QUALITY_METRIC_DELAY:
78 return "delay";
79 case RQ_QUALITY_METRIC_DISTANCE:
80 return "distance";
81 default:
82 GNUNET_break (0);
83 return NULL;
84 }
85}
86
87
65struct MLP_Solution 88struct MLP_Solution
66{ 89{
67 int lp_res; 90 int lp_res;
@@ -125,7 +148,7 @@ struct MLP_Problem
125 /* Row index constraint 9: relativity*/ 148 /* Row index constraint 9: relativity*/
126 unsigned int r_c9; 149 unsigned int r_c9;
127 /* Row indices quality metrics */ 150 /* Row indices quality metrics */
128 int r_q[GNUNET_ATS_QualityPropertiesCount]; 151 int r_q[RQ_QUALITY_METRIC_COUNT];
129 /* Row indices ATS network quotas */ 152 /* Row indices ATS network quotas */
130 int r_quota[GNUNET_ATS_NetworkTypeCount]; 153 int r_quota[GNUNET_ATS_NetworkTypeCount];
131 154
@@ -136,7 +159,7 @@ struct MLP_Problem
136 /* Column index Proportionality (R) column */ 159 /* Column index Proportionality (R) column */
137 int c_r; 160 int c_r;
138 /* Column index quality metrics */ 161 /* Column index quality metrics */
139 int c_q[GNUNET_ATS_QualityPropertiesCount]; 162 int c_q[RQ_QUALITY_METRIC_COUNT];
140 163
141 /* Problem matrix */ 164 /* Problem matrix */
142 /* Current index */ 165 /* Current index */
@@ -161,23 +184,17 @@ struct MLP_Variables
161 /* LP MIP Gap */ 184 /* LP MIP Gap */
162 double lp_mip_gap; 185 double lp_mip_gap;
163 186
164 /* ATS Quality metrics 187 /* Number of quality metrics @deprecated, use RQ_QUALITY_METRIC_COUNT */
165 *
166 * Array with GNUNET_ATS_QualityPropertiesCount elements
167 * contains mapping to GNUNET_ATS_Property*/
168 int q[GNUNET_ATS_QualityPropertiesCount];
169
170 /* Number of quality metrics */
171 int m_q; 188 int m_q;
172 189
173 /* Number of quality metrics */ 190 /* Number of quality metrics */
174 int m_rc; 191 int m_rc;
175 192
176 /* Quality metric coefficients*/ 193 /* Quality metric coefficients*/
177 double co_Q[GNUNET_ATS_QualityPropertiesCount]; 194 double co_Q[RQ_QUALITY_METRIC_COUNT];
178 195
179 /* Ressource costs coefficients*/ 196 /* Ressource costs coefficients*/
180 double co_RC[GNUNET_ATS_QualityPropertiesCount]; 197 double co_RC[RQ_QUALITY_METRIC_COUNT];
181 198
182 /* Diversity coefficient */ 199 /* Diversity coefficient */
183 double co_D; 200 double co_D;
@@ -207,7 +224,7 @@ struct MLP_Variables
207 * array with GNUNET_ATS_QualityPropertiesCount elements 224 * array with GNUNET_ATS_QualityPropertiesCount elements
208 * contains mapping to GNUNET_ATS_Property 225 * contains mapping to GNUNET_ATS_Property
209 * */ 226 * */
210 int rc[GNUNET_ATS_QualityPropertiesCount]; 227 int rc[RQ_QUALITY_METRIC_COUNT];
211 228
212}; 229};
213 230
@@ -584,7 +601,7 @@ mlp_delete_problem (struct GAS_MLP_Handle *mlp)
584 mlp->p.r_c4 = MLP_UNDEFINED; 601 mlp->p.r_c4 = MLP_UNDEFINED;
585 mlp->p.r_c6 = MLP_UNDEFINED; 602 mlp->p.r_c6 = MLP_UNDEFINED;
586 mlp->p.r_c9 = MLP_UNDEFINED; 603 mlp->p.r_c9 = MLP_UNDEFINED;
587 for (c = 0; c < mlp->pv.m_q ; c ++) 604 for (c = 0; c < RQ_QUALITY_METRIC_COUNT ; c ++)
588 mlp->p.r_q[c] = MLP_UNDEFINED; 605 mlp->p.r_q[c] = MLP_UNDEFINED;
589 for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c ++) 606 for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c ++)
590 mlp->p.r_quota[c] = MLP_UNDEFINED; 607 mlp->p.r_quota[c] = MLP_UNDEFINED;
@@ -679,30 +696,6 @@ mlp_solve_to_string (int retcode)
679 } 696 }
680} 697}
681 698
682/**
683 * Extract an ATS performance info from an address
684 *
685 * @param address the address
686 * @param type the type to extract in HBO
687 * @return the value in HBO or GNUNET_ATS_VALUE_UNDEFINED in HBO if value does not exist
688 */
689static uint32_t
690get_performance_info (struct ATS_Address *address, uint32_t type)
691{
692 int c1;
693 GNUNET_assert (NULL != address);
694
695 if ((NULL == address->atsi) || (0 == address->atsi_count))
696 return GNUNET_ATS_VALUE_UNDEFINED;
697
698 for (c1 = 0; c1 < address->atsi_count; c1++)
699 {
700 if (ntohl (address->atsi[c1].type) == type)
701 return ntohl (address->atsi[c1].value);
702 }
703 return GNUNET_ATS_VALUE_UNDEFINED;
704}
705
706 699
707struct CountContext 700struct CountContext
708{ 701{
@@ -960,7 +953,6 @@ mlp_create_problem_add_address_information (void *cls,
960 struct ATS_Peer *peer; 953 struct ATS_Peer *peer;
961 struct MLP_information *mlpi; 954 struct MLP_information *mlpi;
962 char *name; 955 char *name;
963 double prop;
964 double cur_bigm; 956 double cur_bigm;
965 uint32_t addr_net; 957 uint32_t addr_net;
966 uint32_t addr_net_index; 958 uint32_t addr_net_index;
@@ -979,7 +971,7 @@ mlp_create_problem_add_address_information (void *cls,
979 return GNUNET_OK; 971 return GNUNET_OK;
980 } 972 }
981 973
982 addr_net = get_performance_info (address, GNUNET_ATS_NETWORK_TYPE); 974 addr_net = address->properties.scope;
983 for (addr_net_index = 0; addr_net_index < GNUNET_ATS_NetworkTypeCount; addr_net_index++) 975 for (addr_net_index = 0; addr_net_index < GNUNET_ATS_NetworkTypeCount; addr_net_index++)
984 { 976 {
985 if (mlp->pv.quota_index[addr_net_index] == addr_net) 977 if (mlp->pv.quota_index[addr_net_index] == addr_net)
@@ -1110,22 +1102,16 @@ mlp_create_problem_add_address_information (void *cls,
1110 /* For all quality metrics, set quality of this address */ 1102 /* For all quality metrics, set quality of this address */
1111 if (GNUNET_YES == mlp->opt_dbg_optimize_quality) 1103 if (GNUNET_YES == mlp->opt_dbg_optimize_quality)
1112 { 1104 {
1113 for (c = 0; c < mlp->pv.m_q; c++) 1105 mlp_create_problem_set_value (p,
1114 { 1106 p->r_q[RQ_QUALITY_METRIC_DELAY],
1115 prop = address->atsin[c].norm; 1107 mlpi->c_b,
1116 if ((prop < 1.0) && (prop > 2.0)) 1108 address->norm_delay.norm,
1117 { 1109 __LINE__);
1118 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1110 mlp_create_problem_set_value (p,
1119 "PROP == %.3f \t ", 1111 p->r_q[RQ_QUALITY_METRIC_DISTANCE],
1120 prop); 1112 mlpi->c_b,
1121 GNUNET_break (0); 1113 address->norm_distance.norm,
1122 } 1114 __LINE__);
1123 mlp_create_problem_set_value (p,
1124 p->r_q[c],
1125 mlpi->c_b,
1126 prop,
1127 __LINE__);
1128 }
1129 } 1115 }
1130 } 1116 }
1131 1117
@@ -1183,11 +1169,14 @@ mlp_create_problem_add_invariant_rows (struct GAS_MLP_Handle *mlp, struct MLP_Pr
1183 { 1169 {
1184 for (c = 0; c < mlp->pv.m_q; c++) 1170 for (c = 0; c < mlp->pv.m_q; c++)
1185 { 1171 {
1186 GNUNET_asprintf (&name, "c7_q%i_%s", c, 1172 GNUNET_asprintf (&name,
1187 GNUNET_ATS_print_property_type (mlp->pv.q[c])); 1173 "c7_q%i_%s", c,
1174 print_quality_type (c));
1188 p->r_q[c] = mlp_create_problem_create_constraint (p, name, GLP_FX, 0.0, 0.0); 1175 p->r_q[c] = mlp_create_problem_create_constraint (p, name, GLP_FX, 0.0, 0.0);
1189 GNUNET_free (name); 1176 GNUNET_free (name);
1190 mlp_create_problem_set_value (p, p->r_q[c], p->c_q[c], -1, __LINE__); 1177 mlp_create_problem_set_value (p,
1178 p->r_q[c],
1179 p->c_q[c], -1, __LINE__);
1191 } 1180 }
1192 } 1181 }
1193 } 1182 }
@@ -1222,7 +1211,7 @@ mlp_create_problem_add_invariant_columns (struct GAS_MLP_Handle *mlp, struct MLP
1222 { 1211 {
1223 for (c = 0; c < mlp->pv.m_q; c++) 1212 for (c = 0; c < mlp->pv.m_q; c++)
1224 { 1213 {
1225 GNUNET_asprintf (&name, "q_%u", mlp->pv.q[c]); 1214 GNUNET_asprintf (&name, "q_%u", c);
1226 p->c_q[c] = mlp_create_problem_create_column (p, name, GLP_CV, GLP_LO, 0.0, 0.0, mlp->pv.co_Q[c]); 1215 p->c_q[c] = mlp_create_problem_create_column (p, name, GLP_CV, GLP_LO, 0.0, 0.0, mlp->pv.co_Q[c]);
1227 GNUNET_free (name); 1216 GNUNET_free (name);
1228 } 1217 }
@@ -1866,13 +1855,10 @@ GAS_mlp_address_add (void *solver,
1866{ 1855{
1867 struct GAS_MLP_Handle *mlp = solver; 1856 struct GAS_MLP_Handle *mlp = solver;
1868 1857
1869 GNUNET_assert (NULL != solver);
1870 GNUNET_assert (NULL != address);
1871
1872 if (GNUNET_ATS_NetworkTypeCount <= network) 1858 if (GNUNET_ATS_NetworkTypeCount <= network)
1873 { 1859 {
1874 GNUNET_break (0); 1860 GNUNET_break (0);
1875 return; 1861 return;
1876 } 1862 }
1877 1863
1878 if (NULL == address->solver_information) 1864 if (NULL == address->solver_information)
@@ -1911,36 +1897,23 @@ GAS_mlp_address_add (void *solver,
1911 * 1897 *
1912 * @param solver solver handle 1898 * @param solver solver handle
1913 * @param address the address 1899 * @param address the address
1914 * @param type the ATSI type in HBO
1915 * @param abs_value the absolute value of the property
1916 * @param rel_value the normalized value
1917 */ 1900 */
1918static void 1901static void
1919GAS_mlp_address_property_changed (void *solver, 1902GAS_mlp_address_property_changed (void *solver,
1920 struct ATS_Address *address, 1903 struct ATS_Address *address)
1921 enum GNUNET_ATS_Property type,
1922 uint32_t abs_value,
1923 double rel_value)
1924{ 1904{
1925 struct MLP_information *mlpi = address->solver_information; 1905 struct MLP_information *mlpi = address->solver_information;
1926 struct GAS_MLP_Handle *mlp = solver; 1906 struct GAS_MLP_Handle *mlp = solver;
1927 int c1;
1928 int type_index;
1929
1930 GNUNET_assert (NULL != solver);
1931 GNUNET_assert (NULL != address);
1932 1907
1933 if (NULL == mlpi) 1908 if (NULL == mlpi)
1934 { 1909 {
1935 LOG (GNUNET_ERROR_TYPE_INFO, 1910 LOG (GNUNET_ERROR_TYPE_INFO,
1936 _("Updating address property `%s' for peer `%s' %p not added before\n"), 1911 _("Updating address property for peer `%s' %p not added before\n"),
1937 GNUNET_ATS_print_property_type (type), 1912 GNUNET_i2s (&address->peer),
1938 GNUNET_i2s(&address->peer), 1913 address);
1939 address); 1914 GNUNET_break (0);
1940 GNUNET_break (0); 1915 return;
1941 return;
1942 } 1916 }
1943
1944 if (NULL == 1917 if (NULL ==
1945 GNUNET_CONTAINER_multipeermap_get (mlp->requested_peers, 1918 GNUNET_CONTAINER_multipeermap_get (mlp->requested_peers,
1946 &address->peer)) 1919 &address->peer))
@@ -1948,34 +1921,26 @@ GAS_mlp_address_property_changed (void *solver,
1948 /* Peer is not requested, so no need to update problem */ 1921 /* Peer is not requested, so no need to update problem */
1949 return; 1922 return;
1950 } 1923 }
1951 LOG (GNUNET_ERROR_TYPE_INFO, "Updating property `%s' address for peer `%s' to abs %llu rel %.3f\n", 1924 LOG (GNUNET_ERROR_TYPE_DEBUG,
1952 GNUNET_ATS_print_property_type (type), 1925 "Updating properties for peer `%s'\n",
1953 GNUNET_i2s(&address->peer), 1926 GNUNET_i2s(&address->peer));
1954 abs_value,
1955 rel_value);
1956 1927
1957 if (GNUNET_YES == mlp->opt_dbg_feasibility_only) 1928 if (GNUNET_YES == mlp->opt_dbg_feasibility_only)
1958 return; 1929 return;
1959 1930
1960 /* Find row index */
1961 type_index = -1;
1962 for (c1 = 0; c1 < mlp->pv.m_q; c1++)
1963 {
1964 if (type == mlp->pv.q[c1])
1965 {
1966 type_index = c1;
1967 break;
1968 }
1969 }
1970 if (-1 == type_index)
1971 {
1972 GNUNET_break (0);
1973 return; /* quality index not found */
1974 }
1975
1976 /* Update c7) [r_q[index]][c_b] = f_q * q_averaged[type_index] */ 1931 /* Update c7) [r_q[index]][c_b] = f_q * q_averaged[type_index] */
1977 if (GNUNET_YES == mlp_create_problem_update_value (&mlp->p, 1932 if ( (GNUNET_YES ==
1978 mlp->p.r_q[type_index], mlpi->c_b, rel_value, __LINE__)) 1933 mlp_create_problem_update_value (&mlp->p,
1934 mlp->p.r_q[RQ_QUALITY_METRIC_DELAY],
1935 mlpi->c_b,
1936 address->norm_delay.norm,
1937 __LINE__)) ||
1938 (GNUNET_YES ==
1939 mlp_create_problem_update_value (&mlp->p,
1940 mlp->p.r_q[RQ_QUALITY_METRIC_DISTANCE],
1941 mlpi->c_b,
1942 address->norm_distance.norm,
1943 __LINE__)) )
1979 { 1944 {
1980 mlp->stat_mlp_prob_updated = GNUNET_YES; 1945 mlp->stat_mlp_prob_updated = GNUNET_YES;
1981 if (GNUNET_YES == mlp->opt_mlp_auto_solve) 1946 if (GNUNET_YES == mlp->opt_mlp_auto_solve)
@@ -2037,17 +2002,14 @@ get_peer_pref_value (struct GAS_MLP_Handle *mlp,
2037 2002
2038 preferences = mlp->env->get_preferences (mlp->env->cls, peer); 2003 preferences = mlp->env->get_preferences (mlp->env->cls, peer);
2039 res = 0.0; 2004 res = 0.0;
2040 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++) 2005 for (c = 0; c < GNUNET_ATS_PREFERENCE_END; c++)
2041 { 2006 {
2042 if (c != GNUNET_ATS_PREFERENCE_END) 2007 /* fprintf (stderr, "VALUE[%u] %s %.3f \n",
2043 { 2008 * c, GNUNET_i2s (&cur->addr->peer), t[c]); */
2044 /* fprintf (stderr, "VALUE[%u] %s %.3f \n", 2009 res += preferences[c];
2045 * c, GNUNET_i2s (&cur->addr->peer), t[c]); */
2046 res += preferences[c];
2047 }
2048 } 2010 }
2049 2011
2050 res /= (GNUNET_ATS_PreferenceCount -1); 2012 res /= GNUNET_ATS_PREFERENCE_END;
2051 res += 1.0; 2013 res += 1.0;
2052 2014
2053 LOG (GNUNET_ERROR_TYPE_DEBUG, 2015 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -2646,34 +2608,28 @@ libgnunet_plugin_ats_mlp_init (void *cls)
2646 } 2608 }
2647 2609
2648 /* Get quality metric coefficients from configuration */ 2610 /* Get quality metric coefficients from configuration */
2649 int i_delay = MLP_NaN; 2611 for (c = 0; c < RQ_QUALITY_METRIC_COUNT; c++)
2650 int i_distance = MLP_NaN;
2651 int q[GNUNET_ATS_QualityPropertiesCount] = GNUNET_ATS_QualityProperties;
2652 for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++)
2653 { 2612 {
2654 /* initialize quality coefficients with default value 1.0 */ 2613 /* initialize quality coefficients with default value 1.0 */
2655 mlp->pv.co_Q[c] = MLP_DEFAULT_QUALITY; 2614 mlp->pv.co_Q[c] = MLP_DEFAULT_QUALITY;
2656
2657 mlp->pv.q[c] = q[c];
2658 if (q[c] == GNUNET_ATS_QUALITY_NET_DELAY)
2659 i_delay = c;
2660 if (q[c] == GNUNET_ATS_QUALITY_NET_DISTANCE)
2661 i_distance = c;
2662 } 2615 }
2663 2616
2664 if ( (i_delay != MLP_NaN) && 2617
2665 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (env->cfg, "ats", 2618 if (GNUNET_OK ==
2666 "MLP_COEFFICIENT_QUALITY_DELAY", &tmp)) ) 2619 GNUNET_CONFIGURATION_get_value_size (env->cfg, "ats",
2667 mlp->pv.co_Q[i_delay] = (double) tmp / 100; 2620 "MLP_COEFFICIENT_QUALITY_DELAY",
2621 &tmp))
2622 mlp->pv.co_Q[RQ_QUALITY_METRIC_DELAY] = (double) tmp / 100;
2668 else 2623 else
2669 mlp->pv.co_Q[i_delay] = MLP_DEFAULT_QUALITY; 2624 mlp->pv.co_Q[RQ_QUALITY_METRIC_DELAY] = MLP_DEFAULT_QUALITY;
2670 2625
2671 if ( (i_distance != MLP_NaN) && 2626 if (GNUNET_OK ==
2672 (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (env->cfg, "ats", 2627 GNUNET_CONFIGURATION_get_value_size (env->cfg, "ats",
2673 "MLP_COEFFICIENT_QUALITY_DISTANCE", &tmp)) ) 2628 "MLP_COEFFICIENT_QUALITY_DISTANCE",
2674 mlp->pv.co_Q[i_distance] = (double) tmp / 100; 2629 &tmp))
2630 mlp->pv.co_Q[RQ_QUALITY_METRIC_DISTANCE] = (double) tmp / 100;
2675 else 2631 else
2676 mlp->pv.co_Q[i_distance] = MLP_DEFAULT_QUALITY; 2632 mlp->pv.co_Q[RQ_QUALITY_METRIC_DISTANCE] = MLP_DEFAULT_QUALITY;
2677 2633
2678 /* Get minimum bandwidth per used address from configuration */ 2634 /* Get minimum bandwidth per used address from configuration */
2679 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (env->cfg, "ats", 2635 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (env->cfg, "ats",
@@ -2759,7 +2715,7 @@ libgnunet_plugin_ats_mlp_init (void *cls)
2759 /* Setting MLP Input variables */ 2715 /* Setting MLP Input variables */
2760 mlp->pv.b_min = b_min; 2716 mlp->pv.b_min = b_min;
2761 mlp->pv.n_min = n_min; 2717 mlp->pv.n_min = n_min;
2762 mlp->pv.m_q = GNUNET_ATS_QualityPropertiesCount; 2718 mlp->pv.m_q = RQ_QUALITY_METRIC_COUNT;
2763 mlp->stat_mlp_prob_changed = GNUNET_NO; 2719 mlp->stat_mlp_prob_changed = GNUNET_NO;
2764 mlp->stat_mlp_prob_updated = GNUNET_NO; 2720 mlp->stat_mlp_prob_updated = GNUNET_NO;
2765 mlp->opt_mlp_auto_solve = GNUNET_YES; 2721 mlp->opt_mlp_auto_solve = GNUNET_YES;
diff --git a/src/ats/plugin_ats_proportional.c b/src/ats/plugin_ats_proportional.c
index 69afa8a52..9ad00bbb3 100644
--- a/src/ats/plugin_ats_proportional.c
+++ b/src/ats/plugin_ats_proportional.c
@@ -25,8 +25,8 @@
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_statistics_service.h" 27#include "gnunet_statistics_service.h"
28#include "gnunet_ats_plugin.h"
29#include "gnunet_ats_service.h" 28#include "gnunet_ats_service.h"
29#include "gnunet_ats_plugin.h"
30#include "gnunet-service-ats_addresses.h" 30#include "gnunet-service-ats_addresses.h"
31 31
32#define LOG(kind,...) GNUNET_log_from (kind, "ats-proportional",__VA_ARGS__) 32#define LOG(kind,...) GNUNET_log_from (kind, "ats-proportional",__VA_ARGS__)
@@ -308,7 +308,8 @@ distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
308 continue; 308 continue;
309 peer_relative_prefs = s->env->get_preferences (s->env->cls, 309 peer_relative_prefs = s->env->get_preferences (s->env->cls,
310 &aw->addr->peer); 310 &aw->addr->peer);
311 sum_relative_peer_prefences += peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH]; 311 sum_relative_peer_prefences
312 += peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH];
312 count_addresses++; 313 count_addresses++;
313 } 314 }
314 if (count_addresses != net->active_addresses) 315 if (count_addresses != net->active_addresses)
@@ -504,27 +505,6 @@ struct FindBestAddressCtx
504 505
505 506
506/** 507/**
507 * Find index of a ATS property type in the quality properties array.
508 *
509 * @param type ATS property type
510 * @return index in the quality array, #GNUNET_SYSERR if the type
511 * was not a quality property
512 */
513static int
514find_quality_property_index (enum GNUNET_ATS_Property type)
515{
516 enum GNUNET_ATS_Property existing_types[] = GNUNET_ATS_QualityProperties;
517 unsigned int c;
518
519 for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++)
520 if (existing_types[c] == type)
521 return c;
522 GNUNET_break (0);
523 return GNUNET_SYSERR;
524}
525
526
527/**
528 * Find a "good" address to use for a peer by iterating over the 508 * Find a "good" address to use for a peer by iterating over the
529 * addresses for this peer. If we already have an existing address, 509 * addresses for this peer. If we already have an existing address,
530 * we stick to it. Otherwise, we pick by lowest distance and then by 510 * we stick to it. Otherwise, we pick by lowest distance and then by
@@ -548,7 +528,6 @@ find_best_address_it (void *cls,
548 double best_distance; 528 double best_distance;
549 double cur_delay; 529 double cur_delay;
550 double cur_distance; 530 double cur_distance;
551 int index;
552 unsigned int con; 531 unsigned int con;
553 int bw_available; 532 int bw_available;
554 int need; 533 int need;
@@ -601,12 +580,10 @@ find_best_address_it (void *cls,
601 } 580 }
602 581
603 /* Now compare ATS information */ 582 /* Now compare ATS information */
604 index = find_quality_property_index (GNUNET_ATS_QUALITY_NET_DISTANCE); 583 cur_distance = current->norm_distance.norm;
605 cur_distance = current->atsin[index].norm; 584 best_distance = ctx->best->norm_distance.norm;
606 best_distance = ctx->best->atsin[index].norm; 585 cur_delay = current->norm_delay.norm;
607 index = find_quality_property_index (GNUNET_ATS_QUALITY_NET_DELAY); 586 best_delay = ctx->best->norm_delay.norm;
608 cur_delay = current->atsin[index].norm;
609 best_delay = ctx->best->atsin[index].norm;
610 587
611 /* user shorter distance */ 588 /* user shorter distance */
612 if (cur_distance < best_distance) 589 if (cur_distance < best_distance)
@@ -1006,16 +983,10 @@ GAS_proportional_bulk_stop (void *solver)
1006 * 983 *
1007 * @param solver solver handle 984 * @param solver solver handle
1008 * @param address the address 985 * @param address the address
1009 * @param type the ATSI type
1010 * @param abs_value the absolute value of the property
1011 * @param rel_value the normalized value
1012 */ 986 */
1013static void 987static void
1014GAS_proportional_address_property_changed (void *solver, 988GAS_proportional_address_property_changed (void *solver,
1015 struct ATS_Address *address, 989 struct ATS_Address *address)
1016 enum GNUNET_ATS_Property type,
1017 uint32_t abs_value,
1018 double rel_value)
1019{ 990{
1020 struct GAS_PROPORTIONAL_Handle *s = solver; 991 struct GAS_PROPORTIONAL_Handle *s = solver;
1021 struct AddressWrapper *asi = address->solver_information; 992 struct AddressWrapper *asi = address->solver_information;
diff --git a/src/ats/plugin_ats_ril.c b/src/ats/plugin_ats_ril.c
index 78f58e609..0d8b2290c 100644
--- a/src/ats/plugin_ats_ril.c
+++ b/src/ats/plugin_ats_ril.c
@@ -934,29 +934,6 @@ envi_get_state (struct GAS_RIL_Handle *solver, struct RIL_Peer_Agent *agent)
934 return state; 934 return state;
935} 935}
936 936
937/**
938 * Retrieves an ATS information value of an address
939 *
940 * @param address the address in question
941 * @param type the ATS information type
942 * @return the value
943 */
944static unsigned int
945ril_get_atsi (struct ATS_Address *address, uint32_t type)
946{
947 int c1;
948 GNUNET_assert(NULL != address);
949
950 if ((NULL == address->atsi) || (0 == address->atsi_count))
951 return GNUNET_ATS_QUALITY_NET_DELAY == type ? UINT32_MAX : 1;
952
953 for (c1 = 0; c1 < address->atsi_count; c1++)
954 {
955 if (ntohl (address->atsi[c1].type) == type)
956 return ntohl (address->atsi[c1].value);
957 }
958 return GNUNET_ATS_QUALITY_NET_DELAY == type ? UINT32_MAX : 1;
959}
960 937
961/** 938/**
962 * Returns the utility value of the connection an agent manages 939 * Returns the utility value of the connection an agent manages
@@ -975,16 +952,12 @@ agent_get_utility (struct RIL_Peer_Agent *agent)
975 preferences = agent->envi->env->get_preferences (agent->envi->env->cls, 952 preferences = agent->envi->env->get_preferences (agent->envi->env->cls,
976 &agent->peer); 953 &agent->peer);
977 954
978 delay_atsi = (double) ril_get_atsi (agent->address_inuse, GNUNET_ATS_QUALITY_NET_DELAY); 955 delay_atsi = agent->address_inuse->norm_delay.norm;
979 delay_norm = RIL_UTILITY_DELAY_MAX*exp(-delay_atsi*0.00001); 956 delay_norm = RIL_UTILITY_DELAY_MAX*exp(-delay_atsi*0.00001);
980 957
981 pref_match = preferences[GNUNET_ATS_PREFERENCE_LATENCY] * delay_norm; 958 pref_match = preferences[GNUNET_ATS_PREFERENCE_LATENCY] * delay_norm;
982 pref_match += preferences[GNUNET_ATS_PREFERENCE_BANDWIDTH] * 959 pref_match += preferences[GNUNET_ATS_PREFERENCE_BANDWIDTH] *
983 sqrt((double) (agent->bw_in/RIL_MIN_BW) * (double) (agent->bw_out/RIL_MIN_BW)); 960 sqrt((double) (agent->bw_in/RIL_MIN_BW) * (double) (agent->bw_out/RIL_MIN_BW));
984// sqrt((double) (ril_get_atsi (agent->address_inuse, GNUNET_ATS_UTILIZATION_IN)/RIL_MIN_BW) * (double) (ril_get_atsi (agent->address_inuse, GNUNET_ATS_UTILIZATION_OUT)/RIL_MIN_BW));
985
986// return (double) (agent->bw_in/RIL_MIN_BW);
987// return sqrt((double) (agent->bw_in/RIL_MIN_BW) * (double) (agent->bw_out/RIL_MIN_BW));
988 return pref_match; 961 return pref_match;
989} 962}
990 963
@@ -1799,9 +1772,9 @@ ril_network_get_utilized (struct GAS_RIL_Handle *solver, enum GNUNET_ATS_Network
1799 if (net->type == type) 1772 if (net->type == type)
1800 { 1773 {
1801 if (direction_in) 1774 if (direction_in)
1802 sum += ril_get_atsi (cur->address_inuse, GNUNET_ATS_UTILIZATION_IN); 1775 sum += cur->address_inuse->norm_utilization_in.norm;
1803 else 1776 else
1804 sum += ril_get_atsi (cur->address_inuse, GNUNET_ATS_UTILIZATION_OUT); 1777 sum += cur->address_inuse->norm_utilization_out.norm;
1805 } 1778 }
1806 } 1779 }
1807 } 1780 }
@@ -2373,27 +2346,16 @@ GAS_ril_address_delete (void *solver,
2373 * 2346 *
2374 * @param solver solver handle 2347 * @param solver solver handle
2375 * @param address the address 2348 * @param address the address
2376 * @param type the ATSI type
2377 * @param abs_value the absolute value of the property
2378 * @param rel_value the normalized value
2379 */ 2349 */
2380static void 2350static void
2381GAS_ril_address_property_changed (void *solver, 2351GAS_ril_address_property_changed (void *solver,
2382 struct ATS_Address *address, 2352 struct ATS_Address *address)
2383 enum GNUNET_ATS_Property type,
2384 uint32_t abs_value,
2385 double rel_value)
2386{ 2353{
2387 struct GAS_RIL_Handle *s = solver; 2354 struct GAS_RIL_Handle *s = solver;
2388 2355
2389 LOG(GNUNET_ERROR_TYPE_DEBUG, 2356 LOG(GNUNET_ERROR_TYPE_DEBUG,
2390 "API_address_property_changed() Property '%s' for peer '%s' address %s changed " 2357 "Properties for peer '%s' address changed\n",
2391 "to %.2f \n", 2358 GNUNET_i2s (&address->peer));
2392 GNUNET_ATS_print_property_type (type),
2393 GNUNET_i2s (&address->peer),
2394 address->addr, rel_value);
2395
2396
2397 s->parameters.temperature = s->parameters.temperature_init; 2359 s->parameters.temperature = s->parameters.temperature_init;
2398 s->parameters.epsilon = s->parameters.epsilon_init; 2360 s->parameters.epsilon = s->parameters.epsilon_init;
2399 ril_step (s); 2361 ril_step (s);
diff --git a/src/ats/test_ats_api_common.h b/src/ats/test_ats_api_common.h
index 233af72cd..091eb59b6 100644
--- a/src/ats/test_ats_api_common.h
+++ b/src/ats/test_ats_api_common.h
@@ -38,8 +38,7 @@ struct Test_Address
38 void *addr; 38 void *addr;
39 size_t addr_len; 39 size_t addr_len;
40 40
41 struct GNUNET_ATS_Information *ats; 41 struct GNUNET_ATS_Properties properties;
42 int ats_count;
43 42
44 void *session; 43 void *session;
45}; 44};
@@ -61,13 +60,11 @@ free_test_address (struct Test_Address *dest);
61void 60void
62create_test_address (struct Test_Address *dest, char * plugin, void *session, void *addr, size_t addrlen); 61create_test_address (struct Test_Address *dest, char * plugin, void *session, void *addr, size_t addrlen);
63 62
63
64int 64int
65compare_addresses (const struct GNUNET_HELLO_Address *address1, void *session1, 65compare_addresses (const struct GNUNET_HELLO_Address *address1, void *session1,
66 const struct GNUNET_HELLO_Address *address2, void *session2); 66 const struct GNUNET_HELLO_Address *address2, void *session2);
67 67
68int
69compare_ats (const struct GNUNET_ATS_Information *ats_is, uint32_t ats_count_is,
70 const struct GNUNET_ATS_Information *ats_should, uint32_t ats_count_should);
71 68
72struct ATS_Address * 69struct ATS_Address *
73create_address (const struct GNUNET_PeerIdentity *peer, 70create_address (const struct GNUNET_PeerIdentity *peer,
diff --git a/src/dv/gnunet-service-dv.c b/src/dv/gnunet-service-dv.c
index 93cc0628f..7ea4a300e 100644
--- a/src/dv/gnunet-service-dv.c
+++ b/src/dv/gnunet-service-dv.c
@@ -1159,46 +1159,6 @@ schedule_refresh_routes ()
1159 1159
1160 1160
1161/** 1161/**
1162 * Get distance information from 'atsi'.
1163 *
1164 * @param atsi performance data
1165 * @param atsi_count number of entries in atsi
1166 * @return connected transport distance
1167 */
1168static uint32_t
1169get_atsi_distance (const struct GNUNET_ATS_Information *atsi,
1170 uint32_t atsi_count)
1171{
1172 uint32_t i;
1173
1174 for (i = 0; i < atsi_count; i++)
1175 if (ntohl (atsi[i].type) == GNUNET_ATS_QUALITY_NET_DISTANCE)
1176 return (0 == ntohl (atsi[i].value)) ? DIRECT_NEIGHBOR_COST : ntohl (atsi[i].value); // FIXME: 0 check should not be required once ATS is fixed!
1177 /* If we do not have explicit distance data, assume direct neighbor. */
1178 return DIRECT_NEIGHBOR_COST;
1179}
1180
1181
1182/**
1183 * Get network information from 'atsi'.
1184 *
1185 * @param atsi performance data
1186 * @param atsi_count number of entries in atsi
1187 * @return connected transport network
1188 */
1189static enum GNUNET_ATS_Network_Type
1190get_atsi_network (const struct GNUNET_ATS_Information *atsi,
1191 uint32_t atsi_count)
1192{
1193 uint32_t i;
1194
1195 for (i = 0; i < atsi_count; i++)
1196 if (ntohl (atsi[i].type) == GNUNET_ATS_NETWORK_TYPE)
1197 return (enum GNUNET_ATS_Network_Type) ntohl (atsi[i].value);
1198 return GNUNET_ATS_NET_UNSPECIFIED;
1199}
1200
1201/**
1202 * Multipeermap iterator for freeing routes that go via a particular 1162 * Multipeermap iterator for freeing routes that go via a particular
1203 * neighbor that disconnected and is thus no longer available. 1163 * neighbor that disconnected and is thus no longer available.
1204 * 1164 *
@@ -1308,8 +1268,7 @@ handle_direct_disconnect (struct DirectNeighbor *neighbor)
1308 * #GNUNET_SYSERR if this address is no longer available for ATS 1268 * #GNUNET_SYSERR if this address is no longer available for ATS
1309 * @param bandwidth_out assigned outbound bandwidth for the connection 1269 * @param bandwidth_out assigned outbound bandwidth for the connection
1310 * @param bandwidth_in assigned inbound bandwidth for the connection 1270 * @param bandwidth_in assigned inbound bandwidth for the connection
1311 * @param ats performance data for the address (as far as known) 1271 * @param prop performance data for the address (as far as known)
1312 * @param ats_count number of performance records in @a ats
1313 */ 1272 */
1314static void 1273static void
1315handle_ats_update (void *cls, 1274handle_ats_update (void *cls,
@@ -1317,12 +1276,11 @@ handle_ats_update (void *cls,
1317 int active, 1276 int active,
1318 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 1277 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
1319 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 1278 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
1320 const struct GNUNET_ATS_Information *ats, 1279 const struct GNUNET_ATS_Properties *prop)
1321 uint32_t ats_count)
1322{ 1280{
1323 struct DirectNeighbor *neighbor; 1281 struct DirectNeighbor *neighbor;
1324 uint32_t distance; 1282 uint32_t distance;
1325 enum GNUNET_ATS_Network_Type network = GNUNET_ATS_NET_UNSPECIFIED; 1283 enum GNUNET_ATS_Network_Type network;
1326 1284
1327 if (NULL == address) 1285 if (NULL == address)
1328 { 1286 {
@@ -1335,8 +1293,8 @@ handle_ats_update (void *cls,
1335 // FIXME: handle disconnect/inactive case too! 1293 // FIXME: handle disconnect/inactive case too!
1336 return; 1294 return;
1337 } 1295 }
1338 distance = get_atsi_distance (ats, ats_count); 1296 distance = prop->distance;
1339 network = get_atsi_network (ats, ats_count); 1297 network = prop->scope;
1340 GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != network); 1298 GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != network);
1341 /* check if entry exists */ 1299 /* check if entry exists */
1342 neighbor = GNUNET_CONTAINER_multipeermap_get (direct_neighbors, 1300 neighbor = GNUNET_CONTAINER_multipeermap_get (direct_neighbors,
diff --git a/src/dv/plugin_transport_dv.c b/src/dv/plugin_transport_dv.c
index 382e57596..f84c4a1b6 100644
--- a/src/dv/plugin_transport_dv.c
+++ b/src/dv/plugin_transport_dv.c
@@ -234,14 +234,12 @@ static void
234notify_distance_change (struct Session *session) 234notify_distance_change (struct Session *session)
235{ 235{
236 struct Plugin *plugin = session->plugin; 236 struct Plugin *plugin = session->plugin;
237 struct GNUNET_ATS_Information ats;
238 237
239 if (GNUNET_YES != session->active) 238 if (GNUNET_YES != session->active)
240 return; 239 return;
241 ats.type = htonl ((uint32_t) GNUNET_ATS_QUALITY_NET_DISTANCE); 240 plugin->env->update_address_distance (plugin->env->cls,
242 ats.value = htonl (session->distance); 241 session->address,
243 plugin->env->update_address_metrics (plugin->env->cls, 242 session->distance);
244 session->address, session, &ats, 1);
245} 243}
246 244
247 245
@@ -260,21 +258,20 @@ unbox_cb (void *cls,
260{ 258{
261 struct Plugin *plugin = cls; 259 struct Plugin *plugin = cls;
262 struct Session *session = client; 260 struct Session *session = client;
263 struct GNUNET_ATS_Information ats;
264 261
265 ats.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
266 ats.value = htonl (session->distance);
267 session->active = GNUNET_YES; 262 session->active = GNUNET_YES;
268 LOG (GNUNET_ERROR_TYPE_DEBUG, 263 LOG (GNUNET_ERROR_TYPE_DEBUG,
269 "Delivering message of type %u with %u bytes from peer `%s'\n", 264 "Delivering message of type %u with %u bytes from peer `%s'\n",
270 ntohs (message->type), 265 ntohs (message->type),
271 ntohs (message->size), 266 ntohs (message->size),
272 GNUNET_i2s (&session->sender)); 267 GNUNET_i2s (&session->sender));
273 268 plugin->env->receive (plugin->env->cls,
274 plugin->env->receive (plugin->env->cls, session->address, session, 269 session->address,
270 session,
275 message); 271 message);
276 plugin->env->update_address_metrics (plugin->env->cls, 272 plugin->env->update_address_distance (plugin->env->cls,
277 session->address, session, &ats, 1); 273 session->address,
274 session->distance);
278 return GNUNET_OK; 275 return GNUNET_OK;
279} 276}
280 277
@@ -294,12 +291,12 @@ handle_dv_message_received (void *cls,
294 const struct GNUNET_MessageHeader *msg) 291 const struct GNUNET_MessageHeader *msg)
295{ 292{
296 struct Plugin *plugin = cls; 293 struct Plugin *plugin = cls;
297 struct GNUNET_ATS_Information ats;
298 struct Session *session; 294 struct Session *session;
299 295
300 LOG (GNUNET_ERROR_TYPE_DEBUG, 296 LOG (GNUNET_ERROR_TYPE_DEBUG,
301 "Received DV_MESSAGE_RECEIVED message for peer `%s': new distance %u\n", 297 "Received DV_MESSAGE_RECEIVED message for peer `%s': new distance %u\n",
302 GNUNET_i2s (sender), distance); 298 GNUNET_i2s (sender),
299 distance);
303 session = GNUNET_CONTAINER_multipeermap_get (plugin->sessions, 300 session = GNUNET_CONTAINER_multipeermap_get (plugin->sessions,
304 sender); 301 sender);
305 if (NULL == session) 302 if (NULL == session)
@@ -320,17 +317,19 @@ handle_dv_message_received (void *cls,
320 GNUNET_NO); 317 GNUNET_NO);
321 return; 318 return;
322 } 319 }
323 ats.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
324 ats.value = htonl (distance);
325 session->active = GNUNET_YES; 320 session->active = GNUNET_YES;
326 LOG (GNUNET_ERROR_TYPE_DEBUG, 321 LOG (GNUNET_ERROR_TYPE_DEBUG,
327 "Delivering message of type %u with %u bytes from peer `%s'\n", 322 "Delivering message of type %u with %u bytes from peer `%s'\n",
328 ntohs (msg->type), 323 ntohs (msg->type),
329 ntohs (msg->size), 324 ntohs (msg->size),
330 GNUNET_i2s (sender)); 325 GNUNET_i2s (sender));
331 plugin->env->receive (plugin->env->cls, session->address, session, msg); 326 plugin->env->receive (plugin->env->cls,
332 plugin->env->update_address_metrics (plugin->env->cls, 327 session->address,
333 session->address, session, &ats, 1); 328 session,
329 msg);
330 plugin->env->update_address_distance (plugin->env->cls,
331 session->address,
332 session->distance);
334} 333}
335 334
336 335
@@ -350,7 +349,6 @@ handle_dv_connect (void *cls,
350{ 349{
351 struct Plugin *plugin = cls; 350 struct Plugin *plugin = cls;
352 struct Session *session; 351 struct Session *session;
353 struct GNUNET_ATS_Information ats[2];
354 352
355 GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != network); 353 GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != network);
356 /** 354 /**
@@ -358,8 +356,7 @@ handle_dv_connect (void *cls,
358 * If you remove it, also remove libgnunetats linkage from Makefile.am 356 * If you remove it, also remove libgnunetats linkage from Makefile.am
359 */ 357 */
360 LOG (GNUNET_ERROR_TYPE_DEBUG, 358 LOG (GNUNET_ERROR_TYPE_DEBUG,
361 "Received `%s' message for peer `%s' with next hop in network %s\n", 359 "Received DV_CONNECT message for peer `%s' with next hop in network %s\n",
362 "DV_CONNECT",
363 GNUNET_i2s (peer), 360 GNUNET_i2s (peer),
364 GNUNET_ATS_print_network_type (network)); 361 GNUNET_ATS_print_network_type (network));
365 362
@@ -375,7 +372,8 @@ handle_dv_connect (void *cls,
375 372
376 session = GNUNET_new (struct Session); 373 session = GNUNET_new (struct Session);
377 session->address = GNUNET_HELLO_address_allocate (peer, "dv", 374 session->address = GNUNET_HELLO_address_allocate (peer, "dv",
378 NULL, 0, GNUNET_HELLO_ADDRESS_INFO_NONE); 375 NULL, 0,
376 GNUNET_HELLO_ADDRESS_INFO_NONE);
379 session->sender = *peer; 377 session->sender = *peer;
380 session->plugin = plugin; 378 session->plugin = plugin;
381 session->distance = distance; 379 session->distance = distance;
@@ -391,14 +389,15 @@ handle_dv_connect (void *cls,
391 GNUNET_i2s (peer), 389 GNUNET_i2s (peer),
392 distance); 390 distance);
393 391
394 /* Notify transport and ats about new connection */
395 ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
396 ats[0].value = htonl (distance);
397 ats[1].type = htonl (GNUNET_ATS_NETWORK_TYPE);
398 ats[1].value = htonl ((uint32_t) network);
399 session->active = GNUNET_YES; 392 session->active = GNUNET_YES;
400 plugin->env->session_start (plugin->env->cls, session->address, 393 plugin->env->session_start (plugin->env->cls,
401 session, ats, 2); 394 session->address,
395 session,
396 network);
397 plugin->env->update_address_distance (plugin->env->cls,
398 session->address,
399 session->distance);
400
402 notify_session_monitor (session->plugin, 401 notify_session_monitor (session->plugin,
403 session, 402 session,
404 GNUNET_TRANSPORT_SS_UP); 403 GNUNET_TRANSPORT_SS_UP);
diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c
index 1ff0f0496..260ffc902 100644
--- a/src/fs/gnunet-service-fs.c
+++ b/src/fs/gnunet-service-fs.c
@@ -241,14 +241,13 @@ GSF_test_get_load_too_high_ (uint32_t priority)
241/** 241/**
242 * We've received peer performance information. Update 242 * We've received peer performance information. Update
243 * our running average for the P2P latency. 243 * our running average for the P2P latency.
244* 244 *
245 * @param cls closure 245 * @param cls closure
246 * @param address the address 246 * @param address the address
247 * @param active is this address in active use 247 * @param active is this address in active use
248 * @param bandwidth_out assigned outbound bandwidth for the connection 248 * @param bandwidth_out assigned outbound bandwidth for the connection
249 * @param bandwidth_in assigned inbound bandwidth for the connection 249 * @param bandwidth_in assigned inbound bandwidth for the connection
250 * @param ats performance data for the address (as far as known) 250 * @param prop performance data for the address (as far as known)
251 * @param ats_count number of performance records in @a ats
252 */ 251 */
253static void 252static void
254update_latencies (void *cls, 253update_latencies (void *cls,
@@ -256,12 +255,8 @@ update_latencies (void *cls,
256 int active, 255 int active,
257 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 256 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
258 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 257 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
259 const struct GNUNET_ATS_Information *ats, 258 const struct GNUNET_ATS_Properties *prop)
260 uint32_t ats_count)
261{ 259{
262 unsigned int i;
263 struct GNUNET_TIME_Relative latency;
264
265 if (NULL == address) 260 if (NULL == address)
266 { 261 {
267 /* ATS service temporarily disconnected */ 262 /* ATS service temporarily disconnected */
@@ -270,22 +265,15 @@ update_latencies (void *cls,
270 265
271 if (GNUNET_YES != active) 266 if (GNUNET_YES != active)
272 return; 267 return;
273 for (i = 0; i < ats_count; i++) 268 GSF_update_peer_latency_ (&address->peer,
274 { 269 prop->delay);
275 if (GNUNET_ATS_QUALITY_NET_DELAY != ntohl (ats[i].type)) 270 GSF_avg_latency.rel_value_us =
276 continue; 271 (GSF_avg_latency.rel_value_us * 31 +
277 latency.rel_value_us = ntohl (ats[i].value); 272 GNUNET_MIN (5000, prop->delay.rel_value_us)) / 32;
278 GSF_update_peer_latency_ (&address->peer, 273 GNUNET_STATISTICS_set (GSF_stats,
279 latency); 274 gettext_noop ("# running average P2P latency (ms)"),
280 GSF_avg_latency.rel_value_us = 275 GSF_avg_latency.rel_value_us / 1000LL,
281 (GSF_avg_latency.rel_value_us * 31 + 276 GNUNET_NO);
282 GNUNET_MIN (5000, ntohl (ats[i].value))) / 32;
283 GNUNET_STATISTICS_set (GSF_stats,
284 gettext_noop
285 ("# running average P2P latency (ms)"),
286 GSF_avg_latency.rel_value_us / 1000LL, GNUNET_NO);
287 break;
288 }
289} 277}
290 278
291 279
diff --git a/src/fs/gnunet-service-fs_cp.c b/src/fs/gnunet-service-fs_cp.c
index f7d64a49e..749ef15c7 100644
--- a/src/fs/gnunet-service-fs_cp.c
+++ b/src/fs/gnunet-service-fs_cp.c
@@ -348,7 +348,6 @@ GSF_update_peer_latency_ (const struct GNUNET_PeerIdentity *id,
348 if (NULL == cp) 348 if (NULL == cp)
349 return; /* we're not yet connected at the core level, ignore */ 349 return; /* we're not yet connected at the core level, ignore */
350 GNUNET_LOAD_value_set_decline (cp->ppd.transmission_delay, latency); 350 GNUNET_LOAD_value_set_decline (cp->ppd.transmission_delay, latency);
351 /* LATER: merge atsi into cp's performance data (if we ever care...) */
352} 351}
353 352
354 353
@@ -416,9 +415,11 @@ schedule_transmission (struct GSF_PeerTransmitHandle *pth)
416 415
417 if (0 != cp->inc_preference) 416 if (0 != cp->inc_preference)
418 { 417 {
419 GNUNET_ATS_performance_change_preference (GSF_ats, &target, GNUNET_ATS_PREFERENCE_BANDWIDTH, 418 GNUNET_ATS_performance_change_preference (GSF_ats,
420 (double) cp->inc_preference, 419 &target,
421 GNUNET_ATS_PREFERENCE_END); 420 GNUNET_ATS_PREFERENCE_BANDWIDTH,
421 (double) cp->inc_preference,
422 GNUNET_ATS_PREFERENCE_END);
422 cp->inc_preference = 0; 423 cp->inc_preference = 0;
423 } 424 }
424 425
diff --git a/src/fs/gnunet-service-fs_cp.h b/src/fs/gnunet-service-fs_cp.h
index 502b8652f..eca6ff1ed 100644
--- a/src/fs/gnunet-service-fs_cp.h
+++ b/src/fs/gnunet-service-fs_cp.h
@@ -67,11 +67,6 @@ struct GSF_PeerPerformanceData
67{ 67{
68 68
69 /** 69 /**
70 * Transport performance data.
71 */
72 struct GNUNET_ATS_Information *atsi;
73
74 /**
75 * List of the last clients for which this peer successfully 70 * List of the last clients for which this peer successfully
76 * answered a query. 71 * answered a query.
77 */ 72 */
diff --git a/src/include/gnunet_ats_plugin.h b/src/include/gnunet_ats_plugin.h
index 4d6fa43f4..75d7ce3f8 100644
--- a/src/include/gnunet_ats_plugin.h
+++ b/src/include/gnunet_ats_plugin.h
@@ -34,13 +34,11 @@
34#include "gnunet_ats_service.h" 34#include "gnunet_ats_service.h"
35#include "gnunet_statistics_service.h" 35#include "gnunet_statistics_service.h"
36 36
37
38/** 37/**
39 * Representation of an address the plugin can choose from. 38 * Representation of an address the plugin can choose from.
40 */ 39 */
41struct ATS_Address; 40struct ATS_Address;
42 41
43
44/** 42/**
45 * Change the preference for a peer 43 * Change the preference for a peer
46 * 44 *
@@ -125,16 +123,10 @@ typedef void
125 * 123 *
126 * @param solver solver handle 124 * @param solver solver handle
127 * @param address the address 125 * @param address the address
128 * @param type the ATSI type in HBO
129 * @param abs_value the absolute value of the property
130 * @param rel_value the normalized value
131 */ 126 */
132typedef void 127typedef void
133(*GAS_solver_address_property_changed) (void *solver, 128(*GAS_solver_address_property_changed) (void *solver,
134 struct ATS_Address *address, 129 struct ATS_Address *address);
135 enum GNUNET_ATS_Property type,
136 uint32_t abs_value,
137 double rel_value);
138 130
139 131
140/** 132/**
@@ -386,8 +378,8 @@ typedef void
386 378
387 379
388/** 380/**
389 * Callback to call from solver to obtain application preference values for a 381 * Callback to call from solver to obtain application preference
390 * peer 382 * values for a peer.
391 * 383 *
392 * @param cls the cls 384 * @param cls the cls
393 * @param id the peer id 385 * @param id the peer id
diff --git a/src/include/gnunet_ats_service.h b/src/include/gnunet_ats_service.h
index 437984402..8b28f5dc7 100644
--- a/src/include/gnunet_ats_service.h
+++ b/src/include/gnunet_ats_service.h
@@ -100,137 +100,118 @@ enum GNUNET_ATS_Network_Type
100 100
101 101
102/** 102/**
103 * Enum defining all known property types for ATS Enum values are used 103 * ATS performance characteristics for an address.
104 * in the GNUNET_ATS_Information struct as
105 * (key,value)-pairs.
106 *
107 * Cost are always stored in uint32_t, so all units used to define costs
108 * have to be normalized to fit in uint32_t [0 .. UINT32_MAX-1]
109 *
110 * UINT32_MAX is reserved for uninitialized values #GNUNET_ATS_VALUE_UNDEFINED
111 */ 104 */
112enum GNUNET_ATS_Property 105struct GNUNET_ATS_Properties
113{ 106{
114 107
115 /** 108 /**
116 * End of the array.
117 * @deprecated
118 */
119 GNUNET_ATS_ARRAY_TERMINATOR = 0,
120
121 /**
122 * Actual traffic on this connection from this peer to the other peer. 109 * Actual traffic on this connection from this peer to the other peer.
123 * Includes transport overhead 110 * Includes transport overhead.
124 * 111 *
125 * Unit: [bytes/second] 112 * Unit: [bytes/second]
126 */ 113 */
127 GNUNET_ATS_UTILIZATION_OUT = 1, 114 uint32_t utilization_out;
128 115
129 /** 116 /**
130 * Actual traffic on this connection from the other peer to this peer. 117 * Actual traffic on this connection from the other peer to this peer.
131 * Includes transport overhead 118 * Includes transport overhead.
132 * 119 *
133 * Unit: [bytes/second] 120 * Unit: [bytes/second]
134 */ 121 */
135 GNUNET_ATS_UTILIZATION_IN = 2, 122 uint32_t utilization_in;
136 123
137 /** 124 /**
138 * Is this address located in WAN, LAN or a loopback address 125 * Which network scope does the respective address belong to?
139 * Value is element of GNUNET_ATS_Network_Type 126 * This property does not change.
140 */ 127 */
141 GNUNET_ATS_NETWORK_TYPE = 3, 128 enum GNUNET_ATS_Network_Type scope;
142 129
143 /** 130 /**
144 * Delay 131 * Distance on network layer (required for distance-vector routing)
145 * Time between when the time packet is sent and the packet arrives 132 * in hops. Zero for direct connections (i.e. plain TCP/UDP).
146 *
147 * Unit: [microseconds]
148 *
149 * Examples:
150 *
151 * LAN : 1
152 * WLAN : 2
153 * Dialup: 500
154 */ 133 */
155 GNUNET_ATS_QUALITY_NET_DELAY = 4, 134 unsigned int distance;
156 135
157 /** 136 /**
158 * Distance on network layer (required for distance-vector routing). 137 * Delay. Time between when the time packet is sent and the packet
159 * 138 * arrives. FOREVER if we did not measure yet.
160 * Unit: [DV-hops]
161 */ 139 */
162 GNUNET_ATS_QUALITY_NET_DISTANCE = 5 140 struct GNUNET_TIME_Relative delay;
163
164/**
165 * Number of property types supported by ATS
166 */
167#define GNUNET_ATS_PropertyCount 6
168
169 141
170}; 142};
171 143
172 144
173/** 145/**
174 * Number of ATS quality properties 146 * ATS performance characteristics for an address in
147 * network byte order (for IPC).
175 */ 148 */
176#define GNUNET_ATS_QualityPropertiesCount 2 149struct GNUNET_ATS_PropertiesNBO
150{
177 151
178/** 152 /**
179 * ATS quality properties as array initializer 153 * Actual traffic on this connection from this peer to the other peer.
180 */ 154 * Includes transport overhead.
181#define GNUNET_ATS_QualityProperties { GNUNET_ATS_QUALITY_NET_DELAY, GNUNET_ATS_QUALITY_NET_DISTANCE } 155 *
156 * Unit: [bytes/second]
157 */
158 uint32_t utilization_out GNUNET_PACKED;
182 159
183/** 160 /**
184 * ATS quality properties as string array initializer 161 * Actual traffic on this connection from the other peer to this peer.
185 */ 162 * Includes transport overhead.
186#define GNUNET_ATS_QualityPropertiesString {"Delay", "Distance"} 163 *
164 * Unit: [bytes/second]
165 */
166 uint32_t utilization_in GNUNET_PACKED;
187 167
188GNUNET_NETWORK_STRUCT_BEGIN 168 /**
169 * Which network scope does the respective address belong to?
170 * This property does not change.
171 */
172 uint32_t scope GNUNET_PACKED;
189 173
190/**
191 * struct used to communicate the transport's properties like cost and
192 * quality of service as well as high-level constraints on resource
193 * consumption.
194 *
195 * +---+
196 * +-----------+ Constraints | | Plugin properties +---------+
197 * | Highlevel |------------> |ATS| <------------------|Transport|
198 * | Component | ATS struct | | ATS struct | Plugin |
199 * +-----------+ | | +---------+
200 * +---+
201 *
202 * This structure will be used by transport plugins to communicate
203 * costs to ATS or by higher level components to tell ATS their
204 * constraints. Always a pair of (GNUNET_ATS_Property,
205 * uint32_t value). Value is always uint32_t, so all units used to
206 * define costs have to be normalized to fit uint32_t.
207 */
208struct GNUNET_ATS_Information
209{
210 /** 174 /**
211 * ATS property type, in network byte order. 175 * Distance on network layer (required for distance-vector routing)
176 * in hops. Zero for direct connections (i.e. plain TCP/UDP).
212 */ 177 */
213 uint32_t type GNUNET_PACKED; 178 uint32_t distance GNUNET_PACKED;
214 179
215 /** 180 /**
216 * ATS property value, in network byte order. 181 * Delay. Time between when the time packet is sent and the packet
182 * arrives. FOREVER if we did not measure yet.
217 */ 183 */
218 uint32_t value GNUNET_PACKED; 184 struct GNUNET_TIME_RelativeNBO delay;
185
219}; 186};
220GNUNET_NETWORK_STRUCT_END 187
221 188
222 189
223/* ********************* LAN Characterization library ************************ */ 190/* ********************* LAN Characterization library ************************ */
224/* Note: these functions do not really communicate with the ATS service */ 191/* Note: these functions do not really communicate with the ATS service */
225 192
193
226/** 194/**
227 * Convert a ATS property to a string 195 * Convert ATS properties from host to network byte order.
228 * 196 *
229 * @param type the property type 197 * @param nbo[OUT] value written
230 * @return a string or NULL if invalid 198 * @param hbo value read
231 */ 199 */
232const char * 200void
233GNUNET_ATS_print_property_type (enum GNUNET_ATS_Property type); 201GNUNET_ATS_properties_hton (struct GNUNET_ATS_PropertiesNBO *nbo,
202 const struct GNUNET_ATS_Properties *hbo);
203
204
205/**
206 * Convert ATS properties from network to host byte order.
207 *
208 * @param hbo[OUT] value written
209 * @param nbo value read
210 */
211void
212GNUNET_ATS_properties_ntoh (struct GNUNET_ATS_Properties *hbo,
213 const struct GNUNET_ATS_PropertiesNBO *nbo);
214
234 215
235 216
236/** 217/**
@@ -367,11 +348,11 @@ struct Session;
367 */ 348 */
368typedef void 349typedef void
369(*GNUNET_ATS_AddressSuggestionCallback) (void *cls, 350(*GNUNET_ATS_AddressSuggestionCallback) (void *cls,
370 const struct GNUNET_PeerIdentity *peer, 351 const struct GNUNET_PeerIdentity *peer,
371 const struct GNUNET_HELLO_Address *address, 352 const struct GNUNET_HELLO_Address *address,
372 struct Session *session, 353 struct Session *session,
373 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 354 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
374 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in); 355 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in);
375 356
376 357
377/** 358/**
@@ -424,8 +405,7 @@ struct GNUNET_ATS_AddressRecord;
424 * @param sh handle 405 * @param sh handle
425 * @param address the address 406 * @param address the address
426 * @param session session handle (if available, i.e. for incoming connections) 407 * @param session session handle (if available, i.e. for incoming connections)
427 * @param ats performance data for the address 408 * @param prop performance data for the address
428 * @param ats_count number of performance records in @a ats
429 * @return handle to the address representation inside ATS, NULL 409 * @return handle to the address representation inside ATS, NULL
430 * on error (i.e. ATS knows this exact address already, or 410 * on error (i.e. ATS knows this exact address already, or
431 * address is invalid) 411 * address is invalid)
@@ -434,8 +414,7 @@ struct GNUNET_ATS_AddressRecord *
434GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, 414GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
435 const struct GNUNET_HELLO_Address *address, 415 const struct GNUNET_HELLO_Address *address,
436 struct Session *session, 416 struct Session *session,
437 const struct GNUNET_ATS_Information *ats, 417 const struct GNUNET_ATS_Properties *prop);
438 uint32_t ats_count);
439 418
440 419
441/** 420/**
@@ -477,13 +456,11 @@ GNUNET_ATS_address_del_session (struct GNUNET_ATS_AddressRecord *ar,
477 * suggest to switch addresses. 456 * suggest to switch addresses.
478 * 457 *
479 * @param ar address record to update information for 458 * @param ar address record to update information for
480 * @param ats performance data for the address 459 * @param prop performance data for the address
481 * @param ats_count number of performance records in @a ats
482 */ 460 */
483void 461void
484GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar, 462GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar,
485 const struct GNUNET_ATS_Information *ats, 463 const struct GNUNET_ATS_Properties *prop);
486 uint32_t ats_count);
487 464
488 465
489/** 466/**
@@ -515,8 +492,7 @@ struct GNUNET_ATS_PerformanceHandle;
515 * #GNUNET_SYSERR if this address is no longer available for ATS 492 * #GNUNET_SYSERR if this address is no longer available for ATS
516 * @param bandwidth_out assigned outbound bandwidth for the connection 493 * @param bandwidth_out assigned outbound bandwidth for the connection
517 * @param bandwidth_in assigned inbound bandwidth for the connection 494 * @param bandwidth_in assigned inbound bandwidth for the connection
518 * @param ats performance data for the address (as far as known) 495 * @param prop performance data for the address
519 * @param ats_count number of performance records in @a ats
520 */ 496 */
521typedef void 497typedef void
522(*GNUNET_ATS_AddressInformationCallback) (void *cls, 498(*GNUNET_ATS_AddressInformationCallback) (void *cls,
@@ -524,8 +500,7 @@ typedef void
524 int address_active, 500 int address_active,
525 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 501 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
526 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 502 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
527 const struct GNUNET_ATS_Information *ats, 503 const struct GNUNET_ATS_Properties *prop);
528 uint32_t ats_count);
529 504
530 505
531/** 506/**
@@ -650,7 +625,7 @@ GNUNET_ATS_reserve_bandwidth_cancel (struct GNUNET_ATS_ReservationContext *rc);
650/** 625/**
651 * ATS preference types as string array initializer 626 * ATS preference types as string array initializer
652 */ 627 */
653#define GNUNET_ATS_PreferenceTypeString {"END", "BANDWIDTH", "LATENCY"} 628#define GNUNET_ATS_PreferenceTypeString {"BANDWIDTH", "LATENCY", "END" }
654 629
655/** 630/**
656 * Enum defining all known preference categories. 631 * Enum defining all known preference categories.
@@ -659,17 +634,12 @@ enum GNUNET_ATS_PreferenceKind
659{ 634{
660 635
661 /** 636 /**
662 * End of preference list.
663 */
664 GNUNET_ATS_PREFERENCE_END = 0,
665
666 /**
667 * Change the peer's bandwidth value (value per byte of bandwidth in 637 * Change the peer's bandwidth value (value per byte of bandwidth in
668 * the goal function) to the given amount. The argument is followed 638 * the goal function) to the given amount. The argument is followed
669 * by a double value giving the desired value (can be negative). 639 * by a double value giving the desired value (can be negative).
670 * Preference changes are forgotten if peers disconnect. 640 * Preference changes are forgotten if peers disconnect.
671 */ 641 */
672 GNUNET_ATS_PREFERENCE_BANDWIDTH = 1, 642 GNUNET_ATS_PREFERENCE_BANDWIDTH = 0,
673 643
674 /** 644 /**
675 * Change the peer's latency value to the given amount. The 645 * Change the peer's latency value to the given amount. The
@@ -678,13 +648,12 @@ enum GNUNET_ATS_PreferenceKind
678 * the inverse of the latency in microseconds (minimum: 1 648 * the inverse of the latency in microseconds (minimum: 1
679 * microsecond) multiplied by the latency preferences. 649 * microsecond) multiplied by the latency preferences.
680 */ 650 */
681 GNUNET_ATS_PREFERENCE_LATENCY = 2 651 GNUNET_ATS_PREFERENCE_LATENCY = 1,
682
683/**
684 * Number of preference types supported by ATS
685 */
686#define GNUNET_ATS_PreferenceCount 3
687 652
653 /**
654 * End of preference list.
655 */
656 GNUNET_ATS_PREFERENCE_END = 2
688 657
689}; 658};
690 659
@@ -703,9 +672,9 @@ GNUNET_ATS_print_preference_type (enum GNUNET_ATS_PreferenceKind type);
703 * Change preferences for the given peer. Preference changes are forgotten if peers 672 * Change preferences for the given peer. Preference changes are forgotten if peers
704 * disconnect. 673 * disconnect.
705 * 674 *
706 * @param ph performance handle 675 * @param ph performance handle @param peer identifies the peer
707 * @param peer identifies the peer 676 * @param ... #GNUNET_ATS_PREFERENCE_END-terminated specification of the
708 * @param ... 0-terminated specification of the desired changes 677 * desired changes
709 */ 678 */
710void 679void
711GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *ph, 680GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *ph,
@@ -728,7 +697,7 @@ GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *p
728 * @param ph performance handle 697 * @param ph performance handle
729 * @param scope the time interval this valid for: [now - scope .. now] 698 * @param scope the time interval this valid for: [now - scope .. now]
730 * @param peer identifies the peer 699 * @param peer identifies the peer
731 * @param ... 0-terminated specification of the desired changes 700 * @param ... #GNUNET_ATS_PREFERENCE_END-terminated specification of the desired changes
732 */ 701 */
733void 702void
734GNUNET_ATS_performance_give_feedback (struct GNUNET_ATS_PerformanceHandle *ph, 703GNUNET_ATS_performance_give_feedback (struct GNUNET_ATS_PerformanceHandle *ph,
diff --git a/src/include/gnunet_transport_plugin.h b/src/include/gnunet_transport_plugin.h
index 90a85356b..f8394ebc5 100644
--- a/src/include/gnunet_transport_plugin.h
+++ b/src/include/gnunet_transport_plugin.h
@@ -80,15 +80,13 @@ typedef void
80 * @param cls unused 80 * @param cls unused
81 * @param address the address 81 * @param address the address
82 * @param session the new session 82 * @param session the new session
83 * @param ats ats information 83 * @param net network information
84 * @param ats_count number of @a ats information
85 */ 84 */
86typedef void 85typedef void
87(*GNUNET_TRANSPORT_SessionStart) (void *cls, 86(*GNUNET_TRANSPORT_SessionStart) (void *cls,
88 const struct GNUNET_HELLO_Address *address, 87 const struct GNUNET_HELLO_Address *address,
89 struct Session *session, 88 struct Session *session,
90 const struct GNUNET_ATS_Information *ats, 89 enum GNUNET_ATS_Network_Type net);
91 uint32_t ats_count);
92 90
93 91
94/** 92/**
@@ -137,22 +135,16 @@ typedef enum GNUNET_ATS_Network_Type
137 135
138 136
139/** 137/**
140 * Function called when quality properties of an address change. 138 * Function called when distance of an address changes.
141 * 139 *
142 * @param cls closure 140 * @param cls closure
143 * @param peer peer 141 * @param peer peer
144 * @param address address 142 * @param distance new distance
145 * @param address_len length of the @a address
146 * @param session session
147 * @param ats ATS information
148 * @param ats_count number entries in the @a ats array
149 */ 143 */
150typedef void 144typedef void
151(*GNUNET_TRANSPORT_UpdateAddressMetrics) (void *cls, 145(*GNUNET_TRANSPORT_UpdateAddressDistance) (void *cls,
152 const struct GNUNET_HELLO_Address *address, 146 const struct GNUNET_HELLO_Address *address,
153 struct Session *session, 147 uint32_t distance);
154 const struct GNUNET_ATS_Information *ats,
155 uint32_t ats_count);
156 148
157 149
158/** 150/**
@@ -269,10 +261,10 @@ struct GNUNET_TRANSPORT_PluginEnvironment
269 GNUNET_TRANSPORT_AddressToType get_address_type; 261 GNUNET_TRANSPORT_AddressToType get_address_type;
270 262
271 /** 263 /**
272 * Function that will be called to figure if an address is an loopback, 264 * Function that will be called by DV to update distance for
273 * LAN, WAN etc. address 265 * an address.
274 */ 266 */
275 GNUNET_TRANSPORT_UpdateAddressMetrics update_address_metrics; 267 GNUNET_TRANSPORT_UpdateAddressDistance update_address_distance;
276 268
277 /** 269 /**
278 * What is the maximum number of connections that this transport 270 * What is the maximum number of connections that this transport
diff --git a/src/include/gnunet_transport_service.h b/src/include/gnunet_transport_service.h
index 85d28ddd2..655704b1e 100644
--- a/src/include/gnunet_transport_service.h
+++ b/src/include/gnunet_transport_service.h
@@ -333,34 +333,19 @@ GNUNET_TRANSPORT_check_peer_connected (struct GNUNET_TRANSPORT_Handle *handle,
333 * 333 *
334 * @param handle transport handle 334 * @param handle transport handle
335 * @param peer the peer to set the metric for 335 * @param peer the peer to set the metric for
336 * @param inbound set inbound direction (#GNUNET_YES or #GNUNET_NO) 336 * @param prop the performance metrics to set
337 * @param outbound set outbound direction (#GNUNET_YES or #GNUNET_NO) 337 * @param delay_in inbound delay to introduce
338 * @param ats the metric as ATS information 338 * @param delay_out outbound delay to introduce
339 * @param ats_count the number of metrics
340 * 339 *
341 * Supported ATS values: 340 * Note: Delay restrictions in receiving direction will be enforced
342 * #GNUNET_ATS_QUALITY_NET_DELAY (value in ms) 341 * with one message delay.
343 * #GNUNET_ATS_QUALITY_NET_DISTANCE (value in count(hops))
344 *
345 * Example
346 * To enforce a delay of 10 ms for peer p1 in sending direction use:
347 *
348 * struct GNUNET_ATS_Information ats;
349 * ats.type = ntohl (GNUNET_ATS_QUALITY_NET_DELAY);
350 * ats.value = ntohl (10);
351 * GNUNET_TRANSPORT_set_traffic_metric (th, p1, TM_SEND, &ats, 1);
352 *
353 * Note:
354 * Delay restrictions in receiving direction will be enforced with
355 * 1 message delay.
356 */ 342 */
357void 343void
358GNUNET_TRANSPORT_set_traffic_metric (struct GNUNET_TRANSPORT_Handle *handle, 344GNUNET_TRANSPORT_set_traffic_metric (struct GNUNET_TRANSPORT_Handle *handle,
359 const struct GNUNET_PeerIdentity *peer, 345 const struct GNUNET_PeerIdentity *peer,
360 int inbound, 346 const struct GNUNET_ATS_Properties *prop,
361 int outbound, 347 struct GNUNET_TIME_Relative delay_in,
362 const struct GNUNET_ATS_Information *ats, 348 struct GNUNET_TIME_Relative delay_out);
363 size_t ats_count);
364 349
365 350
366/* *************************** HELLO *************************** */ 351/* *************************** HELLO *************************** */
diff --git a/src/testbed/gnunet-daemon-latency-logger.c b/src/testbed/gnunet-daemon-latency-logger.c
index a8951c3dd..2dca73768 100644
--- a/src/testbed/gnunet-daemon-latency-logger.c
+++ b/src/testbed/gnunet-daemon-latency-logger.c
@@ -68,7 +68,8 @@ struct Entry
68 struct GNUNET_PeerIdentity id; 68 struct GNUNET_PeerIdentity id;
69 69
70 /** 70 /**
71 * The last known value for latency 71 * The last known value for latency.
72 * FIXME: type!
72 */ 73 */
73 unsigned int latency; 74 unsigned int latency;
74 75
@@ -166,8 +167,7 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
166 * #GNUNET_SYSERR if this address is no longer available for ATS 167 * #GNUNET_SYSERR if this address is no longer available for ATS
167 * @param bandwidth_out assigned outbound bandwidth for the connection 168 * @param bandwidth_out assigned outbound bandwidth for the connection
168 * @param bandwidth_in assigned inbound bandwidth for the connection 169 * @param bandwidth_in assigned inbound bandwidth for the connection
169 * @param ats performance data for the address (as far as known) 170 * @param prop performance data for the address (as far as known)
170 * @param ats_count number of performance records in 'ats'
171 */ 171 */
172static void 172static void
173addr_info_cb (void *cls, 173addr_info_cb (void *cls,
@@ -175,8 +175,7 @@ addr_info_cb (void *cls,
175 int address_active, 175 int address_active,
176 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 176 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
177 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 177 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
178 const struct GNUNET_ATS_Information *ats, 178 const struct GNUNET_ATS_Properties *prop)
179 uint32_t ats_count)
180{ 179{
181 static const char *query_insert = 180 static const char *query_insert =
182 "INSERT INTO ats_info(" 181 "INSERT INTO ats_info("
@@ -189,8 +188,7 @@ addr_info_cb (void *cls,
189 " datetime('now')" 188 " datetime('now')"
190 ");"; 189 ");";
191 struct Entry *entry; 190 struct Entry *entry;
192 int latency; 191 int latency; /* FIXME: type!? */
193 unsigned int cnt;
194 192
195 if (NULL == address) 193 if (NULL == address)
196 { 194 {
@@ -201,15 +199,7 @@ addr_info_cb (void *cls,
201 GNUNET_assert (NULL != db); 199 GNUNET_assert (NULL != db);
202 if (GNUNET_YES != address_active) 200 if (GNUNET_YES != address_active)
203 return; 201 return;
204 for (cnt = 0; cnt < ats_count; cnt++) 202 latency = (int) prop->delay.rel_value_us;
205 {
206 if (GNUNET_ATS_QUALITY_NET_DELAY == ntohl (ats[cnt].type))
207 goto insert;
208 }
209 return;
210
211 insert:
212 latency = (int) ntohl (ats[cnt].value);
213 entry = NULL; 203 entry = NULL;
214 if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (map, 204 if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (map,
215 &address->peer)) 205 &address->peer))
diff --git a/src/testbed/gnunet-daemon-testbed-underlay.c b/src/testbed/gnunet-daemon-testbed-underlay.c
index 49bfc64bf..e41cf4a4d 100644
--- a/src/testbed/gnunet-daemon-testbed-underlay.c
+++ b/src/testbed/gnunet-daemon-testbed-underlay.c
@@ -365,13 +365,15 @@ run (void *cls, char *const *args, const char *cfgfile,
365 struct WhiteListRow *wl_head; 365 struct WhiteListRow *wl_head;
366 struct WhiteListRow *wl_entry; 366 struct WhiteListRow *wl_entry;
367 struct GNUNET_PeerIdentity identity; 367 struct GNUNET_PeerIdentity identity;
368 struct GNUNET_ATS_Information params[1]; 368 struct GNUNET_ATS_Properties prop;
369 struct GNUNET_TIME_Relative delay;
369 unsigned long long pid; 370 unsigned long long pid;
370 unsigned int nrows; 371 unsigned int nrows;
371 int ret; 372 int ret;
372 373
373 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (c, "TESTBED", 374 if (GNUNET_OK !=
374 "PEERID", &pid)) 375 GNUNET_CONFIGURATION_get_value_number (c, "TESTBED",
376 "PEERID", &pid))
375 { 377 {
376 GNUNET_break (0); 378 GNUNET_break (0);
377 return; 379 return;
@@ -418,11 +420,11 @@ run (void *cls, char *const *args, const char *cfgfile,
418 goto close_db; 420 goto close_db;
419 } 421 }
420 map = GNUNET_CONTAINER_multipeermap_create (nrows, GNUNET_NO); 422 map = GNUNET_CONTAINER_multipeermap_create (nrows, GNUNET_NO);
421 params[0].type = GNUNET_ATS_QUALITY_NET_DELAY;
422 while (NULL != (wl_entry = wl_head)) 423 while (NULL != (wl_entry = wl_head))
423 { 424 {
424 wl_head = wl_entry->next; 425 wl_head = wl_entry->next;
425 params[0].value = wl_entry->latency; 426 delay.rel_value_us = wl_entry->latency;
427 memset (&prop, 0, sizeof (prop));
426 GNUNET_assert (GNUNET_OK == get_identity (wl_entry->id, &identity)); 428 GNUNET_assert (GNUNET_OK == get_identity (wl_entry->id, &identity));
427 GNUNET_break (GNUNET_OK == 429 GNUNET_break (GNUNET_OK ==
428 GNUNET_CONTAINER_multipeermap_put (map, &identity, &identity, 430 GNUNET_CONTAINER_multipeermap_put (map, &identity, &identity,
@@ -432,9 +434,9 @@ run (void *cls, char *const *args, const char *cfgfile,
432 GNUNET_i2s (&identity)); 434 GNUNET_i2s (&identity));
433 GNUNET_TRANSPORT_set_traffic_metric (transport, 435 GNUNET_TRANSPORT_set_traffic_metric (transport,
434 &identity, 436 &identity,
435 GNUNET_YES, 437 &prop,
436 GNUNET_YES, /* FIXME: Separate inbound, outboud metrics */ 438 delay,
437 params, 1); 439 delay);
438 GNUNET_free (wl_entry); 440 GNUNET_free (wl_entry);
439 } 441 }
440 bh = GNUNET_TRANSPORT_blacklist (c, &check_access, NULL); 442 bh = GNUNET_TRANSPORT_blacklist (c, &check_access, NULL);
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