aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-transport_neighbours.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-service-transport_neighbours.c')
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c579
1 files changed, 259 insertions, 320 deletions
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c
index 604112560..386894d48 100644
--- a/src/transport/gnunet-service-transport_neighbours.c
+++ b/src/transport/gnunet-service-transport_neighbours.c
@@ -152,7 +152,7 @@ struct NeighbourMapEntry
152 * Address used for communicating with the peer, NULL for inbound connections. 152 * Address used for communicating with the peer, NULL for inbound connections.
153 */ 153 */
154 void *addr; 154 void *addr;
155 155
156 /** 156 /**
157 * Number of bytes in 'addr'. 157 * Number of bytes in 'addr'.
158 */ 158 */
@@ -236,8 +236,7 @@ static GNUNET_TRANSPORT_NotifyDisconnect disconnect_notify_cb;
236static struct NeighbourMapEntry * 236static struct NeighbourMapEntry *
237lookup_neighbour (const struct GNUNET_PeerIdentity *pid) 237lookup_neighbour (const struct GNUNET_PeerIdentity *pid)
238{ 238{
239 return GNUNET_CONTAINER_multihashmap_get (neighbours, 239 return GNUNET_CONTAINER_multihashmap_get (neighbours, &pid->hashPubKey);
240 &pid->hashPubKey);
241} 240}
242 241
243 242
@@ -248,8 +247,7 @@ lookup_neighbour (const struct GNUNET_PeerIdentity *pid)
248 * @param tc scheduler context 247 * @param tc scheduler context
249 */ 248 */
250static void 249static void
251transmission_task (void *cls, 250transmission_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
252 const struct GNUNET_SCHEDULER_TaskContext *tc);
253 251
254 252
255/** 253/**
@@ -261,25 +259,23 @@ transmission_task (void *cls,
261 */ 259 */
262static void 260static void
263transmit_send_continuation (void *cls, 261transmit_send_continuation (void *cls,
264 const struct GNUNET_PeerIdentity *receiver, 262 const struct GNUNET_PeerIdentity *receiver,
265 int success) 263 int success)
266{ 264{
267 struct MessageQueue *mq; 265 struct MessageQueue *mq;
268 struct NeighbourMapEntry *n; 266 struct NeighbourMapEntry *n;
269 267
270 mq = cls; 268 mq = cls;
271 n = mq->n; 269 n = mq->n;
272 if (NULL != n) 270 if (NULL != n)
273 { 271 {
274 GNUNET_assert (n->is_active == mq); 272 GNUNET_assert (n->is_active == mq);
275 n->is_active = NULL; 273 n->is_active = NULL;
276 GNUNET_assert (n->transmission_task == GNUNET_SCHEDULER_NO_TASK); 274 GNUNET_assert (n->transmission_task == GNUNET_SCHEDULER_NO_TASK);
277 n->transmission_task = GNUNET_SCHEDULER_add_now (&transmission_task, 275 n->transmission_task = GNUNET_SCHEDULER_add_now (&transmission_task, n);
278 n); 276 }
279 }
280 if (NULL != mq->cont) 277 if (NULL != mq->cont)
281 mq->cont (mq->cont_cls, 278 mq->cont (mq->cont_cls, success);
282 success);
283 GNUNET_free (mq); 279 GNUNET_free (mq);
284} 280}
285 281
@@ -299,52 +295,45 @@ try_transmission_to_peer (struct NeighbourMapEntry *n)
299 struct GNUNET_TRANSPORT_PluginFunctions *papi; 295 struct GNUNET_TRANSPORT_PluginFunctions *papi;
300 296
301 if (n->is_active != NULL) 297 if (n->is_active != NULL)
302 return; /* transmission already pending */ 298 return; /* transmission already pending */
303 if (n->transmission_task != GNUNET_SCHEDULER_NO_TASK) 299 if (n->transmission_task != GNUNET_SCHEDULER_NO_TASK)
304 return; /* currently waiting for bandwidth */ 300 return; /* currently waiting for bandwidth */
305 mq = n->messages_head; 301 mq = n->messages_head;
306 while (NULL != (mq = n->messages_head)) 302 while (NULL != (mq = n->messages_head))
307 { 303 {
308 timeout = GNUNET_TIME_absolute_get_remaining (mq->timeout); 304 timeout = GNUNET_TIME_absolute_get_remaining (mq->timeout);
309 if (timeout.rel_value > 0) 305 if (timeout.rel_value > 0)
310 break; 306 break;
311 transmit_send_continuation (mq, &n->id, GNUNET_SYSERR); /* timeout */ 307 transmit_send_continuation (mq, &n->id, GNUNET_SYSERR); /* timeout */
312 } 308 }
313 if (NULL == mq) 309 if (NULL == mq)
314 return; /* no more messages */ 310 return; /* no more messages */
315 311
316 papi = GST_plugins_find (n->plugin_name); 312 papi = GST_plugins_find (n->plugin_name);
317 if (papi == NULL) 313 if (papi == NULL)
318 { 314 {
319 GNUNET_break (0); 315 GNUNET_break (0);
320 return; 316 return;
321 } 317 }
322 GNUNET_CONTAINER_DLL_remove (n->messages_head, 318 GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq);
323 n->messages_tail,
324 mq);
325 n->is_active = mq; 319 n->is_active = mq;
326 mq->n = n; 320 mq->n = n;
327 ret = papi->send (papi->cls, 321 ret = papi->send (papi->cls,
328 &n->id, 322 &n->id,
329 mq->message_buf, 323 mq->message_buf,
330 mq->message_buf_size, 324 mq->message_buf_size,
331 0 /* priority -- remove from plugin API? */, 325 0 /* priority -- remove from plugin API? */ ,
332 timeout, 326 timeout,
333 n->session, 327 n->session,
334 n->addr, 328 n->addr,
335 n->addrlen, 329 n->addrlen, GNUNET_YES, &transmit_send_continuation, mq);
336 GNUNET_YES,
337 &transmit_send_continuation, mq);
338 if (ret == -1) 330 if (ret == -1)
339 { 331 {
340 /* failure, but 'send' would not call continuation in this case, 332 /* failure, but 'send' would not call continuation in this case,
341 so we need to do it here! */ 333 * so we need to do it here! */
342 transmit_send_continuation (mq, 334 transmit_send_continuation (mq, &n->id, GNUNET_SYSERR);
343 &n->id, 335 n->transmission_task = GNUNET_SCHEDULER_add_now (&transmission_task, n);
344 GNUNET_SYSERR); 336 }
345 n->transmission_task = GNUNET_SCHEDULER_add_now (&transmission_task,
346 n);
347 }
348} 337}
349 338
350 339
@@ -355,8 +344,7 @@ try_transmission_to_peer (struct NeighbourMapEntry *n)
355 * @param tc scheduler context 344 * @param tc scheduler context
356 */ 345 */
357static void 346static void
358transmission_task (void *cls, 347transmission_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
359 const struct GNUNET_SCHEDULER_TaskContext *tc)
360{ 348{
361 struct NeighbourMapEntry *n = cls; 349 struct NeighbourMapEntry *n = cls;
362 350
@@ -372,10 +360,10 @@ transmission_task (void *cls,
372 * @param connect_cb function to call if we connect to a peer 360 * @param connect_cb function to call if we connect to a peer
373 * @param disconnect_cb function to call if we disconnect from a peer 361 * @param disconnect_cb function to call if we disconnect from a peer
374 */ 362 */
375void 363void
376GST_neighbours_start (void *cls, 364GST_neighbours_start (void *cls,
377 GNUNET_TRANSPORT_NotifyConnect connect_cb, 365 GNUNET_TRANSPORT_NotifyConnect connect_cb,
378 GNUNET_TRANSPORT_NotifyDisconnect disconnect_cb) 366 GNUNET_TRANSPORT_NotifyDisconnect disconnect_cb)
379{ 367{
380 callback_cls = cls; 368 callback_cls = cls;
381 connect_notify_cb = connect_cb; 369 connect_notify_cb = connect_cb;
@@ -398,57 +386,51 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
398 return; 386 return;
399 n->in_disconnect = GNUNET_YES; 387 n->in_disconnect = GNUNET_YES;
400 while (NULL != (mq = n->messages_head)) 388 while (NULL != (mq = n->messages_head))
401 { 389 {
402 GNUNET_CONTAINER_DLL_remove (n->messages_head, 390 GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq);
403 n->messages_tail, 391 mq->cont (mq->cont_cls, GNUNET_SYSERR);
404 mq); 392 GNUNET_free (mq);
405 mq->cont (mq->cont_cls, GNUNET_SYSERR); 393 }
406 GNUNET_free (mq);
407 }
408 if (NULL != n->is_active) 394 if (NULL != n->is_active)
409 { 395 {
410 n->is_active->n = NULL; 396 n->is_active->n = NULL;
411 n->is_active = NULL; 397 n->is_active = NULL;
412 } 398 }
413 if (GNUNET_YES == n->is_connected) 399 if (GNUNET_YES == n->is_connected)
414 { 400 {
415 n->is_connected = GNUNET_NO; 401 n->is_connected = GNUNET_NO;
416 disconnect_notify_cb (callback_cls, 402 disconnect_notify_cb (callback_cls, &n->id);
417 &n->id); 403 }
418 }
419 GNUNET_assert (GNUNET_YES == 404 GNUNET_assert (GNUNET_YES ==
420 GNUNET_CONTAINER_multihashmap_remove (neighbours, 405 GNUNET_CONTAINER_multihashmap_remove (neighbours,
421 &n->id.hashPubKey, 406 &n->id.hashPubKey, n));
422 n));
423 if (GNUNET_SCHEDULER_NO_TASK != n->timeout_task) 407 if (GNUNET_SCHEDULER_NO_TASK != n->timeout_task)
424 { 408 {
425 GNUNET_SCHEDULER_cancel (n->timeout_task); 409 GNUNET_SCHEDULER_cancel (n->timeout_task);
426 n->timeout_task = GNUNET_SCHEDULER_NO_TASK; 410 n->timeout_task = GNUNET_SCHEDULER_NO_TASK;
427 } 411 }
428 if (GNUNET_SCHEDULER_NO_TASK != n->transmission_task) 412 if (GNUNET_SCHEDULER_NO_TASK != n->transmission_task)
429 { 413 {
430 GNUNET_SCHEDULER_cancel (n->timeout_task); 414 GNUNET_SCHEDULER_cancel (n->timeout_task);
431 n->transmission_task = GNUNET_SCHEDULER_NO_TASK; 415 n->transmission_task = GNUNET_SCHEDULER_NO_TASK;
432 } 416 }
433 if (NULL != n->asc) 417 if (NULL != n->asc)
434 { 418 {
435 GNUNET_ATS_suggest_address_cancel (n->asc); 419 GNUNET_ATS_suggest_address_cancel (n->asc);
436 n->asc = NULL; 420 n->asc = NULL;
437 } 421 }
438 GNUNET_array_grow (n->ats, 422 GNUNET_array_grow (n->ats, n->ats_count, 0);
439 n->ats_count,
440 0);
441 if (NULL != n->plugin_name) 423 if (NULL != n->plugin_name)
442 { 424 {
443 GNUNET_free (n->plugin_name); 425 GNUNET_free (n->plugin_name);
444 n->plugin_name = NULL; 426 n->plugin_name = NULL;
445 } 427 }
446 if (NULL != n->addr) 428 if (NULL != n->addr)
447 { 429 {
448 GNUNET_free (n->addr); 430 GNUNET_free (n->addr);
449 n->addr = NULL; 431 n->addr = NULL;
450 n->addrlen = 0; 432 n->addrlen = 0;
451 } 433 }
452 n->session = NULL; 434 n->session = NULL;
453 GNUNET_free (n); 435 GNUNET_free (n);
454} 436}
@@ -462,7 +444,7 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
462 */ 444 */
463static void 445static void
464neighbour_timeout_task (void *cls, 446neighbour_timeout_task (void *cls,
465 const struct GNUNET_SCHEDULER_TaskContext *tc) 447 const struct GNUNET_SCHEDULER_TaskContext *tc)
466{ 448{
467 struct NeighbourMapEntry *n = cls; 449 struct NeighbourMapEntry *n = cls;
468 450
@@ -479,17 +461,14 @@ neighbour_timeout_task (void *cls,
479 * @param value the 'struct NeighbourMapEntry' of the neighbour 461 * @param value the 'struct NeighbourMapEntry' of the neighbour
480 */ 462 */
481static int 463static int
482disconnect_all_neighbours (void *cls, 464disconnect_all_neighbours (void *cls, const GNUNET_HashCode * key, void *value)
483 const GNUNET_HashCode *key,
484 void *value)
485{ 465{
486 struct NeighbourMapEntry *n = value; 466 struct NeighbourMapEntry *n = value;
487 467
488#if DEBUG_TRANSPORT 468#if DEBUG_TRANSPORT
489 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 469 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
490 "Disconnecting peer `%4s', %s\n", 470 "Disconnecting peer `%4s', %s\n",
491 GNUNET_i2s(&n->id), 471 GNUNET_i2s (&n->id), "SHUTDOWN_TASK");
492 "SHUTDOWN_TASK");
493#endif 472#endif
494 disconnect_neighbour (n); 473 disconnect_neighbour (n);
495 return GNUNET_OK; 474 return GNUNET_OK;
@@ -503,8 +482,7 @@ void
503GST_neighbours_stop () 482GST_neighbours_stop ()
504{ 483{
505 GNUNET_CONTAINER_multihashmap_iterate (neighbours, 484 GNUNET_CONTAINER_multihashmap_iterate (neighbours,
506 &disconnect_all_neighbours, 485 &disconnect_all_neighbours, NULL);
507 NULL);
508 GNUNET_CONTAINER_multihashmap_destroy (neighbours); 486 GNUNET_CONTAINER_multihashmap_destroy (neighbours);
509 neighbours = NULL; 487 neighbours = NULL;
510 callback_cls = NULL; 488 callback_cls = NULL;
@@ -528,46 +506,42 @@ GST_neighbours_stop ()
528 */ 506 */
529void 507void
530GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, 508GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
531 const char *plugin_name, 509 const char *plugin_name,
532 const void *address, 510 const void *address,
533 size_t address_len, 511 size_t address_len,
534 struct Session *session, 512 struct Session *session,
535 const struct GNUNET_TRANSPORT_ATS_Information *ats, 513 const struct GNUNET_TRANSPORT_ATS_Information
536 uint32_t ats_count) 514 *ats, uint32_t ats_count)
537{ 515{
538 struct NeighbourMapEntry *n; 516 struct NeighbourMapEntry *n;
539 struct GNUNET_MessageHeader connect_msg; 517 struct GNUNET_MessageHeader connect_msg;
540 518
541 n = lookup_neighbour (peer); 519 n = lookup_neighbour (peer);
542 if (NULL == n) 520 if (NULL == n)
543 { 521 {
544 GNUNET_break (0); 522 GNUNET_break (0);
545 return; 523 return;
546 } 524 }
547 GNUNET_free_non_null (n->addr); 525 GNUNET_free_non_null (n->addr);
548 n->addr = GNUNET_malloc (address_len); 526 n->addr = GNUNET_malloc (address_len);
549 memcpy (n->addr, address, address_len); 527 memcpy (n->addr, address, address_len);
550 n->addrlen = address_len; 528 n->addrlen = address_len;
551 n->session = session; 529 n->session = session;
552 GNUNET_array_grow (n->ats, 530 GNUNET_array_grow (n->ats, n->ats_count, ats_count);
553 n->ats_count,
554 ats_count);
555 memcpy (n->ats, 531 memcpy (n->ats,
556 ats, 532 ats, ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information));
557 ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information));
558 GNUNET_free_non_null (n->plugin_name); 533 GNUNET_free_non_null (n->plugin_name);
559 n->plugin_name = GNUNET_strdup (plugin_name); 534 n->plugin_name = GNUNET_strdup (plugin_name);
560 GNUNET_SCHEDULER_cancel (n->timeout_task); 535 GNUNET_SCHEDULER_cancel (n->timeout_task);
561 n->timeout_task = 536 n->timeout_task =
562 GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 537 GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
563 &neighbour_timeout_task, n); 538 &neighbour_timeout_task, n);
564 connect_msg.size = htons (sizeof (struct GNUNET_MessageHeader)); 539 connect_msg.size = htons (sizeof (struct GNUNET_MessageHeader));
565 connect_msg.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT); 540 connect_msg.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
566 GST_neighbours_send (peer, 541 GST_neighbours_send (peer,
567 &connect_msg, 542 &connect_msg,
568 sizeof (connect_msg), 543 sizeof (connect_msg),
569 GNUNET_TIME_UNIT_FOREVER_REL, 544 GNUNET_TIME_UNIT_FOREVER_REL, NULL, NULL);
570 NULL, NULL);
571} 545}
572 546
573 547
@@ -585,30 +559,25 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
585 */ 559 */
586static void 560static void
587try_connect_using_address (void *cls, 561try_connect_using_address (void *cls,
588 const struct GNUNET_PeerIdentity *target, 562 const struct GNUNET_PeerIdentity *target,
589 const char *plugin_name, 563 const char *plugin_name,
590 const void *plugin_address, 564 const void *plugin_address,
591 size_t plugin_address_len, 565 size_t plugin_address_len,
592 struct GNUNET_BANDWIDTH_Value32NBO bandwidth, 566 struct GNUNET_BANDWIDTH_Value32NBO bandwidth,
593 const struct GNUNET_TRANSPORT_ATS_Information *ats, 567 const struct GNUNET_TRANSPORT_ATS_Information *ats,
594 uint32_t ats_count) 568 uint32_t ats_count)
595{ 569{
596 struct NeighbourMapEntry *n = cls; 570 struct NeighbourMapEntry *n = cls;
597 571
598 n->asc = NULL; 572 n->asc = NULL;
599 GST_neighbours_switch_to_address (target, 573 GST_neighbours_switch_to_address (target,
600 plugin_name, 574 plugin_name,
601 plugin_address, 575 plugin_address,
602 plugin_address_len, 576 plugin_address_len, NULL, ats, ats_count);
603 NULL,
604 ats, ats_count);
605 if (GNUNET_YES == n->is_connected) 577 if (GNUNET_YES == n->is_connected)
606 return; 578 return;
607 n->is_connected = GNUNET_YES; 579 n->is_connected = GNUNET_YES;
608 connect_notify_cb (callback_cls, 580 connect_notify_cb (callback_cls, target, n->ats, n->ats_count);
609 target,
610 n->ats,
611 n->ats_count);
612} 581}
613 582
614 583
@@ -623,33 +592,30 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target)
623 struct NeighbourMapEntry *n; 592 struct NeighbourMapEntry *n;
624 593
625 GNUNET_assert (0 != memcmp (target, 594 GNUNET_assert (0 != memcmp (target,
626 &GST_my_identity, 595 &GST_my_identity,
627 sizeof (struct GNUNET_PeerIdentity))); 596 sizeof (struct GNUNET_PeerIdentity)));
628 n = lookup_neighbour (target); 597 n = lookup_neighbour (target);
629 if ( (NULL != n) && 598 if ((NULL != n) && (GNUNET_YES == n->is_connected))
630 (GNUNET_YES == n->is_connected) ) 599 return; /* already connected */
631 return; /* already connected */
632 if (n == NULL) 600 if (n == NULL)
633 { 601 {
634 n = GNUNET_malloc (sizeof (struct NeighbourMapEntry)); 602 n = GNUNET_malloc (sizeof (struct NeighbourMapEntry));
635 n->id = *target; 603 n->id = *target;
636 GNUNET_BANDWIDTH_tracker_init (&n->in_tracker, 604 GNUNET_BANDWIDTH_tracker_init (&n->in_tracker,
637 GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT, 605 GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT,
638 MAX_BANDWIDTH_CARRY_S); 606 MAX_BANDWIDTH_CARRY_S);
639 n->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 607 n->timeout_task =
640 &neighbour_timeout_task, n); 608 GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
641 GNUNET_assert (GNUNET_OK == 609 &neighbour_timeout_task, n);
642 GNUNET_CONTAINER_multihashmap_put (neighbours, 610 GNUNET_assert (GNUNET_OK ==
643 &n->id.hashPubKey, 611 GNUNET_CONTAINER_multihashmap_put (neighbours,
644 n, 612 &n->id.hashPubKey, n,
645 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 613 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
646 } 614 }
647 if (n->asc != NULL) 615 if (n->asc != NULL)
648 return; /* already trying */ 616 return; /* already trying */
649 n->asc = GNUNET_ATS_suggest_address (GST_ats, 617 n->asc = GNUNET_ATS_suggest_address (GST_ats,
650 target, 618 target, &try_connect_using_address, n);
651 &try_connect_using_address,
652 n);
653} 619}
654 620
655 621
@@ -665,9 +631,8 @@ GST_neighbours_test_connected (const struct GNUNET_PeerIdentity *target)
665 struct NeighbourMapEntry *n; 631 struct NeighbourMapEntry *n;
666 632
667 n = lookup_neighbour (target); 633 n = lookup_neighbour (target);
668 if ( (NULL == n) || 634 if ((NULL == n) || (n->is_connected == GNUNET_YES))
669 (n->is_connected == GNUNET_YES) ) 635 return GNUNET_NO; /* not connected */
670 return GNUNET_NO; /* not connected */
671 return GNUNET_YES; 636 return GNUNET_YES;
672} 637}
673 638
@@ -680,7 +645,7 @@ GST_neighbours_test_connected (const struct GNUNET_PeerIdentity *target)
680 */ 645 */
681void 646void
682GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, 647GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
683 struct Session *session) 648 struct Session *session)
684{ 649{
685 struct NeighbourMapEntry *n; 650 struct NeighbourMapEntry *n;
686 651
@@ -688,24 +653,23 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
688 if (NULL == n) 653 if (NULL == n)
689 return; 654 return;
690 if (session != n->session) 655 if (session != n->session)
691 return; /* doesn't affect us */ 656 return; /* doesn't affect us */
692 n->session = NULL; 657 n->session = NULL;
693 if (GNUNET_YES != n->is_connected) 658 if (GNUNET_YES != n->is_connected)
694 return; /* not connected anymore anyway, shouldn't matter */ 659 return; /* not connected anymore anyway, shouldn't matter */
695 /* try QUICKLY to re-establish a connection, reduce timeout! */ 660 /* try QUICKLY to re-establish a connection, reduce timeout! */
696 if (NULL != n->ats) 661 if (NULL != n->ats)
697 { 662 {
698 /* how can this be!? */ 663 /* how can this be!? */
699 GNUNET_break (0); 664 GNUNET_break (0);
700 return; 665 return;
701 } 666 }
702 GNUNET_SCHEDULER_cancel (n->timeout_task); 667 GNUNET_SCHEDULER_cancel (n->timeout_task);
703 n->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 668 n->timeout_task =
704 &neighbour_timeout_task, n); 669 GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
705 n->asc = GNUNET_ATS_suggest_address (GST_ats, 670 &neighbour_timeout_task, n);
706 peer, 671 n->asc =
707 &try_connect_using_address, 672 GNUNET_ATS_suggest_address (GST_ats, peer, &try_connect_using_address, n);
708 n);
709} 673}
710 674
711 675
@@ -721,48 +685,42 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
721 */ 685 */
722void 686void
723GST_neighbours_send (const struct GNUNET_PeerIdentity *target, 687GST_neighbours_send (const struct GNUNET_PeerIdentity *target,
724 const void *msg, 688 const void *msg,
725 size_t msg_size, 689 size_t msg_size,
726 struct GNUNET_TIME_Relative timeout, 690 struct GNUNET_TIME_Relative timeout,
727 GST_NeighbourSendContinuation cont, 691 GST_NeighbourSendContinuation cont, void *cont_cls)
728 void *cont_cls)
729{ 692{
730 struct NeighbourMapEntry *n; 693 struct NeighbourMapEntry *n;
731 struct MessageQueue *mq; 694 struct MessageQueue *mq;
732 695
733 n = lookup_neighbour (target); 696 n = lookup_neighbour (target);
734 if ( (n == NULL) || 697 if ((n == NULL) || (GNUNET_YES != n->is_connected))
735 (GNUNET_YES != n->is_connected) ) 698 {
736 { 699 GNUNET_STATISTICS_update (GST_stats,
737 GNUNET_STATISTICS_update (GST_stats, 700 gettext_noop
738 gettext_noop ("# SET QUOTA messages ignored (no such peer)"), 701 ("# SET QUOTA messages ignored (no such peer)"),
739 1, 702 1, GNUNET_NO);
740 GNUNET_NO); 703 if (NULL != cont)
741 if (NULL != cont) 704 cont (cont_cls, GNUNET_SYSERR);
742 cont (cont_cls, 705 return;
743 GNUNET_SYSERR); 706 }
744 return;
745 }
746 GNUNET_assert (msg_size >= sizeof (struct GNUNET_MessageHeader)); 707 GNUNET_assert (msg_size >= sizeof (struct GNUNET_MessageHeader));
747 GNUNET_STATISTICS_update (GST_stats, 708 GNUNET_STATISTICS_update (GST_stats,
748 gettext_noop ("# bytes in message queue for other peers"), 709 gettext_noop
749 msg_size, 710 ("# bytes in message queue for other peers"),
750 GNUNET_NO); 711 msg_size, GNUNET_NO);
751 mq = GNUNET_malloc (sizeof (struct MessageQueue) + msg_size); 712 mq = GNUNET_malloc (sizeof (struct MessageQueue) + msg_size);
752 mq->cont = cont; 713 mq->cont = cont;
753 mq->cont_cls = cont_cls; 714 mq->cont_cls = cont_cls;
754 /* FIXME: this memcpy can be up to 7% of our total runtime! */ 715 /* FIXME: this memcpy can be up to 7% of our total runtime! */
755 memcpy (&mq[1], msg, msg_size); 716 memcpy (&mq[1], msg, msg_size);
756 mq->message_buf = (const char*) &mq[1]; 717 mq->message_buf = (const char *) &mq[1];
757 mq->message_buf_size = msg_size; 718 mq->message_buf_size = msg_size;
758 mq->timeout = GNUNET_TIME_relative_to_absolute (timeout); 719 mq->timeout = GNUNET_TIME_relative_to_absolute (timeout);
759 GNUNET_CONTAINER_DLL_insert_tail (n->messages_head, 720 GNUNET_CONTAINER_DLL_insert_tail (n->messages_head, n->messages_tail, mq);
760 n->messages_tail, 721 if ((GNUNET_SCHEDULER_NO_TASK == n->transmission_task) &&
761 mq); 722 (NULL == n->is_active))
762 if ( (GNUNET_SCHEDULER_NO_TASK == n->transmission_task) && 723 n->transmission_task = GNUNET_SCHEDULER_add_now (&transmission_task, n);
763 (NULL == n->is_active) )
764 n->transmission_task = GNUNET_SCHEDULER_add_now (&transmission_task,
765 n);
766} 724}
767 725
768 726
@@ -778,68 +736,64 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target,
778 * @return how long to wait before reading more from this sender 736 * @return how long to wait before reading more from this sender
779 */ 737 */
780struct GNUNET_TIME_Relative 738struct GNUNET_TIME_Relative
781GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity *sender, 739GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity
782 ssize_t size, 740 *sender, ssize_t size, int *do_forward)
783 int *do_forward)
784{ 741{
785 struct NeighbourMapEntry *n; 742 struct NeighbourMapEntry *n;
786 struct GNUNET_TIME_Relative ret; 743 struct GNUNET_TIME_Relative ret;
787 744
788 n = lookup_neighbour (sender); 745 n = lookup_neighbour (sender);
789 if (n == NULL) 746 if (n == NULL)
790 { 747 {
791 *do_forward = GNUNET_NO; 748 *do_forward = GNUNET_NO;
792 return GNUNET_TIME_UNIT_ZERO; 749 return GNUNET_TIME_UNIT_ZERO;
793 } 750 }
794 if (GNUNET_YES == GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, 751 if (GNUNET_YES == GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, size))
795 size)) 752 {
796 { 753 n->quota_violation_count++;
797 n->quota_violation_count++;
798#if DEBUG_TRANSPORT 754#if DEBUG_TRANSPORT
799 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 755 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
800 "Bandwidth quota (%u b/s) violation detected (total of %u).\n", 756 "Bandwidth quota (%u b/s) violation detected (total of %u).\n",
801 n->in_tracker.available_bytes_per_s__, 757 n->in_tracker.available_bytes_per_s__,
802 n->quota_violation_count); 758 n->quota_violation_count);
803#endif 759#endif
804 /* Discount 32k per violation */ 760 /* Discount 32k per violation */
805 GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, 761 GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, -32 * 1024);
806 - 32 * 1024); 762 }
807 }
808 else 763 else
764 {
765 if (n->quota_violation_count > 0)
809 { 766 {
810 if (n->quota_violation_count > 0) 767 /* try to add 32k back */
811 { 768 GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker, 32 * 1024);
812 /* try to add 32k back */ 769 n->quota_violation_count--;
813 GNUNET_BANDWIDTH_tracker_consume (&n->in_tracker,
814 32 * 1024);
815 n->quota_violation_count--;
816 }
817 } 770 }
771 }
818 if (n->quota_violation_count > QUOTA_VIOLATION_DROP_THRESHOLD) 772 if (n->quota_violation_count > QUOTA_VIOLATION_DROP_THRESHOLD)
819 { 773 {
820 GNUNET_STATISTICS_update (GST_stats, 774 GNUNET_STATISTICS_update (GST_stats,
821 gettext_noop ("# bandwidth quota violations by other peers"), 775 gettext_noop
822 1, 776 ("# bandwidth quota violations by other peers"),
823 GNUNET_NO); 777 1, GNUNET_NO);
824 *do_forward = GNUNET_NO; 778 *do_forward = GNUNET_NO;
825 return GNUNET_CONSTANTS_QUOTA_VIOLATION_TIMEOUT; 779 return GNUNET_CONSTANTS_QUOTA_VIOLATION_TIMEOUT;
826 } 780 }
827 *do_forward = GNUNET_YES; 781 *do_forward = GNUNET_YES;
828 ret = GNUNET_BANDWIDTH_tracker_get_delay (&n->in_tracker, 0); 782 ret = GNUNET_BANDWIDTH_tracker_get_delay (&n->in_tracker, 0);
829 if (ret.rel_value > 0) 783 if (ret.rel_value > 0)
830 { 784 {
831#if DEBUG_TRANSPORT 785#if DEBUG_TRANSPORT
832 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 786 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
833 "Throttling read (%llu bytes excess at %u b/s), waiting %llu ms before reading more.\n", 787 "Throttling read (%llu bytes excess at %u b/s), waiting %llu ms before reading more.\n",
834 (unsigned long long) n->in_tracker.consumption_since_last_update__, 788 (unsigned long long) n->
835 (unsigned int) n->in_tracker.available_bytes_per_s__, 789 in_tracker.consumption_since_last_update__,
836 (unsigned long long) ret.rel_value); 790 (unsigned int) n->in_tracker.available_bytes_per_s__,
791 (unsigned long long) ret.rel_value);
837#endif 792#endif
838 GNUNET_STATISTICS_update (GST_stats, 793 GNUNET_STATISTICS_update (GST_stats,
839 gettext_noop ("# ms throttling suggested"), 794 gettext_noop ("# ms throttling suggested"),
840 (int64_t) ret.rel_value, 795 (int64_t) ret.rel_value, GNUNET_NO);
841 GNUNET_NO); 796 }
842 }
843 return ret; 797 return ret;
844} 798}
845 799
@@ -857,17 +811,17 @@ GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour)
857 811
858 n = lookup_neighbour (neighbour); 812 n = lookup_neighbour (neighbour);
859 if (NULL == n) 813 if (NULL == n)
860 { 814 {
861 GNUNET_STATISTICS_update (GST_stats, 815 GNUNET_STATISTICS_update (GST_stats,
862 gettext_noop ("# KEEPALIVE messages discarded (not connected)"), 816 gettext_noop
863 1, 817 ("# KEEPALIVE messages discarded (not connected)"),
864 GNUNET_NO); 818 1, GNUNET_NO);
865 return; 819 return;
866 } 820 }
867 GNUNET_SCHEDULER_cancel (n->timeout_task); 821 GNUNET_SCHEDULER_cancel (n->timeout_task);
868 n->timeout_task = 822 n->timeout_task =
869 GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 823 GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
870 &neighbour_timeout_task, n); 824 &neighbour_timeout_task, n);
871} 825}
872 826
873 827
@@ -879,33 +833,30 @@ GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour)
879 */ 833 */
880void 834void
881GST_neighbours_set_incoming_quota (const struct GNUNET_PeerIdentity *neighbour, 835GST_neighbours_set_incoming_quota (const struct GNUNET_PeerIdentity *neighbour,
882 struct GNUNET_BANDWIDTH_Value32NBO quota) 836 struct GNUNET_BANDWIDTH_Value32NBO quota)
883{ 837{
884 struct NeighbourMapEntry *n; 838 struct NeighbourMapEntry *n;
885 839
886 n = lookup_neighbour (neighbour); 840 n = lookup_neighbour (neighbour);
887 if (n == NULL) 841 if (n == NULL)
888 { 842 {
889 GNUNET_STATISTICS_update (GST_stats, 843 GNUNET_STATISTICS_update (GST_stats,
890 gettext_noop ("# SET QUOTA messages ignored (no such peer)"), 844 gettext_noop
891 1, 845 ("# SET QUOTA messages ignored (no such peer)"),
892 GNUNET_NO); 846 1, GNUNET_NO);
893 return; 847 return;
894 } 848 }
895 GNUNET_BANDWIDTH_tracker_update_quota (&n->in_tracker, 849 GNUNET_BANDWIDTH_tracker_update_quota (&n->in_tracker, quota);
896 quota);
897 if (0 != ntohl (quota.value__)) 850 if (0 != ntohl (quota.value__))
898 return; 851 return;
899#if DEBUG_TRANSPORT 852#if DEBUG_TRANSPORT
900 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 853 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
901 "Disconnecting peer `%4s' due to `%s'\n", 854 "Disconnecting peer `%4s' due to `%s'\n",
902 GNUNET_i2s(&n->id), 855 GNUNET_i2s (&n->id), "SET_QUOTA");
903 "SET_QUOTA");
904#endif 856#endif
905 GNUNET_STATISTICS_update (GST_stats, 857 GNUNET_STATISTICS_update (GST_stats,
906 gettext_noop ("# disconnects due to quota of 0"), 858 gettext_noop ("# disconnects due to quota of 0"),
907 1, 859 1, GNUNET_NO);
908 GNUNET_NO);
909 disconnect_neighbour (n); 860 disconnect_neighbour (n);
910} 861}
911 862
@@ -936,20 +887,15 @@ struct IteratorContext
936 * @return GNUNET_OK (continue to iterate) 887 * @return GNUNET_OK (continue to iterate)
937 */ 888 */
938static int 889static int
939neighbours_iterate (void *cls, 890neighbours_iterate (void *cls, const GNUNET_HashCode * key, void *value)
940 const GNUNET_HashCode *key,
941 void *value)
942{ 891{
943 struct IteratorContext *ic = cls; 892 struct IteratorContext *ic = cls;
944 struct NeighbourMapEntry *n = value; 893 struct NeighbourMapEntry *n = value;
945 894
946 if (GNUNET_YES != n->is_connected) 895 if (GNUNET_YES != n->is_connected)
947 return GNUNET_OK; 896 return GNUNET_OK;
948 GNUNET_assert (n->ats_count > 0); 897 GNUNET_assert (n->ats_count > 0);
949 ic->cb (ic->cb_cls, 898 ic->cb (ic->cb_cls, &n->id, n->ats, n->ats_count - 1);
950 &n->id,
951 n->ats,
952 n->ats_count - 1);
953 return GNUNET_OK; 899 return GNUNET_OK;
954} 900}
955 901
@@ -961,16 +907,13 @@ neighbours_iterate (void *cls,
961 * @param cb_cls closure for cb 907 * @param cb_cls closure for cb
962 */ 908 */
963void 909void
964GST_neighbours_iterate (GST_NeighbourIterator cb, 910GST_neighbours_iterate (GST_NeighbourIterator cb, void *cb_cls)
965 void *cb_cls)
966{ 911{
967 struct IteratorContext ic; 912 struct IteratorContext ic;
968 913
969 ic.cb = cb; 914 ic.cb = cb;
970 ic.cb_cls = cb_cls; 915 ic.cb_cls = cb_cls;
971 GNUNET_CONTAINER_multihashmap_iterate (neighbours, 916 GNUNET_CONTAINER_multihashmap_iterate (neighbours, &neighbours_iterate, &ic);
972 &neighbours_iterate,
973 &ic);
974} 917}
975 918
976 919
@@ -987,27 +930,23 @@ GST_neighbours_force_disconnect (const struct GNUNET_PeerIdentity *target)
987 struct GNUNET_MessageHeader disconnect_msg; 930 struct GNUNET_MessageHeader disconnect_msg;
988 931
989 n = lookup_neighbour (target); 932 n = lookup_neighbour (target);
990 if (NULL == n) 933 if (NULL == n)
991 return; /* not active */ 934 return; /* not active */
992 if (GNUNET_YES == n->is_connected) 935 if (GNUNET_YES == n->is_connected)
993 { 936 {
994 /* we're actually connected, send DISCONNECT message */ 937 /* we're actually connected, send DISCONNECT message */
995 disconnect_msg.size = htons (sizeof (struct GNUNET_MessageHeader)); 938 disconnect_msg.size = htons (sizeof (struct GNUNET_MessageHeader));
996 disconnect_msg.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT); 939 disconnect_msg.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
997 papi = GST_plugins_find (n->plugin_name); 940 papi = GST_plugins_find (n->plugin_name);
998 if (papi != NULL) 941 if (papi != NULL)
999 papi->send (papi->cls, 942 papi->send (papi->cls,
1000 target, 943 target,
1001 (const void*) &disconnect_msg, 944 (const void *) &disconnect_msg,
1002 sizeof (struct GNUNET_MessageHeader), 945 sizeof (struct GNUNET_MessageHeader),
1003 UINT32_MAX /* priority */, 946 UINT32_MAX /* priority */ ,
1004 GNUNET_TIME_UNIT_FOREVER_REL, 947 GNUNET_TIME_UNIT_FOREVER_REL,
1005 n->session, 948 n->session, n->addr, n->addrlen, GNUNET_YES, NULL, NULL);
1006 n->addr, 949 }
1007 n->addrlen,
1008 GNUNET_YES,
1009 NULL, NULL);
1010 }
1011 disconnect_neighbour (n); 950 disconnect_neighbour (n);
1012} 951}
1013 952