diff options
-rw-r--r-- | src/ats/Makefile.am | 3 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats-new.c | 69 | ||||
-rw-r--r-- | src/ats/plugin_ats2_simple.c | 600 | ||||
-rw-r--r-- | src/hello/hello-ng.c | 5 | ||||
-rw-r--r-- | src/include/gnunet_hello_lib.h | 10 | ||||
-rw-r--r-- | src/transport/gnunet-service-tng.c | 2 |
6 files changed, 612 insertions, 77 deletions
diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am index 97497c94e..147d371e6 100644 --- a/src/ats/Makefile.am +++ b/src/ats/Makefile.am | |||
@@ -81,6 +81,7 @@ libgnunet_plugin_ats_proportional_la_LDFLAGS = \ | |||
81 | libgnunet_plugin_ats2_simple_la_SOURCES = \ | 81 | libgnunet_plugin_ats2_simple_la_SOURCES = \ |
82 | plugin_ats2_simple.c | 82 | plugin_ats2_simple.c |
83 | libgnunet_plugin_ats2_simple_la_LIBADD = \ | 83 | libgnunet_plugin_ats2_simple_la_LIBADD = \ |
84 | $(top_builddir)/src/hello/libgnunethello.la \ | ||
84 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 85 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
85 | $(top_builddir)/src/util/libgnunetutil.la \ | 86 | $(top_builddir)/src/util/libgnunetutil.la \ |
86 | $(LTLIBINTL) | 87 | $(LTLIBINTL) |
@@ -130,7 +131,7 @@ gnunet_service_ats_LDADD = \ | |||
130 | $(GN_LIBINTL) | 131 | $(GN_LIBINTL) |
131 | 132 | ||
132 | gnunet_service_ats_new_SOURCES = \ | 133 | gnunet_service_ats_new_SOURCES = \ |
133 | gnunet-service-ats-new.c | 134 | gnunet-service-ats-new.c |
134 | gnunet_service_ats_new_LDADD = \ | 135 | gnunet_service_ats_new_LDADD = \ |
135 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 136 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
136 | $(top_builddir)/src/util/libgnunetutil.la \ | 137 | $(top_builddir)/src/util/libgnunetutil.la \ |
diff --git a/src/ats/gnunet-service-ats-new.c b/src/ats/gnunet-service-ats-new.c index d3b2f1ead..fa8c07a1a 100644 --- a/src/ats/gnunet-service-ats-new.c +++ b/src/ats/gnunet-service-ats-new.c | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | */ | 17 | */ |
@@ -78,7 +78,7 @@ struct ClientPreference | |||
78 | * Plugin's representation of the preference. | 78 | * Plugin's representation of the preference. |
79 | */ | 79 | */ |
80 | struct GNUNET_ATS_PreferenceHandle *ph; | 80 | struct GNUNET_ATS_PreferenceHandle *ph; |
81 | 81 | ||
82 | /** | 82 | /** |
83 | * Details about the preference. | 83 | * Details about the preference. |
84 | */ | 84 | */ |
@@ -93,7 +93,7 @@ struct GNUNET_ATS_Session | |||
93 | { | 93 | { |
94 | 94 | ||
95 | /** | 95 | /** |
96 | * Session data exposed to the plugin. | 96 | * Session data exposed to the plugin. |
97 | */ | 97 | */ |
98 | struct GNUNET_ATS_SessionData data; | 98 | struct GNUNET_ATS_SessionData data; |
99 | 99 | ||
@@ -106,12 +106,12 @@ struct GNUNET_ATS_Session | |||
106 | * Session state in the plugin. | 106 | * Session state in the plugin. |
107 | */ | 107 | */ |
108 | struct GNUNET_ATS_SessionHandle *sh; | 108 | struct GNUNET_ATS_SessionHandle *sh; |
109 | 109 | ||
110 | /** | 110 | /** |
111 | * Unique ID for the session when talking with the client. | 111 | * Unique ID for the session when talking with the client. |
112 | */ | 112 | */ |
113 | uint32_t session_id; | 113 | uint32_t session_id; |
114 | 114 | ||
115 | }; | 115 | }; |
116 | 116 | ||
117 | 117 | ||
@@ -146,12 +146,12 @@ struct Client | |||
146 | * Head of DLL of preferences expressed by this client. | 146 | * Head of DLL of preferences expressed by this client. |
147 | */ | 147 | */ |
148 | struct ClientPreference *cp_head; | 148 | struct ClientPreference *cp_head; |
149 | 149 | ||
150 | /** | 150 | /** |
151 | * Tail of DLL of preferences expressed by this client. | 151 | * Tail of DLL of preferences expressed by this client. |
152 | */ | 152 | */ |
153 | struct ClientPreference *cp_tail; | 153 | struct ClientPreference *cp_tail; |
154 | 154 | ||
155 | } application; | 155 | } application; |
156 | 156 | ||
157 | struct { | 157 | struct { |
@@ -160,9 +160,9 @@ struct Client | |||
160 | * Map from session IDs to `struct GNUNET_ATS_Session` objects. | 160 | * Map from session IDs to `struct GNUNET_ATS_Session` objects. |
161 | */ | 161 | */ |
162 | struct GNUNET_CONTAINER_MultiHashMap32 *sessions; | 162 | struct GNUNET_CONTAINER_MultiHashMap32 *sessions; |
163 | 163 | ||
164 | } transport; | 164 | } transport; |
165 | 165 | ||
166 | } details; | 166 | } details; |
167 | 167 | ||
168 | }; | 168 | }; |
@@ -196,7 +196,7 @@ static struct Client *transport_client; | |||
196 | * @param cls closure, NULL | 196 | * @param cls closure, NULL |
197 | * @param pid peer this is about | 197 | * @param pid peer this is about |
198 | * @param address address the transport should try | 198 | * @param address address the transport should try |
199 | */ | 199 | */ |
200 | static void | 200 | static void |
201 | suggest_cb (void *cls, | 201 | suggest_cb (void *cls, |
202 | const struct GNUNET_PeerIdentity *pid, | 202 | const struct GNUNET_PeerIdentity *pid, |
@@ -205,7 +205,7 @@ suggest_cb (void *cls, | |||
205 | struct GNUNET_MQ_Envelope *env; | 205 | struct GNUNET_MQ_Envelope *env; |
206 | size_t slen = strlen (address) + 1; | 206 | size_t slen = strlen (address) + 1; |
207 | struct AddressSuggestionMessage *as; | 207 | struct AddressSuggestionMessage *as; |
208 | 208 | ||
209 | if (NULL == transport_client) | 209 | if (NULL == transport_client) |
210 | { | 210 | { |
211 | // FIXME: stats! | 211 | // FIXME: stats! |
@@ -285,7 +285,7 @@ prop_ntoh (const struct PropertiesNBO *properties, | |||
285 | 285 | ||
286 | 286 | ||
287 | /** | 287 | /** |
288 | * We have received a `struct ExpressPreferenceMessage` from an application client. | 288 | * We have received a `struct ExpressPreferenceMessage` from an application client. |
289 | * | 289 | * |
290 | * @param cls handle to the client | 290 | * @param cls handle to the client |
291 | * @param msg the start message | 291 | * @param msg the start message |
@@ -320,7 +320,7 @@ handle_suggest (void *cls, | |||
320 | 320 | ||
321 | 321 | ||
322 | /** | 322 | /** |
323 | * We have received a `struct ExpressPreferenceMessage` from an application client. | 323 | * We have received a `struct ExpressPreferenceMessage` from an application client. |
324 | * | 324 | * |
325 | * @param cls handle to the client | 325 | * @param cls handle to the client |
326 | * @param msg the start message | 326 | * @param msg the start message |
@@ -331,7 +331,7 @@ handle_suggest_cancel (void *cls, | |||
331 | { | 331 | { |
332 | struct Client *c = cls; | 332 | struct Client *c = cls; |
333 | struct ClientPreference *cp; | 333 | struct ClientPreference *cp; |
334 | 334 | ||
335 | if (CT_NONE == c->type) | 335 | if (CT_NONE == c->type) |
336 | c->type = CT_APPLICATION; | 336 | c->type = CT_APPLICATION; |
337 | if (CT_APPLICATION != c->type) | 337 | if (CT_APPLICATION != c->type) |
@@ -398,7 +398,7 @@ handle_start (void *cls, | |||
398 | 398 | ||
399 | 399 | ||
400 | /** | 400 | /** |
401 | * Check 'session_add' message is well-formed and comes from a | 401 | * Check 'session_add' message is well-formed and comes from a |
402 | * transport client. | 402 | * transport client. |
403 | * | 403 | * |
404 | * @param cls client that sent the request | 404 | * @param cls client that sent the request |
@@ -433,7 +433,7 @@ handle_session_add (void *cls, | |||
433 | { | 433 | { |
434 | struct Client *c = cls; | 434 | struct Client *c = cls; |
435 | const char *address = (const char *) &message[1]; | 435 | const char *address = (const char *) &message[1]; |
436 | struct GNUNET_ATS_Session *session; | 436 | struct GNUNET_ATS_Session *session; |
437 | int inbound_only = (GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD_INBOUND_ONLY == | 437 | int inbound_only = (GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD_INBOUND_ONLY == |
438 | ntohs (message->header.type)); | 438 | ntohs (message->header.type)); |
439 | 439 | ||
@@ -477,7 +477,7 @@ handle_session_update (void *cls, | |||
477 | { | 477 | { |
478 | struct Client *c = cls; | 478 | struct Client *c = cls; |
479 | struct GNUNET_ATS_Session *session; | 479 | struct GNUNET_ATS_Session *session; |
480 | 480 | ||
481 | if (CT_TRANSPORT != c->type) | 481 | if (CT_TRANSPORT != c->type) |
482 | { | 482 | { |
483 | GNUNET_break (0); | 483 | GNUNET_break (0); |
@@ -527,7 +527,7 @@ handle_session_del (void *cls, | |||
527 | GNUNET_break (0); | 527 | GNUNET_break (0); |
528 | GNUNET_SERVICE_client_drop (c->client); | 528 | GNUNET_SERVICE_client_drop (c->client); |
529 | return; | 529 | return; |
530 | } | 530 | } |
531 | plugin->session_del (plugin->cls, | 531 | plugin->session_del (plugin->cls, |
532 | session->sh, | 532 | session->sh, |
533 | &session->data); | 533 | &session->data); |
@@ -637,15 +637,14 @@ client_disconnect_cb (void *cls, | |||
637 | 637 | ||
638 | 638 | ||
639 | /** | 639 | /** |
640 | * Task run during shutdown. | 640 | * Task run at the end during shutdown. |
641 | * | 641 | * |
642 | * @param cls unused | 642 | * @param cls unused |
643 | */ | 643 | */ |
644 | static void | 644 | static void |
645 | cleanup_task (void *cls) | 645 | final_cleanup (void *cls) |
646 | { | 646 | { |
647 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 647 | (void) cls; |
648 | "ATS shutdown initiated\n"); | ||
649 | if (NULL != stats) | 648 | if (NULL != stats) |
650 | { | 649 | { |
651 | GNUNET_STATISTICS_destroy (stats, | 650 | GNUNET_STATISTICS_destroy (stats, |
@@ -667,6 +666,22 @@ cleanup_task (void *cls) | |||
667 | 666 | ||
668 | 667 | ||
669 | /** | 668 | /** |
669 | * Task run during shutdown. | ||
670 | * | ||
671 | * @param cls unused | ||
672 | */ | ||
673 | static void | ||
674 | cleanup_task (void *cls) | ||
675 | { | ||
676 | (void) cls; | ||
677 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
678 | "ATS shutdown initiated\n"); | ||
679 | GNUNET_SCHEDULER_add_now (&final_cleanup, | ||
680 | NULL); | ||
681 | } | ||
682 | |||
683 | |||
684 | /** | ||
670 | * Process template requests. | 685 | * Process template requests. |
671 | * | 686 | * |
672 | * @param cls closure | 687 | * @param cls closure |
@@ -680,7 +695,7 @@ run (void *cls, | |||
680 | { | 695 | { |
681 | static struct GNUNET_ATS_PluginEnvironment env; | 696 | static struct GNUNET_ATS_PluginEnvironment env; |
682 | char *solver; | 697 | char *solver; |
683 | 698 | ||
684 | stats = GNUNET_STATISTICS_create ("ats", | 699 | stats = GNUNET_STATISTICS_create ("ats", |
685 | cfg); | 700 | cfg); |
686 | if (GNUNET_SYSERR == | 701 | if (GNUNET_SYSERR == |
@@ -711,7 +726,7 @@ run (void *cls, | |||
711 | _("Failed to initialize solver `%s'!\n"), | 726 | _("Failed to initialize solver `%s'!\n"), |
712 | plugin_name); | 727 | plugin_name); |
713 | GNUNET_SCHEDULER_shutdown (); | 728 | GNUNET_SCHEDULER_shutdown (); |
714 | return; | 729 | return; |
715 | } | 730 | } |
716 | } | 731 | } |
717 | 732 | ||
@@ -746,11 +761,11 @@ GNUNET_SERVICE_MAIN | |||
746 | GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD_INBOUND_ONLY, | 761 | GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD_INBOUND_ONLY, |
747 | struct SessionAddMessage, | 762 | struct SessionAddMessage, |
748 | NULL), | 763 | NULL), |
749 | GNUNET_MQ_hd_fixed_size (session_update, | 764 | GNUNET_MQ_hd_fixed_size (session_update, |
750 | GNUNET_MESSAGE_TYPE_ATS_SESSION_UPDATE, | 765 | GNUNET_MESSAGE_TYPE_ATS_SESSION_UPDATE, |
751 | struct SessionUpdateMessage, | 766 | struct SessionUpdateMessage, |
752 | NULL), | 767 | NULL), |
753 | GNUNET_MQ_hd_fixed_size (session_del, | 768 | GNUNET_MQ_hd_fixed_size (session_del, |
754 | GNUNET_MESSAGE_TYPE_ATS_SESSION_DEL, | 769 | GNUNET_MESSAGE_TYPE_ATS_SESSION_DEL, |
755 | struct SessionDelMessage, | 770 | struct SessionDelMessage, |
756 | NULL), | 771 | NULL), |
diff --git a/src/ats/plugin_ats2_simple.c b/src/ats/plugin_ats2_simple.c index 55234f1bc..6faf8ad7c 100644 --- a/src/ats/plugin_ats2_simple.c +++ b/src/ats/plugin_ats2_simple.c | |||
@@ -22,26 +22,48 @@ | |||
22 | * @author Christian Grothoff | 22 | * @author Christian Grothoff |
23 | * | 23 | * |
24 | * TODO: | 24 | * TODO: |
25 | * - subscribe to PEERSTORE when short on HELLOs (given application preferences!) | 25 | * - needs testing |
26 | * - keep track of HELLOs and when we tried them last => re-suggest | ||
27 | * - sum up preferences per peer, keep totals! => PeerMap pid -> [preferences + sessions + addrs!] | ||
28 | * - sum up preferences overall, keep global sum => starting point for "proportional" | ||
29 | * - store DLL of available sessions per peer | ||
30 | */ | 26 | */ |
31 | #include "platform.h" | 27 | #include "platform.h" |
32 | #include "gnunet_ats_plugin_new.h" | 28 | #include "gnunet_ats_plugin_new.h" |
29 | #include "gnunet_hello_lib.h" | ||
33 | #include "gnunet_peerstore_service.h" | 30 | #include "gnunet_peerstore_service.h" |
34 | 31 | ||
35 | #define LOG(kind,...) GNUNET_log_from (kind, "ats-simple",__VA_ARGS__) | 32 | #define LOG(kind,...) GNUNET_log_from (kind, "ats-simple",__VA_ARGS__) |
36 | 33 | ||
37 | 34 | ||
38 | /** | 35 | /** |
36 | * Base frequency at which we suggest addresses to transport. | ||
37 | * Multiplied by the square of the number of active connections | ||
38 | * (and randomized) to calculate the actual frequency at which | ||
39 | * we will suggest addresses to the transport. Furthermore, each | ||
40 | * address is also bounded by an exponential back-off. | ||
41 | */ | ||
42 | #define SUGGEST_FREQ GNUNET_TIME_UNIT_SECONDS | ||
43 | |||
44 | /** | ||
45 | * What is the minimum bandwidth we always try to allocate for | ||
46 | * any session that is up? (May still be scaled down lower if | ||
47 | * the number of sessions is so high that the total bandwidth | ||
48 | * is insufficient to allow for this value to be granted.) | ||
49 | */ | ||
50 | #define MIN_BANDWIDTH_PER_SESSION 1024 | ||
51 | |||
52 | |||
53 | /** | ||
39 | * A handle for the proportional solver | 54 | * A handle for the proportional solver |
40 | */ | 55 | */ |
41 | struct SimpleHandle; | 56 | struct SimpleHandle; |
42 | 57 | ||
43 | 58 | ||
44 | /** | 59 | /** |
60 | * Information about preferences and sessions we track | ||
61 | * per peer. | ||
62 | */ | ||
63 | struct Peer; | ||
64 | |||
65 | |||
66 | /** | ||
45 | * Entry in list of addresses we could try per peer. | 67 | * Entry in list of addresses we could try per peer. |
46 | */ | 68 | */ |
47 | struct Hello | 69 | struct Hello |
@@ -58,11 +80,27 @@ struct Hello | |||
58 | struct Hello *prev; | 80 | struct Hello *prev; |
59 | 81 | ||
60 | /** | 82 | /** |
83 | * Peer this hello belongs to. | ||
84 | */ | ||
85 | struct Peer *peer; | ||
86 | |||
87 | /** | ||
61 | * The address we could try. | 88 | * The address we could try. |
62 | */ | 89 | */ |
63 | const char *address; | 90 | const char *address; |
64 | 91 | ||
65 | /** | 92 | /** |
93 | * Is a session with this address already up? | ||
94 | * If not, set to NULL. | ||
95 | */ | ||
96 | struct GNUNET_ATS_SessionHandle *sh; | ||
97 | |||
98 | /** | ||
99 | * When does the HELLO expire? | ||
100 | */ | ||
101 | struct GNUNET_TIME_Absolute expiration; | ||
102 | |||
103 | /** | ||
66 | * When did we try it last? | 104 | * When did we try it last? |
67 | */ | 105 | */ |
68 | struct GNUNET_TIME_Absolute last_attempt; | 106 | struct GNUNET_TIME_Absolute last_attempt; |
@@ -73,22 +111,14 @@ struct Hello | |||
73 | struct GNUNET_TIME_Relative backoff; | 111 | struct GNUNET_TIME_Relative backoff; |
74 | 112 | ||
75 | /** | 113 | /** |
76 | * Is a session with this address already up? | 114 | * Type of the network for this HELLO. |
77 | * If not, set to NULL. | ||
78 | */ | 115 | */ |
79 | struct GNUNET_ATS_SessionHandle *sh; | 116 | enum GNUNET_NetworkType nt; |
80 | 117 | ||
81 | }; | 118 | }; |
82 | 119 | ||
83 | 120 | ||
84 | /** | 121 | /** |
85 | * Information about preferences and sessions we track | ||
86 | * per peer. | ||
87 | */ | ||
88 | struct Peer; | ||
89 | |||
90 | |||
91 | /** | ||
92 | * Internal representation of a session by the plugin. | 122 | * Internal representation of a session by the plugin. |
93 | * (If desired, plugin may just use NULL.) | 123 | * (If desired, plugin may just use NULL.) |
94 | */ | 124 | */ |
@@ -131,6 +161,12 @@ struct GNUNET_ATS_SessionHandle | |||
131 | const char *address; | 161 | const char *address; |
132 | 162 | ||
133 | /** | 163 | /** |
164 | * When did we last update transport about the allocation? | ||
165 | * Used to dampen the frequency of updates. | ||
166 | */ | ||
167 | struct GNUNET_TIME_Absolute last_allocation; | ||
168 | |||
169 | /** | ||
134 | * Last BW-in allocation given to the transport service. | 170 | * Last BW-in allocation given to the transport service. |
135 | */ | 171 | */ |
136 | struct GNUNET_BANDWIDTH_Value32NBO bw_in; | 172 | struct GNUNET_BANDWIDTH_Value32NBO bw_in; |
@@ -140,6 +176,16 @@ struct GNUNET_ATS_SessionHandle | |||
140 | */ | 176 | */ |
141 | struct GNUNET_BANDWIDTH_Value32NBO bw_out; | 177 | struct GNUNET_BANDWIDTH_Value32NBO bw_out; |
142 | 178 | ||
179 | /** | ||
180 | * New BW-in allocation given to the transport service. | ||
181 | */ | ||
182 | uint64_t target_in; | ||
183 | |||
184 | /** | ||
185 | * New BW-out allocation given to the transport service. | ||
186 | */ | ||
187 | uint64_t target_out; | ||
188 | |||
143 | }; | 189 | }; |
144 | 190 | ||
145 | 191 | ||
@@ -176,26 +222,31 @@ struct Peer | |||
176 | struct SimpleHandle *h; | 222 | struct SimpleHandle *h; |
177 | 223 | ||
178 | /** | 224 | /** |
179 | * Which peer is this for? | 225 | * Watch context where we are currently looking for HELLOs for |
226 | * this peer. | ||
180 | */ | 227 | */ |
181 | struct GNUNET_PeerIdentity pid; | 228 | struct GNUNET_PEERSTORE_WatchContext *wc; |
182 | 229 | ||
183 | /** | 230 | /** |
184 | * Array where we sum up the bandwidth requests received indexed | 231 | * Task used to try again to suggest an address for this peer. |
185 | * by preference kind (see `enum GNUNET_MQ_PreferenceKind`) | ||
186 | */ | 232 | */ |
187 | uint64_t bw_by_pk[GNUNET_MQ_PREFERENCE_COUNT]; | 233 | struct GNUNET_SCHEDULER_Task *task; |
188 | 234 | ||
189 | /** | 235 | /** |
190 | * Watch context where we are currently looking for HELLOs for | 236 | * Which peer is this for? |
191 | * this peer. | ||
192 | */ | 237 | */ |
193 | struct GNUNET_PEERSTORE_WatchContext *wc; | 238 | struct GNUNET_PeerIdentity pid; |
194 | 239 | ||
195 | /** | 240 | /** |
196 | * Task used to try again to suggest an address for this peer. | 241 | * When did we last suggest an address to connect to for this peer? |
197 | */ | 242 | */ |
198 | struct GNUNET_SCHEDULER_Task *task; | 243 | struct GNUNET_TIME_Absolute last_suggestion; |
244 | |||
245 | /** | ||
246 | * Array where we sum up the bandwidth requests received indexed | ||
247 | * by preference kind (see `enum GNUNET_MQ_PreferenceKind`) | ||
248 | */ | ||
249 | uint64_t bw_by_pk[GNUNET_MQ_PREFERENCE_COUNT]; | ||
199 | 250 | ||
200 | }; | 251 | }; |
201 | 252 | ||
@@ -241,14 +292,21 @@ struct SimpleHandle | |||
241 | struct GNUNET_CONTAINER_MultiPeerMap *peers; | 292 | struct GNUNET_CONTAINER_MultiPeerMap *peers; |
242 | 293 | ||
243 | /** | 294 | /** |
244 | * Information we track per network type (quotas). | 295 | * Handle to the peerstore service. |
245 | */ | 296 | */ |
246 | struct Network networks[GNUNET_NT_COUNT]; | 297 | struct GNUNET_PEERSTORE_Handle *ps; |
247 | 298 | ||
248 | /** | 299 | /** |
249 | * Handle to the peerstore service. | 300 | * Array where we sum up the bandwidth requests received indexed |
301 | * by preference kind (see `enum GNUNET_MQ_PreferenceKind`) (sums | ||
302 | * over all peers). | ||
250 | */ | 303 | */ |
251 | struct GNUNET_PEERSTORE_Handle *ps; | 304 | uint64_t bw_by_pk[GNUNET_MQ_PREFERENCE_COUNT]; |
305 | |||
306 | /** | ||
307 | * Information we track per network type (quotas). | ||
308 | */ | ||
309 | struct Network networks[GNUNET_NT_COUNT]; | ||
252 | 310 | ||
253 | }; | 311 | }; |
254 | 312 | ||
@@ -291,6 +349,129 @@ peer_test_dead (struct Peer *p) | |||
291 | 349 | ||
292 | 350 | ||
293 | /** | 351 | /** |
352 | * Contact the transport service and suggest to it to | ||
353 | * try connecting to the address of @a hello. Updates | ||
354 | * backoff and timestamp values in the @a hello. | ||
355 | * | ||
356 | * @param hello[in,out] address suggestion to make | ||
357 | */ | ||
358 | static void | ||
359 | suggest_hello (struct Hello *hello) | ||
360 | { | ||
361 | struct Peer *p = hello->peer; | ||
362 | struct SimpleHandle *h = p->h; | ||
363 | |||
364 | p->last_suggestion | ||
365 | = hello->last_attempt | ||
366 | = GNUNET_TIME_absolute_get (); | ||
367 | hello->backoff = GNUNET_TIME_randomized_backoff (hello->backoff, | ||
368 | GNUNET_TIME_absolute_get_remaining (hello->expiration)); | ||
369 | h->env->suggest_cb (h->env->cls, | ||
370 | &p->pid, | ||
371 | hello->address); | ||
372 | } | ||
373 | |||
374 | |||
375 | /** | ||
376 | * Consider suggesting a HELLO (without a session) to transport. | ||
377 | * We look at how many active sessions we have for the peer, and | ||
378 | * if there are many, reduce the frequency of trying new addresses. | ||
379 | * Also, for each address we consider when we last tried it, and | ||
380 | * its exponential backoff if the attempt failed. Note that it | ||
381 | * is possible that this function is called when no suggestion | ||
382 | * is to be made. | ||
383 | * | ||
384 | * In this case, we only calculate the time until we make the next | ||
385 | * suggestion. | ||
386 | * | ||
387 | * @param cls a `struct Peer` | ||
388 | */ | ||
389 | static void | ||
390 | suggest_start_cb (void *cls) | ||
391 | { | ||
392 | struct Peer *p = cls; | ||
393 | struct GNUNET_TIME_Relative delay = GNUNET_TIME_UNIT_ZERO; | ||
394 | struct Hello *hello = NULL; | ||
395 | struct GNUNET_TIME_Absolute hpt = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
396 | struct GNUNET_TIME_Relative xdelay; | ||
397 | struct GNUNET_TIME_Absolute xnext; | ||
398 | unsigned int num_sessions = 0; | ||
399 | uint32_t sq; | ||
400 | |||
401 | /* count number of active sessions */ | ||
402 | for (struct GNUNET_ATS_SessionHandle *sh = p->sh_head; | ||
403 | NULL != sh; | ||
404 | sh = sh->next) | ||
405 | num_sessions++; | ||
406 | /* calculate square of number of sessions */ | ||
407 | num_sessions++; /* start with 1, even if we have zero sessions */ | ||
408 | if (num_sessions < UINT16_MAX) | ||
409 | sq = num_sessions * (uint32_t) num_sessions; | ||
410 | else | ||
411 | sq = UINT32_MAX; | ||
412 | xdelay = GNUNET_TIME_randomized_backoff (GNUNET_TIME_relative_multiply (SUGGEST_FREQ, | ||
413 | sq), | ||
414 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
415 | xnext = GNUNET_TIME_relative_to_absolute (xdelay); | ||
416 | |||
417 | p->task = NULL; | ||
418 | while (0 == delay.rel_value_us) | ||
419 | { | ||
420 | struct Hello *next; | ||
421 | struct GNUNET_TIME_Absolute xmax; | ||
422 | |||
423 | if (NULL != hello) | ||
424 | { | ||
425 | /* We went through the loop already once and found | ||
426 | a HELLO that is due *now*, so make a suggestion! */ | ||
427 | GNUNET_break (NULL == hello->sh); | ||
428 | suggest_hello (hello); | ||
429 | hello = NULL; | ||
430 | hpt = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
431 | } | ||
432 | for (struct Hello *pos = p->h_head; NULL != pos; pos = next) | ||
433 | { | ||
434 | struct GNUNET_TIME_Absolute pt; | ||
435 | |||
436 | next = pos->next; | ||
437 | if (NULL != pos->sh) | ||
438 | continue; | ||
439 | if (0 == GNUNET_TIME_absolute_get_remaining (pos->expiration).rel_value_us) | ||
440 | { | ||
441 | /* expired, remove! */ | ||
442 | GNUNET_CONTAINER_DLL_remove (p->h_head, | ||
443 | p->h_tail, | ||
444 | pos); | ||
445 | GNUNET_free (pos); | ||
446 | continue; | ||
447 | } | ||
448 | pt = GNUNET_TIME_absolute_add (pos->last_attempt, | ||
449 | pos->backoff); | ||
450 | if ( (NULL == hello) || | ||
451 | (pt.abs_value_us < hpt.abs_value_us) ) | ||
452 | { | ||
453 | hello = pos; | ||
454 | hpt = pt; | ||
455 | } | ||
456 | } | ||
457 | if (NULL == hello) | ||
458 | return; /* no HELLOs that could still be tried */ | ||
459 | |||
460 | /* hpt is now the *earliest* possible time for any HELLO | ||
461 | but we might not want to go for as early as possible for | ||
462 | this peer. So the actual time is the max of the earliest | ||
463 | HELLO and the 'xnext' */ | ||
464 | xmax = GNUNET_TIME_absolute_max (hpt, | ||
465 | xnext); | ||
466 | delay = GNUNET_TIME_absolute_get_remaining (xmax); | ||
467 | } | ||
468 | p->task = GNUNET_SCHEDULER_add_delayed (delay, | ||
469 | &suggest_start_cb, | ||
470 | p); | ||
471 | } | ||
472 | |||
473 | |||
474 | /** | ||
294 | * Function called by PEERSTORE for each matching record. | 475 | * Function called by PEERSTORE for each matching record. |
295 | * | 476 | * |
296 | * @param cls closure with a `struct Peer` | 477 | * @param cls closure with a `struct Peer` |
@@ -303,15 +484,85 @@ watch_cb (void *cls, | |||
303 | const char *emsg) | 484 | const char *emsg) |
304 | { | 485 | { |
305 | struct Peer *p = cls; | 486 | struct Peer *p = cls; |
487 | char *addr; | ||
488 | size_t alen; | ||
489 | enum GNUNET_NetworkType nt; | ||
490 | struct GNUNET_TIME_Absolute expiration; | ||
491 | struct Hello *hello; | ||
306 | 492 | ||
307 | // FIXME: process hello! | 493 | if (0 != memcmp (&p->pid, |
308 | // check for expiration | 494 | &record->peer, |
309 | // (add to p's doubly-linked list) | 495 | sizeof (struct GNUNET_PeerIdentity))) |
310 | |||
311 | if (NULL == p->task) | ||
312 | { | 496 | { |
313 | // start suggestion task! | 497 | GNUNET_break (0); |
498 | return; | ||
499 | } | ||
500 | if (0 != strcmp (record->key, | ||
501 | GNUNET_HELLO_PEERSTORE_KEY)) | ||
502 | { | ||
503 | GNUNET_break (0); | ||
504 | return; | ||
505 | } | ||
506 | addr = GNUNET_HELLO_extract_address (record->value, | ||
507 | record->value_size, | ||
508 | &p->pid, | ||
509 | &nt, | ||
510 | &expiration); | ||
511 | if (NULL == addr) | ||
512 | return; /* invalid hello, bad signature, other problem */ | ||
513 | if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us) | ||
514 | { | ||
515 | /* expired, ignore */ | ||
516 | GNUNET_free (addr); | ||
517 | return; | ||
518 | } | ||
519 | /* check if addr is already known */ | ||
520 | for (struct Hello *he = p->h_head; | ||
521 | NULL != he; | ||
522 | he = he->next) | ||
523 | { | ||
524 | if (0 != strcmp (he->address, | ||
525 | addr)) | ||
526 | continue; | ||
527 | if (he->expiration.abs_value_us < expiration.abs_value_us) | ||
528 | { | ||
529 | he->expiration = expiration; | ||
530 | he->nt = nt; | ||
531 | } | ||
532 | GNUNET_free (addr); | ||
533 | return; | ||
534 | } | ||
535 | /* create new HELLO */ | ||
536 | alen = strlen (addr) + 1; | ||
537 | hello = GNUNET_malloc (sizeof (struct Hello) + alen); | ||
538 | hello->address = (const char *) &hello[1]; | ||
539 | hello->expiration = expiration; | ||
540 | hello->nt = nt; | ||
541 | hello->peer = p; | ||
542 | memcpy (&hello[1], | ||
543 | addr, | ||
544 | alen); | ||
545 | GNUNET_free (addr); | ||
546 | GNUNET_CONTAINER_DLL_insert (p->h_head, | ||
547 | p->h_tail, | ||
548 | hello); | ||
549 | /* check if sh for this HELLO already exists */ | ||
550 | for (struct GNUNET_ATS_SessionHandle *sh = p->sh_head; | ||
551 | NULL != sh; | ||
552 | sh = sh->next) | ||
553 | { | ||
554 | if ( (NULL == sh->address) || | ||
555 | (0 != strcmp (sh->address, | ||
556 | addr)) ) | ||
557 | continue; | ||
558 | GNUNET_assert (NULL == sh->hello); | ||
559 | sh->hello = hello; | ||
560 | hello->sh = sh; | ||
561 | break; | ||
314 | } | 562 | } |
563 | if (NULL == p->task) | ||
564 | p->task = GNUNET_SCHEDULER_add_now (&suggest_start_cb, | ||
565 | p); | ||
315 | } | 566 | } |
316 | 567 | ||
317 | 568 | ||
@@ -337,7 +588,7 @@ peer_add (struct SimpleHandle *h, | |||
337 | p->wc = GNUNET_PEERSTORE_watch (h->ps, | 588 | p->wc = GNUNET_PEERSTORE_watch (h->ps, |
338 | "transport", | 589 | "transport", |
339 | &p->pid, | 590 | &p->pid, |
340 | "HELLO" /* key */, | 591 | GNUNET_HELLO_PEERSTORE_KEY, |
341 | &watch_cb, | 592 | &watch_cb, |
342 | p); | 593 | p); |
343 | GNUNET_assert (GNUNET_YES == | 594 | GNUNET_assert (GNUNET_YES == |
@@ -390,13 +641,259 @@ peer_free (struct Peer *p) | |||
390 | 641 | ||
391 | 642 | ||
392 | /** | 643 | /** |
644 | * Check if the new allocation for @a sh is significantly different | ||
645 | * from the last one, and if so, tell transport. | ||
646 | * | ||
647 | * @param sh session handle to consider updating transport for | ||
648 | */ | ||
649 | static void | ||
650 | consider_notify_transport (struct GNUNET_ATS_SessionHandle *sh) | ||
651 | { | ||
652 | struct Peer *peer = sh->peer; | ||
653 | struct SimpleHandle *h = peer->h; | ||
654 | enum GNUNET_NetworkType nt = sh->data->prop.nt; | ||
655 | struct GNUNET_TIME_Relative delay; | ||
656 | uint64_t sig_in; | ||
657 | uint64_t sig_out; | ||
658 | int64_t delta_in; | ||
659 | int64_t delta_out; | ||
660 | |||
661 | delay = GNUNET_TIME_absolute_get_duration (sh->last_allocation); | ||
662 | /* A significant change is more than 10% of the quota, | ||
663 | which is given in bytes/second */ | ||
664 | sig_in | ||
665 | = h->networks[nt].total_quota_in * (delay.rel_value_us / 1000LL) / 1000LL / 10; | ||
666 | sig_out | ||
667 | = h->networks[nt].total_quota_out * (delay.rel_value_us / 1000LL) / 1000LL / 10; | ||
668 | delta_in = ( (int64_t) ntohl (sh->bw_in.value__)) - ((int64_t) sh->target_in); | ||
669 | delta_out = ( (int64_t) ntohl (sh->bw_in.value__)) - ((int64_t) sh->target_in); | ||
670 | /* we want the absolute values */ | ||
671 | if (delta_in < 0) | ||
672 | delta_in = - delta_in; | ||
673 | if (INT64_MIN == delta_in) | ||
674 | delta_in = INT64_MAX; /* Handle corner case: INT_MIN == - INT_MIN */ | ||
675 | if (delta_out < 0) | ||
676 | delta_out = - delta_out; | ||
677 | if (INT64_MIN == delta_out) | ||
678 | delta_out = INT64_MAX; /* Handle corner case: INT_MIN == - INT_MIN */ | ||
679 | if ( (sig_in > delta_in) && | ||
680 | (sig_out > delta_out) ) | ||
681 | return; /* insignificant change */ | ||
682 | /* change is significant, tell transport! */ | ||
683 | if (sh->target_in > UINT32_MAX) | ||
684 | sh->target_in = UINT32_MAX; | ||
685 | sh->bw_in.value__ = htonl ((uint32_t) sh->target_in); | ||
686 | if (sh->target_out > UINT32_MAX) | ||
687 | sh->target_out = UINT32_MAX; | ||
688 | sh->bw_out.value__ = htonl ((uint32_t) sh->target_out); | ||
689 | sh->last_allocation = GNUNET_TIME_absolute_get (); | ||
690 | h->env->allocate_cb (h->env->cls, | ||
691 | sh->session, | ||
692 | &peer->pid, | ||
693 | sh->bw_in, | ||
694 | sh->bw_out); | ||
695 | } | ||
696 | |||
697 | |||
698 | /** | ||
699 | * Closure for #update_counters and #update_allocation. | ||
700 | */ | ||
701 | struct Counters | ||
702 | { | ||
703 | /** | ||
704 | * Plugin's state. | ||
705 | */ | ||
706 | struct SimpleHandle *h; | ||
707 | |||
708 | /** | ||
709 | * Bandwidth that applications would prefer to allocate in this | ||
710 | * network type. We initially add all requested allocations to the | ||
711 | * respective network type where the given preference is best | ||
712 | * satisfied. Later we may rebalance. | ||
713 | */ | ||
714 | uint64_t bw_out_by_nt[GNUNET_NT_COUNT]; | ||
715 | |||
716 | /** | ||
717 | * Current bandwidth utilization for this network type. We simply | ||
718 | * add the current goodput up (with some fairness considerations). | ||
719 | */ | ||
720 | uint64_t bw_in_by_nt[GNUNET_NT_COUNT]; | ||
721 | |||
722 | /** | ||
723 | * By how much do we have to scale (up or down) our expectations | ||
724 | * for outbound bandwidth? | ||
725 | */ | ||
726 | double scale_out[GNUNET_NT_COUNT]; | ||
727 | |||
728 | /** | ||
729 | * By how much do we have to scale (up or down) our expectations | ||
730 | * for inbound bandwidth? | ||
731 | */ | ||
732 | double scale_in[GNUNET_NT_COUNT]; | ||
733 | |||
734 | }; | ||
735 | |||
736 | |||
737 | /** | ||
738 | * Function used to iterate over all peers and collect | ||
739 | * counter data. | ||
740 | * | ||
741 | * @param cls a `struct Counters *` | ||
742 | * @param pid identity of the peer we process, unused | ||
743 | * @param value a `struct Peer *` | ||
744 | * @return #GNUNET_YES (continue to iterate) | ||
745 | */ | ||
746 | static int | ||
747 | update_counters (void *cls, | ||
748 | const struct GNUNET_PeerIdentity *pid, | ||
749 | void *value) | ||
750 | { | ||
751 | struct Counters *c = cls; | ||
752 | struct Peer *peer = value; | ||
753 | struct GNUNET_ATS_SessionHandle *best[GNUNET_MQ_PREFERENCE_COUNT]; | ||
754 | |||
755 | (void) pid; | ||
756 | memset (best, | ||
757 | 0, | ||
758 | sizeof (best)); | ||
759 | for (struct GNUNET_ATS_SessionHandle *sh = peer->sh_head; | ||
760 | NULL != sh; | ||
761 | sh = sh->next) | ||
762 | { | ||
763 | enum GNUNET_NetworkType nt = sh->data->prop.nt; | ||
764 | |||
765 | sh->target_out = MIN_BANDWIDTH_PER_SESSION; | ||
766 | c->bw_out_by_nt[nt] += MIN_BANDWIDTH_PER_SESSION; | ||
767 | c->bw_in_by_nt[nt] += GNUNET_MAX (MIN_BANDWIDTH_PER_SESSION, | ||
768 | sh->data->prop.goodput_in); | ||
769 | for (enum GNUNET_MQ_PreferenceKind pk = 0; | ||
770 | pk < GNUNET_MQ_PREFERENCE_COUNT; | ||
771 | pk++) | ||
772 | { | ||
773 | /* General rule: always prefer smaller distance if possible, | ||
774 | otherwise decide by pk: */ | ||
775 | switch (pk) { | ||
776 | case GNUNET_MQ_PREFERENCE_NONE: | ||
777 | break; | ||
778 | case GNUNET_MQ_PREFERENCE_BANDWIDTH: | ||
779 | /* For bandwidth, we compare the sum of transmitted bytes and | ||
780 | confirmed transmitted bytes, so confirmed data counts twice */ | ||
781 | if ( (NULL == best[pk]) || | ||
782 | (sh->data->prop.distance < best[pk]->data->prop.distance) || | ||
783 | (sh->data->prop.utilization_out + sh->data->prop.goodput_out > | ||
784 | best[pk]->data->prop.utilization_out + best[pk]->data->prop.goodput_out) ) | ||
785 | best[pk] = sh; | ||
786 | /* If both are equal (i.e. usually this happens if there is a zero), use | ||
787 | latency as a yardstick */ | ||
788 | if ( (sh->data->prop.utilization_out + sh->data->prop.goodput_out == | ||
789 | best[pk]->data->prop.utilization_out + best[pk]->data->prop.goodput_out) && | ||
790 | (sh->data->prop.distance == best[pk]->data->prop.distance) && | ||
791 | (sh->data->prop.delay.rel_value_us < | ||
792 | best[pk]->data->prop.delay.rel_value_us) ) | ||
793 | best[pk] = sh; | ||
794 | break; | ||
795 | case GNUNET_MQ_PREFERENCE_LATENCY: | ||
796 | if ( (NULL == best[pk]) || | ||
797 | (sh->data->prop.distance < best[pk]->data->prop.distance) || | ||
798 | ( (sh->data->prop.distance == best[pk]->data->prop.distance) && | ||
799 | (sh->data->prop.delay.rel_value_us < | ||
800 | best[pk]->data->prop.delay.rel_value_us) ) ) | ||
801 | best[pk] = sh; | ||
802 | break; | ||
803 | case GNUNET_MQ_PREFERENCE_RELIABILITY: | ||
804 | /* For reliability, we consider the ratio of goodput to utilization | ||
805 | (but use multiplicative formultations to avoid division by zero) */ | ||
806 | if ( (NULL == best[pk]) || | ||
807 | (1ULL * sh->data->prop.goodput_out * best[pk]->data->prop.utilization_out > | ||
808 | 1ULL * sh->data->prop.utilization_out * best[pk]->data->prop.goodput_out) ) | ||
809 | best[pk] = sh; | ||
810 | /* If both are equal (i.e. usually this happens if there is a zero), use | ||
811 | latency as a yardstick */ | ||
812 | if ( (1ULL * sh->data->prop.goodput_out * best[pk]->data->prop.utilization_out == | ||
813 | 1ULL * sh->data->prop.utilization_out * best[pk]->data->prop.goodput_out) && | ||
814 | (sh->data->prop.distance == best[pk]->data->prop.distance) && | ||
815 | (sh->data->prop.delay.rel_value_us < | ||
816 | best[pk]->data->prop.delay.rel_value_us) ) | ||
817 | best[pk] = sh; | ||
818 | break; | ||
819 | } | ||
820 | } | ||
821 | } | ||
822 | /* for first round, assign target bandwidth simply to sum of | ||
823 | requested bandwidth */ | ||
824 | for (enum GNUNET_MQ_PreferenceKind pk = 0; | ||
825 | pk < GNUNET_MQ_PREFERENCE_COUNT; | ||
826 | pk++) | ||
827 | { | ||
828 | enum GNUNET_NetworkType nt = best[pk]->data->prop.nt; | ||
829 | |||
830 | best[pk]->target_out = GNUNET_MIN (peer->bw_by_pk[pk], | ||
831 | MIN_BANDWIDTH_PER_SESSION); | ||
832 | c->bw_out_by_nt[nt] += (uint64_t) (best[pk]->target_out - MIN_BANDWIDTH_PER_SESSION); | ||
833 | } | ||
834 | return GNUNET_YES; | ||
835 | } | ||
836 | |||
837 | |||
838 | /** | ||
839 | * Function used to iterate over all peers and collect | ||
840 | * counter data. | ||
841 | * | ||
842 | * @param cls a `struct Counters *` | ||
843 | * @param pid identity of the peer we process, unused | ||
844 | * @param value a `struct Peer *` | ||
845 | * @return #GNUNET_YES (continue to iterate) | ||
846 | */ | ||
847 | static int | ||
848 | update_allocation (void *cls, | ||
849 | const struct GNUNET_PeerIdentity *pid, | ||
850 | void *value) | ||
851 | { | ||
852 | struct Counters *c = cls; | ||
853 | struct Peer *peer = value; | ||
854 | |||
855 | (void) pid; | ||
856 | for (struct GNUNET_ATS_SessionHandle *sh = peer->sh_head; | ||
857 | NULL != sh; | ||
858 | sh = sh->next) | ||
859 | { | ||
860 | enum GNUNET_NetworkType nt = sh->data->prop.nt; | ||
861 | |||
862 | sh->target_out = (uint64_t) (c->scale_out[nt] * sh->target_out); | ||
863 | sh->target_in = (uint64_t) (c->scale_in[nt] * sh->target_in); | ||
864 | consider_notify_transport (sh); | ||
865 | } | ||
866 | return GNUNET_YES; | ||
867 | } | ||
868 | |||
869 | |||
870 | /** | ||
393 | * The world changed, recalculate our allocations. | 871 | * The world changed, recalculate our allocations. |
394 | */ | 872 | */ |
395 | static void | 873 | static void |
396 | update (struct SimpleHandle *h) | 874 | update (struct SimpleHandle *h) |
397 | { | 875 | { |
398 | // recalculate allocations | 876 | struct Counters cnt = { |
399 | // notify transport if it makes sense (delta significant) | 877 | .h = h |
878 | }; | ||
879 | |||
880 | GNUNET_CONTAINER_multipeermap_iterate (h->peers, | ||
881 | &update_counters, | ||
882 | &cnt); | ||
883 | /* calculate how badly the missmatch between requested | ||
884 | allocations and available bandwidth is per network type */ | ||
885 | for (enum GNUNET_NetworkType nt = 0; | ||
886 | nt < GNUNET_NT_COUNT; | ||
887 | nt++) | ||
888 | { | ||
889 | cnt.scale_out[nt] = 1.0 * cnt.bw_out_by_nt[nt] / h->networks[nt].total_quota_out; | ||
890 | cnt.scale_in[nt] = 1.0 * cnt.bw_in_by_nt[nt] / h->networks[nt].total_quota_in; | ||
891 | } | ||
892 | /* recalculate allocations, considering scaling factor, and | ||
893 | update transport if the change is significant */ | ||
894 | GNUNET_CONTAINER_multipeermap_iterate (h->peers, | ||
895 | &update_allocation, | ||
896 | &cnt); | ||
400 | } | 897 | } |
401 | 898 | ||
402 | 899 | ||
@@ -417,6 +914,7 @@ simple_preference_add (void *cls, | |||
417 | 914 | ||
418 | GNUNET_assert (pref->pk < GNUNET_MQ_PREFERENCE_COUNT); | 915 | GNUNET_assert (pref->pk < GNUNET_MQ_PREFERENCE_COUNT); |
419 | p->bw_by_pk[pref->pk] += ntohl (pref->bw.value__); | 916 | p->bw_by_pk[pref->pk] += ntohl (pref->bw.value__); |
917 | h->bw_by_pk[pref->pk] += ntohl (pref->bw.value__); | ||
420 | update (h); | 918 | update (h); |
421 | return NULL; | 919 | return NULL; |
422 | } | 920 | } |
@@ -442,6 +940,7 @@ simple_preference_del (void *cls, | |||
442 | GNUNET_assert (NULL != p); | 940 | GNUNET_assert (NULL != p); |
443 | GNUNET_assert (pref->pk < GNUNET_MQ_PREFERENCE_COUNT); | 941 | GNUNET_assert (pref->pk < GNUNET_MQ_PREFERENCE_COUNT); |
444 | p->bw_by_pk[pref->pk] -= ntohl (pref->bw.value__); | 942 | p->bw_by_pk[pref->pk] -= ntohl (pref->bw.value__); |
943 | h->bw_by_pk[pref->pk] -= ntohl (pref->bw.value__); | ||
445 | if ( (0 == p->bw_by_pk[pref->pk]) && | 944 | if ( (0 == p->bw_by_pk[pref->pk]) && |
446 | (GNUNET_YES == peer_test_dead (p)) ) | 945 | (GNUNET_YES == peer_test_dead (p)) ) |
447 | peer_free (p); | 946 | peer_free (p); |
@@ -502,6 +1001,7 @@ simple_session_add (void *cls, | |||
502 | if (NULL != hello) | 1001 | if (NULL != hello) |
503 | { | 1002 | { |
504 | hello->sh = sh; | 1003 | hello->sh = sh; |
1004 | hello->backoff = GNUNET_TIME_UNIT_ZERO; | ||
505 | sh->hello = hello; | 1005 | sh->hello = hello; |
506 | } | 1006 | } |
507 | update (h); | 1007 | update (h); |
@@ -543,11 +1043,24 @@ simple_session_del (void *cls, | |||
543 | { | 1043 | { |
544 | struct SimpleHandle *h = cls; | 1044 | struct SimpleHandle *h = cls; |
545 | struct Peer *p = sh->peer; | 1045 | struct Peer *p = sh->peer; |
1046 | struct Hello *hello = sh->hello; | ||
546 | 1047 | ||
547 | // FIXME: tear down session | 1048 | /* clean up sh */ |
548 | // del peer if otherwise dead | 1049 | GNUNET_CONTAINER_DLL_remove (p->sh_head, |
549 | 1050 | p->sh_tail, | |
550 | 1051 | sh); | |
1052 | if (NULL != hello) | ||
1053 | { | ||
1054 | GNUNET_assert (sh == hello->sh); | ||
1055 | hello->sh = NULL; | ||
1056 | /* session went down, if necessary restart suggesting | ||
1057 | addresses */ | ||
1058 | if (NULL == p->task) | ||
1059 | p->task = GNUNET_SCHEDULER_add_now (&suggest_start_cb, | ||
1060 | p); | ||
1061 | } | ||
1062 | GNUNET_free (sh); | ||
1063 | /* del peer if otherwise dead */ | ||
551 | if ( (NULL == p->sh_head) && | 1064 | if ( (NULL == p->sh_head) && |
552 | (GNUNET_YES == peer_test_dead (p)) ) | 1065 | (GNUNET_YES == peer_test_dead (p)) ) |
553 | peer_free (p); | 1066 | peer_free (p); |
@@ -619,7 +1132,8 @@ libgnunet_plugin_ats2_simple_done (void *cls) | |||
619 | struct GNUNET_ATS_SolverFunctions *sf = cls; | 1132 | struct GNUNET_ATS_SolverFunctions *sf = cls; |
620 | struct SimpleHandle *s = sf->cls; | 1133 | struct SimpleHandle *s = sf->cls; |
621 | 1134 | ||
622 | // FIXME: iterate over peers and clean up! | 1135 | GNUNET_break (0 == |
1136 | GNUNET_CONTAINER_multipeermap_size (s->peers)); | ||
623 | GNUNET_CONTAINER_multipeermap_destroy (s->peers); | 1137 | GNUNET_CONTAINER_multipeermap_destroy (s->peers); |
624 | GNUNET_PEERSTORE_disconnect (s->ps, | 1138 | GNUNET_PEERSTORE_disconnect (s->ps, |
625 | GNUNET_NO); | 1139 | GNUNET_NO); |
diff --git a/src/hello/hello-ng.c b/src/hello/hello-ng.c index a16ceb944..723ec0eaa 100644 --- a/src/hello/hello-ng.c +++ b/src/hello/hello-ng.c | |||
@@ -101,7 +101,7 @@ GNUNET_HELLO_sign_address (const char *address, | |||
101 | * | 101 | * |
102 | * @param raw raw signed address | 102 | * @param raw raw signed address |
103 | * @param raw_size size of @a raw | 103 | * @param raw_size size of @a raw |
104 | * @param public_key public key to use for signature verification | 104 | * @param pid public key to use for signature verification |
105 | * @param nt[out] set to network type | 105 | * @param nt[out] set to network type |
106 | * @param expiration[out] how long is the address valid | 106 | * @param expiration[out] how long is the address valid |
107 | * @return NULL on error, otherwise the address | 107 | * @return NULL on error, otherwise the address |
@@ -109,10 +109,11 @@ GNUNET_HELLO_sign_address (const char *address, | |||
109 | char * | 109 | char * |
110 | GNUNET_HELLO_extract_address (const void *raw, | 110 | GNUNET_HELLO_extract_address (const void *raw, |
111 | size_t raw_size, | 111 | size_t raw_size, |
112 | const struct GNUNET_CRYPTO_EddsaPublicKey *public_key, | 112 | const struct GNUNET_PeerIdentity *pid, |
113 | enum GNUNET_NetworkType *nt, | 113 | enum GNUNET_NetworkType *nt, |
114 | struct GNUNET_TIME_Absolute *expiration) | 114 | struct GNUNET_TIME_Absolute *expiration) |
115 | { | 115 | { |
116 | const struct GNUNET_CRYPTO_EddsaPublicKey *public_key = &pid->public_key; | ||
116 | const char *raws = raw; | 117 | const char *raws = raw; |
117 | unsigned long long raw_us; | 118 | unsigned long long raw_us; |
118 | unsigned int raw_nt; | 119 | unsigned int raw_nt; |
diff --git a/src/include/gnunet_hello_lib.h b/src/include/gnunet_hello_lib.h index 8a405a25e..a47162f99 100644 --- a/src/include/gnunet_hello_lib.h +++ b/src/include/gnunet_hello_lib.h | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | */ | 17 | */ |
@@ -476,6 +476,10 @@ GNUNET_HELLO_parse_uri (const char *uri, | |||
476 | /* NG API */ | 476 | /* NG API */ |
477 | #include "gnunet_nt_lib.h" | 477 | #include "gnunet_nt_lib.h" |
478 | 478 | ||
479 | /** | ||
480 | * Key used for storing HELLOs in the peerstore | ||
481 | */ | ||
482 | #define GNUNET_HELLO_PEERSTORE_KEY "hello" | ||
479 | 483 | ||
480 | /** | 484 | /** |
481 | * Build address record by signing raw information with private key. | 485 | * Build address record by signing raw information with private key. |
@@ -501,7 +505,7 @@ GNUNET_HELLO_sign_address (const char *address, | |||
501 | * | 505 | * |
502 | * @param raw raw signed address | 506 | * @param raw raw signed address |
503 | * @param raw_size size of @a raw | 507 | * @param raw_size size of @a raw |
504 | * @param public_key public key to use for signature verification | 508 | * @param pid public key to use for signature verification |
505 | * @param nt[out] set to network type | 509 | * @param nt[out] set to network type |
506 | * @param expiration[out] how long is the address valid | 510 | * @param expiration[out] how long is the address valid |
507 | * @return NULL on error, otherwise the address | 511 | * @return NULL on error, otherwise the address |
@@ -509,7 +513,7 @@ GNUNET_HELLO_sign_address (const char *address, | |||
509 | char * | 513 | char * |
510 | GNUNET_HELLO_extract_address (const void *raw, | 514 | GNUNET_HELLO_extract_address (const void *raw, |
511 | size_t raw_size, | 515 | size_t raw_size, |
512 | const struct GNUNET_CRYPTO_EddsaPublicKey *public_key, | 516 | const struct GNUNET_PeerIdentity *pid, |
513 | enum GNUNET_NetworkType *nt, | 517 | enum GNUNET_NetworkType *nt, |
514 | struct GNUNET_TIME_Absolute *expiration); | 518 | struct GNUNET_TIME_Absolute *expiration); |
515 | 519 | ||
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c index feaa0cfff..3630e6af0 100644 --- a/src/transport/gnunet-service-tng.c +++ b/src/transport/gnunet-service-tng.c | |||
@@ -1196,7 +1196,7 @@ store_pi (void *cls) | |||
1196 | ale->sc = GNUNET_PEERSTORE_store (peerstore, | 1196 | ale->sc = GNUNET_PEERSTORE_store (peerstore, |
1197 | "transport", | 1197 | "transport", |
1198 | &GST_my_identity, | 1198 | &GST_my_identity, |
1199 | "hello", | 1199 | GNUNET_HELLO_PEERSTORE_KEY, |
1200 | addr, | 1200 | addr, |
1201 | addr_len, | 1201 | addr_len, |
1202 | expiration, | 1202 | expiration, |