aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-08-25 12:51:21 +0000
committerChristian Grothoff <christian@grothoff.org>2016-08-25 12:51:21 +0000
commitccf6004e61a5379954aed85be6ed49ab7e886a7d (patch)
tree31b63266ea85235a126aa618126e2f836eb4eef2
parent182fae1b29eafe14018d45beb9613725651a779c (diff)
downloadgnunet-ccf6004e61a5379954aed85be6ed49ab7e886a7d.tar.gz
gnunet-ccf6004e61a5379954aed85be6ed49ab7e886a7d.zip
ensure binding multiple ports to the same service descriptor works (again) with the correct mapping of ports
-rw-r--r--src/exit/gnunet-daemon-exit.c39
-rw-r--r--src/include/gnunet_tun_lib.h17
-rw-r--r--src/tun/regex.c23
-rw-r--r--src/vpn/gnunet-service-vpn.c21
4 files changed, 71 insertions, 29 deletions
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c
index aa96583c0..496ca25f8 100644
--- a/src/exit/gnunet-daemon-exit.c
+++ b/src/exit/gnunet-daemon-exit.c
@@ -154,12 +154,6 @@ struct LocalService
154 struct GNUNET_CADET_Port *port; 154 struct GNUNET_CADET_Port *port;
155 155
156 /** 156 /**
157 * Port I am listening on within GNUnet for this service, in host
158 * byte order. (as we may redirect ports).
159 */
160 uint16_t my_port;
161
162 /**
163 * #GNUNET_YES if this is a UDP service, otherwise TCP. 157 * #GNUNET_YES if this is a UDP service, otherwise TCP.
164 */ 158 */
165 int16_t is_udp; 159 int16_t is_udp;
@@ -836,31 +830,33 @@ store_service (int proto,
836 uint16_t destination_port, 830 uint16_t destination_port,
837 struct LocalService *service) 831 struct LocalService *service)
838{ 832{
839 char key[sizeof (struct GNUNET_HashCode) + sizeof (uint16_t)]; 833 struct GNUNET_HashCode cadet_port;
840 834
835 service->name = GNUNET_strdup (name);
841 GNUNET_TUN_service_name_to_hash (name, 836 GNUNET_TUN_service_name_to_hash (name,
842 &service->descriptor); 837 &service->descriptor);
843 service->name = GNUNET_strdup (name); 838 GNUNET_TUN_compute_service_cadet_port (&service->descriptor,
844 GNUNET_memcpy (&key[0], 839 destination_port,
845 &destination_port, 840 &cadet_port);
846 sizeof (uint16_t)); 841 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
847 GNUNET_memcpy (&key[sizeof(uint16_t)], 842 "Opening CADET port %s for SERVICE exit %s on port %u\n",
848 &service->descriptor, 843 GNUNET_h2s (&cadet_port),
849 sizeof (struct GNUNET_HashCode)); 844 name,
845 (unsigned int) destination_port);
850 service->port = GNUNET_CADET_open_port (cadet_handle, 846 service->port = GNUNET_CADET_open_port (cadet_handle,
851 &service->descriptor, 847 &cadet_port,
852 &new_service_channel, 848 &new_service_channel,
853 service); 849 service);
854 service->is_udp = (IPPROTO_UDP == proto); 850 service->is_udp = (IPPROTO_UDP == proto);
855 if (GNUNET_OK != 851 if (GNUNET_OK !=
856 GNUNET_CONTAINER_multihashmap_put (services, 852 GNUNET_CONTAINER_multihashmap_put (services,
857 (struct GNUNET_HashCode *) key, 853 &cadet_port,
858 service, 854 service,
859 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) 855 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
860 { 856 {
861 free_service_record (NULL, 857 GNUNET_CADET_close_port (service->port);
862 (struct GNUNET_HashCode *) key, 858 GNUNET_free_non_null (service->name);
863 service); 859 GNUNET_free (service);
864 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 860 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
865 _("Got duplicate service records for `%s:%u'\n"), 861 _("Got duplicate service records for `%s:%u'\n"),
866 name, 862 name,
@@ -3322,8 +3318,8 @@ add_services (int proto,
3322 GNUNET_assert (slen >= 8); 3318 GNUNET_assert (slen >= 8);
3323 n = GNUNET_strndup (name, slen - 8 /* remove .gnunet. */); 3319 n = GNUNET_strndup (name, slen - 8 /* remove .gnunet. */);
3324 3320
3325 for (redirect = strtok (cpy, " "); redirect != NULL; 3321 for (redirect = strtok (cpy, " ;"); redirect != NULL;
3326 redirect = strtok (NULL, " ")) 3322 redirect = strtok (NULL, " ;"))
3327 { 3323 {
3328 if (NULL == (hostname = strstr (redirect, ":"))) 3324 if (NULL == (hostname = strstr (redirect, ":")))
3329 { 3325 {
@@ -3368,7 +3364,6 @@ add_services (int proto,
3368 3364
3369 serv = GNUNET_new (struct LocalService); 3365 serv = GNUNET_new (struct LocalService);
3370 serv->address.proto = proto; 3366 serv->address.proto = proto;
3371 serv->my_port = (uint16_t) local_port;
3372 serv->address.port = remote_port; 3367 serv->address.port = remote_port;
3373 if (0 == strcmp ("localhost4", 3368 if (0 == strcmp ("localhost4",
3374 hostname)) 3369 hostname))
diff --git a/src/include/gnunet_tun_lib.h b/src/include/gnunet_tun_lib.h
index 9b98ab13b..822a661cf 100644
--- a/src/include/gnunet_tun_lib.h
+++ b/src/include/gnunet_tun_lib.h
@@ -910,12 +910,27 @@ GNUNET_TUN_ipv4policy2regex (const char *policy);
910 * the network. 910 * the network.
911 * 911 *
912 * @param service_name a string 912 * @param service_name a string
913 * @param hc corresponding hash 913 * @param[out] hc corresponding hash
914 */ 914 */
915void 915void
916GNUNET_TUN_service_name_to_hash (const char *service_name, 916GNUNET_TUN_service_name_to_hash (const char *service_name,
917 struct GNUNET_HashCode *hc); 917 struct GNUNET_HashCode *hc);
918 918
919
920/**
921 * Compute the CADET port given a service descriptor
922 * (returned from #GNUNET_TUN_service_name_to_hash) and
923 * a TCP/UDP port @a ip_port.
924 *
925 * @param desc service shared secret
926 * @param ip_port TCP/UDP port, use 0 for ICMP
927 * @param[out] cadet_port CADET port to use
928 */
929void
930GNUNET_TUN_compute_service_cadet_port (const struct GNUNET_HashCode *desc,
931 uint16_t ip_port,
932 struct GNUNET_HashCode *cadet_port);
933
919#endif 934#endif
920 935
921/** @} */ /* end of group */ 936/** @} */ /* end of group */
diff --git a/src/tun/regex.c b/src/tun/regex.c
index f1ebb85f4..d48fe1da8 100644
--- a/src/tun/regex.c
+++ b/src/tun/regex.c
@@ -810,4 +810,27 @@ GNUNET_TUN_service_name_to_hash (const char *service_name,
810} 810}
811 811
812 812
813/**
814 * Compute the CADET port given a service descriptor
815 * (returned from #GNUNET_TUN_service_name_to_hash) and
816 * a TCP/UDP port @a ip_port.
817 *
818 * @param desc service shared secret
819 * @param ip_port TCP/UDP port, use 0 for ICMP
820 * @param[out] cadet_port CADET port to use
821 */
822void
823GNUNET_TUN_compute_service_cadet_port (const struct GNUNET_HashCode *desc,
824 uint16_t ip_port,
825 struct GNUNET_HashCode *cadet_port)
826{
827 uint16_t be_port = htons (ip_port);
828
829 *cadet_port = *desc;
830 GNUNET_memcpy (cadet_port,
831 &be_port,
832 sizeof (uint16_t));
833}
834
835
813/* end of regex.c */ 836/* end of regex.c */
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c
index 629b59173..d18530dab 100644
--- a/src/vpn/gnunet-service-vpn.c
+++ b/src/vpn/gnunet-service-vpn.c
@@ -795,13 +795,19 @@ create_channel_to_destination (struct DestinationChannel *dt,
795 ts->af = client_af; 795 ts->af = client_af;
796 ts->destination = *dt->destination; 796 ts->destination = *dt->destination;
797 ts->destination.heap_node = NULL; /* copy is NOT in destination heap */ 797 ts->destination.heap_node = NULL; /* copy is NOT in destination heap */
798 ts->destination_port = dt->destination_port;
798 if (dt->destination->is_service) 799 if (dt->destination->is_service)
799 { 800 {
801 struct GNUNET_HashCode cadet_port;
802
803 GNUNET_TUN_compute_service_cadet_port (&ts->destination.details.service_destination.service_descriptor,
804 ts->destination_port,
805 &cadet_port);
800 ts->channel 806 ts->channel
801 = GNUNET_CADET_channel_create (cadet_handle, 807 = GNUNET_CADET_channel_create (cadet_handle,
802 ts, 808 ts,
803 &dt->destination->details.service_destination.target, 809 &dt->destination->details.service_destination.target,
804 &ts->destination.details.service_destination.service_descriptor, 810 &cadet_port,
805 GNUNET_CADET_OPTION_DEFAULT); 811 GNUNET_CADET_OPTION_DEFAULT);
806 if (NULL == ts->channel) 812 if (NULL == ts->channel)
807 { 813 {
@@ -810,10 +816,10 @@ create_channel_to_destination (struct DestinationChannel *dt,
810 return NULL; 816 return NULL;
811 } 817 }
812 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 818 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
813 "Creating channel %p to peer %s offering service %s\n", 819 "Creating channel to peer %s offering service %s on port %u\n",
814 ts->channel,
815 GNUNET_i2s (&dt->destination->details.service_destination.target), 820 GNUNET_i2s (&dt->destination->details.service_destination.target),
816 GNUNET_h2s (&ts->destination.details.service_destination.service_descriptor)); 821 GNUNET_h2s (&ts->destination.details.service_destination.service_descriptor),
822 (unsigned int) ts->destination_port);
817 } 823 }
818 else 824 else
819 { 825 {
@@ -1072,7 +1078,9 @@ route_packet (struct DestinationEntry *destination,
1072 GNUNET_h2s (&destination->details.service_destination.service_descriptor), 1078 GNUNET_h2s (&destination->details.service_destination.service_descriptor),
1073 GNUNET_i2s (&destination->details.service_destination.target)); 1079 GNUNET_i2s (&destination->details.service_destination.target));
1074 } 1080 }
1075 dt = destination->dt_head; 1081 for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1082 if (dt->destination_port == destination_port)
1083 break;
1076 } 1084 }
1077 if (NULL == dt) 1085 if (NULL == dt)
1078 { 1086 {
@@ -1094,7 +1102,8 @@ route_packet (struct DestinationEntry *destination,
1094 GNUNET_h2s (&key)); 1102 GNUNET_h2s (&key));
1095 /* need to either use the existing channel from the destination (if still 1103 /* need to either use the existing channel from the destination (if still
1096 available) or create a fresh one */ 1104 available) or create a fresh one */
1097 ts = create_channel_to_destination (dt, af); 1105 ts = create_channel_to_destination (dt,
1106 af);
1098 if (NULL == ts) 1107 if (NULL == ts)
1099 return; 1108 return;
1100 /* now bind existing "unbound" channel to our IP/port tuple */ 1109 /* now bind existing "unbound" channel to our IP/port tuple */