aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/transport/gnunet-service-transport.c300
-rw-r--r--src/transport/test_transport_ats.c31
-rw-r--r--src/transport/transport_ats.c1055
-rw-r--r--src/transport/transport_ats.h175
4 files changed, 754 insertions, 807 deletions
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index 73239c241..fdd86ac3e 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -935,6 +935,19 @@ static int shutdown_in_progress;
935static struct ATS_Handle *ats; 935static struct ATS_Handle *ats;
936 936
937/** 937/**
938 * Time of last ats execution
939 */
940struct GNUNET_TIME_Absolute last_ats_execution;
941/**
942 * Minimum interval between two ATS executions
943 */
944struct GNUNET_TIME_Relative ats_minimum_interval;
945/**
946 * Regular interval when ATS execution is triggered
947 */
948struct GNUNET_TIME_Relative ats_regular_interval;
949
950/**
938 * The peer specified by the given neighbour has timed-out or a plugin 951 * The peer specified by the given neighbour has timed-out or a plugin
939 * has disconnected. We may either need to do nothing (other plugins 952 * has disconnected. We may either need to do nothing (other plugins
940 * still up), or trigger a full disconnect and clean up. This 953 * still up), or trigger a full disconnect and clean up. This
@@ -2284,10 +2297,11 @@ try_fast_reconnect (struct TransportPlugin *p,
2284 2297
2285 /* No reconnect, signal disconnect instead! */ 2298 /* No reconnect, signal disconnect instead! */
2286#if DEBUG_TRANSPORT 2299#if DEBUG_TRANSPORT
2300#endif
2287 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2301 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2288 "Disconnecting peer `%4s', %s\n", GNUNET_i2s(&nl->id), 2302 "Disconnecting peer `%4s', %s\n", GNUNET_i2s(&nl->id),
2289 "try_fast_reconnect"); 2303 "try_fast_reconnect");
2290#endif 2304
2291 GNUNET_STATISTICS_update (stats, 2305 GNUNET_STATISTICS_update (stats,
2292 gettext_noop ("# disconnects due to try_fast_reconnect"), 2306 gettext_noop ("# disconnects due to try_fast_reconnect"),
2293 1, 2307 1,
@@ -2416,11 +2430,18 @@ plugin_env_session_end (void *cls,
2416 gettext_noop ("# disconnects due to missing pong"), 2430 gettext_noop ("# disconnects due to missing pong"),
2417 1, 2431 1,
2418 GNUNET_NO); 2432 GNUNET_NO);
2433 /* FIXME this is never true?! See: line 2416*/
2419 if (GNUNET_YES == pos->connected) 2434 if (GNUNET_YES == pos->connected)
2420 disconnect_neighbour (nl, GNUNET_YES); 2435 disconnect_neighbour (nl, GNUNET_YES);
2421 } 2436 }
2422 return; 2437 return;
2423 } 2438 }
2439
2440 GNUNET_STATISTICS_update (stats,
2441 gettext_noop ("# connected addresses"),
2442 -1,
2443 GNUNET_NO);
2444
2424 /* was inbound connection, free 'pos' */ 2445 /* was inbound connection, free 'pos' */
2425 if (prev == NULL) 2446 if (prev == NULL)
2426 rl->addresses = pos->next; 2447 rl->addresses = pos->next;
@@ -2607,7 +2628,7 @@ notify_clients_connect (const struct GNUNET_PeerIdentity *peer,
2607 if ((ats != NULL) && (shutdown_in_progress == GNUNET_NO)) 2628 if ((ats != NULL) && (shutdown_in_progress == GNUNET_NO))
2608 { 2629 {
2609 ats_modify_problem_state(ats, ATS_MODIFIED); 2630 ats_modify_problem_state(ats, ATS_MODIFIED);
2610 ats_calculate_bandwidth_distribution (ats, stats, neighbours); 2631 ats_calculate_bandwidth_distribution (ats, stats);
2611 } 2632 }
2612 2633
2613 2634
@@ -2656,7 +2677,7 @@ notify_clients_disconnect (const struct GNUNET_PeerIdentity *peer)
2656 if ((ats != NULL) && (shutdown_in_progress == GNUNET_NO)) 2677 if ((ats != NULL) && (shutdown_in_progress == GNUNET_NO))
2657 { 2678 {
2658 ats_modify_problem_state(ats, ATS_MODIFIED); 2679 ats_modify_problem_state(ats, ATS_MODIFIED);
2659 ats_calculate_bandwidth_distribution (ats, stats, neighbours); 2680 ats_calculate_bandwidth_distribution (ats, stats);
2660 } 2681 }
2661 2682
2662 cpos = clients; 2683 cpos = clients;
@@ -4820,7 +4841,7 @@ disconnect_neighbour (struct NeighbourList *n, int check)
4820 if (GNUNET_YES == n->received_pong) 4841 if (GNUNET_YES == n->received_pong)
4821 notify_clients_disconnect (&n->id); 4842 notify_clients_disconnect (&n->id);
4822 4843
4823 ats_modify_problem_state(ats, ATS_QUALITY_COST_UPDATED); 4844 ats_modify_problem_state(ats, ATS_MODIFIED);
4824 4845
4825 /* clean up all plugins, cancel connections and pending transmissions */ 4846 /* clean up all plugins, cancel connections and pending transmissions */
4826 while (NULL != (rpos = n->plugins)) 4847 while (NULL != (rpos = n->plugins))
@@ -6006,13 +6027,12 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
6006 GNUNET_CONTAINER_multihashmap_destroy (validation_map); 6027 GNUNET_CONTAINER_multihashmap_destroy (validation_map);
6007 validation_map = NULL; 6028 validation_map = NULL;
6008 6029
6030
6009 if (ats_task != GNUNET_SCHEDULER_NO_TASK) 6031 if (ats_task != GNUNET_SCHEDULER_NO_TASK)
6010 { 6032 {
6011 GNUNET_SCHEDULER_cancel(ats_task); 6033 GNUNET_SCHEDULER_cancel(ats_task);
6012 ats_task = GNUNET_SCHEDULER_NO_TASK; 6034 ats_task = GNUNET_SCHEDULER_NO_TASK;
6013 } 6035 }
6014
6015
6016 if (ats != NULL) 6036 if (ats != NULL)
6017 ats_shutdown (ats); 6037 ats_shutdown (ats);
6018 6038
@@ -6058,9 +6078,127 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
6058} 6078}
6059 6079
6060 6080
6081void ats_result_cb ()
6082{
6083 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6084 "ATS Result callback\n");
6085}
6086
6087
6088void create_ats_information ( struct ATS_peer **p,
6089 int * c_p,
6090 struct ATS_mechanism ** m,
6091 int * c_m )
6092{
6093#if VERBOSE_ATS
6094 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6095 "ATS requires clean address information\n");
6096#endif
6097 struct ATS_mechanism * mechanisms;
6098 struct ATS_peer *peers;
6099
6100 int connected_addresses = 0;
6101 int c_peers = 0;
6102 int c_mechs = 0;
6103 struct NeighbourList *next = neighbours;
6104
6105 while (next!=NULL)
6106 {
6107 int found_addresses = GNUNET_NO;
6108 struct ReadyList *r_next = next->plugins;
6109 while (r_next != NULL)
6110 {
6111 struct ForeignAddressList * a_next = r_next->addresses;
6112 while (a_next != NULL)
6113 {
6114 c_mechs++;
6115 found_addresses = GNUNET_YES;
6116 a_next = a_next->next;
6117 }
6118 r_next = r_next->next;
6119 }
6120 if (found_addresses) c_peers++;
6121 next = next->next;
6122 }
6123
6124#if VERBOSE_ATS
6125 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6126 "Found %u peers with % u transport mechanisms\n", c_peers, c_mechs);
6127#endif
6128
6129 if ((c_peers == 0) && (c_mechs == 0))
6130 {
6131 peers = NULL;
6132 (*c_p) = 0;
6133 mechanisms = NULL;
6134 (*c_m) = 0;
6135 return;
6136 }
6137
6138 mechanisms = GNUNET_malloc((1+c_mechs) * sizeof (struct ATS_mechanism));
6139 peers = GNUNET_malloc((1+c_peers) * sizeof (struct ATS_peer));
6140
6141 c_mechs = 1;
6142 c_peers = 1;
6143
6144 next = neighbours;
6145 while (next!=NULL)
6146 {
6147 int found_addresses = GNUNET_NO;
6148 struct ReadyList *r_next = next->plugins;
6149 while (r_next != NULL)
6150 {
6151 struct ForeignAddressList * a_next = r_next->addresses;
6152 while (a_next != NULL)
6153 {
6154 if (a_next->connected == GNUNET_YES)
6155 connected_addresses ++;
6156 if (found_addresses == GNUNET_NO)
6157 {
6158 peers[c_peers].peer = next->id;
6159 peers[c_peers].m_head = NULL;
6160 peers[c_peers].m_tail = NULL;
6161 peers[c_peers].f = 1.0 / c_mechs;
6162 }
6163
6164 mechanisms[c_mechs].addr = a_next;
6165 mechanisms[c_mechs].col_index = c_mechs;
6166 mechanisms[c_mechs].peer = &peers[c_peers];
6167 mechanisms[c_mechs].next = NULL;
6168 mechanisms[c_mechs].plugin = r_next->plugin;
6169 mechanisms[c_mechs].ressources = a_next->ressources;
6170 mechanisms[c_mechs].quality = a_next->quality;
6171
6172 GNUNET_CONTAINER_DLL_insert_tail(peers[c_peers].m_head,
6173 peers[c_peers].m_tail,
6174 &mechanisms[c_mechs]);
6175 found_addresses = GNUNET_YES;
6176 c_mechs++;
6177
6178 a_next = a_next->next;
6179 }
6180 r_next = r_next->next;
6181 }
6182 if (found_addresses == GNUNET_YES)
6183 c_peers++;
6184 next = next->next;
6185 }
6186 c_mechs--;
6187 c_peers--;
6188 (*c_m) = c_mechs;
6189 (*c_p) = c_peers;
6190 (*p) = peers;
6191 (*m) = mechanisms;
6192
6193 GNUNET_STATISTICS_set(stats,
6194 gettext_noop ("# connected addresses"),
6195 connected_addresses,
6196 GNUNET_NO);
6197}
6198
6061static void 6199static void
6062schedule_ats (void *cls, 6200schedule_ats (void *cls,
6063 const struct GNUNET_SCHEDULER_TaskContext *tc) 6201 const struct GNUNET_SCHEDULER_TaskContext *tc)
6064{ 6202{
6065 struct ATS_Handle *ats = (struct ATS_Handle *) cls; 6203 struct ATS_Handle *ats = (struct ATS_Handle *) cls;
6066 if (ats==NULL) 6204 if (ats==NULL)
@@ -6069,13 +6207,28 @@ schedule_ats (void *cls,
6069 ats_task = GNUNET_SCHEDULER_NO_TASK; 6207 ats_task = GNUNET_SCHEDULER_NO_TASK;
6070 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 6208 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
6071 return; 6209 return;
6210
6072 if (shutdown_in_progress == GNUNET_YES) 6211 if (shutdown_in_progress == GNUNET_YES)
6073 return; 6212 return;
6213
6214 struct GNUNET_TIME_Relative delta =
6215 GNUNET_TIME_absolute_get_difference (last_ats_execution, GNUNET_TIME_absolute_get());
6216 if (delta.rel_value < ats_minimum_interval.rel_value)
6217 {
6074#if DEBUG_ATS 6218#if DEBUG_ATS
6075 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Running scheduled calculation\n"); 6219 GNUNET_log (GNUNET_ERROR_TYPE_BULK,
6220 "Minimum time between cycles not reached\n");
6076#endif 6221#endif
6077 ats_calculate_bandwidth_distribution (ats, stats, neighbours); 6222 return;
6078 ats_task = GNUNET_SCHEDULER_add_delayed (ats->exec_interval, 6223 }
6224
6225#if DEBUG_ATS
6226 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Running scheduled calculation\n");
6227#endif
6228 ats_calculate_bandwidth_distribution (ats, stats);
6229 last_ats_execution = GNUNET_TIME_absolute_get();
6230
6231 ats_task = GNUNET_SCHEDULER_add_delayed (ats_regular_interval,
6079 &schedule_ats, ats); 6232 &schedule_ats, ats);
6080} 6233}
6081 6234
@@ -6215,11 +6368,136 @@ run (void *cls,
6215 if (no_transports) 6368 if (no_transports)
6216 refresh_hello (); 6369 refresh_hello ();
6217 6370
6218 ats = ats_init (cfg); 6371 /* Initializing ATS */
6372 int co;
6373 char * section;
6374 unsigned long long value;
6375
6376 double D = 1.0;
6377 double U = 1.0;
6378 double R = 1.0;
6379 int v_b_min = 64000;
6380 int v_n_min = 5;
6381
6382 ats_minimum_interval = ATS_MIN_INTERVAL;
6383 ats_regular_interval = ATS_EXEC_INTERVAL;
6384
6385 /* loading cost ressources */
6386 for (co=0; co<available_ressources; co++)
6387 {
6388 GNUNET_asprintf(&section,"%s_UP",ressources[co].cfg_param);
6389 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", section))
6390 {
6391 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg,
6392 "transport",
6393 section,
6394 &value))
6395 {
6396#if DEBUG_ATS
6397 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6398 "Found ressource cost: [%s] = %llu\n",
6399 section, value);
6400#endif
6401 ressources[co].c_max = value;
6402 }
6403 }
6404 GNUNET_free (section);
6405 GNUNET_asprintf(&section,"%s_DOWN",ressources[co].cfg_param);
6406 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", section))
6407 {
6408 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg,
6409 "transport",
6410 section,
6411 &value))
6412 {
6413#if DEBUG_ATS
6414 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6415 "Found ressource cost: [%s] = %llu\n",
6416 section, value);
6417#endif
6418 ressources[co].c_min = value;
6419 }
6420 }
6421 GNUNET_free (section);
6422 }
6423
6424 ats = ats_init (D, U, R, v_b_min, v_n_min,
6425 ATS_MAX_ITERATIONS, ATS_MAX_EXEC_DURATION,
6426 create_ats_information,
6427 ats_result_cb);
6428
6429 int log_problem = GNUNET_NO;
6430 int log_solution = GNUNET_NO;
6431 int overwrite_dump = GNUNET_NO;
6432 int minimum_peers = 0;
6433 int minimum_addresses = 0;
6434
6435 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_MLP"))
6436 log_problem = GNUNET_CONFIGURATION_get_value_yesno (cfg,
6437 "transport","DUMP_MLP");
6438
6439 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_SOLUTION"))
6440 log_solution = GNUNET_CONFIGURATION_get_value_yesno (cfg,
6441 "transport","DUMP_SOLUTION");
6442 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_OVERWRITE"))
6443 overwrite_dump = GNUNET_CONFIGURATION_get_value_yesno (cfg,
6444 "transport","DUMP_OVERWRITE");
6445 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_MIN_PEERS"))
6446 {
6447 GNUNET_CONFIGURATION_get_value_number(cfg,
6448 "transport","DUMP_MIN_PEERS", &value);
6449 minimum_peers = value;
6450 }
6451 if (GNUNET_CONFIGURATION_have_value(cfg,
6452 "transport", "DUMP_MIN_ADDRS"))
6453 {
6454 GNUNET_CONFIGURATION_get_value_number(cfg,
6455 "transport","DUMP_MIN_ADDRS", &value);
6456 minimum_addresses= value;
6457 }
6458 if (GNUNET_CONFIGURATION_have_value(cfg,
6459 "transport", "DUMP_OVERWRITE"))
6460 {
6461 GNUNET_CONFIGURATION_get_value_number(cfg,
6462 "transport","DUMP_OVERWRITE", &value);
6463 overwrite_dump = value;
6464 }
6465
6466 if (GNUNET_CONFIGURATION_have_value(cfg,
6467 "transport", "ATS_MIN_INTERVAL"))
6468 {
6469 GNUNET_CONFIGURATION_get_value_number(cfg,
6470 "transport","ATS_MIN_INTERVAL", &value);
6471 ats_minimum_interval.rel_value = value;
6472 }
6473
6474 if (GNUNET_CONFIGURATION_have_value(cfg,
6475 "transport", "ATS_EXEC_INTERVAL"))
6476 {
6477 GNUNET_CONFIGURATION_get_value_number(cfg,
6478 "transport","ATS_EXEC_INTERVAL", &value);
6479 ats_regular_interval.rel_value = value;
6480 }
6481 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "ATS_MIN_INTERVAL"))
6482 {
6483 GNUNET_CONFIGURATION_get_value_number(cfg,
6484 "transport","ATS_MIN_INTERVAL", &value);
6485 ats_minimum_interval.rel_value = value;
6486 }
6487
6488 ats_set_logging_options (ats,
6489 minimum_addresses,
6490 minimum_peers,
6491 overwrite_dump,
6492 log_solution,
6493 log_problem);
6494
6219 if (ats != NULL) 6495 if (ats != NULL)
6220 ats_task = GNUNET_SCHEDULER_add_now (&schedule_ats, ats); 6496 ats_task = GNUNET_SCHEDULER_add_now (&schedule_ats, ats);
6221 6497
6222 6498
6499
6500
6223#if DEBUG_TRANSPORT 6501#if DEBUG_TRANSPORT
6224 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 6502 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
6225 _("Transport service ready.\n")); 6503 _("Transport service ready.\n"));
diff --git a/src/transport/test_transport_ats.c b/src/transport/test_transport_ats.c
index 41d1ff0d6..549a3a863 100644
--- a/src/transport/test_transport_ats.c
+++ b/src/transport/test_transport_ats.c
@@ -31,12 +31,40 @@ struct GNUNET_CONFIGURATION_Handle *cfg;
31 31
32static struct ATS_Handle * ats; 32static struct ATS_Handle * ats;
33 33
34void ats_result_cb ()
35{
36 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
37 "ATS Result callback\n");
38}
39
40
41void create_ats_information (struct ATS_peer **p, int * c_p,
42 struct ATS_mechanism ** m, int * c_m)
43{
44 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
45 "ATS needs addresses\n");
46 (*c_m) = 100;
47 (*c_p) = 10;
48}
49
50int run_ats (void)
51{
52 int ret = 0;
53
54 ats_calculate_bandwidth_distribution(ats, NULL);
55
56 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
57 "Running ATS: %s \n", (ret==0)? "SUCCESFULL": "FAILED");
58 return ret;
59}
34 60
35int init_ats (void) 61int init_ats (void)
36{ 62{
37 int ret = 0; 63 int ret = 0;
38 64
39 //ats = ats_init(cfg); 65 ats = ats_init(1.0, 1.0, 1.0, 50000, 5, 10, ATS_MAX_EXEC_DURATION,
66 create_ats_information,
67 ats_result_cb);
40 //GNUNET_assert (ats != NULL); 68 //GNUNET_assert (ats != NULL);
41 69
42 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 70 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -93,6 +121,7 @@ main (int argc, char *argv[])
93 /* Testing */ 121 /* Testing */
94 ats = NULL; 122 ats = NULL;
95 ret += init_ats (); 123 ret += init_ats ();
124 ret += run_ats ();
96 ret += shutdown_ats (); 125 ret += shutdown_ats ();
97 126
98 /* Shutdown */ 127 /* Shutdown */
diff --git a/src/transport/transport_ats.c b/src/transport/transport_ats.c
index 55f5a6886..06c4fa6aa 100644
--- a/src/transport/transport_ats.c
+++ b/src/transport/transport_ats.c
@@ -31,295 +31,86 @@
31#include "gnunet_container_lib.h" 31#include "gnunet_container_lib.h"
32 32
33 33
34/* LP/MIP problem object */
34 35
36#if !HAVE_LIBGLPK
35 37
36/* 38#ifndef GLP_PROB_DEFINED
37 * Temporary included structs and defines 39#define GLP_PROB_DEFINED
38 */ 40 typedef struct { double _opaque_prob[100]; } glp_prob;
39 41#endif
40
41/**
42 * FIXME to be removed
43 * Entry in linked list of all of our current neighbours.
44 */
45struct NeighbourList
46{
47
48 /**
49 * This is a linked list.
50 */
51 struct NeighbourList *next;
52
53 /**
54 * Which of our transports is connected to this peer
55 * and what is their status?
56 */
57 struct ReadyList *plugins;
58
59 /**
60 * Head of list of messages we would like to send to this peer;
61 * must contain at most one message per client.
62 */
63 struct MessageQueue *messages_head;
64
65 /**
66 * Tail of list of messages we would like to send to this peer; must
67 * contain at most one message per client.
68 */
69 struct MessageQueue *messages_tail;
70
71 /**
72 * Head of list of messages of messages we expected the continuation
73 * to be called to destroy the message
74 */
75 struct MessageQueue *cont_head;
76
77 /**
78 * Tail of list of messages of messages we expected the continuation
79 * to be called to destroy the message
80 */
81 struct MessageQueue *cont_tail;
82
83 /**
84 * Buffer for at most one payload message used when we receive
85 * payload data before our PING-PONG has succeeded. We then
86 * store such messages in this intermediary buffer until the
87 * connection is fully up.
88 */
89 struct GNUNET_MessageHeader *pre_connect_message_buffer;
90
91 /**
92 * Context for peerinfo iteration.
93 * NULL after we are done processing peerinfo's information.
94 */
95 struct GNUNET_PEERINFO_IteratorContext *piter;
96
97 /**
98 * Public key for this peer. Valid only if the respective flag is set below.
99 */
100 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded publicKey;
101
102 /**
103 * Identity of this neighbour.
104 */
105 struct GNUNET_PeerIdentity id;
106
107 /**
108 * ID of task scheduled to run when this peer is about to
109 * time out (will free resources associated with the peer).
110 */
111 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
112
113 /**
114 * ID of task scheduled to run when we should retry transmitting
115 * the head of the message queue. Actually triggered when the
116 * transmission is timing out (we trigger instantly when we have
117 * a chance of success).
118 */
119 GNUNET_SCHEDULER_TaskIdentifier retry_task;
120
121 /**
122 * How long until we should consider this peer dead
123 * (if we don't receive another message in the
124 * meantime)?
125 */
126 struct GNUNET_TIME_Absolute peer_timeout;
127
128 /**
129 * Tracker for inbound bandwidth.
130 */
131 struct GNUNET_BANDWIDTH_Tracker in_tracker;
132
133 /**
134 * The latency we have seen for this particular address for
135 * this particular peer. This latency may have been calculated
136 * over multiple transports. This value reflects how long it took
137 * us to receive a response when SENDING via this particular
138 * transport/neighbour/address combination!
139 *
140 * FIXME: we need to periodically send PINGs to update this
141 * latency (at least more often than the current "huge" (11h?)
142 * update interval).
143 */
144 struct GNUNET_TIME_Relative latency;
145
146 /**
147 * How often has the other peer (recently) violated the
148 * inbound traffic limit? Incremented by 10 per violation,
149 * decremented by 1 per non-violation (for each
150 * time interval).
151 */
152 unsigned int quota_violation_count;
153
154 /**
155 * DV distance to this peer (1 if no DV is used).
156 */
157 uint32_t distance;
158
159 /**
160 * Have we seen an PONG from this neighbour in the past (and
161 * not had a disconnect since)?
162 */
163 int received_pong;
164
165 /**
166 * Do we have a valid public key for this neighbour?
167 */
168 int public_key_valid;
169
170 /**
171 * Performance data for the peer.
172 */
173 struct GNUNET_TRANSPORT_ATS_Information *ats;
174
175 /**
176 * Identity of the neighbour.
177 */
178 struct GNUNET_PeerIdentity peer;
179
180};
181
182/**
183 * FIXME to be removed
184 *
185 * List of addresses of other peers
186 */
187struct ForeignAddressList
188{
189 /**
190 * This is a linked list.
191 */
192 struct ForeignAddressList *next;
193
194 /**
195 * Which ready list does this entry belong to.
196 */
197 struct ReadyList *ready_list;
198
199 /**
200 * How long until we auto-expire this address (unless it is
201 * re-confirmed by the transport)?
202 */
203 struct GNUNET_TIME_Absolute expires;
204
205 /**
206 * Task used to re-validate addresses, updates latencies and
207 * verifies liveness.
208 */
209 GNUNET_SCHEDULER_TaskIdentifier revalidate_task;
210
211 /**
212 * The address.
213 */
214 const void *addr;
215
216 /**
217 * Session (or NULL if no valid session currently exists or if the
218 * plugin does not use sessions).
219 */
220 struct Session *session;
221
222 struct ATS_ressource_entry * ressources;
223
224 struct ATS_quality_entry * quality;
225
226 /**
227 * What was the last latency observed for this address, plugin and peer?
228 */
229 struct GNUNET_TIME_Relative latency;
230
231 /**
232 * If we did not successfully transmit a message to the given peer
233 * via this connection during the specified time, we should consider
234 * the connection to be dead. This is used in the case that a TCP
235 * transport simply stalls writing to the stream but does not
236 * formerly get a signal that the other peer died.
237 */
238 struct GNUNET_TIME_Absolute timeout;
239
240 /**
241 * How often have we tried to connect using this plugin? Used to
242 * discriminate against addresses that do not work well.
243 * FIXME: not yet used, but should be!
244 */
245 unsigned int connect_attempts;
246
247 /**
248 * DV distance to this peer (1 if no DV is used).
249 * FIXME: need to set this from transport plugins!
250 */
251 uint32_t distance;
252
253 /**
254 * Length of addr.
255 */
256 uint16_t addrlen;
257
258 /**
259 * Have we ever estimated the latency of this address? Used to
260 * ensure that the first time we add an address, we immediately
261 * probe its latency.
262 */
263 int8_t estimated;
264
265 /**
266 * Are we currently connected via this address? The first time we
267 * successfully transmit or receive data to a peer via a particularcurl:
268 * (56) Recv failure: Connection reset by peer
269 *
270 * address, we set this to GNUNET_YES. If we later get an error
271 * (disconnect notification, transmission failure, timeout), we set
272 * it back to GNUNET_NO.
273 */
274 int8_t connected;
275
276 /**
277 * Is this plugin currently busy transmitting to the specific target?
278 * GNUNET_NO if not (initial, default state is GNUNET_NO). Internal
279 * messages do not count as 'in transmit'.
280 */
281 int8_t in_transmit;
282
283 /**
284 * Has this address been validated yet?
285 */
286 int8_t validated;
287
288};
289 42
290/** 43typedef struct
291 * FIXME: REMOVE 44{ /* integer optimizer control parameters */
292 * 45 int msg_lev; /* message level (see glp_smcp) */
293 * For a given Neighbour, which plugins are available 46 int br_tech; /* branching technique: */
294 * to talk to this peer and what are their costs? 47#define GLP_BR_FFV 1 /* first fractional variable */
295 */ 48#define GLP_BR_LFV 2 /* last fractional variable */
296struct ReadyList 49#define GLP_BR_MFV 3 /* most fractional variable */
297{ 50#define GLP_BR_DTH 4 /* heuristic by Driebeck and Tomlin */
298 /** 51#define GLP_BR_PCH 5 /* hybrid pseudocost heuristic */
299 * This is a linked list. 52 int bt_tech; /* backtracking technique: */
300 */ 53#define GLP_BT_DFS 1 /* depth first search */
301 struct ReadyList *next; 54#define GLP_BT_BFS 2 /* breadth first search */
302 55#define GLP_BT_BLB 3 /* best local bound */
303 /** 56#define GLP_BT_BPH 4 /* best projection heuristic */
304 * Which of our transport plugins does this entry 57 double tol_int; /* mip.tol_int */
305 * represent? 58 double tol_obj; /* mip.tol_obj */
306 */ 59 int tm_lim; /* mip.tm_lim (milliseconds) */
307 struct TransportPlugin *plugin; 60 int out_frq; /* mip.out_frq (milliseconds) */
308 61 int out_dly; /* mip.out_dly (milliseconds) */
309 /** 62 /* mip.cb_func */
310 * Transport addresses, latency, and readiness for 63 void *cb_info; /* mip.cb_info */
311 * this particular plugin. 64 int cb_size; /* mip.cb_size */
312 */ 65 int pp_tech; /* preprocessing technique: */
313 struct ForeignAddressList *addresses; 66#define GLP_PP_NONE 0 /* disable preprocessing */
314 67#define GLP_PP_ROOT 1 /* preprocessing only on root level */
315 /** 68#define GLP_PP_ALL 2 /* preprocessing on all levels */
316 * To which neighbour does this ready list belong to? 69 double mip_gap; /* relative MIP gap tolerance */
317 */ 70 int mir_cuts; /* MIR cuts (GLP_ON/GLP_OFF) */
318 struct NeighbourList *neighbour; 71 int gmi_cuts; /* Gomory's cuts (GLP_ON/GLP_OFF) */
319}; 72 int cov_cuts; /* cover cuts (GLP_ON/GLP_OFF) */
73 int clq_cuts; /* clique cuts (GLP_ON/GLP_OFF) */
74 int presolve; /* enable/disable using MIP presolver */
75 int binarize; /* try to binarize integer variables */
76 int fp_heur; /* feasibility pump heuristic */
77#if 1 /* 28/V-2010 */
78 int alien; /* use alien solver */
79#endif
80 double foo_bar[29]; /* (reserved) */
81} glp_iocp;
320 82
83typedef struct
84{ /* simplex method control parameters */
85 int msg_lev; /* message level: */
86#define GLP_MSG_OFF 0 /* no output */
87#define GLP_MSG_ERR 1 /* warning and error messages only */
88#define GLP_MSG_ON 2 /* normal output */
89#define GLP_MSG_ALL 3 /* full output */
90#define GLP_MSG_DBG 4 /* debug output */
91 int meth; /* simplex method option: */
92#define GLP_PRIMAL 1 /* use primal simplex */
93#define GLP_DUALP 2 /* use dual; if it fails, use primal */
94#define GLP_DUAL 3 /* use dual simplex */
95 int pricing; /* pricing technique: */
96#define GLP_PT_STD 0x11 /* standard (Dantzig rule) */
97#define GLP_PT_PSE 0x22 /* projected steepest edge */
98 int r_test; /* ratio test technique: */
99#define GLP_RT_STD 0x11 /* standard (textbook) */
100#define GLP_RT_HAR 0x22 /* two-pass Harris' ratio test */
101 double tol_bnd; /* spx.tol_bnd */
102 double tol_dj; /* spx.tol_dj */
103 double tol_piv; /* spx.tol_piv */
104 double obj_ll; /* spx.obj_ll */
105 double obj_ul; /* spx.obj_ul */
106 int it_lim; /* spx.it_lim */
107 int tm_lim; /* spx.tm_lim (milliseconds) */
108 int out_frq; /* spx.out_frq */
109 int out_dly; /* spx.out_dly (milliseconds) */
110 int presolve; /* enable/disable using LP presolver */
111 double foo_bar[36]; /* (reserved) */
112} glp_smcp;
321 113
322#if !HAVE_LIBGLPK
323/* optimization direction flag: */ 114/* optimization direction flag: */
324#define GLP_MIN 1 /* minimization */ 115#define GLP_MIN 1 /* minimization */
325#define GLP_MAX 2 /* maximization */ 116#define GLP_MAX 2 /* maximization */
@@ -336,6 +127,11 @@ struct ReadyList
336#define GLP_DB 4 /* double-bounded variable */ 127#define GLP_DB 4 /* double-bounded variable */
337#define GLP_FX 5 /* fixed variable */ 128#define GLP_FX 5 /* fixed variable */
338 129
130/* solution indicator: */
131#define GLP_SOL 1 /* basic solution */
132#define GLP_IPT 2 /* interior-point solution */
133#define GLP_MIP 3 /* mixed integer solution */
134
339/* solution status: */ 135/* solution status: */
340#define GLP_UNDEF 1 /* solution is undefined */ 136#define GLP_UNDEF 1 /* solution is undefined */
341#define GLP_FEAS 2 /* solution is feasible */ 137#define GLP_FEAS 2 /* solution is feasible */
@@ -369,80 +165,7 @@ struct ReadyList
369#define GLP_ON 1 /* enable something */ 165#define GLP_ON 1 /* enable something */
370#define GLP_OFF 0 /* disable something */ 166#define GLP_OFF 0 /* disable something */
371 167
372
373typedef struct
374{ /* simplex method control parameters */
375 int msg_lev; /* message level: */
376#define GLP_MSG_OFF 0 /* no output */
377#define GLP_MSG_ERR 1 /* warning and error messages only */
378#define GLP_MSG_ON 2 /* normal output */
379#define GLP_MSG_ALL 3 /* full output */
380#define GLP_MSG_DBG 4 /* debug output */
381 int meth; /* simplex method option: */
382#define GLP_PRIMAL 1 /* use primal simplex */
383#define GLP_DUALP 2 /* use dual; if it fails, use primal */
384#define GLP_DUAL 3 /* use dual simplex */
385 int pricing; /* pricing technique: */
386#define GLP_PT_STD 0x11 /* standard (Dantzig rule) */
387#define GLP_PT_PSE 0x22 /* projected steepest edge */
388 int r_test; /* ratio test technique: */
389#define GLP_RT_STD 0x11 /* standard (textbook) */
390#define GLP_RT_HAR 0x22 /* two-pass Harris' ratio test */
391 double tol_bnd; /* spx.tol_bnd */
392 double tol_dj; /* spx.tol_dj */
393 double tol_piv; /* spx.tol_piv */
394 double obj_ll; /* spx.obj_ll */
395 double obj_ul; /* spx.obj_ul */
396 int it_lim; /* spx.it_lim */
397 int tm_lim; /* spx.tm_lim (milliseconds) */
398 int out_frq; /* spx.out_frq */
399 int out_dly; /* spx.out_dly (milliseconds) */
400 int presolve; /* enable/disable using LP presolver */
401 double foo_bar[36]; /* (reserved) */
402} glp_smcp;
403
404
405typedef struct
406{ /* integer optimizer control parameters */
407 int msg_lev; /* message level (see glp_smcp) */
408 int br_tech; /* branching technique: */
409#define GLP_BR_FFV 1 /* first fractional variable */
410#define GLP_BR_LFV 2 /* last fractional variable */
411#define GLP_BR_MFV 3 /* most fractional variable */
412#define GLP_BR_DTH 4 /* heuristic by Driebeck and Tomlin */
413#define GLP_BR_PCH 5 /* hybrid pseudocost heuristic */
414 int bt_tech; /* backtracking technique: */
415#define GLP_BT_DFS 1 /* depth first search */
416#define GLP_BT_BFS 2 /* breadth first search */
417#define GLP_BT_BLB 3 /* best local bound */
418#define GLP_BT_BPH 4 /* best projection heuristic */
419 double tol_int; /* mip.tol_int */
420 double tol_obj; /* mip.tol_obj */
421 int tm_lim; /* mip.tm_lim (milliseconds) */
422 int out_frq; /* mip.out_frq (milliseconds) */
423 int out_dly; /* mip.out_dly (milliseconds) */
424
425 void *cb_info; /* mip.cb_info */
426 int cb_size; /* mip.cb_size */
427 int pp_tech; /* preprocessing technique: */
428#define GLP_PP_NONE 0 /* disable preprocessing */
429#define GLP_PP_ROOT 1 /* preprocessing only on root level */
430#define GLP_PP_ALL 2 /* preprocessing on all levels */
431 double mip_gap; /* relative MIP gap tolerance */
432 int mir_cuts; /* MIR cuts (GLP_ON/GLP_OFF) */
433 int gmi_cuts; /* Gomory's cuts (GLP_ON/GLP_OFF) */
434 int cov_cuts; /* cover cuts (GLP_ON/GLP_OFF) */
435 int clq_cuts; /* clique cuts (GLP_ON/GLP_OFF) */
436 int presolve; /* enable/disable using MIP presolver */
437 int binarize; /* try to binarize integer variables */
438 int fp_heur; /* feasibility pump heuristic */
439#if 1 /* 28/V-2010 */
440 int alien; /* use alien solver */
441#endif 168#endif
442 double foo_bar[29]; /* (reserved) */
443} glp_iocp;
444#endif
445
446 169
447/* 170/*
448 * Wrappers for GLPK Functions 171 * Wrappers for GLPK Functions
@@ -460,7 +183,7 @@ void * _lp_create_prob ( void )
460 return NULL; 183 return NULL;
461} 184}
462 185
463void _lp_set_obj_dir (void *P, int dir) 186void _lp_set_obj_dir (glp_prob *P, int dir)
464{ 187{
465#if HAVE_LIBGLPK 188#if HAVE_LIBGLPK
466 return glp_set_obj_dir (P, dir); 189 return glp_set_obj_dir (P, dir);
@@ -470,7 +193,7 @@ void _lp_set_obj_dir (void *P, int dir)
470#endif 193#endif
471} 194}
472 195
473void _lp_set_prob_name (void *P, const char *name) 196void _lp_set_prob_name (glp_prob *P, const char *name)
474{ 197{
475#if HAVE_LIBGLPK 198#if HAVE_LIBGLPK
476 glp_set_prob_name(P, name); 199 glp_set_prob_name(P, name);
@@ -480,7 +203,7 @@ void _lp_set_prob_name (void *P, const char *name)
480#endif 203#endif
481} 204}
482 205
483int _lp_add_cols (void *P, int ncs) 206int _lp_add_cols (glp_prob *P, int ncs)
484{ 207{
485#if HAVE_LIBGLPK 208#if HAVE_LIBGLPK
486 return glp_add_cols(P, ncs); 209 return glp_add_cols(P, ncs);
@@ -491,7 +214,7 @@ int _lp_add_cols (void *P, int ncs)
491 return 0; 214 return 0;
492} 215}
493 216
494int _lp_add_rows (void *P, int nrs) 217int _lp_add_rows (glp_prob *P, int nrs)
495{ 218{
496#if HAVE_LIBGLPK 219#if HAVE_LIBGLPK
497 return glp_add_rows (P, nrs); 220 return glp_add_rows (P, nrs);
@@ -503,7 +226,7 @@ int _lp_add_rows (void *P, int nrs)
503} 226}
504 227
505 228
506void _lp_set_row_bnds (void *P, int i, int type, double lb, double ub) 229void _lp_set_row_bnds (glp_prob *P, int i, int type, double lb, double ub)
507{ 230{
508#if HAVE_LIBGLPK 231#if HAVE_LIBGLPK
509 glp_set_row_bnds(P, i , type, lb, ub); 232 glp_set_row_bnds(P, i , type, lb, ub);
@@ -523,7 +246,7 @@ void _lp_init_smcp (void * parm)
523#endif 246#endif
524} 247}
525 248
526void _lp_set_col_name (void *P, int j, const char *name) 249void _lp_set_col_name (glp_prob *P, int j, const char *name)
527{ 250{
528#if HAVE_LIBGLPK 251#if HAVE_LIBGLPK
529 glp_set_col_name (P, j, name); 252 glp_set_col_name (P, j, name);
@@ -533,7 +256,7 @@ void _lp_set_col_name (void *P, int j, const char *name)
533#endif 256#endif
534} 257}
535 258
536void _lp_set_col_bnds (void *P, int j, int type, double lb, 259void _lp_set_col_bnds (glp_prob *P, int j, int type, double lb,
537 double ub) 260 double ub)
538{ 261{
539#if HAVE_LIBGLPK 262#if HAVE_LIBGLPK
@@ -544,7 +267,7 @@ void _lp_set_col_bnds (void *P, int j, int type, double lb,
544#endif 267#endif
545} 268}
546 269
547void _lp_set_obj_coef(void *P, int j, double coef) 270void _lp_set_obj_coef(glp_prob *P, int j, double coef)
548{ 271{
549#if HAVE_LIBGLPK 272#if HAVE_LIBGLPK
550 glp_set_obj_coef(P, j, coef); 273 glp_set_obj_coef(P, j, coef);
@@ -564,7 +287,7 @@ void _lp_delete_prob (void * P)
564#endif 287#endif
565} 288}
566 289
567static int _lp_simplex(void *P, void *parm) 290static int _lp_simplex(glp_prob *P, void *parm)
568{ 291{
569#if HAVE_LIBGLPK 292#if HAVE_LIBGLPK
570 return glp_simplex (P, parm); 293 return glp_simplex (P, parm);
@@ -575,7 +298,7 @@ static int _lp_simplex(void *P, void *parm)
575 return 0; 298 return 0;
576} 299}
577 300
578static void _lp_load_matrix (void *P, int ne, const int ia[], 301static void _lp_load_matrix (glp_prob *P, int ne, const int ia[],
579 const int ja[], const double ar[]) 302 const int ja[], const double ar[])
580{ 303{
581#if HAVE_LIBGLPK 304#if HAVE_LIBGLPK
@@ -586,7 +309,7 @@ static void _lp_load_matrix (void *P, int ne, const int ia[],
586#endif 309#endif
587} 310}
588 311
589static void _lp_set_mat_row (void *P, int i, int len, const int ind[], 312static void _lp_set_mat_row (glp_prob *P, int i, int len, const int ind[],
590 const double val[]) 313 const double val[])
591{ 314{
592#if HAVE_LIBGLPK 315#if HAVE_LIBGLPK
@@ -597,7 +320,7 @@ static void _lp_set_mat_row (void *P, int i, int len, const int ind[],
597#endif 320#endif
598} 321}
599 322
600static int _lp_write_lp (void *P, const void *parm, const char *fname) 323static int _lp_write_lp (glp_prob *P, const void *parm, const char *fname)
601{ 324{
602#if HAVE_LIBGLPK 325#if HAVE_LIBGLPK
603 return glp_write_lp ( P, parm, fname); 326 return glp_write_lp ( P, parm, fname);
@@ -618,7 +341,7 @@ static void _lp_init_iocp (void *parm)
618#endif 341#endif
619} 342}
620 343
621static int _lp_intopt (void *P, const void *parm) 344static int _lp_intopt (glp_prob *P, const void *parm)
622{ 345{
623#if HAVE_LIBGLPK 346#if HAVE_LIBGLPK
624 return glp_intopt (P, parm); 347 return glp_intopt (P, parm);
@@ -629,7 +352,7 @@ static int _lp_intopt (void *P, const void *parm)
629 return 0; 352 return 0;
630} 353}
631 354
632static int _lp_get_status (void *P) 355static int _lp_get_status (glp_prob *P)
633{ 356{
634#if HAVE_LIBGLPK 357#if HAVE_LIBGLPK
635 return glp_get_status (P); 358 return glp_get_status (P);
@@ -640,7 +363,7 @@ static int _lp_get_status (void *P)
640 return 0; 363 return 0;
641} 364}
642 365
643static int _lp_mip_status (void *P) 366static int _lp_mip_status (glp_prob *P)
644{ 367{
645#if HAVE_LIBGLPK 368#if HAVE_LIBGLPK
646 return glp_mip_status (P); 369 return glp_mip_status (P);
@@ -651,7 +374,7 @@ static int _lp_mip_status (void *P)
651 return 0; 374 return 0;
652} 375}
653 376
654static void _lp_set_col_kind (void *P, int j, int kind) 377static void _lp_set_col_kind (glp_prob *P, int j, int kind)
655{ 378{
656#if HAVE_LIBGLPK 379#if HAVE_LIBGLPK
657 glp_set_col_kind (P, j, kind); 380 glp_set_col_kind (P, j, kind);
@@ -671,7 +394,7 @@ static void _lp_free_env (void)
671#endif 394#endif
672} 395}
673 396
674static const char * _lp_get_col_name ( void *P, int j) 397static const char * _lp_get_col_name ( glp_prob *P, int j)
675{ 398{
676#if HAVE_LIBGLPK 399#if HAVE_LIBGLPK
677 return glp_get_col_name (P, j); 400 return glp_get_col_name (P, j);
@@ -682,7 +405,7 @@ static const char * _lp_get_col_name ( void *P, int j)
682 return NULL; 405 return NULL;
683} 406}
684 407
685static double _lp_mip_obj_val (void *P) 408static double _lp_mip_obj_val (glp_prob *P)
686{ 409{
687#if HAVE_LIBGLPK 410#if HAVE_LIBGLPK
688 return glp_mip_obj_val (P); 411 return glp_mip_obj_val (P);
@@ -694,7 +417,7 @@ static double _lp_mip_obj_val (void *P)
694} 417}
695 418
696 419
697static double _lp_get_col_prim (void *P, int j) 420static double _lp_get_col_prim (glp_prob *P, int j)
698{ 421{
699#if HAVE_LIBGLPK 422#if HAVE_LIBGLPK
700 return glp_get_col_prim (P , j); 423 return glp_get_col_prim (P , j);
@@ -705,10 +428,9 @@ static double _lp_get_col_prim (void *P, int j)
705 return 0.0; 428 return 0.0;
706} 429}
707 430
708static int _lp_print_sol(void *P, const char *fname) 431static int _lp_print_sol(glp_prob *P, const char *fname)
709{ 432{
710#if HAVE_LIBGLPK 433#if HAVE_LIBGLPK
711 return glp_print_sol (P, fname);
712#else 434#else
713 // Function not implemented 435 // Function not implemented
714 GNUNET_break (0); 436 GNUNET_break (0);
@@ -727,6 +449,7 @@ static void _dummy ()
727 _lp_get_col_name (NULL, 0); 449 _lp_get_col_name (NULL, 0);
728 _lp_mip_obj_val (NULL); 450 _lp_mip_obj_val (NULL);
729 _lp_get_col_prim (NULL, 0); 451 _lp_get_col_prim (NULL, 0);
452 _lp_set_mat_row(NULL,0,0,NULL,NULL);
730 _dummy2(); 453 _dummy2();
731} 454}
732 455
@@ -749,7 +472,15 @@ static void _dummy2 ()
749 * @return 472 * @return
750 */ 473 */
751 474
752struct ATS_Handle * ats_init (const struct GNUNET_CONFIGURATION_Handle *cfg) 475struct ATS_Handle * ats_init (double D,
476 double U,
477 double R,
478 int v_b_min,
479 int v_n_min,
480 int max_iterations,
481 struct GNUNET_TIME_Relative max_duration,
482 GNUNET_TRANSPORT_ATS_AddressNotification address_not,
483 GNUNET_TRANSPORT_ATS_ResultCallback res_cb)
753{ 484{
754 485
755#if !HAVE_LIBGLPK 486#if !HAVE_LIBGLPK
@@ -758,123 +489,30 @@ struct ATS_Handle * ats_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
758#endif 489#endif
759 490
760 struct ATS_Handle * ats = NULL; 491 struct ATS_Handle * ats = NULL;
761 int c = 0;
762 unsigned long long value;
763 char * section;
764 492
765 ats = GNUNET_malloc(sizeof (struct ATS_Handle)); 493 ats = GNUNET_malloc(sizeof (struct ATS_Handle));
766 494
767 ats->prob = NULL; 495 ats->prob = NULL;
768 496
769 ats->min_delta = ATS_MIN_INTERVAL; 497 ats->addr_notification = address_not;
770 ats->exec_interval = ATS_EXEC_INTERVAL; 498 ats->result_cb = res_cb;
771 ats->max_exec_duration = ATS_MAX_EXEC_DURATION; 499
772 ats->max_iterations = ATS_MAX_ITERATIONS; 500 ats->max_iterations = max_iterations;
773 501 ats->max_exec_duration = max_duration;
774 ats->D = 1.0; 502
775 ats->U = 1.0; 503 ats->D = D;
776 ats->R = 1.0; 504 ats->U = U;
777 ats->v_b_min = 64000; 505 ats->R = R;
778 ats->v_n_min = 10; 506 ats->v_b_min = v_b_min;
779 ats->dump_min_peers = 1; 507 ats->v_n_min = v_n_min;
780 ats->dump_min_addr = 1; 508 ats->dump_min_peers = 0;
509 ats->dump_min_addr = 0;
781 ats->dump_overwrite = GNUNET_NO; 510 ats->dump_overwrite = GNUNET_NO;
782 ats->mechanisms = NULL; 511 ats->mechanisms = NULL;
783 ats->peers = NULL; 512 ats->peers = NULL;
784 ats->successful_executions = 0; 513 ats->successful_executions = 0;
785 ats->invalid_executions = 0; 514 ats->invalid_executions = 0;
786 515
787 /* loading cost ressources */
788 for (c=0; c<available_ressources; c++)
789 {
790 GNUNET_asprintf(&section,"%s_UP",ressources[c].cfg_param);
791 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", section))
792 {
793 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg,
794 "transport",
795 section,
796 &value))
797 {
798#if DEBUG_ATS
799 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
800 "Found ressource cost: [%s] = %llu\n",
801 section, value);
802#endif
803 ressources[c].c_max = value;
804 }
805 }
806 GNUNET_free (section);
807 GNUNET_asprintf(&section,"%s_DOWN",ressources[c].cfg_param);
808 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", section))
809 {
810 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg,
811 "transport",
812 section,
813 &value))
814 {
815#if DEBUG_ATS
816 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
817 "Found ressource cost: [%s] = %llu\n",
818 section, value);
819#endif
820 ressources[c].c_min = value;
821 }
822 }
823 GNUNET_free (section);
824 }
825
826 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_MLP"))
827 ats->save_mlp = GNUNET_CONFIGURATION_get_value_yesno (cfg,
828 "transport","DUMP_MLP");
829
830 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_SOLUTION"))
831 ats->save_solution = GNUNET_CONFIGURATION_get_value_yesno (cfg,
832 "transport","DUMP_SOLUTION");
833 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_OVERWRITE"))
834 ats->dump_overwrite = GNUNET_CONFIGURATION_get_value_yesno (cfg,
835 "transport","DUMP_OVERWRITE");
836 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_MIN_PEERS"))
837 {
838 GNUNET_CONFIGURATION_get_value_number(cfg,
839 "transport","DUMP_MIN_PEERS", &value);
840 ats->dump_min_peers= value;
841 }
842 if (GNUNET_CONFIGURATION_have_value(cfg,
843 "transport", "DUMP_MIN_ADDRS"))
844 {
845 GNUNET_CONFIGURATION_get_value_number(cfg,
846 "transport","DUMP_MIN_ADDRS", &value);
847 ats->dump_min_addr= value;
848 }
849 if (GNUNET_CONFIGURATION_have_value(cfg,
850 "transport", "DUMP_OVERWRITE"))
851 {
852 GNUNET_CONFIGURATION_get_value_number(cfg,
853 "transport","DUMP_OVERWRITE", &value);
854 ats->min_delta.rel_value = value;
855 }
856
857 if (GNUNET_CONFIGURATION_have_value(cfg,
858 "transport", "ATS_MIN_INTERVAL"))
859 {
860 GNUNET_CONFIGURATION_get_value_number(cfg,
861 "transport","ATS_MIN_INTERVAL", &value);
862 ats->min_delta.rel_value = value;
863 }
864
865 if (GNUNET_CONFIGURATION_have_value(cfg,
866 "transport", "ATS_EXEC_INTERVAL"))
867 {
868 GNUNET_CONFIGURATION_get_value_number(cfg,
869 "transport","ATS_EXEC_INTERVAL", &value);
870 ats->exec_interval.rel_value = value;
871 }
872 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "ATS_MIN_INTERVAL"))
873 {
874 GNUNET_CONFIGURATION_get_value_number(cfg,
875 "transport","ATS_MIN_INTERVAL", &value);
876 ats->min_delta.rel_value = value;
877 }
878 return ats; 516 return ats;
879} 517}
880 518
@@ -891,25 +529,23 @@ struct ATS_Handle * ats_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
891 * @return GNUNET_SYSERR if glpk is not available, number of mechanisms used 529 * @return GNUNET_SYSERR if glpk is not available, number of mechanisms used
892 */ 530 */
893int ats_create_problem (struct ATS_Handle *ats, 531int ats_create_problem (struct ATS_Handle *ats,
894 struct NeighbourList *neighbours, 532 struct ATS_internals *stat,
895 double D, 533 struct ATS_peer *peers,
896 double U, 534 int c_p,
897 double R, 535 struct ATS_mechanism *mechanisms,
898 int v_b_min, 536 int c_m)
899 int v_n_min,
900 struct ATS_stat *stat)
901{ 537{
902#if !HAVE_LIBGLPK 538#if !HAVE_LIBGLPK
903 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS not active\n"); 539 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS not active\n");
904 return GNUNET_SYSERR; 540 return GNUNET_SYSERR;
905#endif 541#endif
906 542
543 if ((c_p == 0) || (c_m == 0))
544 return GNUNET_SYSERR;
545
907 ats->prob = _lp_create_prob(); 546 ats->prob = _lp_create_prob();
908 547
909 int c; 548 int c;
910 int c_peers = 0;
911 int c_mechs = 0;
912
913 int c_c_ressources = available_ressources; 549 int c_c_ressources = available_ressources;
914 int c_q_metrics = available_quality_metrics; 550 int c_q_metrics = available_quality_metrics;
915 551
@@ -920,104 +556,18 @@ int ats_create_problem (struct ATS_Handle *ats,
920 Q[c] = 1; 556 Q[c] = 1;
921 } 557 }
922 558
923 struct NeighbourList *next = neighbours; 559 if (ats->v_n_min > c_p)
924 while (next!=NULL) 560 ats->v_n_min = c_p;
925 {
926 int found_addresses = GNUNET_NO;
927 struct ReadyList *r_next = next->plugins;
928 while (r_next != NULL)
929 {
930 struct ForeignAddressList * a_next = r_next->addresses;
931 while (a_next != NULL)
932 {
933 c_mechs++;
934 found_addresses = GNUNET_YES;
935 a_next = a_next->next;
936 }
937 r_next = r_next->next;
938 }
939 if (found_addresses) c_peers++;
940 next = next->next;
941 }
942
943 if (c_mechs==0)
944 {
945#if DEBUG_ATS
946 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
947 "No addresses for bw distribution available\n",
948 c_peers);
949#endif
950 stat->valid = GNUNET_NO;
951 stat->c_peers = 0;
952 stat->c_mechs = 0;
953 return GNUNET_SYSERR;
954 }
955
956 GNUNET_assert (ats->mechanisms == NULL);
957 ats->mechanisms = GNUNET_malloc((1+c_mechs) * sizeof (struct ATS_mechanism));
958 GNUNET_assert (ats->peers == NULL);
959 ats->peers = GNUNET_malloc((1+c_peers) * sizeof (struct ATS_peer));
960
961 struct ATS_mechanism * mechanisms = ats->mechanisms;
962 struct ATS_peer * peers = ats->peers;
963
964 c_mechs = 1;
965 c_peers = 1;
966
967 next = neighbours;
968 while (next!=NULL)
969 {
970 int found_addresses = GNUNET_NO;
971 struct ReadyList *r_next = next->plugins;
972 while (r_next != NULL)
973 {
974 struct ForeignAddressList * a_next = r_next->addresses;
975 while (a_next != NULL)
976 {
977 if (found_addresses == GNUNET_NO)
978 {
979 peers[c_peers].peer = next->id;
980 peers[c_peers].m_head = NULL;
981 peers[c_peers].m_tail = NULL;
982 peers[c_peers].f = 1.0 / c_mechs;
983 }
984
985 mechanisms[c_mechs].addr = a_next;
986 mechanisms[c_mechs].col_index = c_mechs;
987 mechanisms[c_mechs].peer = &peers[c_peers];
988 mechanisms[c_mechs].next = NULL;
989 mechanisms[c_mechs].plugin = r_next->plugin;
990
991 GNUNET_CONTAINER_DLL_insert_tail(peers[c_peers].m_head,
992 peers[c_peers].m_tail,
993 &mechanisms[c_mechs]);
994 found_addresses = GNUNET_YES;
995 c_mechs++;
996
997 a_next = a_next->next;
998 }
999 r_next = r_next->next;
1000 }
1001 if (found_addresses == GNUNET_YES)
1002 c_peers++;
1003 next = next->next;
1004 }
1005 c_mechs--;
1006 c_peers--;
1007
1008 if (v_n_min > c_peers)
1009 v_n_min = c_peers;
1010
1011#if VERBOSE_ATS 561#if VERBOSE_ATS
1012 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Creating problem with: %i peers, %i mechanisms, %i resource entries, %i quality metrics \n", 562 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Creating problem with: %i peers, %i mechanisms, %i resource entries, %i quality metrics \n",
1013 c_peers, 563 c_p,
1014 c_mechs, 564 c_m,
1015 c_c_ressources, 565 c_c_ressources,
1016 c_q_metrics); 566 c_q_metrics);
1017#endif 567#endif
1018 568
1019 int size = 1 + 3 + 10 *c_mechs + c_peers + 569 int size = 1 + 3 + 10 *c_m + c_p +
1020 (c_q_metrics*c_mechs)+ c_q_metrics + c_c_ressources * c_mechs ; 570 (c_q_metrics*c_m)+ c_q_metrics + c_c_ressources * c_m ;
1021 int row_index; 571 int row_index;
1022 int array_index=1; 572 int array_index=1;
1023 int * ia = GNUNET_malloc (size * sizeof (int)); 573 int * ia = GNUNET_malloc (size * sizeof (int));
@@ -1029,9 +579,9 @@ int ats_create_problem (struct ATS_Handle *ats,
1029 579
1030 /* adding columns */ 580 /* adding columns */
1031 char * name; 581 char * name;
1032 _lp_add_cols(ats->prob, 2 * c_mechs); 582 _lp_add_cols(ats->prob, 2 * c_m);
1033 /* adding b_t cols */ 583 /* adding b_t cols */
1034 for (c=1; c <= c_mechs; c++) 584 for (c=1; c <= c_m; c++)
1035 { 585 {
1036 GNUNET_asprintf(&name, 586 GNUNET_asprintf(&name,
1037 "p_%s_b%i",GNUNET_i2s(&(mechanisms[c].peer->peer)), c); 587 "p_%s_b%i",GNUNET_i2s(&(mechanisms[c].peer->peer)), c);
@@ -1039,14 +589,14 @@ int ats_create_problem (struct ATS_Handle *ats,
1039 GNUNET_free (name); 589 GNUNET_free (name);
1040 _lp_set_col_bnds(ats->prob, c, GLP_LO, 0.0, 0.0); 590 _lp_set_col_bnds(ats->prob, c, GLP_LO, 0.0, 0.0);
1041 _lp_set_col_kind(ats->prob, c, GLP_CV); 591 _lp_set_col_kind(ats->prob, c, GLP_CV);
1042 //_lp_set_obj_coef(ats->prob, c, 0); 592 _lp_set_obj_coef(ats->prob, c, 0);
1043 } 593 }
1044 594
1045 /* adding n_t cols */ 595 /* adding n_t cols */
1046 for (c=c_mechs+1; c <= 2*c_mechs; c++) 596 for (c=c_m+1; c <= 2*c_m; c++)
1047 { 597 {
1048 GNUNET_asprintf(&name, 598 GNUNET_asprintf(&name,
1049 "p_%s_n%i",GNUNET_i2s(&(mechanisms[c-c_mechs].peer->peer)),(c-c_mechs)); 599 "p_%s_n%i",GNUNET_i2s(&(mechanisms[c-c_m].peer->peer)),(c-c_m));
1050 _lp_set_col_name(ats->prob, c, name); 600 _lp_set_col_name(ats->prob, c, name);
1051 GNUNET_free (name); 601 GNUNET_free (name);
1052 _lp_set_col_bnds(ats->prob, c, GLP_DB, 0.0, 1.0); 602 _lp_set_col_bnds(ats->prob, c, GLP_DB, 0.0, 1.0);
@@ -1058,9 +608,9 @@ int ats_create_problem (struct ATS_Handle *ats,
1058 /* Constraint 1: one address per peer*/ 608 /* Constraint 1: one address per peer*/
1059 row_index = 1; 609 row_index = 1;
1060 610
1061 _lp_add_rows(ats->prob, c_peers); 611 _lp_add_rows(ats->prob, c_p);
1062 612
1063 for (c=1; c<=c_peers; c++) 613 for (c=1; c<=c_p; c++)
1064 { 614 {
1065#if VERBOSE_ATS 615#if VERBOSE_ATS
1066 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n", 616 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",
@@ -1072,7 +622,7 @@ int ats_create_problem (struct ATS_Handle *ats,
1072 while (m!=NULL) 622 while (m!=NULL)
1073 { 623 {
1074 ia[array_index] = row_index; 624 ia[array_index] = row_index;
1075 ja[array_index] = (c_mechs + m->col_index); 625 ja[array_index] = (c_m + m->col_index);
1076 ar[array_index] = 1; 626 ar[array_index] = 1;
1077#if VERBOSE_ATS 627#if VERBOSE_ATS
1078 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n", 628 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
@@ -1088,8 +638,8 @@ int ats_create_problem (struct ATS_Handle *ats,
1088 } 638 }
1089 639
1090 /* Constraint 2: only active mechanism gets bandwidth assigned */ 640 /* Constraint 2: only active mechanism gets bandwidth assigned */
1091 _lp_add_rows(ats->prob, c_mechs); 641 _lp_add_rows(ats->prob, c_m);
1092 for (c=1; c<=c_mechs; c++) 642 for (c=1; c<=c_m; c++)
1093 { 643 {
1094 /* b_t - n_t * M <= 0 */ 644 /* b_t - n_t * M <= 0 */
1095#if VERBOSE_ATS 645#if VERBOSE_ATS
@@ -1109,7 +659,7 @@ int ats_create_problem (struct ATS_Handle *ats,
1109#endif 659#endif
1110 array_index++; 660 array_index++;
1111 ia[array_index] = row_index; 661 ia[array_index] = row_index;
1112 ja[array_index] = c_mechs + mechanisms[c].col_index; 662 ja[array_index] = c_m + mechanisms[c].col_index;
1113 ar[array_index] = -M; 663 ar[array_index] = -M;
1114#if VERBOSE_ATS 664#if VERBOSE_ATS
1115 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n", 665 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
@@ -1123,9 +673,9 @@ int ats_create_problem (struct ATS_Handle *ats,
1123 } 673 }
1124 674
1125 /* Constraint 3: minimum bandwidth*/ 675 /* Constraint 3: minimum bandwidth*/
1126 _lp_add_rows(ats->prob, c_mechs); 676 _lp_add_rows(ats->prob, c_m);
1127 677
1128 for (c=1; c<=c_mechs; c++) 678 for (c=1; c<=c_m; c++)
1129 { 679 {
1130 /* b_t - n_t * b_min <= 0 */ 680 /* b_t - n_t * b_min <= 0 */
1131#if VERBOSE_ATS 681#if VERBOSE_ATS
@@ -1147,8 +697,8 @@ int ats_create_problem (struct ATS_Handle *ats,
1147#endif 697#endif
1148 array_index++; 698 array_index++;
1149 ia[array_index] = row_index; 699 ia[array_index] = row_index;
1150 ja[array_index] = c_mechs + mechanisms[c].col_index; 700 ja[array_index] = c_m + mechanisms[c].col_index;
1151 ar[array_index] = -v_b_min; 701 ar[array_index] = -ats->v_b_min;
1152#if VERBOSE_ATS 702#if VERBOSE_ATS
1153 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n", 703 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
1154 array_index, 704 array_index,
@@ -1185,12 +735,12 @@ int ats_create_problem (struct ATS_Handle *ats,
1185#if HAVE_LIBGLPK 735#if HAVE_LIBGLPK
1186 _lp_set_row_bnds(ats->prob, row_index, GLP_DB, ct_min, ct_max); 736 _lp_set_row_bnds(ats->prob, row_index, GLP_DB, ct_min, ct_max);
1187#endif 737#endif
1188 for (c2=1; c2<=c_mechs; c2++) 738 for (c2=1; c2<=c_m; c2++)
1189 { 739 {
1190 double value = 0; 740 double value = 0;
1191 ia[array_index] = row_index; 741 ia[array_index] = row_index;
1192 ja[array_index] = c2; 742 ja[array_index] = c2;
1193 value = mechanisms[c2].addr->ressources[c].c; 743 value = mechanisms[c2].ressources[c].c;
1194 ar[array_index] = value; 744 ar[array_index] = value;
1195#if VERBOSE_ATS 745#if VERBOSE_ATS
1196 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n", 746 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
@@ -1207,16 +757,16 @@ int ats_create_problem (struct ATS_Handle *ats,
1207 /* Constraint 5: min number of connections*/ 757 /* Constraint 5: min number of connections*/
1208 _lp_add_rows(ats->prob, 1); 758 _lp_add_rows(ats->prob, 1);
1209 759
1210 for (c=1; c<=c_mechs; c++) 760 for (c=1; c<=c_m; c++)
1211 { 761 {
1212 // b_t - n_t * b_min >= 0 762 // b_t - n_t * b_min >= 0
1213#if VERBOSE_ATS 763#if VERBOSE_ATS
1214 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n", 764 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",
1215 row_index); 765 row_index);
1216#endif 766#endif
1217 _lp_set_row_bnds(ats->prob, row_index, GLP_LO, v_n_min, 0.0); 767 _lp_set_row_bnds(ats->prob, row_index, GLP_LO, ats->v_n_min, 0.0);
1218 ia[array_index] = row_index; 768 ia[array_index] = row_index;
1219 ja[array_index] = c_mechs + mechanisms[c].col_index; 769 ja[array_index] = c_m + mechanisms[c].col_index;
1220 ar[array_index] = 1; 770 ar[array_index] = 1;
1221#if VERBOSE_ATS 771#if VERBOSE_ATS
1222 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n", 772 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
@@ -1238,7 +788,7 @@ int ats_create_problem (struct ATS_Handle *ats,
1238 col_d = _lp_add_cols(ats->prob, 1); 788 col_d = _lp_add_cols(ats->prob, 1);
1239 789
1240 _lp_set_col_name(ats->prob, col_d, "d"); 790 _lp_set_col_name(ats->prob, col_d, "d");
1241 _lp_set_obj_coef(ats->prob, col_d, D); 791 _lp_set_obj_coef(ats->prob, col_d, ats->D);
1242 _lp_set_col_bnds(ats->prob, col_d, GLP_LO, 0.0, 0.0); 792 _lp_set_col_bnds(ats->prob, col_d, GLP_LO, 0.0, 0.0);
1243 _lp_add_rows(ats->prob, 1); 793 _lp_add_rows(ats->prob, 1);
1244 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0); 794 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0);
@@ -1247,10 +797,10 @@ int ats_create_problem (struct ATS_Handle *ats,
1247#if VERBOSE_ATS 797#if VERBOSE_ATS
1248 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index); 798 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index);
1249#endif 799#endif
1250 for (c=1; c<=c_mechs; c++) 800 for (c=1; c<=c_m; c++)
1251 { 801 {
1252 ia[array_index] = row_index; 802 ia[array_index] = row_index;
1253 ja[array_index] = c_mechs + mechanisms[c].col_index; 803 ja[array_index] = c_m + mechanisms[c].col_index;
1254 ar[array_index] = 1; 804 ar[array_index] = 1;
1255#if VERBOSE_ATS 805#if VERBOSE_ATS
1256 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n", 806 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
@@ -1300,18 +850,18 @@ int ats_create_problem (struct ATS_Handle *ats,
1300#endif 850#endif
1301 double value = 1; 851 double value = 1;
1302 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0); 852 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0);
1303 for (c2=1; c2<=c_mechs; c2++) 853 for (c2=1; c2<=c_m; c2++)
1304 { 854 {
1305 ia[array_index] = row_index; 855 ia[array_index] = row_index;
1306 ja[array_index] = c2; 856 ja[array_index] = c2;
1307 if (qm[c-1].atis_index == GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY) 857 if (qm[c-1].atis_index == GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY)
1308 { 858 {
1309 double v0 = 0, v1 = 0, v2 = 0; 859 double v0 = 0, v1 = 0, v2 = 0;
1310 v0 = mechanisms[c2].addr->quality[c-1].values[0]; 860 v0 = mechanisms[c2].quality[c-1].values[0];
1311 if (v1 < 1) v0 = 0.1; 861 if (v1 < 1) v0 = 0.1;
1312 v1 = mechanisms[c2].addr->quality[c-1].values[1]; 862 v1 = mechanisms[c2].quality[c-1].values[1];
1313 if (v1 < 1) v0 = 0.1; 863 if (v1 < 1) v0 = 0.1;
1314 v2 = mechanisms[c2].addr->quality[c-1].values[2]; 864 v2 = mechanisms[c2].quality[c-1].values[2];
1315 if (v1 < 1) v0 = 0.1; 865 if (v1 < 1) v0 = 0.1;
1316 value = 100.0 / ((v0 + 2 * v1 + 3 * v2) / 6.0); 866 value = 100.0 / ((v0 + 2 * v1 + 3 * v2) / 6.0);
1317 value = 1; 867 value = 1;
@@ -1319,11 +869,11 @@ int ats_create_problem (struct ATS_Handle *ats,
1319 if (qm[c-1].atis_index == GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE) 869 if (qm[c-1].atis_index == GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE)
1320 { 870 {
1321 double v0 = 0, v1 = 0, v2 = 0; 871 double v0 = 0, v1 = 0, v2 = 0;
1322 v0 = mechanisms[c2].addr->quality[c-1].values[0]; 872 v0 = mechanisms[c2].quality[c-1].values[0];
1323 if (v0 < 1) v0 = 1; 873 if (v0 < 1) v0 = 1;
1324 v1 = mechanisms[c2].addr->quality[c-1].values[1]; 874 v1 = mechanisms[c2].quality[c-1].values[1];
1325 if (v1 < 1) v1 = 1; 875 if (v1 < 1) v1 = 1;
1326 v2 = mechanisms[c2].addr->quality[c-1].values[2]; 876 v2 = mechanisms[c2].quality[c-1].values[2];
1327 if (v2 < 1) v2 = 1; 877 if (v2 < 1) v2 = 1;
1328 value = (v0 + 2 * v1 + 3 * v2) / 6.0; 878 value = (v0 + 2 * v1 + 3 * v2) / 6.0;
1329 if (value >= 1) 879 if (value >= 1)
@@ -1363,7 +913,7 @@ int ats_create_problem (struct ATS_Handle *ats,
1363 col_u = _lp_add_cols(ats->prob, 1); 913 col_u = _lp_add_cols(ats->prob, 1);
1364 914
1365 _lp_set_col_name(ats->prob, col_u, "u"); 915 _lp_set_col_name(ats->prob, col_u, "u");
1366 _lp_set_obj_coef(ats->prob, col_u, U); 916 _lp_set_obj_coef(ats->prob, col_u, ats->U);
1367 _lp_set_col_bnds(ats->prob, col_u, GLP_LO, 0.0, 0.0); 917 _lp_set_col_bnds(ats->prob, col_u, GLP_LO, 0.0, 0.0);
1368 _lp_add_rows(ats->prob, 1); 918 _lp_add_rows(ats->prob, 1);
1369 stat->col_u = col_u; 919 stat->col_u = col_u;
@@ -1371,7 +921,7 @@ int ats_create_problem (struct ATS_Handle *ats,
1371 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index); 921 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index);
1372#endif 922#endif
1373 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0); 923 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0);
1374 for (c=1; c<=c_mechs; c++) 924 for (c=1; c<=c_m; c++)
1375 { 925 {
1376 ia[array_index] = row_index; 926 ia[array_index] = row_index;
1377 ja[array_index] = c; 927 ja[array_index] = c;
@@ -1404,12 +954,12 @@ int ats_create_problem (struct ATS_Handle *ats,
1404 col_r = _lp_add_cols(ats->prob, 1); 954 col_r = _lp_add_cols(ats->prob, 1);
1405 955
1406 _lp_set_col_name(ats->prob, col_r, "r"); 956 _lp_set_col_name(ats->prob, col_r, "r");
1407 _lp_set_obj_coef(ats->prob, col_r, R); 957 _lp_set_obj_coef(ats->prob, col_r, ats->R);
1408 _lp_set_col_bnds(ats->prob, col_r, GLP_LO, 0.0, 0.0); 958 _lp_set_col_bnds(ats->prob, col_r, GLP_LO, 0.0, 0.0);
1409 _lp_add_rows(ats->prob, c_peers); 959 _lp_add_rows(ats->prob, c_p);
1410 960
1411 stat->col_r = col_r; 961 stat->col_r = col_r;
1412 for (c=1; c<=c_peers; c++) 962 for (c=1; c<=c_p; c++)
1413 { 963 {
1414 _lp_set_row_bnds(ats->prob, row_index, GLP_LO, 0.0, 0.0); 964 _lp_set_row_bnds(ats->prob, row_index, GLP_LO, 0.0, 0.0);
1415 struct ATS_mechanism *m = peers[c].m_head; 965 struct ATS_mechanism *m = peers[c].m_head;
@@ -1445,8 +995,8 @@ int ats_create_problem (struct ATS_Handle *ats,
1445 /* Loading the matrix */ 995 /* Loading the matrix */
1446 _lp_load_matrix(ats->prob, array_index-1, ia, ja, ar); 996 _lp_load_matrix(ats->prob, array_index-1, ia, ja, ar);
1447 997
1448 stat->c_mechs = c_mechs; 998 stat->c_mechs = c_m;
1449 stat->c_peers = c_peers; 999 stat->c_peers = c_p;
1450 stat->solution = 0; 1000 stat->solution = 0;
1451 stat->valid = GNUNET_YES; 1001 stat->valid = GNUNET_YES;
1452 1002
@@ -1471,7 +1021,7 @@ void ats_delete_problem (struct ATS_Handle * ats)
1471#endif 1021#endif
1472 int c; 1022 int c;
1473 1023
1474 for (c=0; c< (ats->stat).c_mechs; c++) 1024 for (c=0; c< (ats->internal).c_mechs; c++)
1475 GNUNET_free_non_null (ats->mechanisms[c].rc); 1025 GNUNET_free_non_null (ats->mechanisms[c].rc);
1476 if (ats->mechanisms!=NULL) 1026 if (ats->mechanisms!=NULL)
1477 { 1027 {
@@ -1491,14 +1041,14 @@ void ats_delete_problem (struct ATS_Handle * ats)
1491 ats->prob = NULL; 1041 ats->prob = NULL;
1492 } 1042 }
1493 1043
1494 ats->stat.begin_cr = GNUNET_SYSERR; 1044 ats->internal.begin_cr = GNUNET_SYSERR;
1495 ats->stat.begin_qm = GNUNET_SYSERR; 1045 ats->internal.begin_qm = GNUNET_SYSERR;
1496 ats->stat.c_mechs = 0; 1046 ats->internal.c_mechs = 0;
1497 ats->stat.c_peers = 0; 1047 ats->internal.c_peers = 0;
1498 ats->stat.end_cr = GNUNET_SYSERR; 1048 ats->internal.end_cr = GNUNET_SYSERR;
1499 ats->stat.end_qm = GNUNET_SYSERR; 1049 ats->internal.end_qm = GNUNET_SYSERR;
1500 ats->stat.solution = GNUNET_SYSERR; 1050 ats->internal.solution = GNUNET_SYSERR;
1501 ats->stat.valid = GNUNET_SYSERR; 1051 ats->internal.valid = GNUNET_SYSERR;
1502} 1052}
1503 1053
1504void ats_modify_problem_state (struct ATS_Handle * ats, enum ATS_problem_state s) 1054void ats_modify_problem_state (struct ATS_Handle * ats, enum ATS_problem_state s)
@@ -1508,22 +1058,22 @@ void ats_modify_problem_state (struct ATS_Handle * ats, enum ATS_problem_state s
1508 switch (s) 1058 switch (s)
1509 { 1059 {
1510 case ATS_NEW : 1060 case ATS_NEW :
1511 ats->stat.recreate_problem = GNUNET_NO; 1061 ats->internal.recreate_problem = GNUNET_NO;
1512 ats->stat.modified_quality = GNUNET_NO; 1062 ats->internal.modified_quality = GNUNET_NO;
1513 ats->stat.modified_resources = GNUNET_NO; 1063 ats->internal.modified_resources = GNUNET_NO;
1514 break; 1064 break;
1515 case ATS_MODIFIED: 1065 case ATS_MODIFIED:
1516 ats->stat.recreate_problem = GNUNET_YES; 1066 ats->internal.recreate_problem = GNUNET_YES;
1517 break; 1067 break;
1518 case ATS_QUALITY_UPDATED : 1068 case ATS_QUALITY_UPDATED :
1519 ats->stat.modified_quality = GNUNET_YES; 1069 ats->internal.modified_quality = GNUNET_YES;
1520 break; 1070 break;
1521 case ATS_COST_UPDATED : 1071 case ATS_COST_UPDATED :
1522 ats->stat.modified_resources = GNUNET_YES; 1072 ats->internal.modified_resources = GNUNET_YES;
1523 break; 1073 break;
1524 case ATS_QUALITY_COST_UPDATED: 1074 case ATS_QUALITY_COST_UPDATED:
1525 ats->stat.modified_resources = GNUNET_YES; 1075 ats->internal.modified_resources = GNUNET_YES;
1526 ats->stat.modified_quality = GNUNET_YES; 1076 ats->internal.modified_quality = GNUNET_YES;
1527 break; 1077 break;
1528 default: 1078 default:
1529 return; 1079 return;
@@ -1538,7 +1088,7 @@ void ats_solve_problem (struct ATS_Handle * ats,
1538 unsigned int max_dur, 1088 unsigned int max_dur,
1539 unsigned int c_peers, 1089 unsigned int c_peers,
1540 unsigned int c_mechs, 1090 unsigned int c_mechs,
1541 struct ATS_stat *stat) 1091 struct ATS_internals *stat)
1542{ 1092{
1543#if !HAVE_LIBGLPK 1093#if !HAVE_LIBGLPK
1544 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS not active\n"); 1094 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS not active\n");
@@ -1564,7 +1114,7 @@ void ats_solve_problem (struct ATS_Handle * ats,
1564 // maximum duration 1114 // maximum duration
1565 opt_lp.tm_lim = max_dur; 1115 opt_lp.tm_lim = max_dur;
1566 1116
1567 if (ats->stat.recreate_problem == GNUNET_YES) 1117 if (ats->internal.recreate_problem == GNUNET_YES)
1568 opt_lp.presolve = GLP_ON; 1118 opt_lp.presolve = GLP_ON;
1569 1119
1570 result = _lp_simplex(ats->prob, &opt_lp); 1120 result = _lp_simplex(ats->prob, &opt_lp);
@@ -1572,7 +1122,7 @@ void ats_solve_problem (struct ATS_Handle * ats,
1572 1122
1573 if ((result == GLP_ETMLIM) || (result == GLP_EITLIM)) 1123 if ((result == GLP_ETMLIM) || (result == GLP_EITLIM))
1574 { 1124 {
1575 ats->stat.valid = GNUNET_NO; 1125 ats->internal.valid = GNUNET_NO;
1576 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1126 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1577 "ATS exceeded time or iteration limit!\n"); 1127 "ATS exceeded time or iteration limit!\n");
1578 return; 1128 return;
@@ -1584,7 +1134,7 @@ void ats_solve_problem (struct ATS_Handle * ats,
1584 } 1134 }
1585 else 1135 else
1586 { 1136 {
1587 ats->stat.simplex_rerun_required = GNUNET_YES; 1137 ats->internal.simplex_rerun_required = GNUNET_YES;
1588 opt_lp.presolve = GLP_ON; 1138 opt_lp.presolve = GLP_ON;
1589 result = _lp_simplex(ats->prob, &opt_lp); 1139 result = _lp_simplex(ats->prob, &opt_lp);
1590 lp_solution = _lp_get_status (ats->prob); 1140 lp_solution = _lp_get_status (ats->prob);
@@ -1601,13 +1151,13 @@ void ats_solve_problem (struct ATS_Handle * ats,
1601 char * filename; 1151 char * filename;
1602 GNUNET_asprintf (&filename, 1152 GNUNET_asprintf (&filename,
1603 "ats_mlp_p%i_m%i_%llu.mlp", 1153 "ats_mlp_p%i_m%i_%llu.mlp",
1604 ats->stat.c_peers, 1154 ats->internal.c_peers,
1605 ats->stat.c_mechs, 1155 ats->internal.c_mechs,
1606 GNUNET_TIME_absolute_get().abs_value); 1156 GNUNET_TIME_absolute_get().abs_value);
1607 _lp_write_lp ((void *)ats->prob, NULL, filename); 1157 _lp_write_lp ((void *)ats->prob, NULL, filename);
1608 GNUNET_free (filename); 1158 GNUNET_free (filename);
1609 stat->valid = GNUNET_NO; 1159 stat->valid = GNUNET_NO;
1610 ats->stat.recreate_problem = GNUNET_YES; 1160 ats->internal.recreate_problem = GNUNET_YES;
1611 return; 1161 return;
1612 } 1162 }
1613 stat->valid = GNUNET_YES; 1163 stat->valid = GNUNET_YES;
@@ -1638,8 +1188,8 @@ void ats_solve_problem (struct ATS_Handle * ats,
1638 // TODO: Remove if this does not appear until release 1188 // TODO: Remove if this does not appear until release
1639 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1189 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1640 "MLP solution for %i peers, %i mechs is invalid: %i\n", 1190 "MLP solution for %i peers, %i mechs is invalid: %i\n",
1641 ats->stat.c_peers, 1191 ats->internal.c_peers,
1642 ats->stat.c_mechs, 1192 ats->internal.c_mechs,
1643 mlp_solution); 1193 mlp_solution);
1644 stat->valid = GNUNET_NO; 1194 stat->valid = GNUNET_NO;
1645 } 1195 }
@@ -1698,14 +1248,14 @@ void ats_update_problem_qm (struct ATS_Handle * ats)
1698 int c, c2; 1248 int c, c2;
1699 int c_q_metrics = available_quality_metrics; 1249 int c_q_metrics = available_quality_metrics;
1700 1250
1701 int *ja = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 + 1251 int *ja = GNUNET_malloc ((1 + ats->internal.c_mechs*2 + 3 +
1702 available_quality_metrics) * sizeof (int)); 1252 available_quality_metrics) * sizeof (int));
1703 double *ar = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 + 1253 double *ar = GNUNET_malloc ((1 + ats->internal.c_mechs*2 + 3 +
1704 available_quality_metrics) * sizeof (double)); 1254 available_quality_metrics) * sizeof (double));
1705#if DEBUG_ATS 1255#if DEBUG_ATS
1706 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating problem quality metrics\n"); 1256 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating problem quality metrics\n");
1707#endif 1257#endif
1708 row_index = ats->stat.begin_qm; 1258 row_index = ats->internal.begin_qm;
1709 1259
1710 for (c=1; c <= c_q_metrics; c++) 1260 for (c=1; c <= c_q_metrics; c++)
1711 { 1261 {
@@ -1715,7 +1265,7 @@ void ats_update_problem_qm (struct ATS_Handle * ats)
1715 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index); 1265 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index);
1716#endif 1266#endif
1717 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0); 1267 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0);
1718 for (c2=1; c2<=ats->stat.c_mechs; c2++) 1268 for (c2=1; c2<=ats->internal.c_mechs; c2++)
1719 { 1269 {
1720 ja[array_index] = c2; 1270 ja[array_index] = c2;
1721 GNUNET_assert (ats->mechanisms[c2].addr != NULL); 1271 GNUNET_assert (ats->mechanisms[c2].addr != NULL);
@@ -1725,11 +1275,11 @@ void ats_update_problem_qm (struct ATS_Handle * ats)
1725 { 1275 {
1726 double v0 = 0, v1 = 0, v2 = 0; 1276 double v0 = 0, v1 = 0, v2 = 0;
1727 1277
1728 v0 = ats->mechanisms[c2].addr->quality[c-1].values[0]; 1278 v0 = ats->mechanisms[c2].quality[c-1].values[0];
1729 if (v1 < 1) v0 = 0.1; 1279 if (v1 < 1) v0 = 0.1;
1730 v1 = ats->mechanisms[c2].addr->quality[c-1].values[1]; 1280 v1 = ats->mechanisms[c2].quality[c-1].values[1];
1731 if (v1 < 1) v0 = 0.1; 1281 if (v1 < 1) v0 = 0.1;
1732 v2 = ats->mechanisms[c2].addr->quality[c-1].values[2]; 1282 v2 = ats->mechanisms[c2].quality[c-1].values[2];
1733 if (v1 < 1) v0 = 0.1; 1283 if (v1 < 1) v0 = 0.1;
1734 value = 100.0 / ((v0 + 2 * v1 + 3 * v2) / 6.0); 1284 value = 100.0 / ((v0 + 2 * v1 + 3 * v2) / 6.0);
1735 //value = 1; 1285 //value = 1;
@@ -1737,11 +1287,11 @@ void ats_update_problem_qm (struct ATS_Handle * ats)
1737 if (qm[c-1].atis_index == GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE) 1287 if (qm[c-1].atis_index == GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE)
1738 { 1288 {
1739 double v0 = 0, v1 = 0, v2 = 0; 1289 double v0 = 0, v1 = 0, v2 = 0;
1740 v0 = ats->mechanisms[c2].addr->quality[c-1].values[0]; 1290 v0 = ats->mechanisms[c2].quality[c-1].values[0];
1741 if (v0 < 1) v0 = 1; 1291 if (v0 < 1) v0 = 1;
1742 v1 = ats->mechanisms[c2].addr->quality[c-1].values[1]; 1292 v1 = ats->mechanisms[c2].quality[c-1].values[1];
1743 if (v1 < 1) v1 = 1; 1293 if (v1 < 1) v1 = 1;
1744 v2 = ats->mechanisms[c2].addr->quality[c-1].values[2]; 1294 v2 = ats->mechanisms[c2].quality[c-1].values[2];
1745 if (v2 < 1) v2 = 1; 1295 if (v2 < 1) v2 = 1;
1746 value = (v0 + 2 * v1 + 3 * v2) / 6.0; 1296 value = (v0 + 2 * v1 + 3 * v2) / 6.0;
1747 if (value >= 1) 1297 if (value >= 1)
@@ -1760,7 +1310,7 @@ void ats_update_problem_qm (struct ATS_Handle * ats)
1760#endif 1310#endif
1761 array_index++; 1311 array_index++;
1762 } 1312 }
1763 ja[array_index] = ats->stat.col_qm + c - 1; 1313 ja[array_index] = ats->internal.col_qm + c - 1;
1764 ar[array_index] = -1; 1314 ar[array_index] = -1;
1765 1315
1766#if VERBOSE_ATS 1316#if VERBOSE_ATS
@@ -1776,13 +1326,13 @@ void ats_update_problem_qm (struct ATS_Handle * ats)
1776 } 1326 }
1777 GNUNET_free_non_null (ja); 1327 GNUNET_free_non_null (ja);
1778 GNUNET_free_non_null (ar); 1328 GNUNET_free_non_null (ar);
1329
1779} 1330}
1780 1331
1781 1332
1782void 1333void
1783ats_calculate_bandwidth_distribution (struct ATS_Handle * ats, 1334ats_calculate_bandwidth_distribution (struct ATS_Handle * ats,
1784 struct GNUNET_STATISTICS_Handle *stats, 1335 struct GNUNET_STATISTICS_Handle *stats)
1785 struct NeighbourList *neighbours)
1786{ 1336{
1787#if !HAVE_LIBGLPK 1337#if !HAVE_LIBGLPK
1788 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS not active\n"); 1338 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS not active\n");
@@ -1792,19 +1342,10 @@ ats_calculate_bandwidth_distribution (struct ATS_Handle * ats,
1792 struct GNUNET_TIME_Absolute start; 1342 struct GNUNET_TIME_Absolute start;
1793 struct GNUNET_TIME_Relative creation; 1343 struct GNUNET_TIME_Relative creation;
1794 struct GNUNET_TIME_Relative solving; 1344 struct GNUNET_TIME_Relative solving;
1345 int c_m;
1346 int c_p;
1795 char *text = "unmodified"; 1347 char *text = "unmodified";
1796 1348
1797 struct GNUNET_TIME_Relative delta = GNUNET_TIME_absolute_get_difference (ats->last,
1798 GNUNET_TIME_absolute_get());
1799 if (delta.rel_value < ats->min_delta.rel_value)
1800 {
1801#if DEBUG_ATS
1802 GNUNET_log (GNUNET_ERROR_TYPE_BULK,
1803 "Minimum time between cycles not reached\n");
1804#endif
1805 return;
1806 }
1807
1808#if FIXME_WACHS 1349#if FIXME_WACHS
1809 int dur; 1350 int dur;
1810 if (INT_MAX < ats->max_exec_duration.rel_value) 1351 if (INT_MAX < ats->max_exec_duration.rel_value)
@@ -1813,103 +1354,109 @@ ats_calculate_bandwidth_distribution (struct ATS_Handle * ats,
1813 dur = (int) ats->max_exec_duration.rel_value; 1354 dur = (int) ats->max_exec_duration.rel_value;
1814#endif 1355#endif
1815 1356
1816 ats->stat.simplex_rerun_required = GNUNET_NO; 1357 ats->internal.simplex_rerun_required = GNUNET_NO;
1817 start = GNUNET_TIME_absolute_get(); 1358 start = GNUNET_TIME_absolute_get();
1818 if ((ats->stat.recreate_problem == GNUNET_YES) || 1359 if ((ats->internal.recreate_problem == GNUNET_YES) ||
1819 (ats->prob==NULL) || 1360 (ats->prob==NULL) ||
1820 (ats->stat.valid == GNUNET_NO)) 1361 (ats->internal.valid == GNUNET_NO))
1821 { 1362 {
1822 text = "new"; 1363 text = "new";
1823 ats->stat.recreate_problem = GNUNET_YES; 1364 ats->internal.recreate_problem = GNUNET_YES;
1824 ats_delete_problem (ats); 1365 ats_delete_problem (ats);
1825 ats_create_problem (ats, 1366 ats->addr_notification(&ats->peers , &c_p, &ats->mechanisms, &c_m);
1826 neighbours, 1367#if DEBUG_ATS
1827 ats->D, 1368 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1828 ats->U, 1369 "Service returned: %i peer, %i mechs\n",
1829 ats->R, 1370 c_p,
1830 ats->v_b_min, 1371 c_m);
1831 ats->v_n_min, 1372#endif
1832 &ats->stat); 1373 ats_create_problem (ats, &ats->internal, ats->peers, c_p, ats->mechanisms, c_m);
1374
1375
1833#if DEBUG_ATS 1376#if DEBUG_ATS
1834 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1377 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1835 "Peers/Addresses were modified... new problem: %i peer, %i mechs\n", 1378 "Peers/Addresses were modified... new problem: %i peer, %i mechs\n",
1836 ats->stat.c_peers, 1379 ats->internal.c_peers,
1837 ats->stat.c_mechs); 1380 ats->internal.c_mechs);
1838#endif 1381#endif
1839 } 1382 }
1840 1383
1841 else if ((ats->stat.recreate_problem == GNUNET_NO) && 1384 else if ((ats->internal.recreate_problem == GNUNET_NO) &&
1842 (ats->stat.modified_resources == GNUNET_YES) && 1385 (ats->internal.modified_resources == GNUNET_YES) &&
1843 (ats->stat.valid == GNUNET_YES)) 1386 (ats->internal.valid == GNUNET_YES))
1844 { 1387 {
1845 text = "modified resources"; 1388 text = "modified resources";
1846 ats_update_problem_cr (ats); 1389 ats_update_problem_cr (ats);
1847 } 1390 }
1848 else if ((ats->stat.recreate_problem == GNUNET_NO) && 1391 else if ((ats->internal.recreate_problem == GNUNET_NO) &&
1849 (ats->stat.modified_quality == GNUNET_YES) && 1392 (ats->internal.modified_quality == GNUNET_YES) &&
1850 (ats->stat.valid == GNUNET_YES)) 1393 (ats->internal.valid == GNUNET_YES))
1851 { 1394 {
1852 text = "modified quality"; 1395 text = "modified quality";
1853 ats_update_problem_qm (ats); 1396 ats_update_problem_qm (ats);
1854 //ats_update_problem_qm_TEST (); 1397 //ats_update_problem_qm_TEST ();
1855 } 1398 }
1856#if DEBUG_ATS 1399#if DEBUG_ATS
1857 else GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Problem is unmodified\n"); 1400 else GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Problem is %s\n", text);
1858#endif 1401#endif
1859 1402
1860 creation = GNUNET_TIME_absolute_get_difference(start,GNUNET_TIME_absolute_get()); 1403 creation = GNUNET_TIME_absolute_get_difference(start,GNUNET_TIME_absolute_get());
1861 start = GNUNET_TIME_absolute_get(); 1404 start = GNUNET_TIME_absolute_get();
1862 1405
1863 ats->stat.solution = GLP_UNDEF; 1406 ats->internal.solution = GLP_UNDEF;
1864 if (ats->stat.valid == GNUNET_YES) 1407 if (ats->internal.valid == GNUNET_YES)
1865 { 1408 {
1866 ats_solve_problem(ats, 1409 ats_solve_problem(ats,
1867 ats->max_iterations, 1410 ats->max_iterations,
1868 ats->max_exec_duration.rel_value, 1411 ats->max_exec_duration.rel_value,
1869 ats->stat.c_peers, 1412 ats->internal.c_peers,
1870 ats->stat.c_mechs, 1413 ats->internal.c_mechs,
1871 &ats->stat); 1414 &ats->internal);
1872 } 1415 }
1873 solving = GNUNET_TIME_absolute_get_difference(start,GNUNET_TIME_absolute_get()); 1416 solving = GNUNET_TIME_absolute_get_difference(start,GNUNET_TIME_absolute_get());
1874 1417
1875 if (ats->stat.valid == GNUNET_YES) 1418 if (ats->internal.valid == GNUNET_YES)
1876 { 1419 {
1420 /* Telling about new distribution*/
1421 ats->result_cb ();
1422
1877 int msg_type = GNUNET_ERROR_TYPE_DEBUG; 1423 int msg_type = GNUNET_ERROR_TYPE_DEBUG;
1878#if DEBUG_ATS 1424#if DEBUG_ATS
1879 msg_type = GNUNET_ERROR_TYPE_ERROR; 1425 msg_type = GNUNET_ERROR_TYPE_ERROR;
1880#endif 1426#endif
1881 GNUNET_log (msg_type, 1427 GNUNET_log (msg_type,
1882 "MLP %s: creation time: %llu, execution time: %llu, %i mechanisms, simplex rerun: %s, solution %s\n", 1428 "MLP %s: creation time: %llu, execution time: %llu, %i peers, %i mechanisms, simplex rerun: %s, solution %s\n",
1883 text, 1429 text,
1884 creation.rel_value, 1430 creation.rel_value,
1885 solving.rel_value, 1431 solving.rel_value,
1886 ats->stat.c_mechs, 1432 ats->internal.c_peers,
1887 (ats->stat.simplex_rerun_required == GNUNET_NO) ? "NO" : "YES", 1433 ats->internal.c_mechs,
1888 (ats->stat.solution == 5) ? "OPTIMAL" : "INVALID"); 1434 (ats->internal.simplex_rerun_required == GNUNET_NO) ? "NO" : "YES",
1435 (ats->internal.solution == 5) ? "OPTIMAL" : "INVALID");
1889 ats->successful_executions ++; 1436 ats->successful_executions ++;
1890 GNUNET_STATISTICS_set (stats, "# ATS successful executions", 1437 GNUNET_STATISTICS_set (stats, "# ATS successful executions",
1891 ats->successful_executions, 1438 ats->successful_executions,
1892 GNUNET_NO); 1439 GNUNET_NO);
1893 1440
1894 if ((ats->stat.recreate_problem == GNUNET_YES) || (ats->prob==NULL)) 1441 if ((ats->internal.recreate_problem == GNUNET_YES) || (ats->prob==NULL))
1895 GNUNET_STATISTICS_set (stats, "ATS state",ATS_NEW, GNUNET_NO); 1442 GNUNET_STATISTICS_set (stats, "ATS state",ATS_NEW, GNUNET_NO);
1896 else if ((ats->stat.modified_resources == GNUNET_YES) && 1443 else if ((ats->internal.modified_resources == GNUNET_YES) &&
1897 (ats->stat.modified_quality == GNUNET_NO)) 1444 (ats->internal.modified_quality == GNUNET_NO))
1898 GNUNET_STATISTICS_set (stats, "ATS state", ATS_COST_UPDATED, GNUNET_NO); 1445 GNUNET_STATISTICS_set (stats, "ATS state", ATS_COST_UPDATED, GNUNET_NO);
1899 else if ((ats->stat.modified_resources == GNUNET_NO) && 1446 else if ((ats->internal.modified_resources == GNUNET_NO) &&
1900 (ats->stat.modified_quality == GNUNET_YES) && 1447 (ats->internal.modified_quality == GNUNET_YES) &&
1901 (ats->stat.simplex_rerun_required == GNUNET_NO)) 1448 (ats->internal.simplex_rerun_required == GNUNET_NO))
1902 GNUNET_STATISTICS_set (stats, "ATS state", ATS_QUALITY_UPDATED, GNUNET_NO); 1449 GNUNET_STATISTICS_set (stats, "ATS state", ATS_QUALITY_UPDATED, GNUNET_NO);
1903 else if ((ats->stat.modified_resources == GNUNET_YES) && 1450 else if ((ats->internal.modified_resources == GNUNET_YES) &&
1904 (ats->stat.modified_quality == GNUNET_YES) && 1451 (ats->internal.modified_quality == GNUNET_YES) &&
1905 (ats->stat.simplex_rerun_required == GNUNET_NO)) 1452 (ats->internal.simplex_rerun_required == GNUNET_NO))
1906 GNUNET_STATISTICS_set (stats, "ATS state", ATS_QUALITY_COST_UPDATED, GNUNET_NO); 1453 GNUNET_STATISTICS_set (stats, "ATS state", ATS_QUALITY_COST_UPDATED, GNUNET_NO);
1907 else if (ats->stat.simplex_rerun_required == GNUNET_NO) 1454 else if (ats->internal.simplex_rerun_required == GNUNET_NO)
1908 GNUNET_STATISTICS_set (stats, "ATS state", ATS_UNMODIFIED, GNUNET_NO); 1455 GNUNET_STATISTICS_set (stats, "ATS state", ATS_UNMODIFIED, GNUNET_NO);
1909 } 1456 }
1910 else 1457 else
1911 { 1458 {
1912 if (ats->stat.c_peers != 0) 1459 if (ats->internal.c_peers != 0)
1913 { 1460 {
1914 ats->invalid_executions ++; 1461 ats->invalid_executions ++;
1915 GNUNET_STATISTICS_set (stats, "# ATS invalid executions", 1462 GNUNET_STATISTICS_set (stats, "# ATS invalid executions",
@@ -1925,24 +1472,24 @@ ats_calculate_bandwidth_distribution (struct ATS_Handle * ats,
1925 GNUNET_STATISTICS_set (stats, 1472 GNUNET_STATISTICS_set (stats,
1926 "ATS duration", solving.rel_value + creation.rel_value, GNUNET_NO); 1473 "ATS duration", solving.rel_value + creation.rel_value, GNUNET_NO);
1927 GNUNET_STATISTICS_set (stats, 1474 GNUNET_STATISTICS_set (stats,
1928 "ATS mechanisms", ats->stat.c_mechs, GNUNET_NO); 1475 "ATS mechanisms", ats->internal.c_mechs, GNUNET_NO);
1929 GNUNET_STATISTICS_set (stats, 1476 GNUNET_STATISTICS_set (stats,
1930 "ATS peers", ats->stat.c_peers, GNUNET_NO); 1477 "ATS peers", ats->internal.c_peers, GNUNET_NO);
1931 GNUNET_STATISTICS_set (stats, 1478 GNUNET_STATISTICS_set (stats,
1932 "ATS solution", ats->stat.solution, GNUNET_NO); 1479 "ATS solution", ats->internal.solution, GNUNET_NO);
1933 GNUNET_STATISTICS_set (stats, 1480 GNUNET_STATISTICS_set (stats,
1934 "ATS timestamp", start.abs_value, GNUNET_NO); 1481 "ATS timestamp", start.abs_value, GNUNET_NO);
1935 1482
1936 if ((ats->save_mlp == GNUNET_YES) && 1483 if ((ats->save_mlp == GNUNET_YES) &&
1937 (ats->stat.c_mechs >= ats->dump_min_peers) && 1484 (ats->internal.c_mechs >= ats->dump_min_peers) &&
1938 (ats->stat.c_mechs >= ats->dump_min_addr)) 1485 (ats->internal.c_mechs >= ats->dump_min_addr))
1939 { 1486 {
1940 char * filename; 1487 char * filename;
1941 if (ats->dump_overwrite == GNUNET_NO) 1488 if (ats->dump_overwrite == GNUNET_NO)
1942 { 1489 {
1943 GNUNET_asprintf (&filename, "ats_mlp_p%i_m%i_%s_%llu.mlp", 1490 GNUNET_asprintf (&filename, "ats_mlp_p%i_m%i_%s_%llu.mlp",
1944 ats->stat.c_peers, 1491 ats->internal.c_peers,
1945 ats->stat.c_mechs, 1492 ats->internal.c_mechs,
1946 text, 1493 text,
1947 GNUNET_TIME_absolute_get().abs_value); 1494 GNUNET_TIME_absolute_get().abs_value);
1948 _lp_write_lp ((void *) ats->prob, NULL, filename); 1495 _lp_write_lp ((void *) ats->prob, NULL, filename);
@@ -1950,21 +1497,21 @@ ats_calculate_bandwidth_distribution (struct ATS_Handle * ats,
1950 else 1497 else
1951 { 1498 {
1952 GNUNET_asprintf (&filename, "ats_mlp_p%i_m%i.mlp", 1499 GNUNET_asprintf (&filename, "ats_mlp_p%i_m%i.mlp",
1953 ats->stat.c_peers, ats->stat.c_mechs ); 1500 ats->internal.c_peers, ats->internal.c_mechs );
1954 _lp_write_lp ((void *) ats->prob, NULL, filename); 1501 _lp_write_lp ((void *) ats->prob, NULL, filename);
1955 } 1502 }
1956 GNUNET_free (filename); 1503 GNUNET_free (filename);
1957 } 1504 }
1958 if ((ats->save_solution == GNUNET_YES) && 1505 if ((ats->save_solution == GNUNET_YES) &&
1959 (ats->stat.c_mechs >= ats->dump_min_peers) && 1506 (ats->internal.c_mechs >= ats->dump_min_peers) &&
1960 (ats->stat.c_mechs >= ats->dump_min_addr)) 1507 (ats->internal.c_mechs >= ats->dump_min_addr))
1961 { 1508 {
1962 char * filename; 1509 char * filename;
1963 if (ats->dump_overwrite == GNUNET_NO) 1510 if (ats->dump_overwrite == GNUNET_NO)
1964 { 1511 {
1965 GNUNET_asprintf (&filename, "ats_mlp_p%i_m%i_%s_%llu.sol", 1512 GNUNET_asprintf (&filename, "ats_mlp_p%i_m%i_%s_%llu.sol",
1966 ats->stat.c_peers, 1513 ats->internal.c_peers,
1967 ats->stat.c_mechs, 1514 ats->internal.c_mechs,
1968 text, 1515 text,
1969 GNUNET_TIME_absolute_get().abs_value); 1516 GNUNET_TIME_absolute_get().abs_value);
1970 _lp_print_sol (ats->prob, filename); 1517 _lp_print_sol (ats->prob, filename);
@@ -1972,15 +1519,15 @@ ats_calculate_bandwidth_distribution (struct ATS_Handle * ats,
1972 else 1519 else
1973 { 1520 {
1974 GNUNET_asprintf (&filename, "ats_mlp_p%i_m%i.sol", 1521 GNUNET_asprintf (&filename, "ats_mlp_p%i_m%i.sol",
1975 ats->stat.c_peers, ats->stat.c_mechs); 1522 ats->internal.c_peers, ats->internal.c_mechs);
1976 _lp_print_sol (ats->prob, filename); 1523 _lp_print_sol (ats->prob, filename);
1977 } 1524 }
1978 GNUNET_free (filename); 1525 GNUNET_free (filename);
1979 } 1526 }
1980 ats->last = GNUNET_TIME_absolute_get(); 1527
1981 ats->stat.recreate_problem = GNUNET_NO; 1528 ats->internal.recreate_problem = GNUNET_NO;
1982 ats->stat.modified_resources = GNUNET_NO; 1529 ats->internal.modified_resources = GNUNET_NO;
1983 ats->stat.modified_quality = GNUNET_NO; 1530 ats->internal.modified_quality = GNUNET_NO;
1984} 1531}
1985 1532
1986/** 1533/**
@@ -2115,13 +1662,13 @@ void ats_update_problem_cr (struct ATS_Handle * ats)
2115 int c, c2; 1662 int c, c2;
2116 double ct_max, ct_min; 1663 double ct_max, ct_min;
2117 1664
2118 int *ja = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 + 1665 int *ja = GNUNET_malloc ((1 + ats->internal.c_mechs*2 + 3 +
2119 available_quality_metrics) * sizeof (int)); 1666 available_quality_metrics) * sizeof (int));
2120 double *ar = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 + 1667 double *ar = GNUNET_malloc ((1 + ats->internal.c_mechs*2 + 3 +
2121 available_quality_metrics) * sizeof (double)); 1668 available_quality_metrics) * sizeof (double));
2122 1669
2123 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating problem quality metrics\n"); 1670 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating problem quality metrics\n");
2124 row_index = ats->stat.begin_cr; 1671 row_index = ats->internal.begin_cr;
2125 array_index = 1; 1672 array_index = 1;
2126 1673
2127 for (c=0; c<available_ressources; c++) 1674 for (c=0; c<available_ressources; c++)
@@ -2135,14 +1682,14 @@ void ats_update_problem_cr (struct ATS_Handle * ats)
2135 ct_max); 1682 ct_max);
2136#endif 1683#endif
2137 _lp_set_row_bnds(ats->prob, row_index, GLP_DB, ct_min, ct_max); 1684 _lp_set_row_bnds(ats->prob, row_index, GLP_DB, ct_min, ct_max);
2138 for (c2=1; c2<=ats->stat.c_mechs; c2++) 1685 for (c2=1; c2<=ats->internal.c_mechs; c2++)
2139 { 1686 {
2140 double value = 0; 1687 double value = 0;
2141 GNUNET_assert (ats->mechanisms[c2].addr != NULL); 1688 GNUNET_assert (ats->mechanisms[c2].addr != NULL);
2142 GNUNET_assert (ats->mechanisms[c2].peer != NULL); 1689 GNUNET_assert (ats->mechanisms[c2].peer != NULL);
2143 1690
2144 ja[array_index] = c2; 1691 ja[array_index] = c2;
2145 value = ats->mechanisms[c2].addr->ressources[c].c; 1692 value = ats->mechanisms[c2].ressources[c].c;
2146 ar[array_index] = value; 1693 ar[array_index] = value;
2147#if VERBOSE_ATS 1694#if VERBOSE_ATS
2148 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n", 1695 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
@@ -2158,6 +1705,24 @@ void ats_update_problem_cr (struct ATS_Handle * ats)
2158 } 1705 }
2159 GNUNET_free_non_null (ja); 1706 GNUNET_free_non_null (ja);
2160 GNUNET_free_non_null (ar); 1707 GNUNET_free_non_null (ar);
1708
1709}
1710
1711void ats_set_logging_options (struct ATS_Handle * ats,
1712 int minimum_addresses,
1713 int minimum_peers,
1714 int overwrite_dump,
1715 int log_solution,
1716 int log_problem)
1717{
1718 if (ats == NULL)
1719 return;
1720
1721 ats->dump_min_addr = minimum_addresses;
1722 ats->dump_min_peers = minimum_peers;
1723 ats->dump_overwrite = overwrite_dump;
1724 ats->save_mlp = log_problem;
1725 ats->save_solution = log_solution;
2161} 1726}
2162 1727
2163#if 0 1728#if 0
@@ -2169,19 +1734,19 @@ static void ats_update_problem_qm_TEST ()
2169 int c_old; 1734 int c_old;
2170 int changed = 0; 1735 int changed = 0;
2171 1736
2172 int old_ja[ats->stat.c_mechs + 2]; 1737 int old_ja[ats->internal.c_mechs + 2];
2173 double old_ar[ats->stat.c_mechs + 2]; 1738 double old_ar[ats->internal.c_mechs + 2];
2174 1739
2175 int *ja = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 + 1740 int *ja = GNUNET_malloc ((1 + ats->internal.c_mechs*2 + 3 +
2176 available_quality_metrics) * sizeof (int)); 1741 available_quality_metrics) * sizeof (int));
2177 double *ar = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 + 1742 double *ar = GNUNET_malloc ((1 + ats->internal.c_mechs*2 + 3 +
2178 available_quality_metrics) * sizeof (double)); 1743 available_quality_metrics) * sizeof (double));
2179#if DEBUG_ATS 1744#if DEBUG_ATS
2180 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1745 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2181 "Updating problem quality metrics TEST\n"); 1746 "Updating problem quality metrics TEST\n");
2182#endif 1747#endif
2183 if (ats->stat.begin_qm >0) 1748 if (ats->internal.begin_qm >0)
2184 row_index = ats->stat.begin_qm; 1749 row_index = ats->internal.begin_qm;
2185 else 1750 else
2186 return; 1751 return;
2187 for (c=0; c<available_quality_metrics; c++) 1752 for (c=0; c<available_quality_metrics; c++)
diff --git a/src/transport/transport_ats.h b/src/transport/transport_ats.h
index 20bdaadf1..98d8e8325 100644
--- a/src/transport/transport_ats.h
+++ b/src/transport/transport_ats.h
@@ -1,7 +1,36 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file transport/transport_ats.h
23 * @brief common internal definitions for transport service's ats code
24 * @author Matthias Wachs
25 */
26#ifndef TRANSPORT_ATS_H
27#define TRANSPORT_ATS_H
28
1#include "platform.h" 29#include "platform.h"
2#include "gnunet_constants.h" 30#include "gnunet_constants.h"
3#include "gnunet_scheduler_lib.h" 31#include "gnunet_scheduler_lib.h"
4#include "gnunet_statistics_service.h" 32#include "gnunet_statistics_service.h"
33#include "gnunet_time_lib.h"
5 34
6 35
7#if HAVE_LIBGLPK 36#if HAVE_LIBGLPK
@@ -30,10 +59,26 @@
30 59
31#define VERY_BIG_DOUBLE_VALUE 100000000000LL 60#define VERY_BIG_DOUBLE_VALUE 100000000000LL
32 61
62
63/*
64 * Callback Functions
65 */
66
67struct ATS_mechanism;
68struct ATS_peer;
69
70typedef void (*GNUNET_TRANSPORT_ATS_AddressNotification)
71 (struct ATS_peer **peers,
72 int * c_p,
73 struct ATS_mechanism ** mechanisms,
74 int * c_m );
75
76typedef void (*GNUNET_TRANSPORT_ATS_ResultCallback) (void);
77
33enum ATS_problem_state 78enum ATS_problem_state
34{ 79{
35 /** 80 /**
36 * Problem is new / unmodified 81 * Problem is new
37 */ 82 */
38 ATS_NEW = 0, 83 ATS_NEW = 0,
39 84
@@ -59,8 +104,7 @@ enum ATS_problem_state
59 ATS_MODIFIED = 4, 104 ATS_MODIFIED = 4,
60 105
61 /** 106 /**
62 * Problem is modified and needs to be completely recalculated 107 * Problem is unmodified
63 * due to e.g. connecting or disconnecting peers
64 */ 108 */
65 ATS_UNMODIFIED = 8 109 ATS_UNMODIFIED = 8
66}; 110};
@@ -69,7 +113,7 @@ enum ATS_problem_state
69* ATS data structures 113* ATS data structures
70*/ 114*/
71 115
72struct ATS_stat 116struct ATS_internals
73{ 117{
74 /** 118 /**
75 * result of last GLPK run 119 * result of last GLPK run
@@ -163,19 +207,14 @@ struct ATS_stat
163 207
164struct ATS_Handle 208struct ATS_Handle
165{ 209{
166 210 /*
167 /** 211 * Callback functions
168 * Time of last execution
169 */
170 struct GNUNET_TIME_Absolute last;
171 /**
172 * Minimum intervall between two executions
173 */
174 struct GNUNET_TIME_Relative min_delta;
175 /**
176 * Regular intervall when execution is triggered
177 */ 212 */
178 struct GNUNET_TIME_Relative exec_interval; 213
214 GNUNET_TRANSPORT_ATS_AddressNotification addr_notification;
215
216 GNUNET_TRANSPORT_ATS_ResultCallback result_cb;
217
179 /** 218 /**
180 * Maximum execution time per calculation 219 * Maximum execution time per calculation
181 */ 220 */
@@ -192,9 +231,9 @@ struct ATS_Handle
192#endif 231#endif
193 232
194 /** 233 /**
195 * Current state of the GLPK problem 234 * Internal information state of the GLPK problem
196 */ 235 */
197 struct ATS_stat stat; 236 struct ATS_internals internal;
198 237
199 /** 238 /**
200 * mechanisms used in current problem 239 * mechanisms used in current problem
@@ -209,6 +248,13 @@ struct ATS_Handle
209 struct ATS_peer * peers; 248 struct ATS_peer * peers;
210 249
211 /** 250 /**
251 * State of the MLP problem
252 * value of ATS_problem_state
253 *
254 */
255 int state;
256
257 /**
212 * number of successful executions 258 * number of successful executions
213 */ 259 */
214 int successful_executions; 260 int successful_executions;
@@ -223,55 +269,67 @@ struct ATS_Handle
223 */ 269 */
224 int max_iterations; 270 int max_iterations;
225 271
272
273 /*
274 * ATS configuration
275 */
276
277
226 /** 278 /**
227 * Dump problem to a file? 279 * Diversity weight
228 */ 280 */
229 int save_mlp; 281 double D;
230 282
231 /** 283 /**
232 * Dump solution to a file 284 * Utility weight
233 */ 285 */
234 int save_solution; 286 double U;
235 287
236 /** 288 /**
237 * Dump solution when minimum peers: 289 * Relativity weight
238 */ 290 */
239 int dump_min_peers; 291 double R;
240 292
241 /** 293 /**
242 * Dump solution when minimum addresses: 294 * Minimum bandwidth per peer
243 */ 295 */
244 int dump_min_addr; 296 int v_b_min;
245 297
246 /** 298 /**
247 * Dump solution overwrite file: 299 * Minimum number of connections per peer
248 */ 300 */
249 int dump_overwrite; 301 int v_n_min;
302
250 303
251 /** 304 /**
252 * Diversity weight 305 * Logging related variables
253 */ 306 */
254 double D; 307
255 308
256 /** 309 /**
257 * Utility weight 310 * Dump problem to a file?
258 */ 311 */
259 double U; 312 int save_mlp;
260 313
261 /** 314 /**
262 * Relativity weight 315 * Dump solution to a file
263 */ 316 */
264 double R; 317 int save_solution;
265 318
266 /** 319 /**
267 * Minimum bandwidth per peer 320 * Dump solution when minimum peers:
268 */ 321 */
269 int v_b_min; 322 int dump_min_peers;
270 323
271 /** 324 /**
272 * Minimum number of connections per peer 325 * Dump solution when minimum addresses:
273 */ 326 */
274 int v_n_min; 327 int dump_min_addr;
328
329 /**
330 * Dump solution overwrite file:
331 */
332 int dump_overwrite;
275}; 333};
276 334
277struct ATS_mechanism 335struct ATS_mechanism
@@ -279,6 +337,8 @@ struct ATS_mechanism
279 struct ATS_mechanism * prev; 337 struct ATS_mechanism * prev;
280 struct ATS_mechanism * next; 338 struct ATS_mechanism * next;
281 struct ForeignAddressList * addr; 339 struct ForeignAddressList * addr;
340 struct ATS_quality_entry * quality;
341 struct ATS_ressource_entry * ressources;
282 struct TransportPlugin * plugin; 342 struct TransportPlugin * plugin;
283 struct ATS_peer * peer; 343 struct ATS_peer * peer;
284 int col_index; 344 int col_index;
@@ -386,7 +446,15 @@ static struct ATS_quality_metric qm[] =
386 * ATS functions 446 * ATS functions
387 */ 447 */
388struct ATS_Handle * 448struct ATS_Handle *
389ats_init (const struct GNUNET_CONFIGURATION_Handle *cfg); 449ats_init (double D,
450 double U,
451 double R,
452 int v_b_min,
453 int v_n_min,
454 int max_iterations,
455 struct GNUNET_TIME_Relative max_duration,
456 GNUNET_TRANSPORT_ATS_AddressNotification address_not,
457 GNUNET_TRANSPORT_ATS_ResultCallback res_cb);
390 458
391void 459void
392ats_shutdown (struct ATS_Handle * ats); 460ats_shutdown (struct ATS_Handle * ats);
@@ -395,22 +463,19 @@ void
395ats_delete_problem (struct ATS_Handle * ats); 463ats_delete_problem (struct ATS_Handle * ats);
396 464
397int 465int
398ats_create_problem (struct ATS_Handle * ats, 466ats_create_problem (struct ATS_Handle *ats,
399 struct NeighbourList *n, 467 struct ATS_internals *stat,
400 double D, 468 struct ATS_peer *peers,
401 double U, 469 int c_p,
402 double R, 470 struct ATS_mechanism *mechanisms,
403 int v_b_min, 471 int c_m);
404 int v_n_min,
405 struct ATS_stat *stat);
406 472
407void ats_modify_problem_state (struct ATS_Handle * ats, 473void ats_modify_problem_state (struct ATS_Handle * ats,
408 enum ATS_problem_state s); 474 enum ATS_problem_state s);
409 475
410void 476void
411ats_calculate_bandwidth_distribution (struct ATS_Handle * ats, 477ats_calculate_bandwidth_distribution (struct ATS_Handle * ats,
412 struct GNUNET_STATISTICS_Handle *stats, 478 struct GNUNET_STATISTICS_Handle *stats);
413 struct NeighbourList *neighbours);
414 479
415void 480void
416ats_solve_problem (struct ATS_Handle * ats, 481ats_solve_problem (struct ATS_Handle * ats,
@@ -418,7 +483,7 @@ ats_solve_problem (struct ATS_Handle * ats,
418 unsigned int max_dur, 483 unsigned int max_dur,
419 unsigned int c_peers, 484 unsigned int c_peers,
420 unsigned int c_mechs, 485 unsigned int c_mechs,
421 struct ATS_stat *stat); 486 struct ATS_internals *stat);
422 487
423int 488int
424ats_evaluate_results (int result, 489ats_evaluate_results (int result,
@@ -432,3 +497,13 @@ void
432ats_update_problem_cr (struct ATS_Handle * ats); 497ats_update_problem_cr (struct ATS_Handle * ats);
433 498
434 499
500void
501ats_set_logging_options (struct ATS_Handle * ats,
502 int minimum_addresses,
503 int minimum_peers,
504 int overwrite_dump,
505 int log_solution,
506 int log_problem);
507
508#endif
509/* end of file transport_ats.h */