diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-01-18 12:58:16 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-01-18 12:58:16 +0000 |
commit | 41fb4bc77ef852602063c1723366314ccbefc0a6 (patch) | |
tree | 0d06aaa0076c543c9a073828c04c6c699f8778c4 /src/ats/ats_api_scheduling.c | |
parent | 9fae47e9f9555b5d7a10b86b7f2de5cd9e6c0c1c (diff) | |
download | gnunet-41fb4bc77ef852602063c1723366314ccbefc0a6.tar.gz gnunet-41fb4bc77ef852602063c1723366314ccbefc0a6.zip |
always use a slot, even if the session is NULL, simplify logic and document what still needs to be fixed
Diffstat (limited to 'src/ats/ats_api_scheduling.c')
-rw-r--r-- | src/ats/ats_api_scheduling.c | 588 |
1 files changed, 269 insertions, 319 deletions
diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c index 08155eaef..7e44a8660 100644 --- a/src/ats/ats_api_scheduling.c +++ b/src/ats/ats_api_scheduling.c | |||
@@ -40,24 +40,57 @@ | |||
40 | 40 | ||
41 | 41 | ||
42 | /** | 42 | /** |
43 | * Information we track per session. | 43 | * Information we track per address. |
44 | * FIXME: but what about *incoming* connections? | ||
45 | * "address" tells us about those, those | ||
46 | * are only valid while we have a session. | ||
47 | * Need to clarify all this!!! | ||
44 | */ | 48 | */ |
45 | struct SessionRecord | 49 | struct GNUNET_ATS_AddressRecord |
46 | { | 50 | { |
47 | /** | 51 | /** |
48 | * Identity of the peer (just needed for error checking). | 52 | * Address data. |
49 | */ | 53 | */ |
50 | struct GNUNET_PeerIdentity peer; | 54 | struct GNUNET_HELLO_Address *address; |
51 | 55 | ||
52 | /** | 56 | /** |
53 | * Session handle. | 57 | * Session handle. NULL if we have an address but no |
58 | * active session for this address. | ||
54 | */ | 59 | */ |
55 | struct Session *session; | 60 | struct Session *session; |
56 | 61 | ||
57 | /** | 62 | /** |
58 | * Set to #GNUNET_YES if the slot is used. | 63 | * Array with performance data about the address. |
59 | */ | 64 | */ |
60 | int slot_used; | 65 | struct GNUNET_ATS_Information *ats; |
66 | |||
67 | /** | ||
68 | * Number of entries in @e ats. | ||
69 | */ | ||
70 | uint32_t ats_count; | ||
71 | |||
72 | /** | ||
73 | * Which slot (index) in the session array does | ||
74 | * this record correspond to? FIXME: | ||
75 | * FIXME: a linear search on this is really crappy! | ||
76 | * Maybe switch to a 64-bit global counter and be | ||
77 | * done with it? Or does that then cause too much | ||
78 | * trouble on the ATS-service side? | ||
79 | */ | ||
80 | uint32_t slot; | ||
81 | |||
82 | /** | ||
83 | * Is this address currently in use? | ||
84 | * FIXME: document what "in use" means, and why it | ||
85 | * is important! | ||
86 | */ | ||
87 | int in_use; | ||
88 | |||
89 | /** | ||
90 | * We're about to destroy this address record, just ATS does | ||
91 | * not know this yet. | ||
92 | */ | ||
93 | int in_destroy; | ||
61 | }; | 94 | }; |
62 | 95 | ||
63 | 96 | ||
@@ -162,7 +195,7 @@ struct GNUNET_ATS_SchedulingHandle | |||
162 | * network). Index 0 is always NULL and reserved to represent the NULL pointer. | 195 | * network). Index 0 is always NULL and reserved to represent the NULL pointer. |
163 | * Unused entries are also NULL. | 196 | * Unused entries are also NULL. |
164 | */ | 197 | */ |
165 | struct SessionRecord *session_array; | 198 | struct GNUNET_ATS_AddressRecord **session_array; |
166 | 199 | ||
167 | /** | 200 | /** |
168 | * Task to trigger reconnect. | 201 | * Task to trigger reconnect. |
@@ -240,14 +273,12 @@ force_reconnect (struct GNUNET_ATS_SchedulingHandle *sh) | |||
240 | * @param peer peer the session belongs to | 273 | * @param peer peer the session belongs to |
241 | * @return the session object (or NULL) | 274 | * @return the session object (or NULL) |
242 | */ | 275 | */ |
243 | static struct Session * | 276 | static struct GNUNET_ATS_AddressRecord * |
244 | find_session (struct GNUNET_ATS_SchedulingHandle *sh, | 277 | find_session (struct GNUNET_ATS_SchedulingHandle *sh, |
245 | uint32_t session_id, | 278 | uint32_t session_id, |
246 | const struct GNUNET_PeerIdentity *peer) | 279 | const struct GNUNET_PeerIdentity *peer) |
247 | { | 280 | { |
248 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", | 281 | struct GNUNET_ATS_AddressRecord *ar; |
249 | "Find session %u from peer %s in %p\n", | ||
250 | (unsigned int) session_id, GNUNET_i2s (peer), sh); | ||
251 | 282 | ||
252 | if (session_id >= sh->session_array_size) | 283 | if (session_id >= sh->session_array_size) |
253 | { | 284 | { |
@@ -256,90 +287,58 @@ find_session (struct GNUNET_ATS_SchedulingHandle *sh, | |||
256 | } | 287 | } |
257 | if (0 == session_id) | 288 | if (0 == session_id) |
258 | return NULL; | 289 | return NULL; |
259 | if (sh->session_array[session_id].session == NULL) | 290 | ar = sh->session_array[session_id]; |
291 | if (NULL == ar) | ||
260 | { | 292 | { |
261 | GNUNET_break (0 == | 293 | GNUNET_break (0); |
262 | memcmp (peer, &sh->session_array[session_id].peer, | ||
263 | sizeof (struct GNUNET_PeerIdentity))); | ||
264 | return NULL; | 294 | return NULL; |
265 | } | 295 | } |
266 | 296 | if (NULL == ar->address) | |
267 | if (0 != | ||
268 | memcmp (peer, &sh->session_array[session_id].peer, | ||
269 | sizeof (struct GNUNET_PeerIdentity))) | ||
270 | { | 297 | { |
271 | GNUNET_break (0); | 298 | /* address was destroyed in the meantime, this can happen |
272 | force_reconnect (sh); | 299 | as we communicate asynchronously with the ATS service. */ |
273 | return NULL; | 300 | return NULL; |
274 | } | 301 | } |
275 | /* This check exploits the fact that first field of a session object | 302 | if (0 != memcmp (peer, |
276 | * is peer identity. | 303 | &ar->address->peer, |
277 | */ | 304 | sizeof (struct GNUNET_PeerIdentity))) |
278 | if (0 != | ||
279 | memcmp (peer, sh->session_array[session_id].session, | ||
280 | sizeof (struct GNUNET_PeerIdentity))) | ||
281 | { | 305 | { |
282 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
283 | "ats-scheduling-api", | ||
284 | "Session %p belongs to peer `%s'\n", | ||
285 | sh->session_array[session_id].session, | ||
286 | GNUNET_i2s_full ((struct GNUNET_PeerIdentity *) &sh->session_array[session_id].peer)); | ||
287 | /* | ||
288 | GNUNET_break (0); | 306 | GNUNET_break (0); |
289 | sh->reconnect = GNUNET_YES; | 307 | force_reconnect (sh); |
290 | return NULL; | 308 | return NULL; |
291 | */ | ||
292 | } | 309 | } |
293 | return sh->session_array[session_id].session; | 310 | return ar; |
294 | } | 311 | } |
295 | 312 | ||
296 | 313 | ||
297 | /** | 314 | /** |
298 | * Get an available session ID for the given session object. | 315 | * Get an available session ID. |
299 | * | 316 | * |
300 | * @param sh our handle | 317 | * @param sh our handle |
301 | * @param session session object | 318 | * @return an unused slot, but never NOT_FOUND (0) |
302 | * @param peer peer the session belongs to | ||
303 | * @return the session id | ||
304 | */ | 319 | */ |
305 | static uint32_t | 320 | static uint32_t |
306 | find_empty_session_slot (struct GNUNET_ATS_SchedulingHandle *sh, | 321 | find_empty_session_slot (struct GNUNET_ATS_SchedulingHandle *sh) |
307 | struct Session *session, | ||
308 | const struct GNUNET_PeerIdentity *peer) | ||
309 | { | 322 | { |
310 | unsigned int i; | 323 | static uint32_t off; |
311 | unsigned int f; | 324 | uint32_t i; |
312 | 325 | ||
313 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 326 | i = 0; |
314 | "ats-scheduling-api", | 327 | while ( ( (NOT_FOUND == off) || |
315 | "Get session ID for session %p from peer %s in %p\n", | 328 | (NULL != sh->session_array[off % sh->session_array_size]) ) && |
316 | session, | 329 | (i < sh->session_array_size) ) |
317 | GNUNET_i2s (peer), | ||
318 | sh); | ||
319 | if (NULL == session) | ||
320 | return NOT_FOUND; | ||
321 | f = 0; | ||
322 | for (i = 1; i < sh->session_array_size; i++) | ||
323 | { | ||
324 | if ((f == 0) && (sh->session_array[i].slot_used == GNUNET_NO)) | ||
325 | f = i; | ||
326 | } | ||
327 | if (f == 0) | ||
328 | { | 330 | { |
329 | f = sh->session_array_size; | 331 | off++; |
330 | GNUNET_array_grow (sh->session_array, sh->session_array_size, | 332 | i++; |
331 | sh->session_array_size * 2); | ||
332 | } | 333 | } |
333 | GNUNET_assert (f > 0); | 334 | if ( (NOT_FOUND != off) && |
334 | sh->session_array[f].session = session; | 335 | (NULL == sh->session_array[off % sh->session_array_size]) ) |
335 | sh->session_array[f].peer = *peer; | 336 | return off; |
336 | sh->session_array[f].slot_used = GNUNET_YES; | 337 | i = sh->session_array_size; |
337 | 338 | GNUNET_array_grow (sh->session_array, | |
338 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", | 339 | sh->session_array_size, |
339 | "Assigning session ID %u for session %p of peer %s in %p\n", f, | 340 | sh->session_array_size * 2); |
340 | session, GNUNET_i2s (peer), sh); | 341 | return i; |
341 | |||
342 | return f; | ||
343 | } | 342 | } |
344 | 343 | ||
345 | 344 | ||
@@ -348,100 +347,47 @@ find_empty_session_slot (struct GNUNET_ATS_SchedulingHandle *sh, | |||
348 | * | 347 | * |
349 | * @param sh our handle | 348 | * @param sh our handle |
350 | * @param session session object | 349 | * @param session session object |
351 | * @param peer peer the session belongs to | 350 | * @param address the address we are looking for |
352 | * @return the session id or NOT_FOUND for error | 351 | * @return the session id or NOT_FOUND for error |
353 | */ | 352 | */ |
354 | static uint32_t | 353 | static uint32_t |
355 | find_session_id (struct GNUNET_ATS_SchedulingHandle *sh, | 354 | find_session_id (struct GNUNET_ATS_SchedulingHandle *sh, |
356 | struct Session *session, | 355 | struct Session *session, |
357 | const struct GNUNET_PeerIdentity *peer) | 356 | const struct GNUNET_HELLO_Address *address) |
358 | { | 357 | { |
359 | unsigned int i; | 358 | uint32_t i; |
360 | char * p2; | ||
361 | 359 | ||
362 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", | 360 | if (NULL == address) |
363 | "Get session ID for session %p from peer %s in %p\n", session, | 361 | { |
364 | GNUNET_i2s (peer), sh); | 362 | GNUNET_break (0); |
365 | |||
366 | if (NULL == session) | ||
367 | return NOT_FOUND; | 363 | return NOT_FOUND; |
364 | } | ||
368 | for (i = 1; i < sh->session_array_size; i++) | 365 | for (i = 1; i < sh->session_array_size; i++) |
369 | { | 366 | if ( (NULL != sh->session_array[i]) && |
370 | if (session == sh->session_array[i].session) | 367 | ( (session == sh->session_array[i]->session) || |
371 | { | 368 | (NULL == sh->session_array[i]->session) ) && |
372 | if (0 != memcmp (peer, &sh->session_array[i].peer, | 369 | (0 == GNUNET_HELLO_address_cmp (address, |
373 | sizeof (struct GNUNET_PeerIdentity))) | 370 | sh->session_array[i]->address)) ) |
374 | { | ||
375 | p2 = strdup (GNUNET_i2s (&sh->session_array[i].peer)); | ||
376 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "ats-scheduling-api", | ||
377 | "Session %p did not match: old session was for peer `%s' new session is for `%s'\n", | ||
378 | session, GNUNET_i2s (peer), p2); | ||
379 | GNUNET_free (p2); | ||
380 | return NOT_FOUND; | ||
381 | } | ||
382 | return i; | 371 | return i; |
383 | } | ||
384 | } | ||
385 | return NOT_FOUND; | 372 | return NOT_FOUND; |
386 | } | 373 | } |
387 | 374 | ||
388 | 375 | ||
389 | /** | 376 | /** |
390 | * Remove the session of the given session ID from the session | ||
391 | * table (it is no longer valid). | ||
392 | * | ||
393 | * @param sh our handle | ||
394 | * @param session_id identifies session that is no longer valid | ||
395 | * @param peer peer the session belongs to | ||
396 | */ | ||
397 | static void | ||
398 | remove_session (struct GNUNET_ATS_SchedulingHandle *sh, | ||
399 | uint32_t session_id, | ||
400 | const struct GNUNET_PeerIdentity *peer) | ||
401 | { | ||
402 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
403 | "ats-scheduling-api", | ||
404 | "Release sessionID %u from peer %s in %p\n", | ||
405 | (unsigned int) session_id, | ||
406 | GNUNET_i2s (peer), | ||
407 | sh); | ||
408 | |||
409 | if (0 == session_id) | ||
410 | return; | ||
411 | |||
412 | GNUNET_assert (session_id < sh->session_array_size); | ||
413 | GNUNET_assert (GNUNET_YES == sh->session_array[session_id].slot_used); | ||
414 | GNUNET_assert (0 == memcmp (peer, | ||
415 | &sh->session_array[session_id].peer, | ||
416 | sizeof (struct GNUNET_PeerIdentity))); | ||
417 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", | ||
418 | "Session %p for peer `%s' removed from slot %u \n", | ||
419 | sh->session_array[session_id].session, | ||
420 | GNUNET_i2s (peer), | ||
421 | session_id); | ||
422 | sh->session_array[session_id].session = NULL; | ||
423 | } | ||
424 | |||
425 | |||
426 | /** | ||
427 | * Release the session slot from the session table (ATS service is | 377 | * Release the session slot from the session table (ATS service is |
428 | * also done using it). | 378 | * also done using it). |
429 | * | 379 | * |
430 | * @param sh our handle | 380 | * @param sh our handle |
431 | * @param session_id identifies session that is no longer valid | 381 | * @param session_id identifies session that is no longer valid |
432 | * @param peer peer the session belongs to | ||
433 | */ | 382 | */ |
434 | static void | 383 | static void |
435 | release_session (struct GNUNET_ATS_SchedulingHandle *sh, | 384 | release_session (struct GNUNET_ATS_SchedulingHandle *sh, |
436 | uint32_t session_id, | 385 | uint32_t session_id) |
437 | const struct GNUNET_PeerIdentity *peer) | ||
438 | { | 386 | { |
439 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 387 | struct GNUNET_ATS_AddressRecord *ar; |
440 | "ats-scheduling-api", | 388 | |
441 | "Release sessionID %u from peer %s in %p\n", | 389 | if (NOT_FOUND == session_id) |
442 | (unsigned int) session_id, | 390 | return; |
443 | GNUNET_i2s (peer), | ||
444 | sh); | ||
445 | if (session_id >= sh->session_array_size) | 391 | if (session_id >= sh->session_array_size) |
446 | { | 392 | { |
447 | GNUNET_break (0); | 393 | GNUNET_break (0); |
@@ -449,20 +395,16 @@ release_session (struct GNUNET_ATS_SchedulingHandle *sh, | |||
449 | return; | 395 | return; |
450 | } | 396 | } |
451 | /* this slot should have been removed from remove_session before */ | 397 | /* this slot should have been removed from remove_session before */ |
452 | GNUNET_assert (sh->session_array[session_id].session == NULL); | 398 | ar = sh->session_array[session_id]; |
453 | 399 | if (NULL != ar->session) | |
454 | if (0 != | ||
455 | memcmp (peer, &sh->session_array[session_id].peer, | ||
456 | sizeof (struct GNUNET_PeerIdentity))) | ||
457 | { | 400 | { |
458 | GNUNET_break (0); | 401 | GNUNET_break (0); |
459 | force_reconnect (sh); | 402 | force_reconnect (sh); |
460 | return; | 403 | return; |
461 | } | 404 | } |
462 | sh->session_array[session_id].slot_used = GNUNET_NO; | 405 | GNUNET_HELLO_address_free (ar->address); |
463 | memset (&sh->session_array[session_id].peer, | 406 | GNUNET_free (ar); |
464 | 0, | 407 | sh->session_array[session_id] = NULL; |
465 | sizeof (struct GNUNET_PeerIdentity)); | ||
466 | } | 408 | } |
467 | 409 | ||
468 | 410 | ||
@@ -481,10 +423,9 @@ process_ats_session_release_message (void *cls, | |||
481 | const struct SessionReleaseMessage *srm; | 423 | const struct SessionReleaseMessage *srm; |
482 | 424 | ||
483 | srm = (const struct SessionReleaseMessage *) msg; | 425 | srm = (const struct SessionReleaseMessage *) msg; |
484 | 426 | /* FIXME: peer field in srm not necessary anymore */ | |
485 | release_session (sh, | 427 | release_session (sh, |
486 | ntohl (srm->session_id), | 428 | ntohl (srm->session_id)); |
487 | &srm->peer); | ||
488 | } | 429 | } |
489 | 430 | ||
490 | 431 | ||
@@ -509,6 +450,7 @@ process_ats_address_suggestion_message (void *cls, | |||
509 | uint32_t ats_count; | 450 | uint32_t ats_count; |
510 | struct GNUNET_HELLO_Address address; | 451 | struct GNUNET_HELLO_Address address; |
511 | struct Session *s; | 452 | struct Session *s; |
453 | struct GNUNET_ATS_AddressRecord *ar; | ||
512 | 454 | ||
513 | if (ntohs (msg->size) <= sizeof (struct AddressSuggestionMessage)) | 455 | if (ntohs (msg->size) <= sizeof (struct AddressSuggestionMessage)) |
514 | { | 456 | { |
@@ -516,6 +458,8 @@ process_ats_address_suggestion_message (void *cls, | |||
516 | force_reconnect (sh); | 458 | force_reconnect (sh); |
517 | return; | 459 | return; |
518 | } | 460 | } |
461 | /* FIXME: we have all the address details, no need for ATS | ||
462 | to send those back to us any longer! */ | ||
519 | m = (const struct AddressSuggestionMessage *) msg; | 463 | m = (const struct AddressSuggestionMessage *) msg; |
520 | ats_count = ntohl (m->ats_count); | 464 | ats_count = ntohl (m->ats_count); |
521 | plugin_address_length = ntohs (m->address_length); | 465 | plugin_address_length = ntohs (m->address_length); |
@@ -536,22 +480,29 @@ process_ats_address_suggestion_message (void *cls, | |||
536 | } | 480 | } |
537 | uint32_t session_id = ntohl (m->session_id); | 481 | uint32_t session_id = ntohl (m->session_id); |
538 | 482 | ||
539 | if (session_id == 0) | 483 | if (0 == session_id) |
540 | s = NULL; | ||
541 | else | ||
542 | { | 484 | { |
543 | s = find_session (sh, session_id, &m->peer); | 485 | GNUNET_break (0); |
544 | if (NULL == s) | 486 | force_reconnect (sh); |
545 | { | 487 | return; |
546 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 488 | } |
547 | "ats-scheduling-api", | 489 | ar = find_session (sh, session_id, &m->peer); |
548 | "ATS tries to use outdated session `%s'\n", | 490 | if (NULL == ar) |
549 | GNUNET_i2s (&m->peer)); | 491 | { |
550 | return; | 492 | GNUNET_break (0); |
551 | } | 493 | force_reconnect (sh); |
494 | return; | ||
552 | } | 495 | } |
496 | s = ar->session; | ||
553 | if (NULL == sh->suggest_cb) | 497 | if (NULL == sh->suggest_cb) |
554 | return; | 498 | return; |
499 | if ( (GNUNET_YES == ar->in_destroy) && | ||
500 | ( (0 != ntohl (m->bandwidth_out.value__)) || | ||
501 | (0 != ntohl (m->bandwidth_in.value__)) ) ) | ||
502 | { | ||
503 | /* ignore suggestion, as this address is dying */ | ||
504 | return; | ||
505 | } | ||
555 | address.peer = m->peer; | 506 | address.peer = m->peer; |
556 | address.address = plugin_address; | 507 | address.address = plugin_address; |
557 | address.address_length = plugin_address_length; | 508 | address.address_length = plugin_address_length; |
@@ -600,6 +551,66 @@ error_handler (void *cls, | |||
600 | 551 | ||
601 | 552 | ||
602 | /** | 553 | /** |
554 | * Generate the "AddressUpdateMessage" for the given | ||
555 | * session record. | ||
556 | * | ||
557 | * @param sh the scheduling handle to use for transmission | ||
558 | * @param ar the address to inform the ATS service about | ||
559 | * @param msg_type the message type to use when sending the message | ||
560 | * | ||
561 | * FIXME: maybe overloading with msg_type was not the best idea here... | ||
562 | */ | ||
563 | static void | ||
564 | send_add_address_message (struct GNUNET_ATS_SchedulingHandle *sh, | ||
565 | const struct GNUNET_ATS_AddressRecord *ar, | ||
566 | uint16_t msg_type) | ||
567 | { | ||
568 | struct GNUNET_MQ_Envelope *ev; | ||
569 | struct AddressUpdateMessage *m; | ||
570 | struct GNUNET_ATS_Information *am; | ||
571 | char *pm; | ||
572 | size_t namelen; | ||
573 | size_t msize; | ||
574 | |||
575 | if (NULL == sh->mq) | ||
576 | return; /* disconnected, skip for now */ | ||
577 | namelen = (NULL == ar->address->transport_name) | ||
578 | ? 0 | ||
579 | : strlen (ar->address->transport_name) + 1; | ||
580 | msize = ar->address->address_length + | ||
581 | ar->ats_count * sizeof (struct GNUNET_ATS_Information) + namelen; | ||
582 | |||
583 | ev = GNUNET_MQ_msg_extra (m, msize, msg_type); | ||
584 | m->ats_count = htonl (ar->ats_count); | ||
585 | m->peer = ar->address->peer; | ||
586 | m->address_length = htons (ar->address->address_length); | ||
587 | m->address_local_info = htonl ((uint32_t) ar->address->local_info); | ||
588 | m->plugin_name_length = htons (namelen); | ||
589 | m->session_id = htonl (ar->slot); | ||
590 | |||
591 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
592 | "Adding address for peer `%s', plugin `%s', session %p id %u\n", | ||
593 | GNUNET_i2s (&ar->address->peer), | ||
594 | ar->address->transport_name, | ||
595 | ar->session, | ||
596 | ar->slot); | ||
597 | am = (struct GNUNET_ATS_Information *) &m[1]; | ||
598 | memcpy (am, | ||
599 | ar->ats, | ||
600 | ar->ats_count * sizeof (struct GNUNET_ATS_Information)); | ||
601 | pm = (char *) &am[ar->ats_count]; | ||
602 | memcpy (pm, | ||
603 | ar->address->address, | ||
604 | ar->address->address_length); | ||
605 | if (NULL != ar->address->transport_name) | ||
606 | memcpy (&pm[ar->address->address_length], | ||
607 | ar->address->transport_name, | ||
608 | namelen); | ||
609 | GNUNET_MQ_send (sh->mq, ev); | ||
610 | } | ||
611 | |||
612 | |||
613 | /** | ||
603 | * Re-establish the connection to the ATS service. | 614 | * Re-establish the connection to the ATS service. |
604 | * | 615 | * |
605 | * @param sh handle to use to re-connect. | 616 | * @param sh handle to use to re-connect. |
@@ -1082,7 +1093,7 @@ GNUNET_ATS_reset_backoff (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1082 | * | 1093 | * |
1083 | * @param sh handle | 1094 | * @param sh handle |
1084 | * @param peer identity of the peer we need an address for | 1095 | * @param peer identity of the peer we need an address for |
1085 | * @return suggest handle | 1096 | * @return suggest handle, NULL if a request is already pending |
1086 | */ | 1097 | */ |
1087 | struct GNUNET_ATS_SuggestHandle * | 1098 | struct GNUNET_ATS_SuggestHandle * |
1088 | GNUNET_ATS_suggest_address (struct GNUNET_ATS_SchedulingHandle *sh, | 1099 | GNUNET_ATS_suggest_address (struct GNUNET_ATS_SchedulingHandle *sh, |
@@ -1094,11 +1105,15 @@ GNUNET_ATS_suggest_address (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1094 | 1105 | ||
1095 | s = GNUNET_new (struct GNUNET_ATS_SuggestHandle); | 1106 | s = GNUNET_new (struct GNUNET_ATS_SuggestHandle); |
1096 | s->id = *peer; | 1107 | s->id = *peer; |
1097 | GNUNET_break (GNUNET_OK == | 1108 | if (GNUNET_OK != |
1098 | GNUNET_CONTAINER_multipeermap_put (sh->sug_requests, | 1109 | GNUNET_CONTAINER_multipeermap_put (sh->sug_requests, |
1099 | &s->id, | 1110 | &s->id, |
1100 | s, | 1111 | s, |
1101 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 1112 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) |
1113 | { | ||
1114 | GNUNET_break (0); | ||
1115 | return NULL; | ||
1116 | } | ||
1102 | if (NULL == sh->mq) | 1117 | if (NULL == sh->mq) |
1103 | return s; | 1118 | return s; |
1104 | ev = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS); | 1119 | ev = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS); |
@@ -1161,7 +1176,7 @@ GNUNET_ATS_session_known (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1161 | return GNUNET_NO; | 1176 | return GNUNET_NO; |
1162 | if (NOT_FOUND != find_session_id (sh, | 1177 | if (NOT_FOUND != find_session_id (sh, |
1163 | session, | 1178 | session, |
1164 | &address->peer)) | 1179 | address)) |
1165 | return GNUNET_YES; /* Exists */ | 1180 | return GNUNET_YES; /* Exists */ |
1166 | return GNUNET_NO; | 1181 | return GNUNET_NO; |
1167 | } | 1182 | } |
@@ -1186,24 +1201,20 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1186 | const struct GNUNET_ATS_Information *ats, | 1201 | const struct GNUNET_ATS_Information *ats, |
1187 | uint32_t ats_count) | 1202 | uint32_t ats_count) |
1188 | { | 1203 | { |
1189 | struct GNUNET_MQ_Envelope *ev; | 1204 | struct GNUNET_ATS_AddressRecord *ar; |
1190 | struct AddressUpdateMessage *m; | ||
1191 | struct GNUNET_ATS_Information *am; | ||
1192 | char *pm; | ||
1193 | size_t namelen; | 1205 | size_t namelen; |
1194 | size_t msize; | 1206 | size_t msize; |
1195 | uint32_t s = 0; | 1207 | uint32_t s; |
1196 | 1208 | ||
1197 | if (NULL == address) | 1209 | if (NULL == address) |
1198 | { | 1210 | { |
1211 | /* we need a valid address */ | ||
1199 | GNUNET_break (0); | 1212 | GNUNET_break (0); |
1200 | return GNUNET_SYSERR; | 1213 | return GNUNET_SYSERR; |
1201 | } | 1214 | } |
1202 | |||
1203 | namelen = (NULL == address->transport_name) | 1215 | namelen = (NULL == address->transport_name) |
1204 | ? 0 | 1216 | ? 0 |
1205 | : strlen (address->transport_name) + 1; | 1217 | : strlen (address->transport_name) + 1; |
1206 | |||
1207 | msize = address->address_length + | 1218 | msize = address->address_length + |
1208 | ats_count * sizeof (struct GNUNET_ATS_Information) + namelen; | 1219 | ats_count * sizeof (struct GNUNET_ATS_Information) + namelen; |
1209 | if ((msize + sizeof (struct AddressUpdateMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || | 1220 | if ((msize + sizeof (struct AddressUpdateMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || |
@@ -1212,48 +1223,28 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1212 | (ats_count >= | 1223 | (ats_count >= |
1213 | GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information))) | 1224 | GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information))) |
1214 | { | 1225 | { |
1226 | /* address too large for us, this should not happen */ | ||
1215 | GNUNET_break (0); | 1227 | GNUNET_break (0); |
1216 | return GNUNET_SYSERR; | 1228 | return GNUNET_SYSERR; |
1217 | } | 1229 | } |
1218 | 1230 | ||
1219 | if (NULL != session) | 1231 | if (NOT_FOUND != find_session_id (sh, session, address)) |
1220 | { | 1232 | { |
1221 | if (NOT_FOUND != (s = find_session_id (sh, session, &address->peer))) | 1233 | /* Already existing, nothing todo, but this should not happen */ |
1222 | { | 1234 | GNUNET_break (0); |
1223 | /* Already existing, nothing todo */ | 1235 | return GNUNET_SYSERR; |
1224 | return GNUNET_SYSERR; | ||
1225 | } | ||
1226 | s = find_empty_session_slot (sh, | ||
1227 | session, | ||
1228 | &address->peer); | ||
1229 | GNUNET_break (NOT_FOUND != s); | ||
1230 | } | 1236 | } |
1231 | 1237 | s = find_empty_session_slot (sh); | |
1232 | ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD); | 1238 | ar = GNUNET_new (struct GNUNET_ATS_AddressRecord); |
1233 | m->ats_count = htonl (ats_count); | 1239 | ar->slot = s; |
1234 | m->peer = address->peer; | 1240 | ar->session = session; |
1235 | m->address_length = htons (address->address_length); | 1241 | ar->address = GNUNET_HELLO_address_copy (address); |
1236 | m->address_local_info = htonl ((uint32_t) address->local_info); | 1242 | GNUNET_array_grow (ar->ats, |
1237 | m->plugin_name_length = htons (namelen); | 1243 | ar->ats_count, |
1238 | m->session_id = htonl (s); | 1244 | ats_count); |
1239 | 1245 | memcpy (ar->ats, ats, ats_count * sizeof (struct GNUNET_ATS_Information)); | |
1240 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1246 | sh->session_array[s] = ar; |
1241 | "Adding address for peer `%s', plugin `%s', session %p id %u\n", | 1247 | send_add_address_message (sh, ar, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD); |
1242 | GNUNET_i2s (&address->peer), | ||
1243 | address->transport_name, | ||
1244 | session, | ||
1245 | s); | ||
1246 | am = (struct GNUNET_ATS_Information *) &m[1]; | ||
1247 | memcpy (am, | ||
1248 | ats, | ||
1249 | ats_count * sizeof (struct GNUNET_ATS_Information)); | ||
1250 | pm = (char *) &am[ats_count]; | ||
1251 | memcpy (pm, address->address, address->address_length); | ||
1252 | if (NULL != address->transport_name) | ||
1253 | memcpy (&pm[address->address_length], | ||
1254 | address->transport_name, | ||
1255 | namelen); | ||
1256 | GNUNET_MQ_send (sh->mq, ev); | ||
1257 | return GNUNET_OK; | 1248 | return GNUNET_OK; |
1258 | } | 1249 | } |
1259 | 1250 | ||
@@ -1266,6 +1257,8 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1266 | * which case the call may be ignored or the information may be stored | 1257 | * which case the call may be ignored or the information may be stored |
1267 | * for later use). Update bandwidth assignments. | 1258 | * for later use). Update bandwidth assignments. |
1268 | * | 1259 | * |
1260 | * FIXME: change API so we do not have to do the linear search! | ||
1261 | * | ||
1269 | * @param sh handle | 1262 | * @param sh handle |
1270 | * @param address the address | 1263 | * @param address the address |
1271 | * @param session session handle, can be NULL | 1264 | * @param session session handle, can be NULL |
@@ -1281,69 +1274,24 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1281 | const struct GNUNET_ATS_Information *ats, | 1274 | const struct GNUNET_ATS_Information *ats, |
1282 | uint32_t ats_count) | 1275 | uint32_t ats_count) |
1283 | { | 1276 | { |
1284 | struct GNUNET_MQ_Envelope *ev; | 1277 | uint32_t s; |
1285 | struct AddressUpdateMessage *m; | 1278 | struct GNUNET_ATS_AddressRecord *ar; |
1286 | struct GNUNET_ATS_Information *am; | ||
1287 | char *pm; | ||
1288 | size_t namelen; | ||
1289 | size_t msize; | ||
1290 | uint32_t s = 0; | ||
1291 | |||
1292 | if (NULL == address) | ||
1293 | { | ||
1294 | GNUNET_break (0); | ||
1295 | return GNUNET_SYSERR; | ||
1296 | } | ||
1297 | if (NULL == sh) | ||
1298 | { | ||
1299 | GNUNET_break (0); | ||
1300 | return GNUNET_SYSERR; | ||
1301 | } | ||
1302 | 1279 | ||
1303 | namelen = (address->transport_name == | 1280 | s = find_session_id (sh, session, address); |
1304 | NULL) ? 0 : strlen (address->transport_name) + 1; | 1281 | if (NOT_FOUND == s) |
1305 | msize = address->address_length + | ||
1306 | ats_count * sizeof (struct GNUNET_ATS_Information) + namelen; | ||
1307 | if ((msize + sizeof (struct AddressUpdateMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || | ||
1308 | (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || | ||
1309 | (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || | ||
1310 | (ats_count >= | ||
1311 | GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information))) | ||
1312 | { | 1282 | { |
1313 | GNUNET_break (0); | 1283 | GNUNET_break (0); |
1314 | return GNUNET_SYSERR; | 1284 | return GNUNET_NO; |
1315 | } | ||
1316 | |||
1317 | if (NULL != session) | ||
1318 | { | ||
1319 | s = find_session_id (sh, session, &address->peer); | ||
1320 | if (NOT_FOUND == s) | ||
1321 | return GNUNET_NO; | ||
1322 | } | 1285 | } |
1323 | 1286 | ar = sh->session_array[s]; | |
1324 | ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE); | 1287 | GNUNET_array_grow (ar->ats, |
1325 | m->ats_count = htonl (ats_count); | 1288 | ar->ats_count, |
1326 | m->peer = address->peer; | 1289 | ats_count); |
1327 | m->address_length = htons (address->address_length); | 1290 | memcpy (ar->ats, |
1328 | m->address_local_info = htonl ((uint32_t) address->local_info); | ||
1329 | m->plugin_name_length = htons (namelen); | ||
1330 | m->session_id = htonl (s); | ||
1331 | |||
1332 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1333 | "Updating address for peer `%s', plugin `%s', session %p id %u\n", | ||
1334 | GNUNET_i2s (&address->peer), | ||
1335 | address->transport_name, | ||
1336 | session, | ||
1337 | s); | ||
1338 | |||
1339 | am = (struct GNUNET_ATS_Information *) &m[1]; | ||
1340 | memcpy (am, | ||
1341 | ats, | 1291 | ats, |
1342 | ats_count * sizeof (struct GNUNET_ATS_Information)); | 1292 | ats_count * sizeof (struct GNUNET_ATS_Information)); |
1343 | pm = (char *) &am[ats_count]; | 1293 | ar->session = session; |
1344 | memcpy (pm, address->address, address->address_length); | 1294 | send_add_address_message (sh, ar, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE); |
1345 | memcpy (&pm[address->address_length], address->transport_name, namelen); | ||
1346 | GNUNET_MQ_send (sh->mq, ev); | ||
1347 | return GNUNET_YES; | 1295 | return GNUNET_YES; |
1348 | } | 1296 | } |
1349 | 1297 | ||
@@ -1365,42 +1313,25 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1365 | { | 1313 | { |
1366 | struct GNUNET_MQ_Envelope *ev; | 1314 | struct GNUNET_MQ_Envelope *ev; |
1367 | struct AddressUseMessage *m; | 1315 | struct AddressUseMessage *m; |
1316 | struct GNUNET_ATS_AddressRecord *ar; | ||
1368 | char *pm; | 1317 | char *pm; |
1369 | size_t namelen; | 1318 | size_t namelen; |
1370 | size_t msize; | 1319 | size_t msize; |
1371 | uint32_t s = 0; | 1320 | uint32_t s = 0; |
1372 | 1321 | ||
1373 | namelen = | 1322 | s = find_session_id (sh, session, address); |
1374 | (address->transport_name == | 1323 | if (s == NOT_FOUND) |
1375 | NULL) ? 0 : strlen (address->transport_name) + 1; | ||
1376 | msize = address->address_length + namelen; | ||
1377 | if ((msize + sizeof (struct AddressUseMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || | ||
1378 | (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || | ||
1379 | (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)) | ||
1380 | { | 1324 | { |
1325 | /* trying to set unknown address to NO */ | ||
1381 | GNUNET_break (0); | 1326 | GNUNET_break (0); |
1382 | return; | 1327 | return; |
1383 | } | 1328 | } |
1384 | 1329 | ar = sh->session_array[s]; | |
1385 | if (NULL != session) | 1330 | ar->in_use = in_use; |
1386 | { | 1331 | namelen = (NULL == address->transport_name) |
1387 | s = find_session_id (sh, session, &address->peer); | 1332 | ? 0 |
1388 | if ((s == NOT_FOUND) && (GNUNET_NO == in_use)) | 1333 | : strlen (address->transport_name) + 1; |
1389 | { | 1334 | msize = address->address_length + namelen; |
1390 | /* trying to set unknown address to NO */ | ||
1391 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1392 | "Trying to set unknown address to unused for peer `%s', plugin `%s', session %p\n", | ||
1393 | GNUNET_i2s (&address->peer), address->transport_name, session); | ||
1394 | GNUNET_break (0); | ||
1395 | return; | ||
1396 | } | ||
1397 | if ((s == NOT_FOUND) && (GNUNET_YES == in_use)) | ||
1398 | { | ||
1399 | /* trying to set new address to YES */ | ||
1400 | s = find_empty_session_slot (sh, session, &address->peer); | ||
1401 | GNUNET_assert (NOT_FOUND != s); | ||
1402 | } | ||
1403 | } | ||
1404 | 1335 | ||
1405 | ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_IN_USE); | 1336 | ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_IN_USE); |
1406 | m->peer = address->peer; | 1337 | m->peer = address->peer; |
@@ -1412,10 +1343,13 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1412 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1343 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1413 | "Setting address used to %s for peer `%s', plugin `%s', session %p\n", | 1344 | "Setting address used to %s for peer `%s', plugin `%s', session %p\n", |
1414 | (GNUNET_YES == in_use) ? "YES" : "NO", | 1345 | (GNUNET_YES == in_use) ? "YES" : "NO", |
1415 | GNUNET_i2s (&address->peer), address->transport_name, session); | 1346 | GNUNET_i2s (&address->peer), |
1347 | address->transport_name, | ||
1348 | session); | ||
1416 | 1349 | ||
1417 | m->session_id = htonl (s); | 1350 | m->session_id = htonl (s); |
1418 | pm = (char *) &m[1]; | 1351 | pm = (char *) &m[1]; |
1352 | /* FIXME: no need to send the address data */ | ||
1419 | memcpy (pm, address->address, address->address_length); | 1353 | memcpy (pm, address->address, address->address_length); |
1420 | memcpy (&pm[address->address_length], address->transport_name, namelen); | 1354 | memcpy (&pm[address->address_length], address->transport_name, namelen); |
1421 | GNUNET_MQ_send (sh->mq, ev); | 1355 | GNUNET_MQ_send (sh->mq, ev); |
@@ -1428,6 +1362,9 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1428 | * If a session is given, only the session will be removed, if no session is | 1362 | * If a session is given, only the session will be removed, if no session is |
1429 | * given the full address will be deleted. | 1363 | * given the full address will be deleted. |
1430 | * | 1364 | * |
1365 | * FIXME: the above sentence already indicates that this API is a | ||
1366 | * mess and troublesome. FIX IT! | ||
1367 | * | ||
1431 | * @param sh handle | 1368 | * @param sh handle |
1432 | * @param address the address | 1369 | * @param address the address |
1433 | * @param session session handle that is no longer valid, can be NULL | 1370 | * @param session session handle that is no longer valid, can be NULL |
@@ -1437,18 +1374,30 @@ GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1437 | const struct GNUNET_HELLO_Address *address, | 1374 | const struct GNUNET_HELLO_Address *address, |
1438 | struct Session *session) | 1375 | struct Session *session) |
1439 | { | 1376 | { |
1377 | uint32_t s; | ||
1440 | struct GNUNET_MQ_Envelope *ev; | 1378 | struct GNUNET_MQ_Envelope *ev; |
1441 | struct AddressDestroyedMessage *m; | 1379 | struct AddressDestroyedMessage *m; |
1380 | struct GNUNET_ATS_AddressRecord *ar; | ||
1442 | char *pm; | 1381 | char *pm; |
1443 | size_t namelen; | 1382 | size_t namelen; |
1444 | size_t msize; | 1383 | size_t msize; |
1445 | uint32_t s; | ||
1446 | 1384 | ||
1447 | if (NULL == address) | 1385 | s = find_session_id (sh, session, address); |
1386 | if (NOT_FOUND == s) | ||
1448 | { | 1387 | { |
1449 | GNUNET_break (0); | 1388 | GNUNET_break (0); |
1450 | return; | 1389 | return; |
1451 | } | 1390 | } |
1391 | ar = sh->session_array[s]; | ||
1392 | if (NULL != session) | ||
1393 | { | ||
1394 | /* FIXME: this is yucky, fix API! */ | ||
1395 | GNUNET_break (ar->session == session); | ||
1396 | ar->session = NULL; | ||
1397 | return; | ||
1398 | } | ||
1399 | |||
1400 | |||
1452 | GNUNET_assert (NULL != address->transport_name); | 1401 | GNUNET_assert (NULL != address->transport_name); |
1453 | namelen = strlen (address->transport_name) + 1; | 1402 | namelen = strlen (address->transport_name) + 1; |
1454 | GNUNET_assert (namelen > 1); | 1403 | GNUNET_assert (namelen > 1); |
@@ -1461,16 +1410,6 @@ GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1461 | return; | 1410 | return; |
1462 | } | 1411 | } |
1463 | 1412 | ||
1464 | s = find_session_id (sh, session, &address->peer); | ||
1465 | if ((NULL != session) && (NOT_FOUND == s)) | ||
1466 | { | ||
1467 | /* trying to delete unknown address */ | ||
1468 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1469 | "Trying to delete unknown address for peer `%s', plugin `%s', session %p\n", | ||
1470 | GNUNET_i2s (&address->peer), address->transport_name, session); | ||
1471 | return; | ||
1472 | } | ||
1473 | |||
1474 | ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED); | 1413 | ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED); |
1475 | m->peer = address->peer; | 1414 | m->peer = address->peer; |
1476 | m->address_length = htons (address->address_length); | 1415 | m->address_length = htons (address->address_length); |
@@ -1479,14 +1418,25 @@ GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1479 | 1418 | ||
1480 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1419 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1481 | "Deleting address for peer `%s', plugin `%s', session %p\n", | 1420 | "Deleting address for peer `%s', plugin `%s', session %p\n", |
1482 | GNUNET_i2s (&address->peer), address->transport_name, session); | 1421 | GNUNET_i2s (&address->peer), |
1422 | address->transport_name, | ||
1423 | session); | ||
1483 | 1424 | ||
1484 | m->session_id = htonl (s); | 1425 | m->session_id = htonl (s); |
1485 | pm = (char *) &m[1]; | 1426 | pm = (char *) &m[1]; |
1486 | memcpy (pm, address->address, address->address_length); | 1427 | memcpy (pm, |
1487 | memcpy (&pm[address->address_length], address->transport_name, namelen); | 1428 | address->address, |
1429 | address->address_length); | ||
1430 | memcpy (&pm[address->address_length], | ||
1431 | address->transport_name, | ||
1432 | namelen); | ||
1488 | GNUNET_MQ_send (sh->mq, ev); | 1433 | GNUNET_MQ_send (sh->mq, ev); |
1489 | remove_session (sh, s, &address->peer); | 1434 | ar->session = NULL; |
1435 | ar->in_destroy = GNUNET_YES; | ||
1436 | GNUNET_array_grow (ar->ats, | ||
1437 | ar->ats_count, | ||
1438 | 0); | ||
1490 | } | 1439 | } |
1491 | 1440 | ||
1441 | |||
1492 | /* end of ats_api_scheduling.c */ | 1442 | /* end of ats_api_scheduling.c */ |