diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-12-13 17:32:40 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-12-13 17:32:40 +0000 |
commit | 5ae1ed8769f96975fcfe9ead4f5efdba15b68e5a (patch) | |
tree | be51d842ca3ebd005c74494221356e916ab73594 /src/transport/plugin_transport_tcp.c | |
parent | 542fbe05c948ec86c07ea4683e6a387ad8a03f72 (diff) | |
download | gnunet-5ae1ed8769f96975fcfe9ead4f5efdba15b68e5a.tar.gz gnunet-5ae1ed8769f96975fcfe9ead4f5efdba15b68e5a.zip |
-code cleanup, in particular moving towards using client context for storing TCP sessions to be more efficient upon receiving
Diffstat (limited to 'src/transport/plugin_transport_tcp.c')
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 459 |
1 files changed, 230 insertions, 229 deletions
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 83fea8ca5..9038dc66b 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -25,14 +25,10 @@ | |||
25 | #include "platform.h" | 25 | #include "platform.h" |
26 | #include "gnunet_hello_lib.h" | 26 | #include "gnunet_hello_lib.h" |
27 | #include "gnunet_constants.h" | 27 | #include "gnunet_constants.h" |
28 | #include "gnunet_connection_lib.h" | 28 | #include "gnunet_util_lib.h" |
29 | #include "gnunet_container_lib.h" | ||
30 | #include "gnunet_nat_lib.h" | 29 | #include "gnunet_nat_lib.h" |
31 | #include "gnunet_os_lib.h" | ||
32 | #include "gnunet_protocols.h" | 30 | #include "gnunet_protocols.h" |
33 | #include "gnunet_resolver_service.h" | 31 | #include "gnunet_resolver_service.h" |
34 | #include "gnunet_server_lib.h" | ||
35 | #include "gnunet_service_lib.h" | ||
36 | #include "gnunet_signatures.h" | 32 | #include "gnunet_signatures.h" |
37 | #include "gnunet_statistics_service.h" | 33 | #include "gnunet_statistics_service.h" |
38 | #include "gnunet_transport_service.h" | 34 | #include "gnunet_transport_service.h" |
@@ -427,31 +423,20 @@ struct Plugin | |||
427 | 423 | ||
428 | 424 | ||
429 | /** | 425 | /** |
430 | * Start session timeout | 426 | * Function called for a quick conversion of the binary address to |
431 | */ | 427 | * a numeric address. Note that the caller must not free the |
432 | static void | 428 | * address and that the next call to this function is allowed |
433 | start_session_timeout (struct Session *s); | 429 | * to override the address again. |
434 | |||
435 | |||
436 | /** | ||
437 | * Increment session timeout due to activity | ||
438 | */ | ||
439 | static void | ||
440 | reschedule_session_timeout (struct Session *s); | ||
441 | |||
442 | |||
443 | /** | ||
444 | * Cancel timeout | ||
445 | * | 430 | * |
446 | * @param s session to cancel timeout for | 431 | * @param cls closure ('struct Plugin*') |
432 | * @param addr binary address | ||
433 | * @param addrlen length of the address | ||
434 | * @return string representing the same address | ||
447 | */ | 435 | */ |
448 | static void | ||
449 | stop_session_timeout (struct Session *s); | ||
450 | |||
451 | |||
452 | /* DEBUG CODE */ | ||
453 | static const char * | 436 | static const char * |
454 | tcp_address_to_string (void *cls, const void *addr, size_t addrlen); | 437 | tcp_address_to_string (void *cls, |
438 | const void *addr, | ||
439 | size_t addrlen); | ||
455 | 440 | ||
456 | 441 | ||
457 | /** | 442 | /** |
@@ -459,7 +444,7 @@ tcp_address_to_string (void *cls, const void *addr, size_t addrlen); | |||
459 | * Mostly used to limit the total number of open connections | 444 | * Mostly used to limit the total number of open connections |
460 | * we can have. | 445 | * we can have. |
461 | * | 446 | * |
462 | * @param cls the 'struct Plugin' | 447 | * @param cls the `struct Plugin` |
463 | * @param ucred credentials, if available, otherwise NULL | 448 | * @param ucred credentials, if available, otherwise NULL |
464 | * @param addr address | 449 | * @param addr address |
465 | * @param addrlen length of address | 450 | * @param addrlen length of address |
@@ -485,7 +470,7 @@ plugin_tcp_access_check (void *cls, | |||
485 | /** | 470 | /** |
486 | * Our external IP address/port mapping has changed. | 471 | * Our external IP address/port mapping has changed. |
487 | * | 472 | * |
488 | * @param cls closure, the 'struct LocalAddrList' | 473 | * @param cls closure, the 'struct Plugin' |
489 | * @param add_remove #GNUNET_YES to mean the new public IP address, #GNUNET_NO to mean | 474 | * @param add_remove #GNUNET_YES to mean the new public IP address, #GNUNET_NO to mean |
490 | * the previous (now invalid) one | 475 | * the previous (now invalid) one |
491 | * @param addr either the previous or the new public IP address | 476 | * @param addr either the previous or the new public IP address |
@@ -493,7 +478,8 @@ plugin_tcp_access_check (void *cls, | |||
493 | */ | 478 | */ |
494 | static void | 479 | static void |
495 | tcp_nat_port_map_callback (void *cls, int add_remove, | 480 | tcp_nat_port_map_callback (void *cls, int add_remove, |
496 | const struct sockaddr *addr, socklen_t addrlen) | 481 | const struct sockaddr *addr, |
482 | socklen_t addrlen) | ||
497 | { | 483 | { |
498 | struct Plugin *plugin = cls; | 484 | struct Plugin *plugin = cls; |
499 | struct IPv4TcpAddress t4; | 485 | struct IPv4TcpAddress t4; |
@@ -542,7 +528,7 @@ tcp_nat_port_map_callback (void *cls, int add_remove, | |||
542 | * address and that the next call to this function is allowed | 528 | * address and that the next call to this function is allowed |
543 | * to override the address again. | 529 | * to override the address again. |
544 | * | 530 | * |
545 | * @param cls closure ('struct Plugin*') | 531 | * @param cls closure (`struct Plugin*`) |
546 | * @param addr binary address | 532 | * @param addr binary address |
547 | * @param addrlen length of the address | 533 | * @param addrlen length of the address |
548 | * @return string representing the same address | 534 | * @return string representing the same address |
@@ -596,8 +582,15 @@ tcp_address_to_string (void *cls, const void *addr, size_t addrlen) | |||
596 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop"); | 582 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop"); |
597 | return NULL; | 583 | return NULL; |
598 | } | 584 | } |
599 | GNUNET_snprintf (rbuf, sizeof (rbuf), (af == AF_INET6) ? "%s.%u.[%s]:%u" : "%s.%u.%s:%u", | 585 | GNUNET_snprintf (rbuf, |
600 | PLUGIN_NAME, options, buf, port); | 586 | sizeof (rbuf), |
587 | (af == AF_INET6) | ||
588 | ? "%s.%u.[%s]:%u" | ||
589 | : "%s.%u.%s:%u", | ||
590 | PLUGIN_NAME, | ||
591 | options, | ||
592 | buf, | ||
593 | port); | ||
601 | return rbuf; | 594 | return rbuf; |
602 | } | 595 | } |
603 | 596 | ||
@@ -606,7 +599,7 @@ tcp_address_to_string (void *cls, const void *addr, size_t addrlen) | |||
606 | * Function called to convert a string address to | 599 | * Function called to convert a string address to |
607 | * a binary address. | 600 | * a binary address. |
608 | * | 601 | * |
609 | * @param cls closure ('struct Plugin*') | 602 | * @param cls closure (`struct Plugin*`) |
610 | * @param addr string address | 603 | * @param addr string address |
611 | * @param addrlen length of the address | 604 | * @param addrlen length of the address |
612 | * @param buf location to store the buffer | 605 | * @param buf location to store the buffer |
@@ -682,7 +675,7 @@ tcp_string_to_address (void *cls, | |||
682 | { | 675 | { |
683 | struct IPv4TcpAddress *t4; | 676 | struct IPv4TcpAddress *t4; |
684 | struct sockaddr_in *in4 = (struct sockaddr_in *) &socket_address; | 677 | struct sockaddr_in *in4 = (struct sockaddr_in *) &socket_address; |
685 | t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress)); | 678 | t4 = GNUNET_new (struct IPv4TcpAddress); |
686 | t4->options = htonl (options); | 679 | t4->options = htonl (options); |
687 | t4->ipv4_addr = in4->sin_addr.s_addr; | 680 | t4->ipv4_addr = in4->sin_addr.s_addr; |
688 | t4->t4_port = in4->sin_port; | 681 | t4->t4_port = in4->sin_port; |
@@ -694,7 +687,7 @@ tcp_string_to_address (void *cls, | |||
694 | { | 687 | { |
695 | struct IPv6TcpAddress *t6; | 688 | struct IPv6TcpAddress *t6; |
696 | struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &socket_address; | 689 | struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &socket_address; |
697 | t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress)); | 690 | t6 = GNUNET_new (struct IPv6TcpAddress); |
698 | t6->options = htonl (options); | 691 | t6->options = htonl (options); |
699 | t6->ipv6_addr = in6->sin6_addr; | 692 | t6->ipv6_addr = in6->sin6_addr; |
700 | t6->t6_port = in6->sin6_port; | 693 | t6->t6_port = in6->sin6_port; |
@@ -708,9 +701,19 @@ tcp_string_to_address (void *cls, | |||
708 | } | 701 | } |
709 | 702 | ||
710 | 703 | ||
704 | /** | ||
705 | * Closure for #session_lookup_by_client_it(). | ||
706 | */ | ||
711 | struct SessionClientCtx | 707 | struct SessionClientCtx |
712 | { | 708 | { |
709 | /** | ||
710 | * Client we are looking for. | ||
711 | */ | ||
713 | const struct GNUNET_SERVER_Client *client; | 712 | const struct GNUNET_SERVER_Client *client; |
713 | |||
714 | /** | ||
715 | * Session that was found. | ||
716 | */ | ||
714 | struct Session *ret; | 717 | struct Session *ret; |
715 | }; | 718 | }; |
716 | 719 | ||
@@ -734,6 +737,9 @@ session_lookup_by_client_it (void *cls, | |||
734 | 737 | ||
735 | /** | 738 | /** |
736 | * Find the session handle for the given client. | 739 | * Find the session handle for the given client. |
740 | * Currently uses both the hashmap and the client | ||
741 | * context, as the client context is new and the | ||
742 | * logic still needs to be tested. | ||
737 | * | 743 | * |
738 | * @param plugin the plugin | 744 | * @param plugin the plugin |
739 | * @param client which client to find the session handle for | 745 | * @param client which client to find the session handle for |
@@ -743,17 +749,166 @@ static struct Session * | |||
743 | lookup_session_by_client (struct Plugin *plugin, | 749 | lookup_session_by_client (struct Plugin *plugin, |
744 | const struct GNUNET_SERVER_Client *client) | 750 | const struct GNUNET_SERVER_Client *client) |
745 | { | 751 | { |
752 | struct Session *ret; | ||
746 | struct SessionClientCtx sc_ctx; | 753 | struct SessionClientCtx sc_ctx; |
747 | 754 | ||
755 | ret = GNUNET_SERVER_client_get_user_context (client, struct Session); | ||
748 | sc_ctx.client = client; | 756 | sc_ctx.client = client; |
749 | sc_ctx.ret = NULL; | 757 | sc_ctx.ret = NULL; |
750 | GNUNET_CONTAINER_multipeermap_iterate (plugin->sessionmap, | 758 | GNUNET_CONTAINER_multipeermap_iterate (plugin->sessionmap, |
751 | &session_lookup_by_client_it, &sc_ctx); | 759 | &session_lookup_by_client_it, &sc_ctx); |
760 | /* check both methods yield the same result */ | ||
761 | GNUNET_break (ret == sc_ctx.ret); | ||
752 | return sc_ctx.ret; | 762 | return sc_ctx.ret; |
753 | } | 763 | } |
754 | 764 | ||
755 | 765 | ||
756 | /** | 766 | /** |
767 | * Functions with this signature are called whenever we need | ||
768 | * to close a session due to a disconnect or failure to | ||
769 | * establish a connection. | ||
770 | * | ||
771 | * @param cls the `struct Plugin` | ||
772 | * @param session session to close down | ||
773 | * @return #GNUNET_OK on success | ||
774 | */ | ||
775 | static int | ||
776 | tcp_disconnect_session (void *cls, | ||
777 | struct Session *session) | ||
778 | { | ||
779 | struct Plugin *plugin = cls; | ||
780 | struct PendingMessage *pm; | ||
781 | |||
782 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
783 | "Disconnecting session of peer `%s' address `%s'\n", | ||
784 | GNUNET_i2s (&session->target), | ||
785 | tcp_address_to_string (NULL, session->addr, session->addrlen)); | ||
786 | |||
787 | if (GNUNET_SCHEDULER_NO_TASK != session->timeout_task) | ||
788 | { | ||
789 | GNUNET_SCHEDULER_cancel (session->timeout_task); | ||
790 | session->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
791 | } | ||
792 | |||
793 | if (GNUNET_YES == | ||
794 | GNUNET_CONTAINER_multipeermap_remove (plugin->sessionmap, | ||
795 | &session->target, | ||
796 | session)) | ||
797 | { | ||
798 | GNUNET_STATISTICS_update (session->plugin->env->stats, | ||
799 | gettext_noop ("# TCP sessions active"), -1, | ||
800 | GNUNET_NO); | ||
801 | } | ||
802 | else | ||
803 | { | ||
804 | GNUNET_assert (GNUNET_YES == | ||
805 | GNUNET_CONTAINER_multipeermap_remove (plugin->nat_wait_conns, | ||
806 | &session->target, | ||
807 | session)); | ||
808 | } | ||
809 | GNUNET_SERVER_client_set_user_context (session->client, | ||
810 | (void *) NULL); | ||
811 | |||
812 | /* clean up state */ | ||
813 | if (NULL != session->transmit_handle) | ||
814 | { | ||
815 | GNUNET_SERVER_notify_transmit_ready_cancel (session->transmit_handle); | ||
816 | session->transmit_handle = NULL; | ||
817 | } | ||
818 | session->plugin->env->session_end (session->plugin->env->cls, | ||
819 | &session->target, session); | ||
820 | |||
821 | if (GNUNET_SCHEDULER_NO_TASK != session->nat_connection_timeout) | ||
822 | { | ||
823 | GNUNET_SCHEDULER_cancel (session->nat_connection_timeout); | ||
824 | session->nat_connection_timeout = GNUNET_SCHEDULER_NO_TASK; | ||
825 | } | ||
826 | |||
827 | while (NULL != (pm = session->pending_messages_head)) | ||
828 | { | ||
829 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
830 | pm->transmit_cont != | ||
831 | NULL ? "Could not deliver message to `%4s'.\n" : | ||
832 | "Could not deliver message to `%4s', notifying.\n", | ||
833 | GNUNET_i2s (&session->target)); | ||
834 | GNUNET_STATISTICS_update (session->plugin->env->stats, | ||
835 | gettext_noop ("# bytes currently in TCP buffers"), | ||
836 | -(int64_t) pm->message_size, GNUNET_NO); | ||
837 | GNUNET_STATISTICS_update (session->plugin->env->stats, | ||
838 | gettext_noop | ||
839 | ("# bytes discarded by TCP (disconnect)"), | ||
840 | pm->message_size, GNUNET_NO); | ||
841 | GNUNET_CONTAINER_DLL_remove (session->pending_messages_head, | ||
842 | session->pending_messages_tail, pm); | ||
843 | if (NULL != pm->transmit_cont) | ||
844 | pm->transmit_cont (pm->transmit_cont_cls, &session->target, | ||
845 | GNUNET_SYSERR, pm->message_size, 0); | ||
846 | GNUNET_free (pm); | ||
847 | } | ||
848 | if (session->receive_delay_task != GNUNET_SCHEDULER_NO_TASK) | ||
849 | { | ||
850 | GNUNET_SCHEDULER_cancel (session->receive_delay_task); | ||
851 | if (NULL != session->client) | ||
852 | GNUNET_SERVER_receive_done (session->client, GNUNET_SYSERR); | ||
853 | } | ||
854 | if (NULL != session->client) | ||
855 | { | ||
856 | GNUNET_SERVER_client_disconnect (session->client); | ||
857 | GNUNET_SERVER_client_drop (session->client); | ||
858 | session->client = NULL; | ||
859 | } | ||
860 | GNUNET_free_non_null (session->addr); | ||
861 | GNUNET_assert (NULL == session->transmit_handle); | ||
862 | GNUNET_free (session); | ||
863 | return GNUNET_OK; | ||
864 | } | ||
865 | |||
866 | |||
867 | /** | ||
868 | * Session was idle, so disconnect it | ||
869 | * | ||
870 | * @param cls the `struct Session` of the idle session | ||
871 | * @param tc scheduler context | ||
872 | */ | ||
873 | static void | ||
874 | session_timeout (void *cls, | ||
875 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
876 | { | ||
877 | struct Session *s = cls; | ||
878 | |||
879 | s->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
880 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
881 | "Session %p was idle for %s, disconnecting\n", | ||
882 | s, | ||
883 | GNUNET_STRINGS_relative_time_to_string (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
884 | GNUNET_YES)); | ||
885 | /* call session destroy function */ | ||
886 | tcp_disconnect_session (s->plugin, s); | ||
887 | } | ||
888 | |||
889 | |||
890 | /** | ||
891 | * Increment session timeout due to activity | ||
892 | * | ||
893 | * @param s session to increment timeout for | ||
894 | */ | ||
895 | static void | ||
896 | reschedule_session_timeout (struct Session *s) | ||
897 | { | ||
898 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != s->timeout_task); | ||
899 | GNUNET_SCHEDULER_cancel (s->timeout_task); | ||
900 | s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
901 | &session_timeout, | ||
902 | s); | ||
903 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
904 | "Timeout rescheduled for session %p set to %s\n", | ||
905 | s, | ||
906 | GNUNET_STRINGS_relative_time_to_string (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
907 | GNUNET_YES)); | ||
908 | } | ||
909 | |||
910 | |||
911 | /** | ||
757 | * Create a new session. Also queues a welcome message. | 912 | * Create a new session. Also queues a welcome message. |
758 | * | 913 | * |
759 | * @param plugin the plugin | 914 | * @param plugin the plugin |
@@ -809,8 +964,9 @@ create_session (struct Plugin *plugin, | |||
809 | gettext_noop ("# TCP sessions active"), 1, | 964 | gettext_noop ("# TCP sessions active"), 1, |
810 | GNUNET_NO); | 965 | GNUNET_NO); |
811 | } | 966 | } |
812 | start_session_timeout (session); | 967 | session->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, |
813 | 968 | &session_timeout, | |
969 | session); | ||
814 | return session; | 970 | return session; |
815 | } | 971 | } |
816 | 972 | ||
@@ -972,103 +1128,6 @@ process_pending_messages (struct Session *session) | |||
972 | } | 1128 | } |
973 | 1129 | ||
974 | 1130 | ||
975 | /** | ||
976 | * Functions with this signature are called whenever we need | ||
977 | * to close a session due to a disconnect or failure to | ||
978 | * establish a connection. | ||
979 | * | ||
980 | * @param cls the `struct Plugin` | ||
981 | * @param session session to close down | ||
982 | * @return #GNUNET_OK on success | ||
983 | */ | ||
984 | static int | ||
985 | tcp_disconnect_session (void *cls, | ||
986 | struct Session *session) | ||
987 | { | ||
988 | struct Plugin *plugin = cls; | ||
989 | struct PendingMessage *pm; | ||
990 | |||
991 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
992 | "Disconnecting session of peer `%s' address `%s'\n", | ||
993 | GNUNET_i2s (&session->target), | ||
994 | tcp_address_to_string (NULL, session->addr, session->addrlen)); | ||
995 | |||
996 | stop_session_timeout (session); | ||
997 | |||
998 | if (GNUNET_YES == | ||
999 | GNUNET_CONTAINER_multipeermap_remove (plugin->sessionmap, | ||
1000 | &session->target, | ||
1001 | session)) | ||
1002 | { | ||
1003 | GNUNET_STATISTICS_update (session->plugin->env->stats, | ||
1004 | gettext_noop ("# TCP sessions active"), -1, | ||
1005 | GNUNET_NO); | ||
1006 | } | ||
1007 | else | ||
1008 | { | ||
1009 | GNUNET_assert (GNUNET_YES == | ||
1010 | GNUNET_CONTAINER_multipeermap_remove (plugin->nat_wait_conns, | ||
1011 | &session->target, | ||
1012 | session)); | ||
1013 | } | ||
1014 | GNUNET_SERVER_client_set_user_context (session->client, | ||
1015 | (void *) NULL); | ||
1016 | |||
1017 | /* clean up state */ | ||
1018 | if (NULL != session->transmit_handle) | ||
1019 | { | ||
1020 | GNUNET_SERVER_notify_transmit_ready_cancel (session->transmit_handle); | ||
1021 | session->transmit_handle = NULL; | ||
1022 | } | ||
1023 | session->plugin->env->session_end (session->plugin->env->cls, | ||
1024 | &session->target, session); | ||
1025 | |||
1026 | if (GNUNET_SCHEDULER_NO_TASK != session->nat_connection_timeout) | ||
1027 | { | ||
1028 | GNUNET_SCHEDULER_cancel (session->nat_connection_timeout); | ||
1029 | session->nat_connection_timeout = GNUNET_SCHEDULER_NO_TASK; | ||
1030 | } | ||
1031 | |||
1032 | while (NULL != (pm = session->pending_messages_head)) | ||
1033 | { | ||
1034 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1035 | pm->transmit_cont != | ||
1036 | NULL ? "Could not deliver message to `%4s'.\n" : | ||
1037 | "Could not deliver message to `%4s', notifying.\n", | ||
1038 | GNUNET_i2s (&session->target)); | ||
1039 | GNUNET_STATISTICS_update (session->plugin->env->stats, | ||
1040 | gettext_noop ("# bytes currently in TCP buffers"), | ||
1041 | -(int64_t) pm->message_size, GNUNET_NO); | ||
1042 | GNUNET_STATISTICS_update (session->plugin->env->stats, | ||
1043 | gettext_noop | ||
1044 | ("# bytes discarded by TCP (disconnect)"), | ||
1045 | pm->message_size, GNUNET_NO); | ||
1046 | GNUNET_CONTAINER_DLL_remove (session->pending_messages_head, | ||
1047 | session->pending_messages_tail, pm); | ||
1048 | if (NULL != pm->transmit_cont) | ||
1049 | pm->transmit_cont (pm->transmit_cont_cls, &session->target, | ||
1050 | GNUNET_SYSERR, pm->message_size, 0); | ||
1051 | GNUNET_free (pm); | ||
1052 | } | ||
1053 | if (session->receive_delay_task != GNUNET_SCHEDULER_NO_TASK) | ||
1054 | { | ||
1055 | GNUNET_SCHEDULER_cancel (session->receive_delay_task); | ||
1056 | if (NULL != session->client) | ||
1057 | GNUNET_SERVER_receive_done (session->client, GNUNET_SYSERR); | ||
1058 | } | ||
1059 | if (NULL != session->client) | ||
1060 | { | ||
1061 | GNUNET_SERVER_client_disconnect (session->client); | ||
1062 | GNUNET_SERVER_client_drop (session->client); | ||
1063 | session->client = NULL; | ||
1064 | } | ||
1065 | GNUNET_free_non_null (session->addr); | ||
1066 | GNUNET_assert (NULL == session->transmit_handle); | ||
1067 | GNUNET_free (session); | ||
1068 | return GNUNET_OK; | ||
1069 | } | ||
1070 | |||
1071 | |||
1072 | #if EXTRA_CHECKS | 1131 | #if EXTRA_CHECKS |
1073 | /** | 1132 | /** |
1074 | * Closure for #session_it(). | 1133 | * Closure for #session_it(). |
@@ -1253,14 +1312,36 @@ tcp_plugin_send (void *cls, | |||
1253 | } | 1312 | } |
1254 | 1313 | ||
1255 | 1314 | ||
1315 | /** | ||
1316 | * Closure for #session_lookup_it(). | ||
1317 | */ | ||
1256 | struct SessionItCtx | 1318 | struct SessionItCtx |
1257 | { | 1319 | { |
1320 | /** | ||
1321 | * Address we are looking for. | ||
1322 | */ | ||
1258 | void *addr; | 1323 | void *addr; |
1324 | |||
1325 | /** | ||
1326 | * Number of bytes in @e addr. | ||
1327 | */ | ||
1259 | size_t addrlen; | 1328 | size_t addrlen; |
1329 | |||
1330 | /** | ||
1331 | * Where to store the session (if we found it). | ||
1332 | */ | ||
1260 | struct Session *result; | 1333 | struct Session *result; |
1261 | }; | 1334 | }; |
1262 | 1335 | ||
1263 | 1336 | ||
1337 | /** | ||
1338 | * Look for a session by address. | ||
1339 | * | ||
1340 | * @param cls the `struct SessionItCtx` | ||
1341 | * @param key unused | ||
1342 | * @param value a `struct Session` | ||
1343 | * @return #GNUNET_YES to continue looking, #GNUNET_NO if we found the session | ||
1344 | */ | ||
1264 | static int | 1345 | static int |
1265 | session_lookup_it (void *cls, | 1346 | session_lookup_it (void *cls, |
1266 | const struct GNUNET_PeerIdentity *key, | 1347 | const struct GNUNET_PeerIdentity *key, |
@@ -1281,16 +1362,12 @@ session_lookup_it (void *cls, | |||
1281 | GNUNET_free (a2); | 1362 | GNUNET_free (a2); |
1282 | #endif | 1363 | #endif |
1283 | if (session->addrlen != si_ctx->addrlen) | 1364 | if (session->addrlen != si_ctx->addrlen) |
1284 | { | ||
1285 | return GNUNET_YES; | 1365 | return GNUNET_YES; |
1286 | } | ||
1287 | if (0 != memcmp (session->addr, si_ctx->addr, si_ctx->addrlen)) | 1366 | if (0 != memcmp (session->addr, si_ctx->addr, si_ctx->addrlen)) |
1288 | { | ||
1289 | return GNUNET_YES; | 1367 | return GNUNET_YES; |
1290 | } | ||
1291 | #if 0 | 1368 | #if 0 |
1292 | a1 = strdup (tcp_address_to_string(NULL, session->addr, session->addrlen)); | 1369 | a1 = strdup (tcp_address_to_string (NULL, session->addr, session->addrlen)); |
1293 | a2 = strdup (tcp_address_to_string(NULL, si_ctx->addr, si_ctx->addrlen)); | 1370 | a2 = strdup (tcp_address_to_string (NULL, si_ctx->addr, si_ctx->addrlen)); |
1294 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1371 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1295 | "Comparing: %s %u <-> %s %u , OK!\n", | 1372 | "Comparing: %s %u <-> %s %u , OK!\n", |
1296 | a1, | 1373 | a1, |
@@ -1308,6 +1385,9 @@ session_lookup_it (void *cls, | |||
1308 | 1385 | ||
1309 | /** | 1386 | /** |
1310 | * Task cleaning up a NAT connection attempt after timeout | 1387 | * Task cleaning up a NAT connection attempt after timeout |
1388 | * | ||
1389 | * @param cls the `struct Session` | ||
1390 | * @param tc scheduler context (unused) | ||
1311 | */ | 1391 | */ |
1312 | static void | 1392 | static void |
1313 | nat_connect_timeout (void *cls, | 1393 | nat_connect_timeout (void *cls, |
@@ -1332,7 +1412,7 @@ nat_connect_timeout (void *cls, | |||
1332 | * notify us by calling the env->session_end function | 1412 | * notify us by calling the env->session_end function |
1333 | * | 1413 | * |
1334 | * @param cls closure | 1414 | * @param cls closure |
1335 | * @param address pointer to the GNUNET_HELLO_Address | 1415 | * @param address the address to use |
1336 | * @return the session if the address is valid, NULL otherwise | 1416 | * @return the session if the address is valid, NULL otherwise |
1337 | */ | 1417 | */ |
1338 | static struct Session * | 1418 | static struct Session * |
@@ -1353,8 +1433,6 @@ tcp_plugin_get_session (void *cls, | |||
1353 | unsigned int is_natd = GNUNET_NO; | 1433 | unsigned int is_natd = GNUNET_NO; |
1354 | size_t addrlen; | 1434 | size_t addrlen; |
1355 | 1435 | ||
1356 | GNUNET_assert (plugin != NULL); | ||
1357 | GNUNET_assert (address != NULL); | ||
1358 | addrlen = address->address_length; | 1436 | addrlen = address->address_length; |
1359 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1437 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1360 | "Trying to get session for `%s' address of peer `%s'\n", | 1438 | "Trying to get session for `%s' address of peer `%s'\n", |
@@ -1580,12 +1658,14 @@ session_disconnect_it (void *cls, | |||
1580 | * to be cancelled | 1658 | * to be cancelled |
1581 | */ | 1659 | */ |
1582 | static void | 1660 | static void |
1583 | tcp_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) | 1661 | tcp_plugin_disconnect (void *cls, |
1662 | const struct GNUNET_PeerIdentity *target) | ||
1584 | { | 1663 | { |
1585 | struct Plugin *plugin = cls; | 1664 | struct Plugin *plugin = cls; |
1586 | 1665 | ||
1587 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1666 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1588 | "Disconnecting peer `%4s'\n", GNUNET_i2s (target)); | 1667 | "Disconnecting peer `%4s'\n", |
1668 | GNUNET_i2s (target)); | ||
1589 | GNUNET_CONTAINER_multipeermap_get_multiple (plugin->sessionmap, target, | 1669 | GNUNET_CONTAINER_multipeermap_get_multiple (plugin->sessionmap, target, |
1590 | &session_disconnect_it, plugin); | 1670 | &session_disconnect_it, plugin); |
1591 | GNUNET_CONTAINER_multipeermap_get_multiple (plugin->nat_wait_conns, target, | 1671 | GNUNET_CONTAINER_multipeermap_get_multiple (plugin->nat_wait_conns, target, |
@@ -1832,11 +1912,11 @@ tcp_plugin_address_pretty_printer (void *cls, const char *type, | |||
1832 | * Check if the given port is plausible (must be either our listen | 1912 | * Check if the given port is plausible (must be either our listen |
1833 | * port or our advertised port), or any port if we are behind NAT | 1913 | * port or our advertised port), or any port if we are behind NAT |
1834 | * and do not have a port open. If it is neither, we return | 1914 | * and do not have a port open. If it is neither, we return |
1835 | * GNUNET_SYSERR. | 1915 | * #GNUNET_SYSERR. |
1836 | * | 1916 | * |
1837 | * @param plugin global variables | 1917 | * @param plugin global variables |
1838 | * @param in_port port number to check | 1918 | * @param in_port port number to check |
1839 | * @return GNUNET_OK if port is either open_port or adv_port | 1919 | * @return #GNUNET_OK if port is either open_port or adv_port |
1840 | */ | 1920 | */ |
1841 | static int | 1921 | static int |
1842 | check_port (struct Plugin *plugin, uint16_t in_port) | 1922 | check_port (struct Plugin *plugin, uint16_t in_port) |
@@ -1859,8 +1939,8 @@ check_port (struct Plugin *plugin, uint16_t in_port) | |||
1859 | * @param cls closure, our 'struct Plugin*' | 1939 | * @param cls closure, our 'struct Plugin*' |
1860 | * @param addr pointer to the address | 1940 | * @param addr pointer to the address |
1861 | * @param addrlen length of addr | 1941 | * @param addrlen length of addr |
1862 | * @return GNUNET_OK if this is a plausible address for this peer | 1942 | * @return #GNUNET_OK if this is a plausible address for this peer |
1863 | * and transport, GNUNET_SYSERR if not | 1943 | * and transport, #GNUNET_SYSERR if not |
1864 | */ | 1944 | */ |
1865 | static int | 1945 | static int |
1866 | tcp_plugin_check_address (void *cls, const void *addr, size_t addrlen) | 1946 | tcp_plugin_check_address (void *cls, const void *addr, size_t addrlen) |
@@ -2442,85 +2522,6 @@ try_connection_reversal (void *cls, const struct sockaddr *addr, | |||
2442 | 2522 | ||
2443 | 2523 | ||
2444 | /** | 2524 | /** |
2445 | * Session was idle, so disconnect it | ||
2446 | */ | ||
2447 | static void | ||
2448 | session_timeout (void *cls, | ||
2449 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
2450 | { | ||
2451 | struct Session *s = cls; | ||
2452 | |||
2453 | s->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
2454 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2455 | "Session %p was idle for %s, disconnecting\n", | ||
2456 | s, | ||
2457 | GNUNET_STRINGS_relative_time_to_string (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
2458 | GNUNET_YES)); | ||
2459 | /* call session destroy function */ | ||
2460 | tcp_disconnect_session(s->plugin, s); | ||
2461 | } | ||
2462 | |||
2463 | |||
2464 | /** | ||
2465 | * Start session timeout | ||
2466 | */ | ||
2467 | static void | ||
2468 | start_session_timeout (struct Session *s) | ||
2469 | { | ||
2470 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == s->timeout_task); | ||
2471 | s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
2472 | &session_timeout, | ||
2473 | s); | ||
2474 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2475 | "Timeout for session %p set to %s\n", | ||
2476 | s, | ||
2477 | GNUNET_STRINGS_relative_time_to_string (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
2478 | GNUNET_YES)); | ||
2479 | } | ||
2480 | |||
2481 | |||
2482 | /** | ||
2483 | * Increment session timeout due to activity | ||
2484 | */ | ||
2485 | static void | ||
2486 | reschedule_session_timeout (struct Session *s) | ||
2487 | { | ||
2488 | GNUNET_assert (NULL != s); | ||
2489 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != s->timeout_task); | ||
2490 | |||
2491 | GNUNET_SCHEDULER_cancel (s->timeout_task); | ||
2492 | s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
2493 | &session_timeout, | ||
2494 | s); | ||
2495 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2496 | "Timeout rescheduled for session %p set to %s\n", | ||
2497 | s, | ||
2498 | GNUNET_STRINGS_relative_time_to_string (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
2499 | GNUNET_YES)); | ||
2500 | } | ||
2501 | |||
2502 | |||
2503 | /** | ||
2504 | * Cancel timeout. | ||
2505 | * | ||
2506 | * @param s session to cancel timeout for | ||
2507 | */ | ||
2508 | static void | ||
2509 | stop_session_timeout (struct Session *s) | ||
2510 | { | ||
2511 | GNUNET_assert (NULL != s); | ||
2512 | |||
2513 | if (GNUNET_SCHEDULER_NO_TASK != s->timeout_task) | ||
2514 | { | ||
2515 | GNUNET_SCHEDULER_cancel (s->timeout_task); | ||
2516 | s->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
2517 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2518 | "Timeout stopped for session %p canceled\n", | ||
2519 | s); | ||
2520 | } | ||
2521 | } | ||
2522 | |||
2523 | /** | ||
2524 | * Function obtain the network type for a session | 2525 | * Function obtain the network type for a session |
2525 | * | 2526 | * |
2526 | * @param cls closure ('struct Plugin*') | 2527 | * @param cls closure ('struct Plugin*') |