aboutsummaryrefslogtreecommitdiff
path: root/src/arm
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-11-10 11:46:41 +0000
committerChristian Grothoff <christian@grothoff.org>2010-11-10 11:46:41 +0000
commitdac677dc13d582025d688c06da7412782bb254c4 (patch)
treeccfc6d53aed03d5869f7eaed7c0ded6571e0e1ba /src/arm
parent14850182c5db8fff8d31ad4059e62bcf5ed54795 (diff)
downloadgnunet-dac677dc13d582025d688c06da7412782bb254c4.tar.gz
gnunet-dac677dc13d582025d688c06da7412782bb254c4.zip
enabling forwarding for AF_UNIX, no longer doing both IPv4 and IPv6 -- since this can never really be needed
Diffstat (limited to 'src/arm')
-rw-r--r--src/arm/gnunet-service-arm_interceptor.c294
1 files changed, 101 insertions, 193 deletions
diff --git a/src/arm/gnunet-service-arm_interceptor.c b/src/arm/gnunet-service-arm_interceptor.c
index acdfe0a55..1bf69181a 100644
--- a/src/arm/gnunet-service-arm_interceptor.c
+++ b/src/arm/gnunet-service-arm_interceptor.c
@@ -56,6 +56,7 @@
56 */ 56 */
57#define REASON_ERROR 3 57#define REASON_ERROR 3
58 58
59struct ForwardedConnection;
59 60
60/** 61/**
61 * 62 *
@@ -93,6 +94,11 @@ struct ServiceListeningInfo
93 struct GNUNET_NETWORK_Handle *listeningSocket; 94 struct GNUNET_NETWORK_Handle *listeningSocket;
94 95
95 /** 96 /**
97 *
98 */
99 struct ForwardedConnection *fc;
100
101 /**
96 * Task doing the accepting. 102 * Task doing the accepting.
97 */ 103 */
98 GNUNET_SCHEDULER_TaskIdentifier acceptTask; 104 GNUNET_SCHEDULER_TaskIdentifier acceptTask;
@@ -188,15 +194,6 @@ struct ForwardedConnection
188 */ 194 */
189 int first_write_done; 195 int first_write_done;
190 196
191 /**
192 * Service connection attempts for IPv4
193 */
194 struct ServiceListeningInfo *service_connect_ipv4;
195
196 /**
197 * Service connection attempts for IPv6
198 */
199 struct ServiceListeningInfo *service_connect_ipv6;
200}; 197};
201 198
202/** 199/**
@@ -711,129 +708,79 @@ receiveFromClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
711 708
712 709
713static void 710static void
714fc_acceptConnection_ipv4 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
715
716static void
717fc_acceptConnection_ipv6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
718
719
720static void
721fc_acceptConnection (void *cls, 711fc_acceptConnection (void *cls,
722 const struct GNUNET_SCHEDULER_TaskContext *tc, 712 const struct GNUNET_SCHEDULER_TaskContext *tc)
723 int is_ipv4)
724{ 713{
725 struct ForwardedConnection *fc = cls; 714 struct ServiceListeningInfo *sli = cls;
726 struct ServiceListeningInfo *sli; 715 struct ForwardedConnection *fc = sli->fc;
727
728 if (is_ipv4)
729 sli = fc->service_connect_ipv4;
730 else
731 sli = fc->service_connect_ipv6;
732 716
733 if ( (tc->reason & (GNUNET_SCHEDULER_REASON_SHUTDOWN | GNUNET_SCHEDULER_REASON_TIMEOUT | GNUNET_SCHEDULER_REASON_PREREQ_DONE)) || 717 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY))
734 ((tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) && fc->armServiceSocket) )
735 { 718 {
736 GNUNET_NETWORK_socket_close (sli->listeningSocket); 719 GNUNET_NETWORK_socket_close (sli->listeningSocket);
737 if (is_ipv4) 720 closeClientAndServiceSockets (fc, REASON_ERROR);
738 fc->service_connect_ipv4 = NULL; 721 GNUNET_free (sli);
739 else 722 return;
740 fc->service_connect_ipv6 = NULL;
741 } 723 }
742 else if (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)
743 {
744#if DEBUG_SERVICE_MANAGER 724#if DEBUG_SERVICE_MANAGER
745 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 725 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
746 "Connected to service, now starting forwarding\n"); 726 "Connected to service, now starting forwarding\n");
747#endif 727#endif
748 fc->armServiceSocket = sli->listeningSocket; 728 fc->armServiceSocket = sli->listeningSocket;
749 if ( (GNUNET_YES == is_ipv4) && (fc->service_connect_ipv6 != NULL) ) 729 GNUNET_free (fc->listen_info->service_addr);
750 { 730 fc->listen_info->service_addr = sli->service_addr;
751 GNUNET_SCHEDULER_cancel (fc->service_connect_ipv6->acceptTask); 731 fc->listen_info->service_addr_len = sli->service_addr_len;
752 fc->service_connect_ipv6->acceptTask = GNUNET_SCHEDULER_add_now (fc_acceptConnection_ipv6, fc); 732 if (fc->client_to_service_task == GNUNET_SCHEDULER_NO_TASK)
753 } 733 {
754 else if ( (GNUNET_NO == is_ipv4) && (fc->service_connect_ipv4 != NULL) ) 734 if (fc->client_to_service_bufferDataLength == 0)
755 { 735 fc->client_to_service_task =
756 GNUNET_SCHEDULER_cancel (fc->service_connect_ipv4->acceptTask); 736 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
757 fc->service_connect_ipv4->acceptTask = GNUNET_SCHEDULER_add_now (fc_acceptConnection_ipv4, fc); 737 fc->armClientSocket,
758 } 738 &receiveFromClient, fc);
759 GNUNET_free (fc->listen_info->service_addr); 739 else
760 fc->listen_info->service_addr = sli->service_addr; 740 fc->client_to_service_task =
761 fc->listen_info->service_addr_len = sli->service_addr_len; 741 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
762 /* fc->listen_info->listeningSocket is it closed already ?*/ 742 fc->armServiceSocket,
763 if (fc->client_to_service_task == GNUNET_SCHEDULER_NO_TASK) 743 &forwardToService, fc);
764 {
765 if (fc->client_to_service_bufferDataLength == 0)
766 fc->client_to_service_task =
767 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
768 fc->armClientSocket,
769 &receiveFromClient, fc);
770 else
771 fc->client_to_service_task =
772 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
773 fc->armServiceSocket,
774 &forwardToService, fc);
775 }
776 if (fc->service_to_client_task == GNUNET_SCHEDULER_NO_TASK)
777 {
778 if (fc->service_to_client_bufferDataLength == 0)
779 fc->service_to_client_task =
780 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
781 fc->armServiceSocket,
782 &receiveFromService, fc);
783 else
784 fc->service_to_client_task =
785 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
786 fc->armClientSocket,
787 &forwardToClient, fc);
788 }
789 } 744 }
790 else 745 if (fc->service_to_client_task == GNUNET_SCHEDULER_NO_TASK)
791 { 746 {
792 GNUNET_break (0); 747 if (fc->service_to_client_bufferDataLength == 0)
748 fc->service_to_client_task =
749 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
750 fc->armServiceSocket,
751 &receiveFromService, fc);
752 else
753 fc->service_to_client_task =
754 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
755 fc->armClientSocket,
756 &forwardToClient, fc);
793 } 757 }
794 GNUNET_free (sli); 758 GNUNET_free (sli);
795} 759}
796 760
797 761
798static void 762static struct ServiceListeningInfo *
799fc_acceptConnection_ipv4 (void *cls,
800 const struct GNUNET_SCHEDULER_TaskContext *tc)
801{
802 fc_acceptConnection (cls, tc, GNUNET_YES);
803}
804
805
806static void
807fc_acceptConnection_ipv6 (void *cls,
808 const struct GNUNET_SCHEDULER_TaskContext *tc)
809{
810 fc_acceptConnection (cls, tc, GNUNET_NO);
811}
812
813
814static int
815service_try_to_connect (const struct sockaddr *addr, 763service_try_to_connect (const struct sockaddr *addr,
764 int pf,
816 socklen_t addrlen, 765 socklen_t addrlen,
817 struct ForwardedConnection *fc) 766 struct ForwardedConnection *fc)
818{ 767{
819 struct GNUNET_NETWORK_Handle *sock; 768 struct GNUNET_NETWORK_Handle *sock;
820 struct ServiceListeningInfo *serviceListeningInfo; 769 struct ServiceListeningInfo *serviceListeningInfo;
821 770
822 sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0); 771 sock = GNUNET_NETWORK_socket_create (pf, SOCK_STREAM, 0);
823 if (sock == NULL) 772 if (sock == NULL)
824 { 773 {
825 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to create a socket\n"); 774 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket");
826 return 1; 775 return NULL;
827 } 776 }
828
829 if ( (GNUNET_SYSERR == GNUNET_NETWORK_socket_connect (sock, addr, addrlen)) && 777 if ( (GNUNET_SYSERR == GNUNET_NETWORK_socket_connect (sock, addr, addrlen)) &&
830 (errno != EINPROGRESS) ) 778 (errno != EINPROGRESS) )
831 { 779 {
832 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to connect\n"); 780 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "connect");
833 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); 781 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
834 return 1; 782 return NULL;
835 } 783 }
836
837 serviceListeningInfo = GNUNET_malloc (sizeof (struct ServiceListeningInfo)); 784 serviceListeningInfo = GNUNET_malloc (sizeof (struct ServiceListeningInfo));
838 serviceListeningInfo->serviceName = NULL; 785 serviceListeningInfo->serviceName = NULL;
839 serviceListeningInfo->service_addr = GNUNET_malloc (addrlen); 786 serviceListeningInfo->service_addr = GNUNET_malloc (addrlen);
@@ -842,28 +789,11 @@ service_try_to_connect (const struct sockaddr *addr,
842 addrlen); 789 addrlen);
843 serviceListeningInfo->service_addr_len = addrlen; 790 serviceListeningInfo->service_addr_len = addrlen;
844 serviceListeningInfo->listeningSocket = sock; 791 serviceListeningInfo->listeningSocket = sock;
845 792 serviceListeningInfo->acceptTask =
846 switch (addrlen) 793 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
847 { 794 serviceListeningInfo->listeningSocket,
848 case sizeof (struct sockaddr_in): 795 &fc_acceptConnection, serviceListeningInfo);
849 fc->service_connect_ipv4 = serviceListeningInfo; 796 return serviceListeningInfo;
850 serviceListeningInfo->acceptTask =
851 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
852 serviceListeningInfo->listeningSocket,
853 &fc_acceptConnection_ipv4, fc);
854 break;
855 case sizeof (struct sockaddr_in6):
856 fc->service_connect_ipv6 = serviceListeningInfo;
857 serviceListeningInfo->acceptTask =
858 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
859 serviceListeningInfo->listeningSocket,
860 &fc_acceptConnection_ipv6, fc);
861 break;
862 default:
863 GNUNET_break (0);
864 return 1;
865 }
866 return 0;
867} 797}
868 798
869 799
@@ -875,17 +805,12 @@ start_forwarding (void *cls,
875 const struct GNUNET_SCHEDULER_TaskContext *tc) 805 const struct GNUNET_SCHEDULER_TaskContext *tc)
876{ 806{
877 struct ForwardedConnection *fc = cls; 807 struct ForwardedConnection *fc = cls;
878 struct GNUNET_TIME_Relative rem; 808 struct ServiceListeningInfo *sc;
879 int failures;
880 int is_zero;
881 int is_ipv4;
882 int is_ipv6;
883 struct sockaddr_in target_ipv4; 809 struct sockaddr_in target_ipv4;
884 struct sockaddr_in6 target_ipv6; 810 struct sockaddr_in6 target_ipv6;
885 const struct sockaddr *v4; 811 const struct sockaddr_in *v4;
886 const struct sockaddr *v6; 812 const struct sockaddr_in6 *v6;
887 char listen_address[INET_ADDRSTRLEN]; 813 char listen_address[INET6_ADDRSTRLEN];
888 uint16_t listening_port; /* in big endian */
889 814
890 fc->start_task = GNUNET_SCHEDULER_NO_TASK; 815 fc->start_task = GNUNET_SCHEDULER_NO_TASK;
891 if ( (NULL != tc) && 816 if ( (NULL != tc) &&
@@ -897,8 +822,7 @@ start_forwarding (void *cls,
897 closeClientAndServiceSockets (fc, REASON_ERROR); 822 closeClientAndServiceSockets (fc, REASON_ERROR);
898 return; 823 return;
899 } 824 }
900 rem = GNUNET_TIME_absolute_get_remaining (fc->timeout); 825 if (0 == GNUNET_TIME_absolute_get_remaining (fc->timeout).rel_value)
901 if (rem.rel_value == 0)
902 { 826 {
903 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 827 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
904 _("Unable to forward to service `%s': timeout before connect\n"), 828 _("Unable to forward to service `%s': timeout before connect\n"),
@@ -909,69 +833,56 @@ start_forwarding (void *cls,
909 switch (fc->listen_info->service_addr->sa_family) 833 switch (fc->listen_info->service_addr->sa_family)
910 { 834 {
911 case AF_INET: 835 case AF_INET:
836 v4 = (const struct sockaddr_in *) fc->listen_info->service_addr;
912 inet_ntop (fc->listen_info->service_addr->sa_family, 837 inet_ntop (fc->listen_info->service_addr->sa_family,
913 (const void *) &((struct sockaddr_in *) fc->listen_info->service_addr)->sin_addr, 838 (const void *) &v4->sin_addr,
914 listen_address, 839 listen_address,
915 INET_ADDRSTRLEN); 840 INET_ADDRSTRLEN);
916 is_zero = (strncmp (listen_address, "0.0.0.0:", 8) == 0) || (strncmp (listen_address, "0.0.0.0", 7) == 0); 841 if (0 == strncmp (listen_address, "0.0.0.0", 7))
917 is_ipv4 = GNUNET_YES; 842 {
918 is_ipv6 = GNUNET_NO; 843 /* connect to [::1] and 127.0.0.1 instead of [::] and 0.0.0.0 */
919 listening_port = ((struct sockaddr_in *)fc->listen_info->service_addr)->sin_port; 844 memset (&target_ipv4, 0, sizeof (target_ipv4));
845 inet_pton (AF_INET, "127.0.0.1", &target_ipv4.sin_addr);
846 target_ipv4.sin_family = AF_INET;
847 target_ipv4.sin_port = v4->sin_port;
848 v4 = &target_ipv4;
849 }
850 sc = service_try_to_connect ((const struct sockaddr*) v4,
851 PF_INET,
852 sizeof (struct sockaddr_in),
853 fc);
920 break; 854 break;
921 case AF_INET6: 855 case AF_INET6:
856 v6 = (struct sockaddr_in6 *)fc->listen_info->service_addr;
922 inet_ntop (fc->listen_info->service_addr->sa_family, 857 inet_ntop (fc->listen_info->service_addr->sa_family,
923 (const void *) &((struct sockaddr_in6 *) fc->listen_info->service_addr)->sin6_addr, 858 (const void *) &v6->sin6_addr,
924 listen_address, 859 listen_address,
925 INET6_ADDRSTRLEN); 860 INET6_ADDRSTRLEN);
926 is_zero = (strncmp (listen_address, "[::]:", 5) == 0) || (strncmp (listen_address, "::", 2) == 0); 861 if ( (strncmp (listen_address, "[::]:", 5) == 0) || (strncmp (listen_address, "::", 2) == 0) )
927 is_ipv4 = GNUNET_NO; 862 {
928 is_ipv6 = GNUNET_YES; 863 memset (&target_ipv6, 0, sizeof (target_ipv6));
929 listening_port = ((struct sockaddr_in6 *)fc->listen_info->service_addr)->sin6_port; 864 inet_pton (AF_INET6, "::1", &target_ipv6.sin6_addr);
865 target_ipv6.sin6_family = AF_INET6;
866 target_ipv6.sin6_port = v6->sin6_port;
867 v6 = &target_ipv6;
868 }
869 sc = service_try_to_connect ((const struct sockaddr*) v6,
870 PF_INET6,
871 sizeof (struct sockaddr_in6),
872 fc);
873 break;
874 case AF_UNIX:
875 sc = service_try_to_connect (fc->listen_info->service_addr,
876 PF_UNIX,
877 fc->listen_info->service_addr_len,
878 fc);
930 break; 879 break;
931 default: 880 default:
932 GNUNET_break (0); 881 GNUNET_break (0);
933 closeClientAndServiceSockets (fc, REASON_ERROR); 882 closeClientAndServiceSockets (fc, REASON_ERROR);
934 return; 883 return;
935 } 884 }
936 885 if (NULL == sc)
937 fc->service_connect_ipv4 = NULL;
938 fc->service_connect_ipv6 = NULL;
939 v4 = NULL;
940 v6 = NULL;
941 if (is_zero)
942 {
943 /* connect to [::1] and 127.0.0.1 instead of [::] and 0.0.0.0 */
944 memset (&target_ipv4, 0, sizeof (target_ipv4));
945 inet_pton (AF_INET, "127.0.0.1", &target_ipv4.sin_addr);
946 target_ipv4.sin_family = AF_INET;
947 target_ipv4.sin_port = listening_port;
948 v4 = (const struct sockaddr *) &target_ipv4;
949 is_ipv4 = GNUNET_YES;
950
951 memset (&target_ipv6, 0, sizeof (target_ipv6));
952 inet_pton (AF_INET6, "::1", &target_ipv6.sin6_addr);
953 target_ipv6.sin6_family = AF_INET6;
954 target_ipv6.sin6_port = listening_port;
955 is_ipv6 = GNUNET_YES;
956 v6 = (const struct sockaddr *) &target_ipv6;
957 }
958 else
959 {
960 if (is_ipv4)
961 v4 = (const struct sockaddr*) fc->listen_info->service_addr;
962 if (is_ipv6)
963 v6 = (const struct sockaddr*) fc->listen_info->service_addr;
964 }
965 failures = 0;
966 if (is_ipv4)
967 failures += service_try_to_connect (v4,
968 sizeof (struct sockaddr_in),
969 fc);
970 if (is_ipv6)
971 failures += service_try_to_connect (v6,
972 sizeof (struct sockaddr_in6),
973 fc);
974 if (is_ipv4 + is_ipv6 == failures)
975 { 886 {
976 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 887 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
977 _ ("Unable to start service `%s': %s\n"), 888 _ ("Unable to start service `%s': %s\n"),
@@ -1051,8 +962,7 @@ accept_and_forward (struct ServiceListeningInfo *serviceListeningInfo)
1051 serviceListeningInfoList_tail, 962 serviceListeningInfoList_tail,
1052 serviceListeningInfo); 963 serviceListeningInfo);
1053 serviceListeningInfo->acceptTask = 964 serviceListeningInfo->acceptTask =
1054 GNUNET_SCHEDULER_add_read_net ( 965 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1055 GNUNET_TIME_UNIT_FOREVER_REL,
1056 serviceListeningInfo->listeningSocket, 966 serviceListeningInfo->listeningSocket,
1057 &acceptConnection, 967 &acceptConnection,
1058 serviceListeningInfo); 968 serviceListeningInfo);
@@ -1067,8 +977,7 @@ accept_and_forward (struct ServiceListeningInfo *serviceListeningInfo)
1067 fc->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_SERVICE_TIMEOUT); 977 fc->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_SERVICE_TIMEOUT);
1068 fc->back_off = GNUNET_TIME_UNIT_MILLISECONDS; 978 fc->back_off = GNUNET_TIME_UNIT_MILLISECONDS;
1069 fc->client_to_service_task = 979 fc->client_to_service_task =
1070 GNUNET_SCHEDULER_add_read_net ( 980 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1071 GNUNET_TIME_UNIT_FOREVER_REL,
1072 fc->armClientSocket, 981 fc->armClientSocket,
1073 &receiveFromClient, fc); 982 &receiveFromClient, fc);
1074 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == fc->start_task); 983 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == fc->start_task);
@@ -1240,8 +1149,7 @@ createListeningSocket (struct sockaddr *sa,
1240 serviceListeningInfo->service_addr_len = addr_len; 1149 serviceListeningInfo->service_addr_len = addr_len;
1241 serviceListeningInfo->listeningSocket = sock; 1150 serviceListeningInfo->listeningSocket = sock;
1242 serviceListeningInfo->acceptTask = 1151 serviceListeningInfo->acceptTask =
1243 GNUNET_SCHEDULER_add_read_net ( 1152 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, sock,
1244 GNUNET_TIME_UNIT_FOREVER_REL, sock,
1245 &acceptConnection, 1153 &acceptConnection,
1246 serviceListeningInfo); 1154 serviceListeningInfo);
1247 GNUNET_CONTAINER_DLL_insert (serviceListeningInfoList_head, 1155 GNUNET_CONTAINER_DLL_insert (serviceListeningInfoList_head,