aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/plugin_transport_tcp.c')
-rw-r--r--src/transport/plugin_transport_tcp.c1679
1 files changed, 791 insertions, 888 deletions
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c
index 2c20ba35e..bd2f4aa6a 100644
--- a/src/transport/plugin_transport_tcp.c
+++ b/src/transport/plugin_transport_tcp.c
@@ -343,7 +343,7 @@ struct Plugin
343 * Map of peers we have tried to contact behind a NAT 343 * Map of peers we have tried to contact behind a NAT
344 */ 344 */
345 struct GNUNET_CONTAINER_MultiHashMap *nat_wait_conns; 345 struct GNUNET_CONTAINER_MultiHashMap *nat_wait_conns;
346 346
347 /** 347 /**
348 * List of active TCP probes. 348 * List of active TCP probes.
349 */ 349 */
@@ -358,7 +358,7 @@ struct Plugin
358 * Handle for (DYN)DNS lookup of our external IP. 358 * Handle for (DYN)DNS lookup of our external IP.
359 */ 359 */
360 struct GNUNET_RESOLVER_RequestHandle *ext_dns; 360 struct GNUNET_RESOLVER_RequestHandle *ext_dns;
361 361
362 /** 362 /**
363 * How many more TCP sessions are we allowed to open right now? 363 * How many more TCP sessions are we allowed to open right now?
364 */ 364 */
@@ -397,9 +397,8 @@ struct Plugin
397 */ 397 */
398static int 398static int
399plugin_tcp_access_check (void *cls, 399plugin_tcp_access_check (void *cls,
400 const struct GNUNET_CONNECTION_Credentials *ucred, 400 const struct GNUNET_CONNECTION_Credentials *ucred,
401 const struct sockaddr *addr, 401 const struct sockaddr *addr, socklen_t addrlen)
402 socklen_t addrlen)
403{ 402{
404 struct Plugin *plugin = cls; 403 struct Plugin *plugin = cls;
405 404
@@ -421,9 +420,8 @@ plugin_tcp_access_check (void *cls,
421 */ 420 */
422static void 421static void
423tcp_nat_port_map_callback (void *cls, 422tcp_nat_port_map_callback (void *cls,
424 int add_remove, 423 int add_remove,
425 const struct sockaddr *addr, 424 const struct sockaddr *addr, socklen_t addrlen)
426 socklen_t addrlen)
427{ 425{
428 struct Plugin *plugin = cls; 426 struct Plugin *plugin = cls;
429 struct IPv4TcpAddress t4; 427 struct IPv4TcpAddress t4;
@@ -432,37 +430,34 @@ tcp_nat_port_map_callback (void *cls,
432 size_t args; 430 size_t args;
433 431
434 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 432 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
435 "tcp", 433 "tcp",
436 "NPMC called with %d for address `%s'\n", 434 "NPMC called with %d for address `%s'\n",
437 add_remove, 435 add_remove, GNUNET_a2s (addr, addrlen));
438 GNUNET_a2s (addr, addrlen));
439 /* convert 'addr' to our internal format */ 436 /* convert 'addr' to our internal format */
440 switch (addr->sa_family) 437 switch (addr->sa_family)
441 { 438 {
442 case AF_INET: 439 case AF_INET:
443 GNUNET_assert (addrlen == sizeof (struct sockaddr_in)); 440 GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
444 t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; 441 t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
445 t4.t4_port = ((struct sockaddr_in *) addr)->sin_port; 442 t4.t4_port = ((struct sockaddr_in *) addr)->sin_port;
446 arg = &t4; 443 arg = &t4;
447 args = sizeof (t4); 444 args = sizeof (t4);
448 break; 445 break;
449 case AF_INET6: 446 case AF_INET6:
450 GNUNET_assert (addrlen == sizeof (struct sockaddr_in6)); 447 GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
451 memcpy (&t6.ipv6_addr, 448 memcpy (&t6.ipv6_addr,
452 &((struct sockaddr_in6 *) addr)->sin6_addr, 449 &((struct sockaddr_in6 *) addr)->sin6_addr,
453 sizeof (struct in6_addr)); 450 sizeof (struct in6_addr));
454 t6.t6_port = ((struct sockaddr_in6 *) addr)->sin6_port; 451 t6.t6_port = ((struct sockaddr_in6 *) addr)->sin6_port;
455 arg = &t6; 452 arg = &t6;
456 args = sizeof (t6); 453 args = sizeof (t6);
457 break; 454 break;
458 default: 455 default:
459 GNUNET_break (0); 456 GNUNET_break (0);
460 return; 457 return;
461 } 458 }
462 /* modify our published address list */ 459 /* modify our published address list */
463 plugin->env->notify_address (plugin->env->cls, 460 plugin->env->notify_address (plugin->env->cls, add_remove, arg, args);
464 add_remove,
465 arg, args);
466} 461}
467 462
468 463
@@ -477,10 +472,8 @@ tcp_nat_port_map_callback (void *cls,
477 * @param addrlen length of the address 472 * @param addrlen length of the address
478 * @return string representing the same address 473 * @return string representing the same address
479 */ 474 */
480static const char* 475static const char *
481tcp_address_to_string (void *cls, 476tcp_address_to_string (void *cls, const void *addr, size_t addrlen)
482 const void *addr,
483 size_t addrlen)
484{ 477{
485 static char rbuf[INET6_ADDRSTRLEN + 12]; 478 static char rbuf[INET6_ADDRSTRLEN + 12];
486 char buf[INET6_ADDRSTRLEN]; 479 char buf[INET6_ADDRSTRLEN];
@@ -493,40 +486,38 @@ tcp_address_to_string (void *cls,
493 uint16_t port; 486 uint16_t port;
494 487
495 if (addrlen == sizeof (struct IPv6TcpAddress)) 488 if (addrlen == sizeof (struct IPv6TcpAddress))
496 { 489 {
497 t6 = addr; 490 t6 = addr;
498 af = AF_INET6; 491 af = AF_INET6;
499 port = ntohs (t6->t6_port); 492 port = ntohs (t6->t6_port);
500 memcpy (&a6, &t6->ipv6_addr, sizeof (a6)); 493 memcpy (&a6, &t6->ipv6_addr, sizeof (a6));
501 sb = &a6; 494 sb = &a6;
502 } 495 }
503 else if (addrlen == sizeof (struct IPv4TcpAddress)) 496 else if (addrlen == sizeof (struct IPv4TcpAddress))
504 { 497 {
505 t4 = addr; 498 t4 = addr;
506 af = AF_INET; 499 af = AF_INET;
507 port = ntohs (t4->t4_port); 500 port = ntohs (t4->t4_port);
508 memcpy (&a4, &t4->ipv4_addr, sizeof (a4)); 501 memcpy (&a4, &t4->ipv4_addr, sizeof (a4));
509 sb = &a4; 502 sb = &a4;
510 } 503 }
511 else 504 else
512 { 505 {
513 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, 506 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
514 "tcp", 507 "tcp",
515 _("Unexpected address length: %u bytes\n"), 508 _("Unexpected address length: %u bytes\n"),
516 (unsigned int) addrlen); 509 (unsigned int) addrlen);
517 GNUNET_break (0); 510 GNUNET_break (0);
518 return NULL; 511 return NULL;
519 } 512 }
520 if (NULL == inet_ntop (af, sb, buf, INET6_ADDRSTRLEN)) 513 if (NULL == inet_ntop (af, sb, buf, INET6_ADDRSTRLEN))
521 { 514 {
522 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop"); 515 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop");
523 return NULL; 516 return NULL;
524 } 517 }
525 GNUNET_snprintf (rbuf, 518 GNUNET_snprintf (rbuf,
526 sizeof (rbuf), 519 sizeof (rbuf),
527 (af == AF_INET6) ? "[%s]:%u" : "%s:%u", 520 (af == AF_INET6) ? "[%s]:%u" : "%s:%u", buf, port);
528 buf,
529 port);
530 return rbuf; 521 return rbuf;
531} 522}
532 523
@@ -565,8 +556,7 @@ find_session_by_client (struct Plugin *plugin,
565static struct Session * 556static struct Session *
566create_session (struct Plugin *plugin, 557create_session (struct Plugin *plugin,
567 const struct GNUNET_PeerIdentity *target, 558 const struct GNUNET_PeerIdentity *target,
568 struct GNUNET_SERVER_Client *client, 559 struct GNUNET_SERVER_Client *client, int is_nat)
569 int is_nat)
570{ 560{
571 struct Session *ret; 561 struct Session *ret;
572 struct PendingMessage *pm; 562 struct PendingMessage *pm;
@@ -578,24 +568,25 @@ create_session (struct Plugin *plugin,
578 GNUNET_assert (client == NULL); 568 GNUNET_assert (client == NULL);
579#if DEBUG_TCP 569#if DEBUG_TCP
580 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 570 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
581 "tcp", 571 "tcp",
582 "Creating new session for peer `%4s'\n", 572 "Creating new session for peer `%4s'\n",
583 GNUNET_i2s (target)); 573 GNUNET_i2s (target));
584#endif 574#endif
585 ret = GNUNET_malloc (sizeof (struct Session)); 575 ret = GNUNET_malloc (sizeof (struct Session));
586 ret->last_activity = GNUNET_TIME_absolute_get (); 576 ret->last_activity = GNUNET_TIME_absolute_get ();
587 ret->plugin = plugin; 577 ret->plugin = plugin;
588 ret->is_nat = is_nat; 578 ret->is_nat = is_nat;
589 if (is_nat != GNUNET_YES) /* If not a NAT WAIT conn, add it to global list */ 579 if (is_nat != GNUNET_YES) /* If not a NAT WAIT conn, add it to global list */
590 { 580 {
591 ret->next = plugin->sessions; 581 ret->next = plugin->sessions;
592 plugin->sessions = ret; 582 plugin->sessions = ret;
593 } 583 }
594 ret->client = client; 584 ret->client = client;
595 ret->target = *target; 585 ret->target = *target;
596 ret->expecting_welcome = GNUNET_YES; 586 ret->expecting_welcome = GNUNET_YES;
597 pm = GNUNET_malloc (sizeof (struct PendingMessage) + sizeof (struct WelcomeMessage)); 587 pm = GNUNET_malloc (sizeof (struct PendingMessage) +
598 pm->msg = (const char*) &pm[1]; 588 sizeof (struct WelcomeMessage));
589 pm->msg = (const char *) &pm[1];
599 pm->message_size = sizeof (struct WelcomeMessage); 590 pm->message_size = sizeof (struct WelcomeMessage);
600 welcome.header.size = htons (sizeof (struct WelcomeMessage)); 591 welcome.header.size = htons (sizeof (struct WelcomeMessage));
601 welcome.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME); 592 welcome.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME);
@@ -603,17 +594,14 @@ create_session (struct Plugin *plugin,
603 memcpy (&pm[1], &welcome, sizeof (welcome)); 594 memcpy (&pm[1], &welcome, sizeof (welcome));
604 pm->timeout = GNUNET_TIME_UNIT_FOREVER_ABS; 595 pm->timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
605 GNUNET_STATISTICS_update (plugin->env->stats, 596 GNUNET_STATISTICS_update (plugin->env->stats,
606 gettext_noop ("# bytes currently in TCP buffers"), 597 gettext_noop ("# bytes currently in TCP buffers"),
607 pm->message_size, 598 pm->message_size, GNUNET_NO);
608 GNUNET_NO);
609 GNUNET_CONTAINER_DLL_insert (ret->pending_messages_head, 599 GNUNET_CONTAINER_DLL_insert (ret->pending_messages_head,
610 ret->pending_messages_tail, 600 ret->pending_messages_tail, pm);
611 pm);
612 if (is_nat != GNUNET_YES) 601 if (is_nat != GNUNET_YES)
613 GNUNET_STATISTICS_update (plugin->env->stats, 602 GNUNET_STATISTICS_update (plugin->env->stats,
614 gettext_noop ("# TCP sessions active"), 603 gettext_noop ("# TCP sessions active"),
615 1, 604 1, GNUNET_NO);
616 GNUNET_NO);
617 return ret; 605 return ret;
618} 606}
619 607
@@ -655,111 +643,101 @@ do_transmit (void *cls, size_t size, void *buf)
655 session->transmit_handle = NULL; 643 session->transmit_handle = NULL;
656 plugin = session->plugin; 644 plugin = session->plugin;
657 if (buf == NULL) 645 if (buf == NULL)
658 { 646 {
659#if DEBUG_TCP 647#if DEBUG_TCP
660 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 648 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
661 "tcp", 649 "tcp",
662 "Timeout trying to transmit to peer `%4s', discarding message queue.\n", 650 "Timeout trying to transmit to peer `%4s', discarding message queue.\n",
663 GNUNET_i2s (&session->target)); 651 GNUNET_i2s (&session->target));
664#endif 652#endif
665 /* timeout; cancel all messages that have already expired */ 653 /* timeout; cancel all messages that have already expired */
666 hd = NULL; 654 hd = NULL;
667 tl = NULL; 655 tl = NULL;
668 ret = 0; 656 ret = 0;
669 now = GNUNET_TIME_absolute_get (); 657 now = GNUNET_TIME_absolute_get ();
670 while ( (NULL != (pos = session->pending_messages_head)) && 658 while ((NULL != (pos = session->pending_messages_head)) &&
671 (pos->timeout.abs_value <= now.abs_value) ) 659 (pos->timeout.abs_value <= now.abs_value))
672 { 660 {
673 GNUNET_CONTAINER_DLL_remove (session->pending_messages_head, 661 GNUNET_CONTAINER_DLL_remove (session->pending_messages_head,
674 session->pending_messages_tail, 662 session->pending_messages_tail, pos);
675 pos);
676#if DEBUG_TCP 663#if DEBUG_TCP
677 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 664 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
678 "tcp", 665 "tcp",
679 "Failed to transmit %u byte message to `%4s'.\n", 666 "Failed to transmit %u byte message to `%4s'.\n",
680 pos->message_size, 667 pos->message_size, GNUNET_i2s (&session->target));
681 GNUNET_i2s (&session->target));
682#endif 668#endif
683 ret += pos->message_size; 669 ret += pos->message_size;
684 GNUNET_CONTAINER_DLL_insert_after (hd, tl, tl, pos); 670 GNUNET_CONTAINER_DLL_insert_after (hd, tl, tl, pos);
685 } 671 }
686 /* do this call before callbacks (so that if callbacks destroy 672 /* do this call before callbacks (so that if callbacks destroy
687 session, they have a chance to cancel actions done by this 673 * session, they have a chance to cancel actions done by this
688 call) */ 674 * call) */
689 process_pending_messages (session); 675 process_pending_messages (session);
690 pid = session->target; 676 pid = session->target;
691 /* no do callbacks and do not use session again since 677 /* no do callbacks and do not use session again since
692 the callbacks may abort the session */ 678 * the callbacks may abort the session */
693 while (NULL != (pos = hd)) 679 while (NULL != (pos = hd))
694 { 680 {
695 GNUNET_CONTAINER_DLL_remove (hd, tl, pos); 681 GNUNET_CONTAINER_DLL_remove (hd, tl, pos);
696 if (pos->transmit_cont != NULL) 682 if (pos->transmit_cont != NULL)
697 pos->transmit_cont (pos->transmit_cont_cls, 683 pos->transmit_cont (pos->transmit_cont_cls, &pid, GNUNET_SYSERR);
698 &pid, GNUNET_SYSERR); 684 GNUNET_free (pos);
699 GNUNET_free (pos);
700 }
701 GNUNET_STATISTICS_update (plugin->env->stats,
702 gettext_noop ("# bytes currently in TCP buffers"),
703 - (int64_t) ret,
704 GNUNET_NO);
705 GNUNET_STATISTICS_update (plugin->env->stats,
706 gettext_noop ("# bytes discarded by TCP (timeout)"),
707 ret,
708 GNUNET_NO);
709 return 0;
710 } 685 }
686 GNUNET_STATISTICS_update (plugin->env->stats,
687 gettext_noop ("# bytes currently in TCP buffers"),
688 -(int64_t) ret, GNUNET_NO);
689 GNUNET_STATISTICS_update (plugin->env->stats,
690 gettext_noop
691 ("# bytes discarded by TCP (timeout)"), ret,
692 GNUNET_NO);
693 return 0;
694 }
711 /* copy all pending messages that would fit */ 695 /* copy all pending messages that would fit */
712 ret = 0; 696 ret = 0;
713 cbuf = buf; 697 cbuf = buf;
714 hd = NULL; 698 hd = NULL;
715 tl = NULL; 699 tl = NULL;
716 while (NULL != (pos = session->pending_messages_head)) 700 while (NULL != (pos = session->pending_messages_head))
717 { 701 {
718 if (ret + pos->message_size > size) 702 if (ret + pos->message_size > size)
719 break; 703 break;
720 GNUNET_CONTAINER_DLL_remove (session->pending_messages_head, 704 GNUNET_CONTAINER_DLL_remove (session->pending_messages_head,
721 session->pending_messages_tail, 705 session->pending_messages_tail, pos);
722 pos); 706 GNUNET_assert (size >= pos->message_size);
723 GNUNET_assert (size >= pos->message_size); 707 /* FIXME: this memcpy can be up to 7% of our total runtime */
724 /* FIXME: this memcpy can be up to 7% of our total runtime */ 708 memcpy (cbuf, pos->msg, pos->message_size);
725 memcpy (cbuf, pos->msg, pos->message_size); 709 cbuf += pos->message_size;
726 cbuf += pos->message_size; 710 ret += pos->message_size;
727 ret += pos->message_size; 711 size -= pos->message_size;
728 size -= pos->message_size; 712 GNUNET_CONTAINER_DLL_insert_after (hd, tl, tl, pos);
729 GNUNET_CONTAINER_DLL_insert_after (hd, tl, tl, pos); 713 }
730 }
731 /* schedule 'continuation' before callbacks so that callbacks that 714 /* schedule 'continuation' before callbacks so that callbacks that
732 cancel everything don't cause us to use a session that no longer 715 * cancel everything don't cause us to use a session that no longer
733 exists... */ 716 * exists... */
734 process_pending_messages (session); 717 process_pending_messages (session);
735 session->last_activity = GNUNET_TIME_absolute_get (); 718 session->last_activity = GNUNET_TIME_absolute_get ();
736 pid = session->target; 719 pid = session->target;
737 /* we'll now call callbacks that may cancel the session; hence 720 /* we'll now call callbacks that may cancel the session; hence
738 we should not use 'session' after this point */ 721 * we should not use 'session' after this point */
739 while (NULL != (pos = hd)) 722 while (NULL != (pos = hd))
740 { 723 {
741 GNUNET_CONTAINER_DLL_remove (hd, tl, pos); 724 GNUNET_CONTAINER_DLL_remove (hd, tl, pos);
742 if (pos->transmit_cont != NULL) 725 if (pos->transmit_cont != NULL)
743 pos->transmit_cont (pos->transmit_cont_cls, 726 pos->transmit_cont (pos->transmit_cont_cls, &pid, GNUNET_OK);
744 &pid, GNUNET_OK); 727 GNUNET_free (pos);
745 GNUNET_free (pos); 728 }
746 }
747 GNUNET_assert (hd == NULL); 729 GNUNET_assert (hd == NULL);
748 GNUNET_assert (tl == NULL); 730 GNUNET_assert (tl == NULL);
749#if DEBUG_TCP > 1 731#if DEBUG_TCP > 1
750 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 732 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
751 "tcp", 733 "tcp", "Transmitting %u bytes\n", ret);
752 "Transmitting %u bytes\n",
753 ret);
754#endif 734#endif
755 GNUNET_STATISTICS_update (plugin->env->stats, 735 GNUNET_STATISTICS_update (plugin->env->stats,
756 gettext_noop ("# bytes currently in TCP buffers"), 736 gettext_noop ("# bytes currently in TCP buffers"),
757 - (int64_t) ret, 737 -(int64_t) ret, GNUNET_NO);
758 GNUNET_NO);
759 GNUNET_STATISTICS_update (plugin->env->stats, 738 GNUNET_STATISTICS_update (plugin->env->stats,
760 gettext_noop ("# bytes transmitted via TCP"), 739 gettext_noop ("# bytes transmitted via TCP"),
761 ret, 740 ret, GNUNET_NO);
762 GNUNET_NO);
763 return ret; 741 return ret;
764} 742}
765 743
@@ -782,11 +760,11 @@ process_pending_messages (struct Session *session)
782 return; 760 return;
783 761
784 session->transmit_handle 762 session->transmit_handle
785 = GNUNET_SERVER_notify_transmit_ready (session->client, 763 = GNUNET_SERVER_notify_transmit_ready (session->client,
786 pm->message_size, 764 pm->message_size,
787 GNUNET_TIME_absolute_get_remaining 765 GNUNET_TIME_absolute_get_remaining
788 (pm->timeout), 766 (pm->timeout),
789 &do_transmit, session); 767 &do_transmit, session);
790} 768}
791 769
792 770
@@ -806,22 +784,22 @@ disconnect_session (struct Session *session)
806 784
807#if DEBUG_TCP 785#if DEBUG_TCP
808 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 786 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
809 "tcp", 787 "tcp",
810 "Disconnecting from `%4s' at %s.\n", 788 "Disconnecting from `%4s' at %s.\n",
811 GNUNET_i2s (&session->target), 789 GNUNET_i2s (&session->target),
812 (session->connect_addr != NULL) ? 790 (session->connect_addr != NULL) ?
813 tcp_address_to_string (session->plugin, 791 tcp_address_to_string (session->plugin,
814 session->connect_addr, 792 session->connect_addr,
815 session->connect_alen) : "*"); 793 session->connect_alen) : "*");
816#endif 794#endif
817 /* remove from session list */ 795 /* remove from session list */
818 prev = NULL; 796 prev = NULL;
819 pos = session->plugin->sessions; 797 pos = session->plugin->sessions;
820 while (pos != session) 798 while (pos != session)
821 { 799 {
822 prev = pos; 800 prev = pos;
823 pos = pos->next; 801 pos = pos->next;
824 } 802 }
825 if (prev == NULL) 803 if (prev == NULL)
826 session->plugin->sessions = session->next; 804 session->plugin->sessions = session->next;
827 else 805 else
@@ -829,57 +807,51 @@ disconnect_session (struct Session *session)
829 807
830 /* clean up state */ 808 /* clean up state */
831 if (session->transmit_handle != NULL) 809 if (session->transmit_handle != NULL)
832 { 810 {
833 GNUNET_CONNECTION_notify_transmit_ready_cancel 811 GNUNET_CONNECTION_notify_transmit_ready_cancel (session->transmit_handle);
834 (session->transmit_handle); 812 session->transmit_handle = NULL;
835 session->transmit_handle = NULL; 813 }
836 }
837 session->plugin->env->session_end (session->plugin->env->cls, 814 session->plugin->env->session_end (session->plugin->env->cls,
838 &session->target, 815 &session->target, session);
839 session);
840 while (NULL != (pm = session->pending_messages_head)) 816 while (NULL != (pm = session->pending_messages_head))
841 { 817 {
842#if DEBUG_TCP 818#if DEBUG_TCP
843 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 819 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
844 "tcp", 820 "tcp",
845 pm->transmit_cont != NULL 821 pm->transmit_cont != NULL
846 ? "Could not deliver message to `%4s'.\n" 822 ? "Could not deliver message to `%4s'.\n"
847 : "Could not deliver message to `%4s', notifying.\n", 823 : "Could not deliver message to `%4s', notifying.\n",
848 GNUNET_i2s (&session->target)); 824 GNUNET_i2s (&session->target));
849#endif 825#endif
850 GNUNET_STATISTICS_update (session->plugin->env->stats, 826 GNUNET_STATISTICS_update (session->plugin->env->stats,
851 gettext_noop ("# bytes currently in TCP buffers"), 827 gettext_noop ("# bytes currently in TCP buffers"),
852 - (int64_t) pm->message_size, 828 -(int64_t) pm->message_size, GNUNET_NO);
853 GNUNET_NO); 829 GNUNET_STATISTICS_update (session->plugin->env->stats,
854 GNUNET_STATISTICS_update (session->plugin->env->stats, 830 gettext_noop
855 gettext_noop ("# bytes discarded by TCP (disconnect)"), 831 ("# bytes discarded by TCP (disconnect)"),
856 pm->message_size, 832 pm->message_size, GNUNET_NO);
857 GNUNET_NO); 833 GNUNET_CONTAINER_DLL_remove (session->pending_messages_head,
858 GNUNET_CONTAINER_DLL_remove (session->pending_messages_head, 834 session->pending_messages_tail, pm);
859 session->pending_messages_tail, 835 if (NULL != pm->transmit_cont)
860 pm); 836 pm->transmit_cont (pm->transmit_cont_cls,
861 if (NULL != pm->transmit_cont) 837 &session->target, GNUNET_SYSERR);
862 pm->transmit_cont (pm->transmit_cont_cls, 838 GNUNET_free (pm);
863 &session->target, GNUNET_SYSERR); 839 }
864 GNUNET_free (pm);
865 }
866 GNUNET_break (session->client != NULL); 840 GNUNET_break (session->client != NULL);
867 if (session->receive_delay_task != GNUNET_SCHEDULER_NO_TASK) 841 if (session->receive_delay_task != GNUNET_SCHEDULER_NO_TASK)
868 { 842 {
869 GNUNET_SCHEDULER_cancel (session->receive_delay_task); 843 GNUNET_SCHEDULER_cancel (session->receive_delay_task);
870 if (session->client != NULL) 844 if (session->client != NULL)
871 GNUNET_SERVER_receive_done (session->client, 845 GNUNET_SERVER_receive_done (session->client, GNUNET_SYSERR);
872 GNUNET_SYSERR); 846 }
873 }
874 if (session->client != NULL) 847 if (session->client != NULL)
875 { 848 {
876 GNUNET_SERVER_client_drop (session->client); 849 GNUNET_SERVER_client_drop (session->client);
877 session->client = NULL; 850 session->client = NULL;
878 } 851 }
879 GNUNET_STATISTICS_update (session->plugin->env->stats, 852 GNUNET_STATISTICS_update (session->plugin->env->stats,
880 gettext_noop ("# TCP sessions active"), 853 gettext_noop ("# TCP sessions active"),
881 -1, 854 -1, GNUNET_NO);
882 GNUNET_NO);
883 GNUNET_free_non_null (session->connect_addr); 855 GNUNET_free_non_null (session->connect_addr);
884 GNUNET_assert (NULL == session->transmit_handle); 856 GNUNET_assert (NULL == session->transmit_handle);
885 GNUNET_free (session); 857 GNUNET_free (session);
@@ -894,28 +866,25 @@ disconnect_session (struct Session *session)
894 * @return "better" session (more active) 866 * @return "better" session (more active)
895 */ 867 */
896static struct Session * 868static struct Session *
897select_better_session (struct Session *s1, 869select_better_session (struct Session *s1, struct Session *s2)
898 struct Session *s2)
899{ 870{
900 if (s1 == NULL) 871 if (s1 == NULL)
901 return s2; 872 return s2;
902 if (s2 == NULL) 873 if (s2 == NULL)
903 return s1; 874 return s1;
904 if ( (s1->expecting_welcome == GNUNET_NO) && 875 if ((s1->expecting_welcome == GNUNET_NO) &&
905 (s2->expecting_welcome == GNUNET_YES) ) 876 (s2->expecting_welcome == GNUNET_YES))
906 return s1; 877 return s1;
907 if ( (s1->expecting_welcome == GNUNET_YES) && 878 if ((s1->expecting_welcome == GNUNET_YES) &&
908 (s2->expecting_welcome == GNUNET_NO) ) 879 (s2->expecting_welcome == GNUNET_NO))
909 return s2; 880 return s2;
910 if (s1->last_activity.abs_value < s2->last_activity.abs_value) 881 if (s1->last_activity.abs_value < s2->last_activity.abs_value)
911 return s2; 882 return s2;
912 if (s1->last_activity.abs_value > s2->last_activity.abs_value) 883 if (s1->last_activity.abs_value > s2->last_activity.abs_value)
913 return s1; 884 return s1;
914 if ( (GNUNET_YES == s1->inbound) && 885 if ((GNUNET_YES == s1->inbound) && (GNUNET_NO == s2->inbound))
915 (GNUNET_NO == s2->inbound) )
916 return s1; 886 return s1;
917 if ( (GNUNET_NO == s1->inbound) && 887 if ((GNUNET_NO == s1->inbound) && (GNUNET_YES == s2->inbound))
918 (GNUNET_YES == s2->inbound) )
919 return s2; 888 return s2;
920 return s1; 889 return s1;
921} 890}
@@ -965,10 +934,10 @@ tcp_plugin_send (void *cls,
965 size_t msgbuf_size, 934 size_t msgbuf_size,
966 uint32_t priority, 935 uint32_t priority,
967 struct GNUNET_TIME_Relative timeout, 936 struct GNUNET_TIME_Relative timeout,
968 struct Session *session, 937 struct Session *session,
969 const void *addr, 938 const void *addr,
970 size_t addrlen, 939 size_t addrlen,
971 int force_address, 940 int force_address,
972 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) 941 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
973{ 942{
974 struct Plugin *plugin = cls; 943 struct Plugin *plugin = cls;
@@ -986,234 +955,217 @@ tcp_plugin_send (void *cls,
986 unsigned int is_natd; 955 unsigned int is_natd;
987 956
988 GNUNET_STATISTICS_update (plugin->env->stats, 957 GNUNET_STATISTICS_update (plugin->env->stats,
989 gettext_noop ("# bytes TCP was asked to transmit"), 958 gettext_noop ("# bytes TCP was asked to transmit"),
990 msgbuf_size, 959 msgbuf_size, GNUNET_NO);
991 GNUNET_NO);
992 /* FIXME: we could do this cheaper with a hash table 960 /* FIXME: we could do this cheaper with a hash table
993 where we could restrict the iteration to entries that match 961 * where we could restrict the iteration to entries that match
994 the target peer... */ 962 * the target peer... */
995 is_natd = GNUNET_NO; 963 is_natd = GNUNET_NO;
996 if (session == NULL) 964 if (session == NULL)
965 {
966 cand_session = NULL;
967 next = plugin->sessions;
968 while (NULL != (session = next))
997 { 969 {
998 cand_session = NULL; 970 next = session->next;
999 next = plugin->sessions; 971 GNUNET_assert (session->client != NULL);
1000 while (NULL != (session = next)) 972 if (0 != memcmp (target,
1001 { 973 &session->target, sizeof (struct GNUNET_PeerIdentity)))
1002 next = session->next; 974 continue;
1003 GNUNET_assert (session->client != NULL); 975 if (((GNUNET_SYSERR == force_address) &&
1004 if (0 != memcmp (target, 976 (session->expecting_welcome == GNUNET_NO)) ||
1005 &session->target, 977 (GNUNET_NO == force_address))
1006 sizeof (struct GNUNET_PeerIdentity))) 978 {
1007 continue; 979 cand_session = select_better_session (cand_session, session);
1008 if ( ( (GNUNET_SYSERR == force_address) && 980 continue;
1009 (session->expecting_welcome == GNUNET_NO) ) || 981 }
1010 (GNUNET_NO == force_address) ) 982 if (GNUNET_SYSERR == force_address)
1011 { 983 continue;
1012 cand_session = select_better_session (cand_session, 984 GNUNET_break (GNUNET_YES == force_address);
1013 session); 985 if (addr == NULL)
1014 continue; 986 {
1015 } 987 GNUNET_break (0);
1016 if (GNUNET_SYSERR == force_address) 988 break;
1017 continue; 989 }
1018 GNUNET_break (GNUNET_YES == force_address); 990 if ((addrlen != session->connect_alen) && (session->is_nat == GNUNET_NO))
1019 if (addr == NULL) 991 continue;
1020 { 992 if ((0 != memcmp (session->connect_addr,
1021 GNUNET_break (0); 993 addr, addrlen)) && (session->is_nat == GNUNET_NO))
1022 break; 994 continue;
1023 } 995 cand_session = select_better_session (cand_session, session);
1024 if ( (addrlen != session->connect_alen) &&
1025 (session->is_nat == GNUNET_NO) )
1026 continue;
1027 if ((0 != memcmp (session->connect_addr,
1028 addr,
1029 addrlen)) && (session->is_nat == GNUNET_NO))
1030 continue;
1031 cand_session = select_better_session (cand_session,
1032 session);
1033 }
1034 session = cand_session;
1035 } 996 }
1036 if ( (session == NULL) && 997 session = cand_session;
1037 (addr == NULL) ) 998 }
1038 { 999 if ((session == NULL) && (addr == NULL))
1000 {
1039#if DEBUG_TCP 1001#if DEBUG_TCP
1040 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1002 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1041 "tcp", 1003 "tcp",
1042 "Asked to transmit to `%4s' without address and I have no existing connection (failing).\n", 1004 "Asked to transmit to `%4s' without address and I have no existing connection (failing).\n",
1043 GNUNET_i2s (target)); 1005 GNUNET_i2s (target));
1044#endif 1006#endif
1045 GNUNET_STATISTICS_update (plugin->env->stats, 1007 GNUNET_STATISTICS_update (plugin->env->stats,
1046 gettext_noop ("# bytes discarded by TCP (no address and no connection)"), 1008 gettext_noop
1047 msgbuf_size, 1009 ("# bytes discarded by TCP (no address and no connection)"),
1048 GNUNET_NO); 1010 msgbuf_size, GNUNET_NO);
1049 return -1; 1011 return -1;
1050 } 1012 }
1051 if (session == NULL) 1013 if (session == NULL)
1014 {
1015 if (addrlen == sizeof (struct IPv6TcpAddress))
1052 { 1016 {
1053 if (addrlen == sizeof (struct IPv6TcpAddress)) 1017 t6 = addr;
1054 { 1018 af = AF_INET6;
1055 t6 = addr; 1019 memset (&a6, 0, sizeof (a6));
1056 af = AF_INET6;
1057 memset (&a6, 0, sizeof (a6));
1058#if HAVE_SOCKADDR_IN_SIN_LEN 1020#if HAVE_SOCKADDR_IN_SIN_LEN
1059 a6.sin6_len = sizeof (a6); 1021 a6.sin6_len = sizeof (a6);
1060#endif 1022#endif
1061 a6.sin6_family = AF_INET6; 1023 a6.sin6_family = AF_INET6;
1062 a6.sin6_port = t6->t6_port; 1024 a6.sin6_port = t6->t6_port;
1063 if (t6->t6_port == 0) 1025 if (t6->t6_port == 0)
1064 is_natd = GNUNET_YES; 1026 is_natd = GNUNET_YES;
1065 memcpy (&a6.sin6_addr, 1027 memcpy (&a6.sin6_addr, &t6->ipv6_addr, sizeof (struct in6_addr));
1066 &t6->ipv6_addr, 1028 sb = &a6;
1067 sizeof (struct in6_addr)); 1029 sbs = sizeof (a6);
1068 sb = &a6; 1030 }
1069 sbs = sizeof (a6); 1031 else if (addrlen == sizeof (struct IPv4TcpAddress))
1070 } 1032 {
1071 else if (addrlen == sizeof (struct IPv4TcpAddress)) 1033 t4 = addr;
1072 { 1034 af = AF_INET;
1073 t4 = addr; 1035 memset (&a4, 0, sizeof (a4));
1074 af = AF_INET;
1075 memset (&a4, 0, sizeof (a4));
1076#if HAVE_SOCKADDR_IN_SIN_LEN 1036#if HAVE_SOCKADDR_IN_SIN_LEN
1077 a4.sin_len = sizeof (a4); 1037 a4.sin_len = sizeof (a4);
1078#endif 1038#endif
1079 a4.sin_family = AF_INET; 1039 a4.sin_family = AF_INET;
1080 a4.sin_port = t4->t4_port; 1040 a4.sin_port = t4->t4_port;
1081 if (t4->t4_port == 0) 1041 if (t4->t4_port == 0)
1082 is_natd = GNUNET_YES; 1042 is_natd = GNUNET_YES;
1083 a4.sin_addr.s_addr = t4->ipv4_addr; 1043 a4.sin_addr.s_addr = t4->ipv4_addr;
1084 sb = &a4; 1044 sb = &a4;
1085 sbs = sizeof (a4); 1045 sbs = sizeof (a4);
1086 } 1046 }
1087 else 1047 else
1088 { 1048 {
1089 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, 1049 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
1090 "tcp", 1050 "tcp", _("Address of unexpected length: %u\n"), addrlen);
1091 _("Address of unexpected length: %u\n"), 1051 GNUNET_break (0);
1092 addrlen); 1052 return -1;
1093 GNUNET_break (0); 1053 }
1094 return -1; 1054
1095 } 1055 if ((is_natd == GNUNET_YES) && (addrlen == sizeof (struct IPv6TcpAddress)))
1096 1056 return -1; /* NAT client only works with IPv4 addresses */
1097 if ((is_natd == GNUNET_YES) && (addrlen == sizeof (struct IPv6TcpAddress))) 1057 if (0 == plugin->max_connections)
1098 return -1; /* NAT client only works with IPv4 addresses */ 1058 return -1; /* saturated */
1099 if (0 == plugin->max_connections) 1059
1100 return -1; /* saturated */ 1060 if ((is_natd == GNUNET_YES) &&
1101 1061 (NULL != plugin->nat) &&
1102 if ( (is_natd == GNUNET_YES) && 1062 (GNUNET_NO ==
1103 (NULL != plugin->nat) && 1063 GNUNET_CONTAINER_multihashmap_contains (plugin->nat_wait_conns,
1104 (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(plugin->nat_wait_conns, 1064 &target->hashPubKey)))
1105 &target->hashPubKey)) ) 1065 {
1106 {
1107#if DEBUG_TCP_NAT 1066#if DEBUG_TCP_NAT
1108 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1067 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1109 "tcp", 1068 "tcp",
1110 _("Found valid IPv4 NAT address (creating session)!\n")); 1069 _("Found valid IPv4 NAT address (creating session)!\n"));
1111#endif 1070#endif
1112 session = create_session (plugin, 1071 session = create_session (plugin, target, NULL, GNUNET_YES);
1113 target, 1072 GNUNET_assert (session != NULL);
1114 NULL, 1073
1115 GNUNET_YES); 1074 /* create new message entry */
1116 GNUNET_assert (session != NULL); 1075 pm = GNUNET_malloc (sizeof (struct PendingMessage) + msgbuf_size);
1117 1076 /* FIXME: the memset of this malloc can be up to 2% of our total runtime */
1118 /* create new message entry */ 1077 pm->msg = (const char *) &pm[1];
1119 pm = GNUNET_malloc (sizeof (struct PendingMessage) + msgbuf_size); 1078 memcpy (&pm[1], msg, msgbuf_size);
1120 /* FIXME: the memset of this malloc can be up to 2% of our total runtime */ 1079 /* FIXME: this memcpy can be up to 7% of our total run-time
1121 pm->msg = (const char*) &pm[1]; 1080 * (for transport service) */
1122 memcpy (&pm[1], msg, msgbuf_size); 1081 pm->message_size = msgbuf_size;
1123 /* FIXME: this memcpy can be up to 7% of our total run-time 1082 pm->timeout = GNUNET_TIME_relative_to_absolute (timeout);
1124 (for transport service) */ 1083 pm->transmit_cont = cont;
1125 pm->message_size = msgbuf_size; 1084 pm->transmit_cont_cls = cont_cls;
1126 pm->timeout = GNUNET_TIME_relative_to_absolute (timeout); 1085
1127 pm->transmit_cont = cont; 1086 /* append pm to pending_messages list */
1128 pm->transmit_cont_cls = cont_cls; 1087 GNUNET_CONTAINER_DLL_insert_after (session->pending_messages_head,
1129 1088 session->pending_messages_tail,
1130 /* append pm to pending_messages list */ 1089 session->pending_messages_tail, pm);
1131 GNUNET_CONTAINER_DLL_insert_after (session->pending_messages_head, 1090
1132 session->pending_messages_tail, 1091 GNUNET_assert (GNUNET_CONTAINER_multihashmap_put (plugin->nat_wait_conns,
1133 session->pending_messages_tail, 1092 &target->hashPubKey,
1134 pm); 1093 session,
1135 1094 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)
1136 GNUNET_assert(GNUNET_CONTAINER_multihashmap_put(plugin->nat_wait_conns, 1095 == GNUNET_OK);
1137 &target->hashPubKey,
1138 session,
1139 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY) == GNUNET_OK);
1140#if DEBUG_TCP_NAT 1096#if DEBUG_TCP_NAT
1141 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1097 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1142 "tcp", 1098 "tcp",
1143 "Created NAT WAIT connection to `%4s' at `%s'\n", 1099 "Created NAT WAIT connection to `%4s' at `%s'\n",
1144 GNUNET_i2s (target), 1100 GNUNET_i2s (target), GNUNET_a2s (sb, sbs));
1145 GNUNET_a2s (sb, sbs));
1146#endif 1101#endif
1147 GNUNET_NAT_run_client (plugin->nat, &a4); 1102 GNUNET_NAT_run_client (plugin->nat, &a4);
1148 return 0; 1103 return 0;
1149 } 1104 }
1150 if ( (is_natd == GNUNET_YES) && 1105 if ((is_natd == GNUNET_YES) &&
1151 (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(plugin->nat_wait_conns, 1106 (GNUNET_YES ==
1152 &target->hashPubKey)) ) 1107 GNUNET_CONTAINER_multihashmap_contains (plugin->nat_wait_conns,
1153 { 1108 &target->hashPubKey)))
1154 /* Only do one NAT punch attempt per peer identity */ 1109 {
1155 return -1; 1110 /* Only do one NAT punch attempt per peer identity */
1156 } 1111 return -1;
1157 sa = GNUNET_CONNECTION_create_from_sockaddr (af, sb, sbs); 1112 }
1158 if (sa == NULL) 1113 sa = GNUNET_CONNECTION_create_from_sockaddr (af, sb, sbs);
1159 { 1114 if (sa == NULL)
1115 {
1160#if DEBUG_TCP 1116#if DEBUG_TCP
1161 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1162 "tcp",
1163 "Failed to create connection to `%4s' at `%s'\n",
1164 GNUNET_i2s (target),
1165 GNUNET_a2s (sb, sbs));
1166#endif
1167 GNUNET_STATISTICS_update (plugin->env->stats,
1168 gettext_noop ("# bytes discarded by TCP (failed to connect)"),
1169 msgbuf_size,
1170 GNUNET_NO);
1171 return -1;
1172 }
1173 GNUNET_assert (0 != plugin->max_connections);
1174 plugin->max_connections--;
1175#if DEBUG_TCP_NAT
1176 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1117 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1177 "tcp", 1118 "tcp",
1178 "Asked to transmit to `%4s', creating fresh session using address `%s'.\n", 1119 "Failed to create connection to `%4s' at `%s'\n",
1179 GNUNET_i2s (target), 1120 GNUNET_i2s (target), GNUNET_a2s (sb, sbs));
1180 GNUNET_a2s (sb, sbs));
1181#endif 1121#endif
1182 session = create_session (plugin, 1122 GNUNET_STATISTICS_update (plugin->env->stats,
1183 target, 1123 gettext_noop
1184 GNUNET_SERVER_connect_socket (plugin->server, 1124 ("# bytes discarded by TCP (failed to connect)"),
1185 sa), 1125 msgbuf_size, GNUNET_NO);
1186 GNUNET_NO); 1126 return -1;
1187 session->connect_addr = GNUNET_malloc (addrlen);
1188 memcpy (session->connect_addr,
1189 addr,
1190 addrlen);
1191 session->connect_alen = addrlen;
1192 } 1127 }
1193 else /* session != NULL */ 1128 GNUNET_assert (0 != plugin->max_connections);
1129 plugin->max_connections--;
1130#if DEBUG_TCP_NAT
1131 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1132 "tcp",
1133 "Asked to transmit to `%4s', creating fresh session using address `%s'.\n",
1134 GNUNET_i2s (target), GNUNET_a2s (sb, sbs));
1135#endif
1136 session = create_session (plugin,
1137 target,
1138 GNUNET_SERVER_connect_socket (plugin->server,
1139 sa), GNUNET_NO);
1140 session->connect_addr = GNUNET_malloc (addrlen);
1141 memcpy (session->connect_addr, addr, addrlen);
1142 session->connect_alen = addrlen;
1143 }
1144 else /* session != NULL */
1145 {
1146 /* check if session is valid */
1147 struct Session *ses = plugin->sessions;
1148
1149 while ((ses != NULL) && (ses != session))
1150 ses = ses->next;
1151 if (ses == NULL)
1194 { 1152 {
1195 /* check if session is valid */ 1153 GNUNET_break (0);
1196 struct Session * ses = plugin->sessions; 1154 return -1;
1197 while ((ses != NULL) && (ses != session))
1198 ses = ses->next;
1199 if (ses == NULL)
1200 {
1201 GNUNET_break (0);
1202 return -1;
1203 }
1204 } 1155 }
1156 }
1205 GNUNET_assert (session != NULL); 1157 GNUNET_assert (session != NULL);
1206 GNUNET_assert (session->client != NULL); 1158 GNUNET_assert (session->client != NULL);
1207 1159
1208 1160
1209 GNUNET_SERVER_client_set_timeout(session->client, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); 1161 GNUNET_SERVER_client_set_timeout (session->client,
1162 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1210 GNUNET_STATISTICS_update (plugin->env->stats, 1163 GNUNET_STATISTICS_update (plugin->env->stats,
1211 gettext_noop ("# bytes currently in TCP buffers"), 1164 gettext_noop ("# bytes currently in TCP buffers"),
1212 msgbuf_size, 1165 msgbuf_size, GNUNET_NO);
1213 GNUNET_NO);
1214 /* create new message entry */ 1166 /* create new message entry */
1215 pm = GNUNET_malloc (sizeof (struct PendingMessage) + msgbuf_size); 1167 pm = GNUNET_malloc (sizeof (struct PendingMessage) + msgbuf_size);
1216 pm->msg = (const char*) &pm[1]; 1168 pm->msg = (const char *) &pm[1];
1217 memcpy (&pm[1], msg, msgbuf_size); 1169 memcpy (&pm[1], msg, msgbuf_size);
1218 pm->message_size = msgbuf_size; 1170 pm->message_size = msgbuf_size;
1219 pm->timeout = GNUNET_TIME_relative_to_absolute (timeout); 1171 pm->timeout = GNUNET_TIME_relative_to_absolute (timeout);
@@ -1222,15 +1174,13 @@ tcp_plugin_send (void *cls,
1222 1174
1223 /* append pm to pending_messages list */ 1175 /* append pm to pending_messages list */
1224 GNUNET_CONTAINER_DLL_insert_after (session->pending_messages_head, 1176 GNUNET_CONTAINER_DLL_insert_after (session->pending_messages_head,
1225 session->pending_messages_tail, 1177 session->pending_messages_tail,
1226 session->pending_messages_tail, 1178 session->pending_messages_tail, pm);
1227 pm);
1228#if DEBUG_TCP 1179#if DEBUG_TCP
1229 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1180 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1230 "tcp", 1181 "tcp",
1231 "Asked to transmit %u bytes to `%s', added message to list.\n", 1182 "Asked to transmit %u bytes to `%s', added message to list.\n",
1232 msgbuf_size, 1183 msgbuf_size, GNUNET_i2s (target));
1233 GNUNET_i2s (target));
1234#endif 1184#endif
1235 process_pending_messages (session); 1185 process_pending_messages (session);
1236 return msgbuf_size; 1186 return msgbuf_size;
@@ -1254,8 +1204,7 @@ tcp_plugin_send (void *cls,
1254 * to be cancelled 1204 * to be cancelled
1255 */ 1205 */
1256static void 1206static void
1257tcp_plugin_disconnect (void *cls, 1207tcp_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
1258 const struct GNUNET_PeerIdentity *target)
1259{ 1208{
1260 struct Plugin *plugin = cls; 1209 struct Plugin *plugin = cls;
1261 struct Session *session; 1210 struct Session *session;
@@ -1264,31 +1213,29 @@ tcp_plugin_disconnect (void *cls,
1264 1213
1265#if DEBUG_TCP 1214#if DEBUG_TCP
1266 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1215 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1267 "tcp", 1216 "tcp",
1268 "Asked to cancel session with `%4s'\n", 1217 "Asked to cancel session with `%4s'\n", GNUNET_i2s (target));
1269 GNUNET_i2s (target));
1270#endif 1218#endif
1271 next = plugin->sessions; 1219 next = plugin->sessions;
1272 while (NULL != (session = next)) 1220 while (NULL != (session = next))
1221 {
1222 next = session->next;
1223 if (0 != memcmp (target,
1224 &session->target, sizeof (struct GNUNET_PeerIdentity)))
1225 continue;
1226 pm = session->pending_messages_head;
1227 while (pm != NULL)
1273 { 1228 {
1274 next = session->next; 1229 pm->transmit_cont = NULL;
1275 if (0 != memcmp (target, 1230 pm->transmit_cont_cls = NULL;
1276 &session->target, 1231 pm = pm->next;
1277 sizeof (struct GNUNET_PeerIdentity)))
1278 continue;
1279 pm = session->pending_messages_head;
1280 while (pm != NULL)
1281 {
1282 pm->transmit_cont = NULL;
1283 pm->transmit_cont_cls = NULL;
1284 pm = pm->next;
1285 }
1286 GNUNET_STATISTICS_update (session->plugin->env->stats,
1287 gettext_noop ("# transport-service disconnect requests for TCP"),
1288 1,
1289 GNUNET_NO);
1290 disconnect_session (session);
1291 } 1232 }
1233 GNUNET_STATISTICS_update (session->plugin->env->stats,
1234 gettext_noop
1235 ("# transport-service disconnect requests for TCP"),
1236 1, GNUNET_NO);
1237 disconnect_session (session);
1238 }
1292} 1239}
1293 1240
1294 1241
@@ -1327,11 +1274,11 @@ append_port (void *cls, const char *hostname)
1327 char *ret; 1274 char *ret;
1328 1275
1329 if (hostname == NULL) 1276 if (hostname == NULL)
1330 { 1277 {
1331 ppc->asc (ppc->asc_cls, NULL); 1278 ppc->asc (ppc->asc_cls, NULL);
1332 GNUNET_free (ppc); 1279 GNUNET_free (ppc);
1333 return; 1280 return;
1334 } 1281 }
1335 GNUNET_asprintf (&ret, "%s:%d", hostname, ppc->port); 1282 GNUNET_asprintf (&ret, "%s:%d", hostname, ppc->port);
1336 ppc->asc (ppc->asc_cls, ret); 1283 ppc->asc (ppc->asc_cls, ret);
1337 GNUNET_free (ret); 1284 GNUNET_free (ret);
@@ -1372,43 +1319,39 @@ tcp_plugin_address_pretty_printer (void *cls,
1372 uint16_t port; 1319 uint16_t port;
1373 1320
1374 if (addrlen == sizeof (struct IPv6TcpAddress)) 1321 if (addrlen == sizeof (struct IPv6TcpAddress))
1375 { 1322 {
1376 t6 = addr; 1323 t6 = addr;
1377 memset (&a6, 0, sizeof (a6)); 1324 memset (&a6, 0, sizeof (a6));
1378 a6.sin6_family = AF_INET6; 1325 a6.sin6_family = AF_INET6;
1379 a6.sin6_port = t6->t6_port; 1326 a6.sin6_port = t6->t6_port;
1380 memcpy (&a6.sin6_addr, 1327 memcpy (&a6.sin6_addr, &t6->ipv6_addr, sizeof (struct in6_addr));
1381 &t6->ipv6_addr, 1328 port = ntohs (t6->t6_port);
1382 sizeof (struct in6_addr)); 1329 sb = &a6;
1383 port = ntohs (t6->t6_port); 1330 sbs = sizeof (a6);
1384 sb = &a6; 1331 }
1385 sbs = sizeof (a6);
1386 }
1387 else if (addrlen == sizeof (struct IPv4TcpAddress)) 1332 else if (addrlen == sizeof (struct IPv4TcpAddress))
1388 { 1333 {
1389 t4 = addr; 1334 t4 = addr;
1390 memset (&a4, 0, sizeof (a4)); 1335 memset (&a4, 0, sizeof (a4));
1391 a4.sin_family = AF_INET; 1336 a4.sin_family = AF_INET;
1392 a4.sin_port = t4->t4_port; 1337 a4.sin_port = t4->t4_port;
1393 a4.sin_addr.s_addr = t4->ipv4_addr; 1338 a4.sin_addr.s_addr = t4->ipv4_addr;
1394 port = ntohs (t4->t4_port); 1339 port = ntohs (t4->t4_port);
1395 sb = &a4; 1340 sb = &a4;
1396 sbs = sizeof (a4); 1341 sbs = sizeof (a4);
1397 } 1342 }
1398 else 1343 else
1399 { 1344 {
1400 /* invalid address */ 1345 /* invalid address */
1401 GNUNET_break_op (0); 1346 GNUNET_break_op (0);
1402 asc (asc_cls, NULL); 1347 asc (asc_cls, NULL);
1403 return; 1348 return;
1404 } 1349 }
1405 ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext)); 1350 ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext));
1406 ppc->asc = asc; 1351 ppc->asc = asc;
1407 ppc->asc_cls = asc_cls; 1352 ppc->asc_cls = asc_cls;
1408 ppc->port = port; 1353 ppc->port = port;
1409 GNUNET_RESOLVER_hostname_get (sb, 1354 GNUNET_RESOLVER_hostname_get (sb, sbs, !numeric, timeout, &append_port, ppc);
1410 sbs,
1411 !numeric, timeout, &append_port, ppc);
1412} 1355}
1413 1356
1414 1357
@@ -1423,8 +1366,7 @@ tcp_plugin_address_pretty_printer (void *cls,
1423 * @return GNUNET_OK if port is either open_port or adv_port 1366 * @return GNUNET_OK if port is either open_port or adv_port
1424 */ 1367 */
1425static int 1368static int
1426check_port (struct Plugin *plugin, 1369check_port (struct Plugin *plugin, uint16_t in_port)
1427 uint16_t in_port)
1428{ 1370{
1429 if ((in_port == plugin->adv_port) || (in_port == plugin->open_port)) 1371 if ((in_port == plugin->adv_port) || (in_port == plugin->open_port))
1430 return GNUNET_OK; 1372 return GNUNET_OK;
@@ -1448,9 +1390,7 @@ check_port (struct Plugin *plugin,
1448 * and transport, GNUNET_SYSERR if not 1390 * and transport, GNUNET_SYSERR if not
1449 */ 1391 */
1450static int 1392static int
1451tcp_plugin_check_address (void *cls, 1393tcp_plugin_check_address (void *cls, const void *addr, size_t addrlen)
1452 const void *addr,
1453 size_t addrlen)
1454{ 1394{
1455 struct Plugin *plugin = cls; 1395 struct Plugin *plugin = cls;
1456 struct IPv4TcpAddress *v4; 1396 struct IPv4TcpAddress *v4;
@@ -1458,37 +1398,35 @@ tcp_plugin_check_address (void *cls,
1458 1398
1459 if ((addrlen != sizeof (struct IPv4TcpAddress)) && 1399 if ((addrlen != sizeof (struct IPv4TcpAddress)) &&
1460 (addrlen != sizeof (struct IPv6TcpAddress))) 1400 (addrlen != sizeof (struct IPv6TcpAddress)))
1461 { 1401 {
1462 GNUNET_break_op (0); 1402 GNUNET_break_op (0);
1463 return GNUNET_SYSERR; 1403 return GNUNET_SYSERR;
1464 } 1404 }
1465 if (addrlen == sizeof (struct IPv4TcpAddress)) 1405 if (addrlen == sizeof (struct IPv4TcpAddress))
1466 { 1406 {
1467 v4 = (struct IPv4TcpAddress *) addr; 1407 v4 = (struct IPv4TcpAddress *) addr;
1468 if (GNUNET_OK != 1408 if (GNUNET_OK != check_port (plugin, ntohs (v4->t4_port)))
1469 check_port (plugin, ntohs (v4->t4_port))) 1409 return GNUNET_SYSERR;
1470 return GNUNET_SYSERR; 1410 if (GNUNET_OK !=
1471 if (GNUNET_OK != 1411 GNUNET_NAT_test_address (plugin->nat,
1472 GNUNET_NAT_test_address (plugin->nat, 1412 &v4->ipv4_addr, sizeof (struct in_addr)))
1473 &v4->ipv4_addr, sizeof (struct in_addr))) 1413 return GNUNET_SYSERR;
1474 return GNUNET_SYSERR; 1414 }
1475 }
1476 else 1415 else
1416 {
1417 v6 = (struct IPv6TcpAddress *) addr;
1418 if (IN6_IS_ADDR_LINKLOCAL (&v6->ipv6_addr))
1477 { 1419 {
1478 v6 = (struct IPv6TcpAddress *) addr; 1420 GNUNET_break_op (0);
1479 if (IN6_IS_ADDR_LINKLOCAL (&v6->ipv6_addr)) 1421 return GNUNET_SYSERR;
1480 {
1481 GNUNET_break_op (0);
1482 return GNUNET_SYSERR;
1483 }
1484 if (GNUNET_OK !=
1485 check_port (plugin, ntohs (v6->t6_port)))
1486 return GNUNET_SYSERR;
1487 if (GNUNET_OK !=
1488 GNUNET_NAT_test_address (plugin->nat,
1489 &v6->ipv6_addr, sizeof (struct in6_addr)))
1490 return GNUNET_SYSERR;
1491 } 1422 }
1423 if (GNUNET_OK != check_port (plugin, ntohs (v6->t6_port)))
1424 return GNUNET_SYSERR;
1425 if (GNUNET_OK !=
1426 GNUNET_NAT_test_address (plugin->nat,
1427 &v6->ipv6_addr, sizeof (struct in6_addr)))
1428 return GNUNET_SYSERR;
1429 }
1492 return GNUNET_OK; 1430 return GNUNET_OK;
1493} 1431}
1494 1432
@@ -1504,8 +1442,8 @@ tcp_plugin_check_address (void *cls,
1504 */ 1442 */
1505static void 1443static void
1506handle_tcp_nat_probe (void *cls, 1444handle_tcp_nat_probe (void *cls,
1507 struct GNUNET_SERVER_Client *client, 1445 struct GNUNET_SERVER_Client *client,
1508 const struct GNUNET_MessageHeader *message) 1446 const struct GNUNET_MessageHeader *message)
1509{ 1447{
1510 struct Plugin *plugin = cls; 1448 struct Plugin *plugin = cls;
1511 struct Session *session; 1449 struct Session *session;
@@ -1518,9 +1456,7 @@ handle_tcp_nat_probe (void *cls,
1518 const struct sockaddr_in6 *s6; 1456 const struct sockaddr_in6 *s6;
1519 1457
1520#if DEBUG_TCP_NAT 1458#if DEBUG_TCP_NAT
1521 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1459 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", "received NAT probe\n");
1522 "tcp",
1523 "received NAT probe\n");
1524#endif 1460#endif
1525 /* We have received a TCP NAT probe, meaning we (hopefully) initiated 1461 /* We have received a TCP NAT probe, meaning we (hopefully) initiated
1526 * a connection to this peer by running gnunet-nat-client. This peer 1462 * a connection to this peer by running gnunet-nat-client. This peer
@@ -1528,51 +1464,49 @@ handle_tcp_nat_probe (void *cls,
1528 * as the default for that peer. Do so and then send a WELCOME message 1464 * as the default for that peer. Do so and then send a WELCOME message
1529 * so we can really be connected! 1465 * so we can really be connected!
1530 */ 1466 */
1531 if (ntohs(message->size) != sizeof(struct TCP_NAT_ProbeMessage)) 1467 if (ntohs (message->size) != sizeof (struct TCP_NAT_ProbeMessage))
1532 { 1468 {
1533 GNUNET_break_op(0); 1469 GNUNET_break_op (0);
1534 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1470 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1535 return; 1471 return;
1536 } 1472 }
1537 1473
1538 tcp_nat_probe = (const struct TCP_NAT_ProbeMessage *)message; 1474 tcp_nat_probe = (const struct TCP_NAT_ProbeMessage *) message;
1539 if (0 == memcmp (&tcp_nat_probe->clientIdentity, 1475 if (0 == memcmp (&tcp_nat_probe->clientIdentity,
1540 plugin->env->my_identity, 1476 plugin->env->my_identity,
1541 sizeof (struct GNUNET_PeerIdentity))) 1477 sizeof (struct GNUNET_PeerIdentity)))
1542 { 1478 {
1543 /* refuse connections from ourselves */ 1479 /* refuse connections from ourselves */
1544 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1480 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1545 return; 1481 return;
1546 } 1482 }
1547 1483
1548 session = GNUNET_CONTAINER_multihashmap_get(plugin->nat_wait_conns, 1484 session = GNUNET_CONTAINER_multihashmap_get (plugin->nat_wait_conns,
1549 &tcp_nat_probe->clientIdentity.hashPubKey); 1485 &tcp_nat_probe->
1486 clientIdentity.hashPubKey);
1550 if (session == NULL) 1487 if (session == NULL)
1551 { 1488 {
1552#if DEBUG_TCP_NAT 1489#if DEBUG_TCP_NAT
1553 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1490 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1554 "tcp", 1491 "tcp", "Did NOT find session for NAT probe!\n");
1555 "Did NOT find session for NAT probe!\n");
1556#endif 1492#endif
1557 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1493 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1558 return; 1494 return;
1559 } 1495 }
1560#if DEBUG_TCP_NAT 1496#if DEBUG_TCP_NAT
1561 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1497 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1562 "tcp", 1498 "tcp", "Found session for NAT probe!\n");
1563 "Found session for NAT probe!\n");
1564#endif 1499#endif
1565 GNUNET_assert(GNUNET_CONTAINER_multihashmap_remove(plugin->nat_wait_conns, 1500 GNUNET_assert (GNUNET_CONTAINER_multihashmap_remove (plugin->nat_wait_conns,
1566 &tcp_nat_probe->clientIdentity.hashPubKey, 1501 &tcp_nat_probe->clientIdentity.hashPubKey,
1567 session) == GNUNET_YES); 1502 session) == GNUNET_YES);
1568 if (GNUNET_OK != 1503 if (GNUNET_OK != GNUNET_SERVER_client_get_address (client, &vaddr, &alen))
1569 GNUNET_SERVER_client_get_address (client, &vaddr, &alen)) 1504 {
1570 { 1505 GNUNET_break (0);
1571 GNUNET_break (0); 1506 GNUNET_free (session);
1572 GNUNET_free (session); 1507 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1573 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1508 return;
1574 return; 1509 }
1575 }
1576 1510
1577 GNUNET_SERVER_client_keep (client); 1511 GNUNET_SERVER_client_keep (client);
1578 session->client = client; 1512 session->client = client;
@@ -1581,51 +1515,47 @@ handle_tcp_nat_probe (void *cls,
1581 1515
1582#if DEBUG_TCP_NAT 1516#if DEBUG_TCP_NAT
1583 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1517 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1584 "tcp", 1518 "tcp",
1585 "Found address `%s' for incoming connection\n", 1519 "Found address `%s' for incoming connection\n",
1586 GNUNET_a2s (vaddr, alen)); 1520 GNUNET_a2s (vaddr, alen));
1587#endif 1521#endif
1588 switch (((const struct sockaddr *)vaddr)->sa_family) 1522 switch (((const struct sockaddr *) vaddr)->sa_family)
1589 { 1523 {
1590 case AF_INET: 1524 case AF_INET:
1591 s4 = vaddr; 1525 s4 = vaddr;
1592 t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress)); 1526 t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress));
1593 t4->t4_port = s4->sin_port; 1527 t4->t4_port = s4->sin_port;
1594 t4->ipv4_addr = s4->sin_addr.s_addr; 1528 t4->ipv4_addr = s4->sin_addr.s_addr;
1595 session->connect_addr = t4; 1529 session->connect_addr = t4;
1596 session->connect_alen = sizeof (struct IPv4TcpAddress); 1530 session->connect_alen = sizeof (struct IPv4TcpAddress);
1597 break; 1531 break;
1598 case AF_INET6: 1532 case AF_INET6:
1599 s6 = vaddr; 1533 s6 = vaddr;
1600 t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress)); 1534 t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress));
1601 t6->t6_port = s6->sin6_port; 1535 t6->t6_port = s6->sin6_port;
1602 memcpy (&t6->ipv6_addr, 1536 memcpy (&t6->ipv6_addr, &s6->sin6_addr, sizeof (struct in6_addr));
1603 &s6->sin6_addr, 1537 session->connect_addr = t6;
1604 sizeof (struct in6_addr)); 1538 session->connect_alen = sizeof (struct IPv6TcpAddress);
1605 session->connect_addr = t6; 1539 break;
1606 session->connect_alen = sizeof (struct IPv6TcpAddress); 1540 default:
1607 break; 1541 GNUNET_break_op (0);
1608 default:
1609 GNUNET_break_op (0);
1610#if DEBUG_TCP_NAT 1542#if DEBUG_TCP_NAT
1611 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1543 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1612 "tcp", 1544 "tcp", "Bad address for incoming connection!\n");
1613 "Bad address for incoming connection!\n");
1614#endif 1545#endif
1615 GNUNET_free (vaddr); 1546 GNUNET_free (vaddr);
1616 GNUNET_SERVER_client_drop (client); 1547 GNUNET_SERVER_client_drop (client);
1617 GNUNET_free (session); 1548 GNUNET_free (session);
1618 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1549 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1619 return; 1550 return;
1620 } 1551 }
1621 GNUNET_free (vaddr); 1552 GNUNET_free (vaddr);
1622 1553
1623 session->next = plugin->sessions; 1554 session->next = plugin->sessions;
1624 plugin->sessions = session; 1555 plugin->sessions = session;
1625 GNUNET_STATISTICS_update (plugin->env->stats, 1556 GNUNET_STATISTICS_update (plugin->env->stats,
1626 gettext_noop ("# TCP sessions active"), 1557 gettext_noop ("# TCP sessions active"),
1627 1, 1558 1, GNUNET_NO);
1628 GNUNET_NO);
1629 process_pending_messages (session); 1559 process_pending_messages (session);
1630 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1560 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1631} 1561}
@@ -1653,109 +1583,100 @@ handle_tcp_welcome (void *cls,
1653 struct IPv6TcpAddress *t6; 1583 struct IPv6TcpAddress *t6;
1654 const struct sockaddr_in *s4; 1584 const struct sockaddr_in *s4;
1655 const struct sockaddr_in6 *s6; 1585 const struct sockaddr_in6 *s6;
1656 1586
1657 if (0 == memcmp (&wm->clientIdentity, 1587 if (0 == memcmp (&wm->clientIdentity,
1658 plugin->env->my_identity, 1588 plugin->env->my_identity,
1659 sizeof (struct GNUNET_PeerIdentity))) 1589 sizeof (struct GNUNET_PeerIdentity)))
1660 { 1590 {
1661 /* refuse connections from ourselves */ 1591 /* refuse connections from ourselves */
1662 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1592 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1663 return; 1593 return;
1664 } 1594 }
1665#if DEBUG_TCP 1595#if DEBUG_TCP
1666 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1596 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1667 "tcp", 1597 "tcp",
1668 "Received %s message from `%4s'.\n", 1598 "Received %s message from `%4s'.\n",
1669 "WELCOME", 1599 "WELCOME", GNUNET_i2s (&wm->clientIdentity));
1670 GNUNET_i2s (&wm->clientIdentity));
1671#endif 1600#endif
1672 GNUNET_STATISTICS_update (plugin->env->stats, 1601 GNUNET_STATISTICS_update (plugin->env->stats,
1673 gettext_noop ("# TCP WELCOME messages received"), 1602 gettext_noop ("# TCP WELCOME messages received"),
1674 1, 1603 1, GNUNET_NO);
1675 GNUNET_NO);
1676 session = find_session_by_client (plugin, client); 1604 session = find_session_by_client (plugin, client);
1677 1605
1678 if (session == NULL) 1606 if (session == NULL)
1679 { 1607 {
1680#if DEBUG_TCP_NAT 1608#if DEBUG_TCP_NAT
1681 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1609 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1682 "tcp", 1610 "tcp",
1683 "Received %s message from a `%4s', creating new session\n", 1611 "Received %s message from a `%4s', creating new session\n",
1684 "WELCOME", 1612 "WELCOME", GNUNET_i2s (&wm->clientIdentity));
1685 GNUNET_i2s (&wm->clientIdentity));
1686#endif 1613#endif
1687 GNUNET_SERVER_client_keep (client); 1614 GNUNET_SERVER_client_keep (client);
1688 session = create_session (plugin, 1615 session = create_session (plugin, &wm->clientIdentity, client, GNUNET_NO);
1689 &wm->clientIdentity, 1616 session->inbound = GNUNET_YES;
1690 client, 1617 if (GNUNET_OK == GNUNET_SERVER_client_get_address (client, &vaddr, &alen))
1691 GNUNET_NO); 1618 {
1692 session->inbound = GNUNET_YES;
1693 if (GNUNET_OK ==
1694 GNUNET_SERVER_client_get_address (client, &vaddr, &alen))
1695 {
1696#if DEBUG_TCP_NAT 1619#if DEBUG_TCP_NAT
1697 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1620 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1698 "tcp", 1621 "tcp",
1699 "Found address `%s' for incoming connection\n", 1622 "Found address `%s' for incoming connection\n",
1700 GNUNET_a2s (vaddr, alen)); 1623 GNUNET_a2s (vaddr, alen));
1701#endif 1624#endif
1702 if (alen == sizeof (struct sockaddr_in)) 1625 if (alen == sizeof (struct sockaddr_in))
1703 { 1626 {
1704 s4 = vaddr; 1627 s4 = vaddr;
1705 t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress)); 1628 t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress));
1706 t4->t4_port = s4->sin_port; 1629 t4->t4_port = s4->sin_port;
1707 t4->ipv4_addr = s4->sin_addr.s_addr; 1630 t4->ipv4_addr = s4->sin_addr.s_addr;
1708 session->connect_addr = t4; 1631 session->connect_addr = t4;
1709 session->connect_alen = sizeof (struct IPv4TcpAddress); 1632 session->connect_alen = sizeof (struct IPv4TcpAddress);
1710 } 1633 }
1711 else if (alen == sizeof (struct sockaddr_in6)) 1634 else if (alen == sizeof (struct sockaddr_in6))
1712 { 1635 {
1713 s6 = vaddr; 1636 s6 = vaddr;
1714 t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress)); 1637 t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress));
1715 t6->t6_port = s6->sin6_port; 1638 t6->t6_port = s6->sin6_port;
1716 memcpy (&t6->ipv6_addr, 1639 memcpy (&t6->ipv6_addr, &s6->sin6_addr, sizeof (struct in6_addr));
1717 &s6->sin6_addr, 1640 session->connect_addr = t6;
1718 sizeof (struct in6_addr)); 1641 session->connect_alen = sizeof (struct IPv6TcpAddress);
1719 session->connect_addr = t6; 1642 }
1720 session->connect_alen = sizeof (struct IPv6TcpAddress); 1643
1721 } 1644 GNUNET_free (vaddr);
1722 1645 }
1723 GNUNET_free (vaddr); 1646 else
1724 } 1647 {
1725 else
1726 {
1727#if DEBUG_TCP 1648#if DEBUG_TCP
1728 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1649 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1729 "tcp", 1650 "tcp",
1730 "Did not obtain TCP socket address for incoming connection\n"); 1651 "Did not obtain TCP socket address for incoming connection\n");
1731#endif 1652#endif
1732 }
1733 process_pending_messages (session);
1734 } 1653 }
1654 process_pending_messages (session);
1655 }
1735 else 1656 else
1736 { 1657 {
1737#if DEBUG_TCP_NAT 1658#if DEBUG_TCP_NAT
1738 if (GNUNET_OK == 1659 if (GNUNET_OK == GNUNET_SERVER_client_get_address (client, &vaddr, &alen))
1739 GNUNET_SERVER_client_get_address (client, &vaddr, &alen)) 1660 {
1740 { 1661 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1741 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1662 "tcp",
1742 "tcp", 1663 "Found address `%s' (already have session)\n",
1743 "Found address `%s' (already have session)\n", 1664 GNUNET_a2s (vaddr, alen));
1744 GNUNET_a2s (vaddr, alen)); 1665 GNUNET_free (vaddr);
1745 GNUNET_free (vaddr);
1746 }
1747#endif
1748 } 1666 }
1667#endif
1668 }
1749 1669
1750 if (session->expecting_welcome != GNUNET_YES) 1670 if (session->expecting_welcome != GNUNET_YES)
1751 { 1671 {
1752 GNUNET_break_op (0); 1672 GNUNET_break_op (0);
1753 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1673 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1754 return; 1674 return;
1755 } 1675 }
1756 session->last_activity = GNUNET_TIME_absolute_get (); 1676 session->last_activity = GNUNET_TIME_absolute_get ();
1757 session->expecting_welcome = GNUNET_NO; 1677 session->expecting_welcome = GNUNET_NO;
1758 GNUNET_SERVER_client_set_timeout(client, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); 1678 GNUNET_SERVER_client_set_timeout (client,
1679 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1759 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1680 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1760} 1681}
1761 1682
@@ -1768,24 +1689,20 @@ handle_tcp_welcome (void *cls,
1768 * @param tc task context (unused) 1689 * @param tc task context (unused)
1769 */ 1690 */
1770static void 1691static void
1771delayed_done (void *cls, 1692delayed_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1772 const struct GNUNET_SCHEDULER_TaskContext *tc)
1773{ 1693{
1774 struct Session *session = cls; 1694 struct Session *session = cls;
1775 struct GNUNET_TIME_Relative delay; 1695 struct GNUNET_TIME_Relative delay;
1776 1696
1777 session->receive_delay_task = GNUNET_SCHEDULER_NO_TASK; 1697 session->receive_delay_task = GNUNET_SCHEDULER_NO_TASK;
1778 delay = session->plugin->env->receive (session->plugin->env->cls, 1698 delay = session->plugin->env->receive (session->plugin->env->cls,
1779 &session->target, 1699 &session->target,
1780 NULL, 1700 NULL, NULL, 0, session, NULL, 0);
1781 NULL, 0,
1782 session,
1783 NULL, 0);
1784 if (delay.rel_value == 0) 1701 if (delay.rel_value == 0)
1785 GNUNET_SERVER_receive_done (session->client, GNUNET_OK); 1702 GNUNET_SERVER_receive_done (session->client, GNUNET_OK);
1786 else 1703 else
1787 session->receive_delay_task = 1704 session->receive_delay_task =
1788 GNUNET_SCHEDULER_add_delayed (delay, &delayed_done, session); 1705 GNUNET_SCHEDULER_add_delayed (delay, &delayed_done, session);
1789} 1706}
1790 1707
1791 1708
@@ -1808,60 +1725,62 @@ handle_tcp_data (void *cls,
1808 uint16_t type; 1725 uint16_t type;
1809 1726
1810 type = ntohs (message->type); 1727 type = ntohs (message->type);
1811 if ( (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME == type) || 1728 if ((GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME == type) ||
1812 (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE == type) ) 1729 (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE == type))
1813 { 1730 {
1814 /* We don't want to propagate WELCOME and NAT Probe messages up! */ 1731 /* We don't want to propagate WELCOME and NAT Probe messages up! */
1815 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1732 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1816 return; 1733 return;
1817 } 1734 }
1818 session = find_session_by_client (plugin, client); 1735 session = find_session_by_client (plugin, client);
1819 if ( (NULL == session) || (GNUNET_YES == session->expecting_welcome) ) 1736 if ((NULL == session) || (GNUNET_YES == session->expecting_welcome))
1820 { 1737 {
1821 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1738 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1822 return; 1739 return;
1823 } 1740 }
1824 session->last_activity = GNUNET_TIME_absolute_get (); 1741 session->last_activity = GNUNET_TIME_absolute_get ();
1825#if DEBUG_TCP > 1 1742#if DEBUG_TCP > 1
1826 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1743 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1827 "tcp", 1744 "tcp",
1828 "Passing %u bytes of type %u from `%4s' to transport service.\n", 1745 "Passing %u bytes of type %u from `%4s' to transport service.\n",
1829 (unsigned int) ntohs (message->size), 1746 (unsigned int) ntohs (message->size),
1830 (unsigned int) ntohs (message->type), 1747 (unsigned int) ntohs (message->type),
1831 GNUNET_i2s (&session->target)); 1748 GNUNET_i2s (&session->target));
1832#endif 1749#endif
1833 GNUNET_STATISTICS_update (plugin->env->stats, 1750 GNUNET_STATISTICS_update (plugin->env->stats,
1834 gettext_noop ("# bytes received via TCP"), 1751 gettext_noop ("# bytes received via TCP"),
1835 ntohs (message->size), 1752 ntohs (message->size), GNUNET_NO);
1836 GNUNET_NO);
1837 struct GNUNET_TRANSPORT_ATS_Information distance[2]; 1753 struct GNUNET_TRANSPORT_ATS_Information distance[2];
1754
1838 distance[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE); 1755 distance[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
1839 distance[0].value = htonl (1); 1756 distance[0].value = htonl (1);
1840 distance[1].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); 1757 distance[1].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
1841 distance[1].value = htonl (0); 1758 distance[1].value = htonl (0);
1842 delay = plugin->env->receive (plugin->env->cls, &session->target, message, 1759 delay = plugin->env->receive (plugin->env->cls, &session->target, message,
1843 (const struct GNUNET_TRANSPORT_ATS_Information *) &distance, 1760 (const struct GNUNET_TRANSPORT_ATS_Information
1844 2, 1761 *) &distance, 2, session,
1845 session, 1762 (GNUNET_YES ==
1846 (GNUNET_YES == session->inbound) ? NULL : session->connect_addr, 1763 session->
1847 (GNUNET_YES == session->inbound) ? 0 : session->connect_alen); 1764 inbound) ? NULL : session->connect_addr,
1765 (GNUNET_YES ==
1766 session->inbound) ? 0 : session->connect_alen);
1848 if (delay.rel_value == 0) 1767 if (delay.rel_value == 0)
1849 { 1768 {
1850 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1769 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1851 } 1770 }
1852 else 1771 else
1853 { 1772 {
1854#if DEBUG_TCP 1773#if DEBUG_TCP
1855 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1774 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1856 "tcp", 1775 "tcp",
1857 "Throttling receiving from `%s' for %llu ms\n", 1776 "Throttling receiving from `%s' for %llu ms\n",
1858 GNUNET_i2s (&session->target), 1777 GNUNET_i2s (&session->target),
1859 (unsigned long long) delay.rel_value); 1778 (unsigned long long) delay.rel_value);
1860#endif 1779#endif
1861 GNUNET_SERVER_disable_receive_done_warning (client); 1780 GNUNET_SERVER_disable_receive_done_warning (client);
1862 session->receive_delay_task = 1781 session->receive_delay_task =
1863 GNUNET_SCHEDULER_add_delayed (delay, &delayed_done, session); 1782 GNUNET_SCHEDULER_add_delayed (delay, &delayed_done, session);
1864 } 1783 }
1865} 1784}
1866 1785
1867 1786
@@ -1873,8 +1792,7 @@ handle_tcp_data (void *cls,
1873 * @param client identification of the client 1792 * @param client identification of the client
1874 */ 1793 */
1875static void 1794static void
1876disconnect_notify (void *cls, 1795disconnect_notify (void *cls, struct GNUNET_SERVER_Client *client)
1877 struct GNUNET_SERVER_Client *client)
1878{ 1796{
1879 struct Plugin *plugin = cls; 1797 struct Plugin *plugin = cls;
1880 struct Session *session; 1798 struct Session *session;
@@ -1887,18 +1805,18 @@ disconnect_notify (void *cls,
1887 return; /* unknown, nothing to do */ 1805 return; /* unknown, nothing to do */
1888#if DEBUG_TCP 1806#if DEBUG_TCP
1889 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1807 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1890 "tcp", 1808 "tcp",
1891 "Destroying session of `%4s' with %s due to network-level disconnect.\n", 1809 "Destroying session of `%4s' with %s due to network-level disconnect.\n",
1892 GNUNET_i2s (&session->target), 1810 GNUNET_i2s (&session->target),
1893 (session->connect_addr != NULL) ? 1811 (session->connect_addr != NULL) ?
1894 tcp_address_to_string (session->plugin, 1812 tcp_address_to_string (session->plugin,
1895 session->connect_addr, 1813 session->connect_addr,
1896 session->connect_alen) : "*"); 1814 session->connect_alen) : "*");
1897#endif 1815#endif
1898 GNUNET_STATISTICS_update (session->plugin->env->stats, 1816 GNUNET_STATISTICS_update (session->plugin->env->stats,
1899 gettext_noop ("# network-level TCP disconnect events"), 1817 gettext_noop
1900 1, 1818 ("# network-level TCP disconnect events"), 1,
1901 GNUNET_NO); 1819 GNUNET_NO);
1902 disconnect_session (session); 1820 disconnect_session (session);
1903} 1821}
1904 1822
@@ -1912,9 +1830,7 @@ disconnect_notify (void *cls,
1912 * @return number of bytes copied into buf 1830 * @return number of bytes copied into buf
1913 */ 1831 */
1914static size_t 1832static size_t
1915notify_send_probe (void *cls, 1833notify_send_probe (void *cls, size_t size, void *buf)
1916 size_t size,
1917 void *buf)
1918{ 1834{
1919 struct TCPProbeContext *tcp_probe_ctx = cls; 1835 struct TCPProbeContext *tcp_probe_ctx = cls;
1920 struct Plugin *plugin = tcp_probe_ctx->plugin; 1836 struct Plugin *plugin = tcp_probe_ctx->plugin;
@@ -1922,20 +1838,19 @@ notify_send_probe (void *cls,
1922 1838
1923 tcp_probe_ctx->transmit_handle = NULL; 1839 tcp_probe_ctx->transmit_handle = NULL;
1924 GNUNET_CONTAINER_DLL_remove (plugin->probe_head, 1840 GNUNET_CONTAINER_DLL_remove (plugin->probe_head,
1925 plugin->probe_tail, 1841 plugin->probe_tail, tcp_probe_ctx);
1926 tcp_probe_ctx);
1927 if (buf == NULL) 1842 if (buf == NULL)
1928 { 1843 {
1929 GNUNET_CONNECTION_destroy (tcp_probe_ctx->sock, GNUNET_NO); 1844 GNUNET_CONNECTION_destroy (tcp_probe_ctx->sock, GNUNET_NO);
1930 GNUNET_free(tcp_probe_ctx); 1845 GNUNET_free (tcp_probe_ctx);
1931 return 0; 1846 return 0;
1932 } 1847 }
1933 GNUNET_assert(size >= sizeof(tcp_probe_ctx->message)); 1848 GNUNET_assert (size >= sizeof (tcp_probe_ctx->message));
1934 memcpy(buf, &tcp_probe_ctx->message, sizeof(tcp_probe_ctx->message)); 1849 memcpy (buf, &tcp_probe_ctx->message, sizeof (tcp_probe_ctx->message));
1935 GNUNET_SERVER_connect_socket (tcp_probe_ctx->plugin->server, 1850 GNUNET_SERVER_connect_socket (tcp_probe_ctx->plugin->server,
1936 tcp_probe_ctx->sock); 1851 tcp_probe_ctx->sock);
1937 ret = sizeof(tcp_probe_ctx->message); 1852 ret = sizeof (tcp_probe_ctx->message);
1938 GNUNET_free(tcp_probe_ctx); 1853 GNUNET_free (tcp_probe_ctx);
1939 return ret; 1854 return ret;
1940} 1855}
1941 1856
@@ -1951,8 +1866,7 @@ notify_send_probe (void *cls,
1951 */ 1866 */
1952static void 1867static void
1953try_connection_reversal (void *cls, 1868try_connection_reversal (void *cls,
1954 const struct sockaddr *addr, 1869 const struct sockaddr *addr, socklen_t addrlen)
1955 socklen_t addrlen)
1956{ 1870{
1957 struct Plugin *plugin = cls; 1871 struct Plugin *plugin = cls;
1958 struct GNUNET_CONNECTION_Handle *sock; 1872 struct GNUNET_CONNECTION_Handle *sock;
@@ -1962,37 +1876,34 @@ try_connection_reversal (void *cls,
1962 * We have received an ICMP response, ostensibly from a peer 1876 * We have received an ICMP response, ostensibly from a peer
1963 * that wants to connect to us! Send a message to establish a connection. 1877 * that wants to connect to us! Send a message to establish a connection.
1964 */ 1878 */
1965 sock = GNUNET_CONNECTION_create_from_sockaddr (AF_INET, 1879 sock = GNUNET_CONNECTION_create_from_sockaddr (AF_INET, addr, addrlen);
1966 addr,
1967 addrlen);
1968 if (sock == NULL) 1880 if (sock == NULL)
1969 { 1881 {
1970 /* failed for some odd reason (out of sockets?); ignore attempt */ 1882 /* failed for some odd reason (out of sockets?); ignore attempt */
1971 return; 1883 return;
1972 } 1884 }
1973 1885
1974 /* FIXME: do we need to track these probe context objects so that 1886 /* FIXME: do we need to track these probe context objects so that
1975 we can clean them up on plugin unload? */ 1887 * we can clean them up on plugin unload? */
1976 tcp_probe_ctx 1888 tcp_probe_ctx = GNUNET_malloc (sizeof (struct TCPProbeContext));
1977 = GNUNET_malloc(sizeof(struct TCPProbeContext));
1978 tcp_probe_ctx->message.header.size 1889 tcp_probe_ctx->message.header.size
1979 = htons(sizeof(struct TCP_NAT_ProbeMessage)); 1890 = htons (sizeof (struct TCP_NAT_ProbeMessage));
1980 tcp_probe_ctx->message.header.type 1891 tcp_probe_ctx->message.header.type
1981 = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE); 1892 = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE);
1982 memcpy (&tcp_probe_ctx->message.clientIdentity, 1893 memcpy (&tcp_probe_ctx->message.clientIdentity,
1983 plugin->env->my_identity, 1894 plugin->env->my_identity, sizeof (struct GNUNET_PeerIdentity));
1984 sizeof(struct GNUNET_PeerIdentity));
1985 tcp_probe_ctx->plugin = plugin; 1895 tcp_probe_ctx->plugin = plugin;
1986 tcp_probe_ctx->sock = sock; 1896 tcp_probe_ctx->sock = sock;
1987 GNUNET_CONTAINER_DLL_insert (plugin->probe_head, 1897 GNUNET_CONTAINER_DLL_insert (plugin->probe_head,
1988 plugin->probe_tail, 1898 plugin->probe_tail, tcp_probe_ctx);
1989 tcp_probe_ctx); 1899 tcp_probe_ctx->transmit_handle
1990 tcp_probe_ctx->transmit_handle 1900 = GNUNET_CONNECTION_notify_transmit_ready (sock,
1991 = GNUNET_CONNECTION_notify_transmit_ready (sock, 1901 ntohs (tcp_probe_ctx->
1992 ntohs (tcp_probe_ctx->message.header.size), 1902 message.header.size),
1993 GNUNET_TIME_UNIT_FOREVER_REL, 1903 GNUNET_TIME_UNIT_FOREVER_REL,
1994 &notify_send_probe, tcp_probe_ctx); 1904 &notify_send_probe,
1995 1905 tcp_probe_ctx);
1906
1996} 1907}
1997 1908
1998 1909
@@ -2008,7 +1919,8 @@ libgnunet_plugin_transport_tcp_init (void *cls)
2008 static const struct GNUNET_SERVER_MessageHandler my_handlers[] = { 1919 static const struct GNUNET_SERVER_MessageHandler my_handlers[] = {
2009 {&handle_tcp_welcome, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME, 1920 {&handle_tcp_welcome, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME,
2010 sizeof (struct WelcomeMessage)}, 1921 sizeof (struct WelcomeMessage)},
2011 {&handle_tcp_nat_probe, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE, sizeof (struct TCP_NAT_ProbeMessage)}, 1922 {&handle_tcp_nat_probe, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE,
1923 sizeof (struct TCP_NAT_ProbeMessage)},
2012 {&handle_tcp_data, NULL, GNUNET_MESSAGE_TYPE_ALL, 0}, 1924 {&handle_tcp_data, NULL, GNUNET_MESSAGE_TYPE_ALL, 0},
2013 {NULL, NULL, 0, 0} 1925 {NULL, NULL, 0, 0}
2014 }; 1926 };
@@ -2031,42 +1943,41 @@ libgnunet_plugin_transport_tcp_init (void *cls)
2031 "MAX_CONNECTIONS", 1943 "MAX_CONNECTIONS",
2032 &max_connections)) 1944 &max_connections))
2033 max_connections = 128; 1945 max_connections = 128;
2034 1946
2035 aport = 0; 1947 aport = 0;
2036 if ( (GNUNET_OK != 1948 if ((GNUNET_OK !=
2037 GNUNET_CONFIGURATION_get_value_number (env->cfg, 1949 GNUNET_CONFIGURATION_get_value_number (env->cfg,
2038 "transport-tcp", 1950 "transport-tcp",
2039 "PORT", 1951 "PORT",
2040 &bport)) || 1952 &bport)) ||
2041 (bport > 65535) || 1953 (bport > 65535) ||
2042 ((GNUNET_OK == 1954 ((GNUNET_OK ==
2043 GNUNET_CONFIGURATION_get_value_number (env->cfg, 1955 GNUNET_CONFIGURATION_get_value_number (env->cfg,
2044 "transport-tcp", 1956 "transport-tcp",
2045 "ADVERTISED-PORT", 1957 "ADVERTISED-PORT",
2046 &aport)) && 1958 &aport)) && (aport > 65535)))
2047 (aport > 65535)) ) 1959 {
2048 { 1960 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
2049 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, 1961 "tcp",
2050 "tcp", 1962 _
2051 _("Require valid port number for service `%s' in configuration!\n"), 1963 ("Require valid port number for service `%s' in configuration!\n"),
2052 "transport-tcp"); 1964 "transport-tcp");
2053 return NULL; 1965 return NULL;
2054 } 1966 }
2055 if (aport == 0) 1967 if (aport == 0)
2056 aport = bport; 1968 aport = bport;
2057 if (bport == 0) 1969 if (bport == 0)
2058 aport = 0; 1970 aport = 0;
2059 if (bport != 0) 1971 if (bport != 0)
1972 {
1973 service = GNUNET_SERVICE_start ("transport-tcp", env->cfg);
1974 if (service == NULL)
2060 { 1975 {
2061 service = GNUNET_SERVICE_start ("transport-tcp", env->cfg); 1976 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
2062 if (service == NULL) 1977 "tcp", _("Failed to start service.\n"));
2063 { 1978 return NULL;
2064 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
2065 "tcp",
2066 _("Failed to start service.\n"));
2067 return NULL;
2068 }
2069 } 1979 }
1980 }
2070 else 1981 else
2071 service = NULL; 1982 service = NULL;
2072 1983
@@ -2078,41 +1989,37 @@ libgnunet_plugin_transport_tcp_init (void *cls)
2078 plugin->adv_port = aport; 1989 plugin->adv_port = aport;
2079 plugin->env = env; 1990 plugin->env = env;
2080 plugin->lsock = NULL; 1991 plugin->lsock = NULL;
2081 if ( (service != NULL) && 1992 if ((service != NULL) &&
2082 (GNUNET_SYSERR != 1993 (GNUNET_SYSERR !=
2083 (ret = GNUNET_SERVICE_get_server_addresses ("transport-tcp", 1994 (ret = GNUNET_SERVICE_get_server_addresses ("transport-tcp",
2084 env->cfg, 1995 env->cfg,
2085 &addrs, 1996 &addrs, &addrlens))))
2086 &addrlens))) ) 1997 {
1998 plugin->nat = GNUNET_NAT_register (env->cfg,
1999 GNUNET_YES,
2000 aport,
2001 (unsigned int) ret,
2002 (const struct sockaddr **) addrs,
2003 addrlens,
2004 &tcp_nat_port_map_callback,
2005 &try_connection_reversal, plugin);
2006 while (ret > 0)
2087 { 2007 {
2088 plugin->nat = GNUNET_NAT_register (env->cfg, 2008 ret--;
2089 GNUNET_YES, 2009 GNUNET_assert (addrs[ret] != NULL);
2090 aport, 2010 GNUNET_free (addrs[ret]);
2091 (unsigned int) ret,
2092 (const struct sockaddr **) addrs,
2093 addrlens,
2094 &tcp_nat_port_map_callback,
2095 &try_connection_reversal,
2096 plugin);
2097 while (ret > 0)
2098 {
2099 ret--;
2100 GNUNET_assert (addrs[ret] != NULL);
2101 GNUNET_free (addrs[ret]);
2102 }
2103 GNUNET_free_non_null (addrs);
2104 GNUNET_free_non_null (addrlens);
2105 } 2011 }
2012 GNUNET_free_non_null (addrs);
2013 GNUNET_free_non_null (addrlens);
2014 }
2106 else 2015 else
2107 { 2016 {
2108 plugin->nat = GNUNET_NAT_register (env->cfg, 2017 plugin->nat = GNUNET_NAT_register (env->cfg,
2109 GNUNET_YES, 2018 GNUNET_YES,
2110 0, 2019 0,
2111 0, NULL, NULL, 2020 0, NULL, NULL,
2112 NULL, 2021 NULL, &try_connection_reversal, plugin);
2113 &try_connection_reversal, 2022 }
2114 plugin);
2115 }
2116 api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); 2023 api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
2117 api->cls = plugin; 2024 api->cls = plugin;
2118 api->send = &tcp_plugin_send; 2025 api->send = &tcp_plugin_send;
@@ -2121,32 +2028,31 @@ libgnunet_plugin_transport_tcp_init (void *cls)
2121 api->check_address = &tcp_plugin_check_address; 2028 api->check_address = &tcp_plugin_check_address;
2122 api->address_to_string = &tcp_address_to_string; 2029 api->address_to_string = &tcp_address_to_string;
2123 plugin->service = service; 2030 plugin->service = service;
2124 if (service != NULL) 2031 if (service != NULL)
2125 { 2032 {
2126 plugin->server = GNUNET_SERVICE_get_server (service); 2033 plugin->server = GNUNET_SERVICE_get_server (service);
2127 } 2034 }
2128 else 2035 else
2036 {
2037 if (GNUNET_OK !=
2038 GNUNET_CONFIGURATION_get_value_time (env->cfg,
2039 "transport-tcp",
2040 "TIMEOUT", &idle_timeout))
2129 { 2041 {
2130 if (GNUNET_OK != 2042 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
2131 GNUNET_CONFIGURATION_get_value_time (env->cfg, 2043 "tcp",
2132 "transport-tcp", 2044 _("Failed to find option %s in section %s!\n"),
2133 "TIMEOUT", 2045 "TIMEOUT", "transport-tcp");
2134 &idle_timeout)) 2046 if (plugin->nat != NULL)
2135 { 2047 GNUNET_NAT_unregister (plugin->nat);
2136 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, 2048 GNUNET_free (plugin);
2137 "tcp", 2049 GNUNET_free (api);
2138 _("Failed to find option %s in section %s!\n"), 2050 return NULL;
2139 "TIMEOUT",
2140 "transport-tcp");
2141 if (plugin->nat != NULL)
2142 GNUNET_NAT_unregister (plugin->nat);
2143 GNUNET_free (plugin);
2144 GNUNET_free (api);
2145 return NULL;
2146 }
2147 plugin->server = GNUNET_SERVER_create_with_sockets (&plugin_tcp_access_check, plugin, NULL,
2148 idle_timeout, GNUNET_YES);
2149 } 2051 }
2052 plugin->server =
2053 GNUNET_SERVER_create_with_sockets (&plugin_tcp_access_check, plugin,
2054 NULL, idle_timeout, GNUNET_YES);
2055 }
2150 plugin->handlers = GNUNET_malloc (sizeof (my_handlers)); 2056 plugin->handlers = GNUNET_malloc (sizeof (my_handlers));
2151 memcpy (plugin->handlers, my_handlers, sizeof (my_handlers)); 2057 memcpy (plugin->handlers, my_handlers, sizeof (my_handlers));
2152 for (i = 0; 2058 for (i = 0;
@@ -2154,23 +2060,21 @@ libgnunet_plugin_transport_tcp_init (void *cls)
2154 i++) 2060 i++)
2155 plugin->handlers[i].callback_cls = plugin; 2061 plugin->handlers[i].callback_cls = plugin;
2156 GNUNET_SERVER_add_handlers (plugin->server, plugin->handlers); 2062 GNUNET_SERVER_add_handlers (plugin->server, plugin->handlers);
2157 GNUNET_SERVER_disconnect_notify (plugin->server, 2063 GNUNET_SERVER_disconnect_notify (plugin->server, &disconnect_notify, plugin);
2158 &disconnect_notify, 2064 plugin->nat_wait_conns = GNUNET_CONTAINER_multihashmap_create (16);
2159 plugin);
2160 plugin->nat_wait_conns = GNUNET_CONTAINER_multihashmap_create(16);
2161 if (bport != 0) 2065 if (bport != 0)
2162 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, 2066 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO,
2163 "tcp", 2067 "tcp", _("TCP transport listening on port %llu\n"), bport);
2164 _("TCP transport listening on port %llu\n"),
2165 bport);
2166 else 2068 else
2167 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, 2069 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO,
2168 "tcp", 2070 "tcp",
2169 _("TCP transport not listening on any port (client only)\n")); 2071 _
2072 ("TCP transport not listening on any port (client only)\n"));
2170 if (aport != bport) 2073 if (aport != bport)
2171 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, 2074 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO,
2172 "tcp", 2075 "tcp",
2173 _("TCP transport advertises itself as being on port %llu\n"), 2076 _
2077 ("TCP transport advertises itself as being on port %llu\n"),
2174 aport); 2078 aport);
2175 return api; 2079 return api;
2176} 2080}
@@ -2197,13 +2101,12 @@ libgnunet_plugin_transport_tcp_done (void *cls)
2197 if (plugin->nat != NULL) 2101 if (plugin->nat != NULL)
2198 GNUNET_NAT_unregister (plugin->nat); 2102 GNUNET_NAT_unregister (plugin->nat);
2199 while (NULL != (tcp_probe = plugin->probe_head)) 2103 while (NULL != (tcp_probe = plugin->probe_head))
2200 { 2104 {
2201 GNUNET_CONTAINER_DLL_remove (plugin->probe_head, 2105 GNUNET_CONTAINER_DLL_remove (plugin->probe_head,
2202 plugin->probe_tail, 2106 plugin->probe_tail, tcp_probe);
2203 tcp_probe); 2107 GNUNET_CONNECTION_destroy (tcp_probe->sock, GNUNET_NO);
2204 GNUNET_CONNECTION_destroy (tcp_probe->sock, GNUNET_NO); 2108 GNUNET_free (tcp_probe);
2205 GNUNET_free (tcp_probe); 2109 }
2206 }
2207 GNUNET_CONTAINER_multihashmap_destroy (plugin->nat_wait_conns); 2110 GNUNET_CONTAINER_multihashmap_destroy (plugin->nat_wait_conns);
2208 GNUNET_free (plugin); 2111 GNUNET_free (plugin);
2209 GNUNET_free (api); 2112 GNUNET_free (api);