diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-09-22 15:25:57 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-09-22 15:25:57 +0000 |
commit | 69cf9d7768b72fd21a9aa2ba9e208dba193a21a1 (patch) | |
tree | fede2ce61fcda3bc6dd78ec1204ec3931e2feba0 /src/vpn | |
parent | 2e1bfb2f75c216e0dbacb31a9e58e01bd1dff6d4 (diff) | |
download | gnunet-69cf9d7768b72fd21a9aa2ba9e208dba193a21a1.tar.gz gnunet-69cf9d7768b72fd21a9aa2ba9e208dba193a21a1.zip |
fixing #2916, but untested
Diffstat (limited to 'src/vpn')
-rw-r--r-- | src/vpn/gnunet-service-vpn.c | 219 |
1 files changed, 153 insertions, 66 deletions
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index f26369d11..13cbf5021 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c | |||
@@ -28,7 +28,7 @@ | |||
28 | * | 28 | * |
29 | * TODO: | 29 | * TODO: |
30 | * - keep multiple peers/mesh tunnels ready as alternative exits / | 30 | * - keep multiple peers/mesh tunnels ready as alternative exits / |
31 | * recover from tunnel-to-exit failure gracefully | 31 | * detect & recover from tunnel-to-exit failure gracefully |
32 | */ | 32 | */ |
33 | #include "platform.h" | 33 | #include "platform.h" |
34 | #include "gnunet_util_lib.h" | 34 | #include "gnunet_util_lib.h" |
@@ -50,13 +50,51 @@ | |||
50 | #define MAX_MESSAGE_QUEUE_SIZE 4 | 50 | #define MAX_MESSAGE_QUEUE_SIZE 4 |
51 | 51 | ||
52 | 52 | ||
53 | #define PORT_VPN 42 | ||
54 | |||
55 | /** | 53 | /** |
56 | * State we keep for each of our tunnels. | 54 | * State we keep for each of our tunnels. |
57 | */ | 55 | */ |
58 | struct TunnelState; | 56 | struct TunnelState; |
59 | 57 | ||
58 | /** | ||
59 | * Information we track for each IP address to determine which tunnel | ||
60 | * to send the traffic over to the destination. | ||
61 | */ | ||
62 | struct DestinationEntry; | ||
63 | |||
64 | /** | ||
65 | * List of tunnels we keep for each destination port for a given | ||
66 | * destination entry. | ||
67 | */ | ||
68 | struct DestinationTunnel | ||
69 | { | ||
70 | |||
71 | /** | ||
72 | * Kept in a DLL. | ||
73 | */ | ||
74 | struct DestinationTunnel *next; | ||
75 | |||
76 | /** | ||
77 | * Kept in a DLL. | ||
78 | */ | ||
79 | struct DestinationTunnel *prev; | ||
80 | |||
81 | /** | ||
82 | * Destination entry list this `struct DestinationTunnel` belongs with. | ||
83 | */ | ||
84 | struct DestinationEntry *destination; | ||
85 | |||
86 | /** | ||
87 | * Pre-allocated tunnel for this destination, or NULL for none. | ||
88 | */ | ||
89 | struct TunnelState *ts; | ||
90 | |||
91 | /** | ||
92 | * Destination port this tunnel state is used for. | ||
93 | */ | ||
94 | uint16_t destination_port; | ||
95 | |||
96 | }; | ||
97 | |||
60 | 98 | ||
61 | /** | 99 | /** |
62 | * Information we track for each IP address to determine which tunnel | 100 | * Information we track for each IP address to determine which tunnel |
@@ -72,9 +110,14 @@ struct DestinationEntry | |||
72 | struct GNUNET_HashCode key; | 110 | struct GNUNET_HashCode key; |
73 | 111 | ||
74 | /** | 112 | /** |
75 | * Pre-allocated tunnel for this destination, or NULL for none. | 113 | * Head of DLL of tunnels associated with this destination. |
76 | */ | 114 | */ |
77 | struct TunnelState *ts; | 115 | struct DestinationTunnel *dt_head; |
116 | |||
117 | /** | ||
118 | * Tail of DLL of tunnels associated with this destination. | ||
119 | */ | ||
120 | struct DestinationTunnel *dt_tail; | ||
78 | 121 | ||
79 | /** | 122 | /** |
80 | * Entry for this entry in the destination_heap. | 123 | * Entry for this entry in the destination_heap. |
@@ -207,7 +250,7 @@ struct TunnelState | |||
207 | * Destination entry that has a pointer to this tunnel state; | 250 | * Destination entry that has a pointer to this tunnel state; |
208 | * NULL if this tunnel state is in the tunnel map. | 251 | * NULL if this tunnel state is in the tunnel map. |
209 | */ | 252 | */ |
210 | struct DestinationEntry *destination_container; | 253 | struct DestinationTunnel *destination_container; |
211 | 254 | ||
212 | /** | 255 | /** |
213 | * Destination to which this tunnel leads. Note that | 256 | * Destination to which this tunnel leads. Note that |
@@ -655,9 +698,9 @@ send_to_tunnel (struct TunnelMessageQueueEntry *tnq, | |||
655 | * @param cls the 'struct TunnelState' | 698 | * @param cls the 'struct TunnelState' |
656 | * @param id Peer providing a regex that matches the string. | 699 | * @param id Peer providing a regex that matches the string. |
657 | * @param get_path Path of the get request. | 700 | * @param get_path Path of the get request. |
658 | * @param get_path_length Lenght of get_path. | 701 | * @param get_path_length Lenght of @a get_path. |
659 | * @param put_path Path of the put request. | 702 | * @param put_path Path of the put request. |
660 | * @param put_path_length Length of the put_path. | 703 | * @param put_path_length Length of the @a put_path. |
661 | */ | 704 | */ |
662 | static void | 705 | static void |
663 | handle_regex_result (void *cls, | 706 | handle_regex_result (void *cls, |
@@ -668,13 +711,26 @@ handle_regex_result (void *cls, | |||
668 | unsigned int put_path_length) | 711 | unsigned int put_path_length) |
669 | { | 712 | { |
670 | struct TunnelState *ts = cls; | 713 | struct TunnelState *ts = cls; |
714 | unsigned int apptype; | ||
671 | 715 | ||
672 | GNUNET_REGEX_search_cancel (ts->search); | 716 | GNUNET_REGEX_search_cancel (ts->search); |
673 | ts->search = NULL; | 717 | ts->search = NULL; |
718 | switch (ts->af) | ||
719 | { | ||
720 | case AF_INET: | ||
721 | apptype = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY; | ||
722 | break; | ||
723 | case AF_INET6: | ||
724 | apptype = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY; | ||
725 | break; | ||
726 | default: | ||
727 | GNUNET_break (0); | ||
728 | return; | ||
729 | } | ||
674 | ts->tunnel = GNUNET_MESH_tunnel_create (mesh_handle, | 730 | ts->tunnel = GNUNET_MESH_tunnel_create (mesh_handle, |
675 | ts, | 731 | ts, |
676 | id, | 732 | id, |
677 | PORT_VPN, | 733 | apptype, |
678 | GNUNET_YES, | 734 | GNUNET_YES, |
679 | GNUNET_NO); | 735 | GNUNET_NO); |
680 | } | 736 | } |
@@ -683,32 +739,45 @@ handle_regex_result (void *cls, | |||
683 | /** | 739 | /** |
684 | * Initialize the given destination entry's mesh tunnel. | 740 | * Initialize the given destination entry's mesh tunnel. |
685 | * | 741 | * |
686 | * @param de destination entry for which we need to setup a tunnel | 742 | * @param dt destination tunnel for which we need to setup a tunnel |
687 | * @param client_af address family of the address returned to the client | 743 | * @param client_af address family of the address returned to the client |
688 | * @return tunnel state of the tunnel that was created | 744 | * @return tunnel state of the tunnel that was created |
689 | */ | 745 | */ |
690 | static struct TunnelState * | 746 | static struct TunnelState * |
691 | create_tunnel_to_destination (struct DestinationEntry *de, | 747 | create_tunnel_to_destination (struct DestinationTunnel *dt, |
692 | int client_af) | 748 | int client_af) |
693 | { | 749 | { |
694 | struct TunnelState *ts; | 750 | struct TunnelState *ts; |
751 | unsigned int apptype; | ||
695 | 752 | ||
696 | GNUNET_STATISTICS_update (stats, | 753 | GNUNET_STATISTICS_update (stats, |
697 | gettext_noop ("# Mesh tunnels created"), | 754 | gettext_noop ("# Mesh tunnels created"), |
698 | 1, GNUNET_NO); | 755 | 1, GNUNET_NO); |
699 | GNUNET_assert (NULL == de->ts); | 756 | GNUNET_assert (NULL == dt->ts); |
757 | switch (client_af) | ||
758 | { | ||
759 | case AF_INET: | ||
760 | apptype = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY; | ||
761 | break; | ||
762 | case AF_INET6: | ||
763 | apptype = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY; | ||
764 | break; | ||
765 | default: | ||
766 | GNUNET_break (0); | ||
767 | return NULL; | ||
768 | } | ||
700 | ts = GNUNET_new (struct TunnelState); | 769 | ts = GNUNET_new (struct TunnelState); |
701 | ts->af = client_af; | 770 | ts->af = client_af; |
702 | ts->destination = *de; | 771 | ts->destination = *dt->destination; |
703 | ts->destination.heap_node = NULL; /* copy is NOT in destination heap */ | 772 | ts->destination.heap_node = NULL; /* copy is NOT in destination heap */ |
704 | de->ts = ts; | 773 | dt->ts = ts; |
705 | ts->destination_container = de; /* we are referenced from de */ | 774 | ts->destination_container = dt; /* we are referenced from dt */ |
706 | if (de->is_service) | 775 | if (dt->destination->is_service) |
707 | { | 776 | { |
708 | ts->tunnel = GNUNET_MESH_tunnel_create (mesh_handle, | 777 | ts->tunnel = GNUNET_MESH_tunnel_create (mesh_handle, |
709 | ts, | 778 | ts, |
710 | &de->details.service_destination.target, | 779 | &dt->destination->details.service_destination.target, |
711 | PORT_VPN, | 780 | apptype, |
712 | GNUNET_YES, | 781 | GNUNET_YES, |
713 | GNUNET_NO); | 782 | GNUNET_NO); |
714 | if (NULL == ts->tunnel) | 783 | if (NULL == ts->tunnel) |
@@ -720,37 +789,40 @@ create_tunnel_to_destination (struct DestinationEntry *de, | |||
720 | } | 789 | } |
721 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 790 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
722 | "Creating tunnel to peer %s offering service %s\n", | 791 | "Creating tunnel to peer %s offering service %s\n", |
723 | GNUNET_i2s (&de->details.service_destination.target), | 792 | GNUNET_i2s (&dt->destination->details.service_destination.target), |
724 | GNUNET_h2s (&de->details.service_destination.service_descriptor)); | 793 | GNUNET_h2s (&dt->destination->details.service_destination.service_descriptor)); |
725 | } | 794 | } |
726 | else | 795 | else |
727 | { | 796 | { |
728 | char *policy; | 797 | char *policy; |
729 | 798 | ||
730 | switch (de->details.exit_destination.af) | 799 | switch (dt->destination->details.exit_destination.af) |
731 | { | 800 | { |
732 | case AF_INET: | 801 | case AF_INET: |
733 | { | 802 | { |
734 | char address[GNUNET_TUN_IPV4_REGEXLEN]; | 803 | char address[GNUNET_TUN_IPV4_REGEXLEN]; |
735 | 804 | ||
736 | GNUNET_TUN_ipv4toregexsearch (&de->details.exit_destination.ip.v4, | 805 | GNUNET_TUN_ipv4toregexsearch (&dt->destination->details.exit_destination.ip.v4, |
737 | "255.255.255.255", address); | 806 | "255.255.255.255", |
738 | GNUNET_asprintf (&policy, "%s%s%s", | 807 | address); |
808 | GNUNET_asprintf (&policy, "%s%s%s:%u", | ||
739 | GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX, | 809 | GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX, |
740 | "4", | 810 | "4", |
741 | address); | 811 | address, |
812 | (unsigned int) dt->destination_port); | ||
742 | break; | 813 | break; |
743 | } | 814 | } |
744 | case AF_INET6: | 815 | case AF_INET6: |
745 | { | 816 | { |
746 | char address[GNUNET_TUN_IPV6_REGEXLEN]; | 817 | char address[GNUNET_TUN_IPV6_REGEXLEN]; |
747 | 818 | ||
748 | GNUNET_TUN_ipv6toregexsearch (&de->details.exit_destination.ip.v6, | 819 | GNUNET_TUN_ipv6toregexsearch (&dt->destination->details.exit_destination.ip.v6, |
749 | 128, address); | 820 | 128, address); |
750 | GNUNET_asprintf (&policy, "%s%s%s", | 821 | GNUNET_asprintf (&policy, "%s%s%s:%u", |
751 | GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX, | 822 | GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX, |
752 | "6", | 823 | "6", |
753 | address); | 824 | address, |
825 | (unsigned int) dt->destination_port); | ||
754 | break; | 826 | break; |
755 | } | 827 | } |
756 | default: | 828 | default: |
@@ -798,7 +870,7 @@ expire_tunnel (struct TunnelState *except) | |||
798 | * @param source_ip source IP used by the sender (struct in_addr or struct in6_addr) | 870 | * @param source_ip source IP used by the sender (struct in_addr or struct in6_addr) |
799 | * @param destination_ip destination IP used by the sender (struct in_addr or struct in6_addr) | 871 | * @param destination_ip destination IP used by the sender (struct in_addr or struct in6_addr) |
800 | * @param payload payload of the packet after the IP header | 872 | * @param payload payload of the packet after the IP header |
801 | * @param payload_length number of bytes in payload | 873 | * @param payload_length number of bytes in @a payload |
802 | */ | 874 | */ |
803 | static void | 875 | static void |
804 | route_packet (struct DestinationEntry *destination, | 876 | route_packet (struct DestinationEntry *destination, |
@@ -818,6 +890,7 @@ route_packet (struct DestinationEntry *destination, | |||
818 | const struct GNUNET_TUN_UdpHeader *udp; | 890 | const struct GNUNET_TUN_UdpHeader *udp; |
819 | const struct GNUNET_TUN_TcpHeader *tcp; | 891 | const struct GNUNET_TUN_TcpHeader *tcp; |
820 | const struct GNUNET_TUN_IcmpHeader *icmp; | 892 | const struct GNUNET_TUN_IcmpHeader *icmp; |
893 | struct DestinationTunnel *dt; | ||
821 | uint16_t source_port; | 894 | uint16_t source_port; |
822 | uint16_t destination_port; | 895 | uint16_t destination_port; |
823 | 896 | ||
@@ -943,6 +1016,9 @@ route_packet (struct DestinationEntry *destination, | |||
943 | xbuf, sizeof (xbuf)), | 1016 | xbuf, sizeof (xbuf)), |
944 | destination_port); | 1017 | destination_port); |
945 | } | 1018 | } |
1019 | for (dt = destination->dt_head; NULL != dt; dt = dt->next) | ||
1020 | if (dt->destination_port == destination_port) | ||
1021 | break; | ||
946 | } | 1022 | } |
947 | else | 1023 | else |
948 | { | 1024 | { |
@@ -960,7 +1036,16 @@ route_packet (struct DestinationEntry *destination, | |||
960 | GNUNET_h2s (&destination->details.service_destination.service_descriptor), | 1036 | GNUNET_h2s (&destination->details.service_destination.service_descriptor), |
961 | GNUNET_i2s (&destination->details.service_destination.target)); | 1037 | GNUNET_i2s (&destination->details.service_destination.target)); |
962 | } | 1038 | } |
963 | 1039 | dt = destination->dt_head; | |
1040 | } | ||
1041 | if (NULL == dt) | ||
1042 | { | ||
1043 | dt = GNUNET_new (struct DestinationTunnel); | ||
1044 | dt->destination = destination; | ||
1045 | GNUNET_CONTAINER_DLL_insert (destination->dt_head, | ||
1046 | destination->dt_tail, | ||
1047 | dt); | ||
1048 | dt->destination_port = destination_port; | ||
964 | } | 1049 | } |
965 | 1050 | ||
966 | /* see if we have an existing tunnel for this destination */ | 1051 | /* see if we have an existing tunnel for this destination */ |
@@ -971,18 +1056,18 @@ route_packet (struct DestinationEntry *destination, | |||
971 | /* need to either use the existing tunnel from the destination (if still | 1056 | /* need to either use the existing tunnel from the destination (if still |
972 | available) or create a fresh one */ | 1057 | available) or create a fresh one */ |
973 | is_new = GNUNET_YES; | 1058 | is_new = GNUNET_YES; |
974 | if (NULL == destination->ts) | 1059 | if (NULL == dt->ts) |
975 | ts = create_tunnel_to_destination (destination, af); | 1060 | ts = create_tunnel_to_destination (dt, af); |
976 | else | 1061 | else |
977 | ts = destination->ts; | 1062 | ts = dt->ts; |
978 | if (NULL == ts) | 1063 | if (NULL == ts) |
979 | return; | 1064 | return; |
980 | destination->ts = NULL; | 1065 | dt->ts = NULL; |
981 | ts->destination_container = NULL; /* no longer 'contained' */ | 1066 | ts->destination_container = NULL; /* no longer 'contained' */ |
982 | /* now bind existing "unbound" tunnel to our IP/port tuple */ | 1067 | /* now bind existing "unbound" tunnel to our IP/port tuple */ |
983 | ts->protocol = protocol; | 1068 | ts->protocol = protocol; |
984 | ts->af = af; | 1069 | ts->af = af; |
985 | if (af == AF_INET) | 1070 | if (AF_INET == af) |
986 | { | 1071 | { |
987 | ts->source_ip.v4 = * (const struct in_addr *) source_ip; | 1072 | ts->source_ip.v4 = * (const struct in_addr *) source_ip; |
988 | ts->destination_ip.v4 = * (const struct in_addr *) destination_ip; | 1073 | ts->destination_ip.v4 = * (const struct in_addr *) destination_ip; |
@@ -1061,8 +1146,7 @@ route_packet (struct DestinationEntry *destination, | |||
1061 | GNUNET_break (0); | 1146 | GNUNET_break (0); |
1062 | return; | 1147 | return; |
1063 | } | 1148 | } |
1064 | tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + | 1149 | tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + mlen); |
1065 | mlen); | ||
1066 | tnq->len = mlen; | 1150 | tnq->len = mlen; |
1067 | tnq->msg = &tnq[1]; | 1151 | tnq->msg = &tnq[1]; |
1068 | uim = (struct GNUNET_EXIT_UdpInternetMessage *) &tnq[1]; | 1152 | uim = (struct GNUNET_EXIT_UdpInternetMessage *) &tnq[1]; |
@@ -1279,8 +1363,7 @@ route_packet (struct DestinationEntry *destination, | |||
1279 | GNUNET_break (0); | 1363 | GNUNET_break (0); |
1280 | return; | 1364 | return; |
1281 | } | 1365 | } |
1282 | tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + | 1366 | tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + mlen); |
1283 | mlen); | ||
1284 | tnq->msg = &tnq[1]; | 1367 | tnq->msg = &tnq[1]; |
1285 | iim = (struct GNUNET_EXIT_IcmpInternetMessage *) &tnq[1]; | 1368 | iim = (struct GNUNET_EXIT_IcmpInternetMessage *) &tnq[1]; |
1286 | iim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET); | 1369 | iim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET); |
@@ -1440,7 +1523,8 @@ route_packet (struct DestinationEntry *destination, | |||
1440 | * @param message message we got from the client (VPN tunnel interface) | 1523 | * @param message message we got from the client (VPN tunnel interface) |
1441 | */ | 1524 | */ |
1442 | static int | 1525 | static int |
1443 | message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, | 1526 | message_token (void *cls, |
1527 | void *client, | ||
1444 | const struct GNUNET_MessageHeader *message) | 1528 | const struct GNUNET_MessageHeader *message) |
1445 | { | 1529 | { |
1446 | const struct GNUNET_TUN_Layer2PacketHeader *tun; | 1530 | const struct GNUNET_TUN_Layer2PacketHeader *tun; |
@@ -1614,7 +1698,8 @@ make_up_icmpv6_payload (struct TunnelState *ts, | |||
1614 | * #GNUNET_SYSERR to close it (signal serious error) | 1698 | * #GNUNET_SYSERR to close it (signal serious error) |
1615 | */ | 1699 | */ |
1616 | static int | 1700 | static int |
1617 | receive_icmp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | 1701 | receive_icmp_back (void *cls, |
1702 | struct GNUNET_MESH_Tunnel *tunnel, | ||
1618 | void **tunnel_ctx, | 1703 | void **tunnel_ctx, |
1619 | const struct GNUNET_MessageHeader *message) | 1704 | const struct GNUNET_MessageHeader *message) |
1620 | { | 1705 | { |
@@ -1952,7 +2037,8 @@ receive_icmp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1952 | * #GNUNET_SYSERR to close it (signal serious error) | 2037 | * #GNUNET_SYSERR to close it (signal serious error) |
1953 | */ | 2038 | */ |
1954 | static int | 2039 | static int |
1955 | receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | 2040 | receive_udp_back (void *cls, |
2041 | struct GNUNET_MESH_Tunnel *tunnel, | ||
1956 | void **tunnel_ctx, | 2042 | void **tunnel_ctx, |
1957 | const struct GNUNET_MessageHeader *message) | 2043 | const struct GNUNET_MessageHeader *message) |
1958 | { | 2044 | { |
@@ -2106,7 +2192,8 @@ receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
2106 | * #GNUNET_SYSERR to close it (signal serious error) | 2192 | * #GNUNET_SYSERR to close it (signal serious error) |
2107 | */ | 2193 | */ |
2108 | static int | 2194 | static int |
2109 | receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | 2195 | receive_tcp_back (void *cls, |
2196 | struct GNUNET_MESH_Tunnel *tunnel, | ||
2110 | void **tunnel_ctx, | 2197 | void **tunnel_ctx, |
2111 | const struct GNUNET_MessageHeader *message) | 2198 | const struct GNUNET_MessageHeader *message) |
2112 | { | 2199 | { |
@@ -2357,15 +2444,24 @@ allocate_v6_address (struct in6_addr *v6) | |||
2357 | static void | 2444 | static void |
2358 | free_destination_entry (struct DestinationEntry *de) | 2445 | free_destination_entry (struct DestinationEntry *de) |
2359 | { | 2446 | { |
2447 | struct DestinationTunnel *dt; | ||
2448 | |||
2360 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2449 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2361 | "Cleaning up destination entry\n"); | 2450 | "Cleaning up destination entry\n"); |
2362 | GNUNET_STATISTICS_update (stats, | 2451 | GNUNET_STATISTICS_update (stats, |
2363 | gettext_noop ("# Active destinations"), | 2452 | gettext_noop ("# Active destinations"), |
2364 | -1, GNUNET_NO); | 2453 | -1, GNUNET_NO); |
2365 | if (NULL != de->ts) | 2454 | while (NULL != (dt = de->dt_head)) |
2366 | { | 2455 | { |
2367 | free_tunnel_state (de->ts); | 2456 | if (NULL != dt->ts) |
2368 | GNUNET_assert (NULL == de->ts); | 2457 | { |
2458 | free_tunnel_state (dt->ts); | ||
2459 | GNUNET_assert (NULL == dt->ts); | ||
2460 | } | ||
2461 | GNUNET_CONTAINER_DLL_remove (de->dt_head, | ||
2462 | de->dt_tail, | ||
2463 | dt); | ||
2464 | GNUNET_free (dt); | ||
2369 | } | 2465 | } |
2370 | if (NULL != de->heap_node) | 2466 | if (NULL != de->heap_node) |
2371 | { | 2467 | { |
@@ -2481,7 +2577,6 @@ service_redirect_to_ip (void *cls, | |||
2481 | void *addr; | 2577 | void *addr; |
2482 | struct DestinationEntry *de; | 2578 | struct DestinationEntry *de; |
2483 | struct GNUNET_HashCode key; | 2579 | struct GNUNET_HashCode key; |
2484 | struct TunnelState *ts; | ||
2485 | 2580 | ||
2486 | /* validate and parse request */ | 2581 | /* validate and parse request */ |
2487 | mlen = ntohs (message->size); | 2582 | mlen = ntohs (message->size); |
@@ -2574,22 +2669,6 @@ service_redirect_to_ip (void *cls, | |||
2574 | 1, GNUNET_NO); | 2669 | 1, GNUNET_NO); |
2575 | while (GNUNET_CONTAINER_multihashmap_size (destination_map) > max_destination_mappings) | 2670 | while (GNUNET_CONTAINER_multihashmap_size (destination_map) > max_destination_mappings) |
2576 | expire_destination (de); | 2671 | expire_destination (de); |
2577 | |||
2578 | /* setup tunnel to destination */ | ||
2579 | ts = create_tunnel_to_destination (de, | ||
2580 | result_af); | ||
2581 | switch (result_af) | ||
2582 | { | ||
2583 | case AF_INET: | ||
2584 | ts->destination_ip.v4 = v4; | ||
2585 | break; | ||
2586 | case AF_INET6: | ||
2587 | ts->destination_ip.v6 = v6; | ||
2588 | break; | ||
2589 | default: | ||
2590 | GNUNET_assert (0); | ||
2591 | } | ||
2592 | /* we're done */ | ||
2593 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 2672 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
2594 | } | 2673 | } |
2595 | 2674 | ||
@@ -2604,7 +2683,8 @@ service_redirect_to_ip (void *cls, | |||
2604 | * @param message redirection request (a `struct RedirectToPeerRequestMessage`) | 2683 | * @param message redirection request (a `struct RedirectToPeerRequestMessage`) |
2605 | */ | 2684 | */ |
2606 | static void | 2685 | static void |
2607 | service_redirect_to_service (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Client *client, | 2686 | service_redirect_to_service (void *cls, |
2687 | struct GNUNET_SERVER_Client *client, | ||
2608 | const struct GNUNET_MessageHeader *message) | 2688 | const struct GNUNET_MessageHeader *message) |
2609 | { | 2689 | { |
2610 | const struct RedirectToServiceRequestMessage *msg; | 2690 | const struct RedirectToServiceRequestMessage *msg; |
@@ -2615,6 +2695,7 @@ service_redirect_to_service (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Clien | |||
2615 | struct DestinationEntry *de; | 2695 | struct DestinationEntry *de; |
2616 | struct GNUNET_HashCode key; | 2696 | struct GNUNET_HashCode key; |
2617 | struct TunnelState *ts; | 2697 | struct TunnelState *ts; |
2698 | struct DestinationTunnel *dt; | ||
2618 | 2699 | ||
2619 | /* parse request */ | 2700 | /* parse request */ |
2620 | msg = (const struct RedirectToServiceRequestMessage *) message; | 2701 | msg = (const struct RedirectToServiceRequestMessage *) message; |
@@ -2670,7 +2751,13 @@ service_redirect_to_service (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Clien | |||
2670 | GNUNET_TIME_absolute_ntoh (msg->expiration_time).abs_value_us); | 2751 | GNUNET_TIME_absolute_ntoh (msg->expiration_time).abs_value_us); |
2671 | while (GNUNET_CONTAINER_multihashmap_size (destination_map) > max_destination_mappings) | 2752 | while (GNUNET_CONTAINER_multihashmap_size (destination_map) > max_destination_mappings) |
2672 | expire_destination (de); | 2753 | expire_destination (de); |
2673 | ts = create_tunnel_to_destination (de, | 2754 | |
2755 | dt = GNUNET_new (struct DestinationTunnel); | ||
2756 | dt->destination = de; | ||
2757 | GNUNET_CONTAINER_DLL_insert (de->dt_head, | ||
2758 | de->dt_tail, | ||
2759 | dt); | ||
2760 | ts = create_tunnel_to_destination (dt, | ||
2674 | result_af); | 2761 | result_af); |
2675 | switch (result_af) | 2762 | switch (result_af) |
2676 | { | 2763 | { |