diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2013-05-28 09:34:50 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2013-05-28 09:34:50 +0000 |
commit | eaea0bc446148dd6e211d13a15457c77b879f3a1 (patch) | |
tree | 795195d5b927c59f8a0388357ec506be2e84d6f6 | |
parent | 51f0c7e4b5a2e0d51ef419394f1cc057746eb7c8 (diff) | |
download | gnunet-eaea0bc446148dd6e211d13a15457c77b879f3a1.tar.gz gnunet-eaea0bc446148dd6e211d13a15457c77b879f3a1.zip |
changes``
-rw-r--r-- | src/experimentation/gnunet-daemon-experimentation.h | 35 | ||||
-rw-r--r-- | src/experimentation/gnunet-daemon-experimentation_nodes.c | 112 |
2 files changed, 125 insertions, 22 deletions
diff --git a/src/experimentation/gnunet-daemon-experimentation.h b/src/experimentation/gnunet-daemon-experimentation.h index 4a7e62028..181256b94 100644 --- a/src/experimentation/gnunet-daemon-experimentation.h +++ b/src/experimentation/gnunet-daemon-experimentation.h | |||
@@ -64,6 +64,10 @@ extern struct GNUNET_CONFIGURATION_Handle *GSE_cfg; | |||
64 | extern uint32_t GSE_node_capabilities; | 64 | extern uint32_t GSE_node_capabilities; |
65 | 65 | ||
66 | 66 | ||
67 | extern uint32_t GSE_my_issuer_count; | ||
68 | |||
69 | extern struct Experimentation_Request_Issuer *GSE_my_issuer; | ||
70 | |||
67 | /** | 71 | /** |
68 | * Capabilities a node has or an experiment requires | 72 | * Capabilities a node has or an experiment requires |
69 | */ | 73 | */ |
@@ -147,18 +151,42 @@ struct Node | |||
147 | */ | 151 | */ |
148 | struct GNUNET_CORE_TransmitHandle *cth; | 152 | struct GNUNET_CORE_TransmitHandle *cth; |
149 | 153 | ||
154 | /** | ||
155 | * Node capabilities | ||
156 | */ | ||
150 | uint32_t capabilities; | 157 | uint32_t capabilities; |
158 | |||
159 | /* Experiment version as timestamp of creation */ | ||
160 | struct GNUNET_TIME_Absolute version; | ||
161 | |||
162 | uint32_t issuer_count; | ||
163 | |||
164 | /** | ||
165 | * Array of fssuer ids | ||
166 | */ | ||
167 | struct GNUNET_PeerIdentity *issuer_id; | ||
168 | }; | ||
169 | |||
170 | struct Experimentation_Request_Issuer | ||
171 | { | ||
172 | struct GNUNET_PeerIdentity issuer_id; | ||
151 | }; | 173 | }; |
152 | 174 | ||
153 | /** | 175 | /** |
154 | * Experimentation request message | 176 | * Experimentation request message |
155 | * Used to detect experimentation capability | 177 | * Used to detect experimentation capability |
178 | * | ||
179 | * This struct is followed by issuer identities: | ||
180 | * (issuer_count * struct Experimentation_Request_Issuer) | ||
181 | * | ||
156 | */ | 182 | */ |
157 | struct Experimentation_Request | 183 | struct Experimentation_Request |
158 | { | 184 | { |
159 | struct GNUNET_MessageHeader msg; | 185 | struct GNUNET_MessageHeader msg; |
160 | 186 | ||
161 | uint32_t capabilities; | 187 | uint32_t capabilities; |
188 | |||
189 | uint32_t issuer_count; | ||
162 | }; | 190 | }; |
163 | 191 | ||
164 | /** | 192 | /** |
@@ -231,6 +259,13 @@ int | |||
231 | GNUNET_EXPERIMENTATION_experiments_issuer_accepted (struct GNUNET_PeerIdentity *issuer_ID); | 259 | GNUNET_EXPERIMENTATION_experiments_issuer_accepted (struct GNUNET_PeerIdentity *issuer_ID); |
232 | 260 | ||
233 | 261 | ||
262 | typedef void (*GNUNET_EXPERIMENTATION_experiments_get_cb) (struct Node *n, struct Experiment *e); | ||
263 | |||
264 | void | ||
265 | GNUNET_EXPERIMENTATION_experiments_get (struct Node *n, | ||
266 | struct GNUNET_PeerIdentity *issuer, | ||
267 | GNUNET_EXPERIMENTATION_experiments_get_cb get_cb); | ||
268 | |||
234 | /** | 269 | /** |
235 | * Start experiments management | 270 | * Start experiments management |
236 | * | 271 | * |
diff --git a/src/experimentation/gnunet-daemon-experimentation_nodes.c b/src/experimentation/gnunet-daemon-experimentation_nodes.c index 266f82ce3..9d96bfa2d 100644 --- a/src/experimentation/gnunet-daemon-experimentation_nodes.c +++ b/src/experimentation/gnunet-daemon-experimentation_nodes.c | |||
@@ -121,7 +121,7 @@ cleanup_nodes (void *cls, | |||
121 | GNUNET_CORE_notify_transmit_ready_cancel (n->cth); | 121 | GNUNET_CORE_notify_transmit_ready_cancel (n->cth); |
122 | n->cth = NULL; | 122 | n->cth = NULL; |
123 | } | 123 | } |
124 | 124 | GNUNET_free_non_null (n->issuer_id); | |
125 | 125 | ||
126 | GNUNET_CONTAINER_multihashmap_remove (cur, key, value); | 126 | GNUNET_CONTAINER_multihashmap_remove (cur, key, value); |
127 | GNUNET_free (value); | 127 | GNUNET_free (value); |
@@ -203,8 +203,11 @@ size_t send_request_cb (void *cls, size_t bufsize, void *buf) | |||
203 | { | 203 | { |
204 | struct Node *n = cls; | 204 | struct Node *n = cls; |
205 | struct Experimentation_Request msg; | 205 | struct Experimentation_Request msg; |
206 | size_t size = sizeof (msg); | 206 | size_t msg_size = sizeof (msg); |
207 | size_t ri_size = sizeof (struct Experimentation_Request_Issuer) * GSE_my_issuer_count; | ||
208 | size_t total_size = msg_size + ri_size; | ||
207 | 209 | ||
210 | memset (buf, '0', bufsize); | ||
208 | n->cth = NULL; | 211 | n->cth = NULL; |
209 | if (buf == NULL) | 212 | if (buf == NULL) |
210 | { | 213 | { |
@@ -215,16 +218,18 @@ size_t send_request_cb (void *cls, size_t bufsize, void *buf) | |||
215 | GNUNET_SCHEDULER_add_now (&remove_request, n); | 218 | GNUNET_SCHEDULER_add_now (&remove_request, n); |
216 | return 0; | 219 | return 0; |
217 | } | 220 | } |
218 | GNUNET_assert (bufsize >= size); | 221 | GNUNET_assert (bufsize >= total_size); |
219 | 222 | ||
220 | msg.msg.size = htons (size); | 223 | msg.msg.size = htons (total_size); |
221 | msg.msg.type = htons (GNUNET_MESSAGE_TYPE_EXPERIMENTATION_REQUEST); | 224 | msg.msg.type = htons (GNUNET_MESSAGE_TYPE_EXPERIMENTATION_REQUEST); |
222 | msg.capabilities = htonl (GSE_node_capabilities); | 225 | msg.capabilities = htonl (GSE_node_capabilities); |
223 | memcpy (buf, &msg, size); | 226 | msg.issuer_count = htonl (GSE_my_issuer_count); |
227 | memcpy (buf, &msg, msg_size); | ||
228 | memcpy (&buf[msg_size], GSE_my_issuer, ri_size); | ||
224 | 229 | ||
225 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Sending request to peer %s\n"), | 230 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Sending request to peer %s\n"), |
226 | GNUNET_i2s (&n->id)); | 231 | GNUNET_i2s (&n->id)); |
227 | return size; | 232 | return total_size; |
228 | } | 233 | } |
229 | 234 | ||
230 | 235 | ||
@@ -237,19 +242,22 @@ static void send_request (const struct GNUNET_PeerIdentity *peer) | |||
237 | { | 242 | { |
238 | struct Node *n; | 243 | struct Node *n; |
239 | size_t size; | 244 | size_t size; |
245 | size_t c_issuers; | ||
240 | 246 | ||
241 | size = sizeof (struct Experimentation_Request); | 247 | c_issuers = GSE_my_issuer_count; |
248 | |||
249 | size = sizeof (struct Experimentation_Request) + | ||
250 | c_issuers * sizeof (struct Experimentation_Request_Issuer); | ||
242 | n = GNUNET_malloc (sizeof (struct Node)); | 251 | n = GNUNET_malloc (sizeof (struct Node)); |
243 | n->id = *peer; | 252 | n->id = *peer; |
244 | n->timeout_task = GNUNET_SCHEDULER_add_delayed (EXP_RESPONSE_TIMEOUT, &remove_request, n); | 253 | n->timeout_task = GNUNET_SCHEDULER_add_delayed (EXP_RESPONSE_TIMEOUT, &remove_request, n); |
254 | n->capabilities = NONE; | ||
245 | n->cth = GNUNET_CORE_notify_transmit_ready(ch, GNUNET_NO, 0, | 255 | n->cth = GNUNET_CORE_notify_transmit_ready(ch, GNUNET_NO, 0, |
246 | GNUNET_TIME_relative_get_forever_(), | 256 | GNUNET_TIME_relative_get_forever_(), |
247 | peer, size, send_request_cb, n); | 257 | peer, size, send_request_cb, n); |
248 | n->capabilities = NONE; | ||
249 | 258 | ||
250 | GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (nodes_requested, | 259 | GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (nodes_requested, |
251 | &peer->hashPubKey, n, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); | 260 | &peer->hashPubKey, n, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); |
252 | |||
253 | update_stats (nodes_requested); | 261 | update_stats (nodes_requested); |
254 | } | 262 | } |
255 | 263 | ||
@@ -288,6 +296,23 @@ size_t send_response_cb (void *cls, size_t bufsize, void *buf) | |||
288 | } | 296 | } |
289 | 297 | ||
290 | 298 | ||
299 | static void | ||
300 | get_experiments_cb (struct Node *n, struct Experiment *e) | ||
301 | { | ||
302 | static int counter = 0; | ||
303 | if (NULL == e) | ||
304 | { | ||
305 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Added %u experiments for peer %s\n"), | ||
306 | counter, GNUNET_i2s (&n->id)); | ||
307 | return; | ||
308 | } | ||
309 | |||
310 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Scheduling experiment `%s' for peer %s\n"), | ||
311 | GNUNET_i2s (&n->id)); | ||
312 | GNUNET_EXPERIMENTATION_scheduler_add (e); | ||
313 | counter ++; | ||
314 | } | ||
315 | |||
291 | /** | 316 | /** |
292 | * Set a specific node as active | 317 | * Set a specific node as active |
293 | * | 318 | * |
@@ -295,11 +320,16 @@ size_t send_response_cb (void *cls, size_t bufsize, void *buf) | |||
295 | */ | 320 | */ |
296 | static void node_make_active (struct Node *n) | 321 | static void node_make_active (struct Node *n) |
297 | { | 322 | { |
323 | int c1; | ||
298 | GNUNET_CONTAINER_multihashmap_put (nodes_active, | 324 | GNUNET_CONTAINER_multihashmap_put (nodes_active, |
299 | &n->id.hashPubKey, n, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | 325 | &n->id.hashPubKey, n, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); |
300 | update_stats (nodes_active); | 326 | update_stats (nodes_active); |
301 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Added peer `%s' as active node\n"), | 327 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Added peer `%s' as active node\n"), |
302 | GNUNET_i2s (&n->id)); | 328 | GNUNET_i2s (&n->id)); |
329 | |||
330 | /* Request experiments for this node to start them */ | ||
331 | for (c1 = 0; c1 < n->issuer_count; c1++) | ||
332 | GNUNET_EXPERIMENTATION_experiments_get (n, &n->issuer_id[c1], &get_experiments_cb); | ||
303 | } | 333 | } |
304 | 334 | ||
305 | 335 | ||
@@ -314,18 +344,32 @@ static void handle_request (const struct GNUNET_PeerIdentity *peer, | |||
314 | { | 344 | { |
315 | struct Node *n; | 345 | struct Node *n; |
316 | struct Experimentation_Request *rm = (struct Experimentation_Request *) message; | 346 | struct Experimentation_Request *rm = (struct Experimentation_Request *) message; |
347 | struct Experimentation_Request_Issuer *rmi = (struct Experimentation_Request_Issuer *) &rm[1]; | ||
348 | int c1; | ||
349 | int c2; | ||
350 | uint32_t ic; | ||
351 | uint32_t ic_accepted; | ||
352 | int make_active; | ||
353 | |||
354 | if (ntohs (message->size) < sizeof (struct Experimentation_Request)) | ||
355 | { | ||
356 | GNUNET_break (0); | ||
357 | return; | ||
358 | } | ||
359 | ic = ntohl (rm->issuer_count); | ||
360 | if (ntohs (message->size) != sizeof (struct Experimentation_Request) + ic * sizeof (struct Experimentation_Request_Issuer)) | ||
361 | { | ||
362 | GNUNET_break (0); | ||
363 | return; | ||
364 | } | ||
317 | 365 | ||
366 | make_active = GNUNET_NO; | ||
318 | if (NULL != (n = GNUNET_CONTAINER_multihashmap_get (nodes_active, &peer->hashPubKey))) | 367 | if (NULL != (n = GNUNET_CONTAINER_multihashmap_get (nodes_active, &peer->hashPubKey))) |
319 | { | 368 | { |
320 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from %s peer `%s'\n"), | 369 | /* Nothing to do */ |
321 | "REQUEST", "active", GNUNET_i2s (peer)); | ||
322 | n->capabilities = ntohl (rm->capabilities); | ||
323 | } | 370 | } |
324 | else if (NULL != (n = GNUNET_CONTAINER_multihashmap_get (nodes_requested, &peer->hashPubKey))) | 371 | else if (NULL != (n = GNUNET_CONTAINER_multihashmap_get (nodes_requested, &peer->hashPubKey))) |
325 | { | 372 | { |
326 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from %s peer `%s'\n"), | ||
327 | "REQUEST", "requested", GNUNET_i2s (peer)); | ||
328 | n->capabilities = ntohl (rm->capabilities); | ||
329 | GNUNET_CONTAINER_multihashmap_remove (nodes_requested, &peer->hashPubKey, n); | 373 | GNUNET_CONTAINER_multihashmap_remove (nodes_requested, &peer->hashPubKey, n); |
330 | if (GNUNET_SCHEDULER_NO_TASK != n->timeout_task) | 374 | if (GNUNET_SCHEDULER_NO_TASK != n->timeout_task) |
331 | { | 375 | { |
@@ -342,12 +386,9 @@ static void handle_request (const struct GNUNET_PeerIdentity *peer, | |||
342 | } | 386 | } |
343 | else if (NULL != (n = GNUNET_CONTAINER_multihashmap_get (nodes_inactive, &peer->hashPubKey))) | 387 | else if (NULL != (n = GNUNET_CONTAINER_multihashmap_get (nodes_inactive, &peer->hashPubKey))) |
344 | { | 388 | { |
345 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from %s peer `%s'\n"), | ||
346 | "REQUEST", "inactive", GNUNET_i2s (peer)); | ||
347 | n->capabilities = ntohl (rm->capabilities); | ||
348 | GNUNET_CONTAINER_multihashmap_remove (nodes_inactive, &peer->hashPubKey, n); | 389 | GNUNET_CONTAINER_multihashmap_remove (nodes_inactive, &peer->hashPubKey, n); |
349 | update_stats (nodes_inactive); | 390 | update_stats (nodes_inactive); |
350 | node_make_active (n); | 391 | make_active = GNUNET_YES; |
351 | } | 392 | } |
352 | else | 393 | else |
353 | { | 394 | { |
@@ -355,11 +396,38 @@ static void handle_request (const struct GNUNET_PeerIdentity *peer, | |||
355 | n = GNUNET_malloc (sizeof (struct Node)); | 396 | n = GNUNET_malloc (sizeof (struct Node)); |
356 | n->id = *peer; | 397 | n->id = *peer; |
357 | n->capabilities = NONE; | 398 | n->capabilities = NONE; |
358 | n->capabilities = ntohl (rm->capabilities); | ||
359 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received %s from %s peer `%s'\n"), | ||
360 | "REQUEST", "new", GNUNET_i2s (peer)); | ||
361 | node_make_active (n); | 399 | node_make_active (n); |
362 | } | 400 | } |
401 | |||
402 | /* Update node */ | ||
403 | n->capabilities = ntohl (rm->capabilities); | ||
404 | |||
405 | /* Filter accepted issuer */ | ||
406 | ic_accepted = 0; | ||
407 | for (c1 = 0; c1 < ic; c1++) | ||
408 | { | ||
409 | if (GNUNET_YES == GNUNET_EXPERIMENTATION_experiments_issuer_accepted(&rmi[c1].issuer_id)) | ||
410 | ic_accepted ++; | ||
411 | } | ||
412 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Request from peer `%s' with %u issuers, we accepted %u issuer \n"), | ||
413 | GNUNET_i2s (peer), ic, ic_accepted); | ||
414 | GNUNET_free_non_null (n->issuer_id); | ||
415 | n->issuer_id = GNUNET_malloc (ic_accepted * sizeof (struct GNUNET_PeerIdentity)); | ||
416 | c2 = 0; | ||
417 | for (c1 = 0; c1 < ic; c1++) | ||
418 | { | ||
419 | if (GNUNET_YES == GNUNET_EXPERIMENTATION_experiments_issuer_accepted(&rmi[c1].issuer_id)) | ||
420 | { | ||
421 | n->issuer_id[c2] = rmi[c1].issuer_id; | ||
422 | c2 ++; | ||
423 | } | ||
424 | } | ||
425 | n->issuer_count = ic_accepted; | ||
426 | |||
427 | if (GNUNET_YES == make_active) | ||
428 | node_make_active (n); | ||
429 | |||
430 | /* Send response */ | ||
363 | n->cth = GNUNET_CORE_notify_transmit_ready (ch, GNUNET_NO, 0, | 431 | n->cth = GNUNET_CORE_notify_transmit_ready (ch, GNUNET_NO, 0, |
364 | GNUNET_TIME_relative_get_forever_(), | 432 | GNUNET_TIME_relative_get_forever_(), |
365 | peer, sizeof (struct Experimentation_Response), | 433 | peer, sizeof (struct Experimentation_Response), |