diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-06 01:02:51 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-06 01:02:51 +0000 |
commit | e7708b300114cd6612d2d643d3291324515a1e46 (patch) | |
tree | 43edae76860c432a074d2ecf009bd59d01653df6 /src/exit/gnunet-daemon-exit.c | |
parent | cdfe91f4823e6733e588acd1bbc5cb6c1a197938 (diff) | |
download | gnunet-e7708b300114cd6612d2d643d3291324515a1e46.tar.gz gnunet-e7708b300114cd6612d2d643d3291324515a1e46.zip |
-late night code cleanup
Diffstat (limited to 'src/exit/gnunet-daemon-exit.c')
-rw-r--r-- | src/exit/gnunet-daemon-exit.c | 577 |
1 files changed, 332 insertions, 245 deletions
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c index 4986b9344..77830020e 100644 --- a/src/exit/gnunet-daemon-exit.c +++ b/src/exit/gnunet-daemon-exit.c | |||
@@ -463,9 +463,10 @@ get_redirect_state (int af, | |||
463 | if (NULL == state) | 463 | if (NULL == state) |
464 | return NULL; | 464 | return NULL; |
465 | /* Mark this connection as freshly used */ | 465 | /* Mark this connection as freshly used */ |
466 | GNUNET_CONTAINER_heap_update_cost (connections_heap, | 466 | if (NULL == state_key) |
467 | state->heap_node, | 467 | GNUNET_CONTAINER_heap_update_cost (connections_heap, |
468 | GNUNET_TIME_absolute_get ().abs_value); | 468 | state->heap_node, |
469 | GNUNET_TIME_absolute_get ().abs_value); | ||
469 | return state; | 470 | return state; |
470 | } | 471 | } |
471 | 472 | ||
@@ -479,7 +480,7 @@ get_redirect_state (int af, | |||
479 | * @param dpt destination port | 480 | * @param dpt destination port |
480 | * @return NULL if we are not aware of such a service | 481 | * @return NULL if we are not aware of such a service |
481 | */ | 482 | */ |
482 | struct LocalService * | 483 | static struct LocalService * |
483 | find_service (struct GNUNET_CONTAINER_MultiHashMap *service_map, | 484 | find_service (struct GNUNET_CONTAINER_MultiHashMap *service_map, |
484 | const GNUNET_HashCode *desc, | 485 | const GNUNET_HashCode *desc, |
485 | uint16_t dpt) | 486 | uint16_t dpt) |
@@ -875,73 +876,182 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, | |||
875 | } | 876 | } |
876 | 877 | ||
877 | 878 | ||
879 | /** | ||
880 | * We need to create a (unique) fresh local address (IP+port). | ||
881 | * Fill one in. | ||
882 | * | ||
883 | * @param af desired address family | ||
884 | * @param proto desired protocol (IPPROTO_UDP or IPPROTO_TCP) | ||
885 | * @param local_address address to initialize | ||
886 | */ | ||
887 | static void | ||
888 | setup_fresh_address (int af, | ||
889 | int proto, | ||
890 | struct SocketAddress *local_address) | ||
891 | { | ||
892 | switch (af) | ||
893 | { | ||
894 | case AF_INET: | ||
895 | { | ||
896 | const char *ipv4addr = exit_argv[4]; | ||
897 | const char *ipv4mask = exit_argv[5]; | ||
898 | uint32_t tmp; | ||
899 | uint32_t tmp2; | ||
900 | |||
901 | GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &tmp)); | ||
902 | GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &tmp2)); | ||
903 | // FIXME | ||
904 | /* This should be a noop */ | ||
905 | tmp = tmp & tmp2; | ||
906 | tmp |= ntohl (*((uint32_t *) /*tunnel*/ 42)) & (~tmp2); | ||
907 | |||
908 | // pkt4->source_address.s_addr = tmp; | ||
909 | } | ||
910 | break; | ||
911 | case AF_INET6: | ||
912 | { | ||
913 | const char *ipv6addr = exit_argv[2]; | ||
914 | /* Generate a new src-address | ||
915 | * This takes as much from the address of the tunnel as fits into | ||
916 | * the host-mask*/ | ||
917 | unsigned long long ipv6prefix_r = (ipv6prefix + 7) / 8; | ||
918 | inet_pton (AF_INET6, ipv6addr, &local_address->address.ipv6); | ||
919 | if (ipv6prefix_r < (16 - sizeof (void *))) | ||
920 | ipv6prefix_r = 16 - sizeof (void *); | ||
921 | |||
922 | unsigned int offset = ipv6prefix_r - (16 - sizeof (void *)); | ||
923 | // memcpy ((((char *) &pkt6->source_address)) + ipv6prefix_r, ((char *) &tunnel) + offset, 16 - ipv6prefix_r); | ||
924 | offset++; | ||
925 | } | ||
926 | break; | ||
927 | default: | ||
928 | GNUNET_assert (0); | ||
929 | } | ||
930 | } | ||
931 | |||
878 | 932 | ||
933 | /** | ||
934 | * FIXME: document! | ||
935 | */ | ||
936 | static void | ||
937 | setup_state_record (struct TunnelState *state) | ||
938 | { | ||
939 | GNUNET_HashCode key; | ||
940 | struct TunnelState *s; | ||
879 | 941 | ||
942 | /* generate fresh, unique address */ | ||
943 | do | ||
944 | { | ||
945 | setup_fresh_address (state->serv->address.af, | ||
946 | state->serv->address.proto, | ||
947 | &state->ri.local_address); | ||
948 | } while (NULL != get_redirect_state (state->serv->address.af, | ||
949 | IPPROTO_UDP, | ||
950 | &state->ri.remote_address.address, | ||
951 | state->ri.remote_address.port, | ||
952 | &state->ri.local_address.address, | ||
953 | state->ri.local_address.port, | ||
954 | &key)); | ||
955 | GNUNET_assert (GNUNET_OK == | ||
956 | GNUNET_CONTAINER_multihashmap_put (connections_map, | ||
957 | &key, state, | ||
958 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
959 | state->heap_node = GNUNET_CONTAINER_heap_insert (connections_heap, | ||
960 | state, | ||
961 | GNUNET_TIME_absolute_get ().abs_value); | ||
962 | while (GNUNET_CONTAINER_heap_get_size (connections_heap) > max_connections) | ||
963 | { | ||
964 | s = GNUNET_CONTAINER_heap_remove_root (connections_heap); | ||
965 | GNUNET_assert (state != s); | ||
966 | s->heap_node = NULL; | ||
967 | GNUNET_MESH_tunnel_destroy (s->tunnel); | ||
968 | GNUNET_assert (GNUNET_OK == | ||
969 | GNUNET_CONTAINER_multihashmap_remove (connections_map, | ||
970 | &s->state_key, | ||
971 | s)); | ||
972 | GNUNET_free (s); | ||
973 | } | ||
974 | } | ||
880 | 975 | ||
881 | 976 | ||
882 | void | 977 | /** |
883 | prepare_ipv4_packet (size_t len, | 978 | * FIXME: document |
884 | uint16_t pktlen, void *payload, | 979 | */ |
885 | uint8_t protocol, | 980 | static void |
886 | void *ipaddress, void *tunnel, | 981 | prepare_ipv4_packet (const void *payload, size_t payload_length, |
887 | struct RedirectInformation * | 982 | int protocol, |
888 | state, struct ip4_header *pkt4) | 983 | const struct SocketAddress *src_address, |
984 | const struct SocketAddress *dst_address, | ||
985 | struct ip4_header *pkt4) | ||
889 | { | 986 | { |
890 | const char *ipv4addr = exit_argv[4]; | 987 | size_t len; |
891 | const char *ipv4mask = exit_argv[5]; | 988 | |
892 | uint32_t tmp; | 989 | len = payload_length; |
893 | uint32_t tmp2; | 990 | switch (protocol) |
894 | 991 | { | |
895 | GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &tmp)); | 992 | case IPPROTO_UDP: |
896 | GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &tmp2)); | 993 | len += sizeof (struct udp_packet); |
897 | memcpy (&pkt4[1], payload, pktlen); | 994 | break; |
995 | case IPPROTO_TCP: | ||
996 | /* tcp_header (with port/crc not set) must be part of payload! */ | ||
997 | if (len < sizeof (struct tcp_packet)) | ||
998 | { | ||
999 | GNUNET_break (0); | ||
1000 | return; | ||
1001 | } | ||
1002 | break; | ||
1003 | default: | ||
1004 | GNUNET_break (0); | ||
1005 | return; | ||
1006 | } | ||
1007 | if (len + sizeof (struct ip4_header) > UINT16_MAX) | ||
1008 | { | ||
1009 | GNUNET_break (0); | ||
1010 | return; | ||
1011 | } | ||
1012 | |||
898 | pkt4->version = 4; | 1013 | pkt4->version = 4; |
899 | pkt4->header_length = sizeof (struct ip4_header) / 4; | 1014 | pkt4->header_length = sizeof (struct ip4_header) / 4; |
900 | pkt4->diff_serv = 0; | 1015 | pkt4->diff_serv = 0; |
901 | pkt4->total_length = htons (sizeof (struct ip4_header) + pktlen); | 1016 | pkt4->total_length = htons ((uint16_t) (sizeof (struct ip4_header) + len)); |
902 | pkt4->identification = 0; // FIXME! | 1017 | pkt4->identification = 0; // FIXME: pick at random! |
903 | pkt4->flags = 0; | 1018 | pkt4->flags = 0; |
904 | pkt4->fragmentation_offset = 0; | 1019 | pkt4->fragmentation_offset = 0; |
905 | pkt4->ttl = 255; | 1020 | pkt4->ttl = 255; |
906 | pkt4->protocol = protocol; | 1021 | pkt4->protocol = protocol; |
907 | pkt4->checksum = 0; /* Will be calculated later */ | 1022 | pkt4->checksum = 0; |
908 | 1023 | pkt4->destination_address = dst_address->address.ipv4; | |
909 | memcpy (&pkt4->destination_address, ipaddress, sizeof (struct in_addr)); | 1024 | pkt4->source_address = src_address->address.ipv4; |
910 | |||
911 | /* Generate a new src-address -- FIXME: not always, right!? */ | ||
912 | |||
913 | /* This should be a noop */ | ||
914 | tmp = tmp & tmp2; | ||
915 | tmp |= ntohl (*((uint32_t *) tunnel)) & (~tmp2); | ||
916 | |||
917 | pkt4->source_address.s_addr = tmp; | ||
918 | pkt4->checksum = GNUNET_CRYPTO_crc16_n (pkt4, sizeof (struct ip4_header)); | 1025 | pkt4->checksum = GNUNET_CRYPTO_crc16_n (pkt4, sizeof (struct ip4_header)); |
919 | 1026 | ||
920 | // FIXME: memcpy (&state->addr, &tmp, 4); | ||
921 | |||
922 | switch (protocol) | 1027 | switch (protocol) |
923 | { | 1028 | { |
924 | case IPPROTO_UDP: | 1029 | case IPPROTO_UDP: |
925 | { | 1030 | { |
926 | struct udp_packet *pkt4_udp = (struct udp_packet *) &pkt4[1]; | 1031 | struct udp_packet *pkt4_udp = (struct udp_packet *) &pkt4[1]; |
927 | // FIXME: state->pt = pkt4_udp->spt; | 1032 | |
1033 | pkt4_udp->spt = htons (src_address->port); | ||
1034 | pkt4_udp->dpt = htons (dst_address->port); | ||
928 | pkt4_udp->crc = 0; /* Optional for IPv4 */ | 1035 | pkt4_udp->crc = 0; /* Optional for IPv4 */ |
1036 | pkt4_udp->len = htons ((uint16_t) payload_length); | ||
1037 | memcpy (&pkt4_udp[1], payload, payload_length); | ||
929 | } | 1038 | } |
930 | break; | 1039 | break; |
931 | case IPPROTO_TCP: | 1040 | case IPPROTO_TCP: |
932 | { | 1041 | { |
933 | struct tcp_packet *pkt4_tcp = (struct tcp_packet *) &pkt4[1]; | 1042 | struct tcp_packet *pkt4_tcp = (struct tcp_packet *) &pkt4[1]; |
934 | 1043 | ||
935 | // FIXME: state->pt = pkt4_tcp->spt; | 1044 | memcpy (pkt4_tcp, payload, payload_length); |
1045 | pkt4_tcp->spt = htons (src_address->port); | ||
1046 | pkt4_tcp->dpt = htons (dst_address->port); | ||
936 | pkt4_tcp->crc = 0; | 1047 | pkt4_tcp->crc = 0; |
937 | uint32_t sum = 0; | 1048 | uint32_t sum = 0; |
938 | sum = GNUNET_CRYPTO_crc16_step (sum, | 1049 | sum = GNUNET_CRYPTO_crc16_step (sum, |
939 | &pkt4->source_address, | 1050 | &pkt4->source_address, |
940 | sizeof (struct in_addr) * 2); | 1051 | sizeof (struct in_addr) * 2); |
941 | tmp = (protocol << 16) | (0xffff & pktlen); | 1052 | uint32_t tmp = htonl ((protocol << 16) | (0xffff & len)); |
942 | tmp = htonl (tmp); | 1053 | sum = GNUNET_CRYPTO_crc16_step (sum, & tmp, sizeof (uint32_t)); |
943 | sum = GNUNET_CRYPTO_crc16_step (sum, & tmp, 4); | 1054 | sum = GNUNET_CRYPTO_crc16_step (sum, & pkt4_tcp, len); |
944 | sum = GNUNET_CRYPTO_crc16_step (sum, & pkt4_tcp, pktlen); | ||
945 | pkt4_tcp->crc = GNUNET_CRYPTO_crc16_finish (sum); | 1055 | pkt4_tcp->crc = GNUNET_CRYPTO_crc16_finish (sum); |
946 | } | 1056 | } |
947 | break; | 1057 | break; |
@@ -951,62 +1061,70 @@ prepare_ipv4_packet (size_t len, | |||
951 | } | 1061 | } |
952 | 1062 | ||
953 | 1063 | ||
954 | void | 1064 | /** |
955 | prepare_ipv6_packet (size_t len, uint16_t pktlen, void *payload, | 1065 | * FIXME: document |
956 | uint16_t protocol, void *ipaddress, void *tunnel, | 1066 | */ |
957 | struct RedirectInformation *state, struct ip6_header *pkt6) | 1067 | static void |
1068 | prepare_ipv6_packet (const void *payload, size_t payload_length, | ||
1069 | int protocol, | ||
1070 | const struct SocketAddress *src_address, | ||
1071 | const struct SocketAddress *dst_address, | ||
1072 | struct ip6_header *pkt6) | ||
958 | { | 1073 | { |
959 | const char *ipv6addr = exit_argv[2]; | 1074 | size_t len; |
960 | uint32_t tmp; | ||
961 | |||
962 | 1075 | ||
963 | memcpy (&pkt6[1], payload, pktlen); | 1076 | len = payload_length; |
1077 | switch (protocol) | ||
1078 | { | ||
1079 | case IPPROTO_UDP: | ||
1080 | len += sizeof (struct udp_packet); | ||
1081 | break; | ||
1082 | case IPPROTO_TCP: | ||
1083 | /* tcp_header (with port/crc not set) must be part of payload! */ | ||
1084 | if (len < sizeof (struct tcp_packet)) | ||
1085 | { | ||
1086 | GNUNET_break (0); | ||
1087 | return; | ||
1088 | } | ||
1089 | break; | ||
1090 | default: | ||
1091 | GNUNET_break (0); | ||
1092 | return; | ||
1093 | } | ||
1094 | if (len > UINT16_MAX) | ||
1095 | { | ||
1096 | GNUNET_break (0); | ||
1097 | return; | ||
1098 | } | ||
964 | 1099 | ||
965 | pkt6->version = 6; | 1100 | pkt6->version = 6; |
966 | pkt6->next_header = protocol; | 1101 | pkt6->next_header = protocol; |
967 | pkt6->payload_length = htons (pktlen); | 1102 | pkt6->payload_length = htons ((uint16_t) (len + sizeof (struct ip6_header))); |
968 | pkt6->hop_limit = 64; | 1103 | pkt6->hop_limit = 255; |
969 | 1104 | pkt6->destination_address = dst_address->address.ipv6; | |
970 | memcpy (&pkt6->destination_address, ipaddress, sizeof (struct in6_addr)); | 1105 | pkt6->source_address = src_address->address.ipv6; |
971 | |||
972 | /* Generate a new src-address | ||
973 | * This takes as much from the address of the tunnel as fits into | ||
974 | * the host-mask*/ | ||
975 | |||
976 | unsigned long long ipv6prefix_r = (ipv6prefix + 7) / 8; | ||
977 | |||
978 | inet_pton (AF_INET6, ipv6addr, &pkt6->source_address); | ||
979 | |||
980 | if (ipv6prefix_r < (16 - sizeof (void *))) | ||
981 | ipv6prefix_r = 16 - sizeof (void *); | ||
982 | |||
983 | unsigned int offset = ipv6prefix_r - (16 - sizeof (void *)); | ||
984 | |||
985 | memcpy ((((char *) &pkt6->source_address)) + ipv6prefix_r, | ||
986 | ((char *) &tunnel) + offset, 16 - ipv6prefix_r); | ||
987 | |||
988 | /* copy the needed information into the state */ | ||
989 | // FIXME: memcpy (&state->addr, &pkt6->source_address, 16); | ||
990 | 1106 | ||
991 | switch (protocol) | 1107 | switch (protocol) |
992 | { | 1108 | { |
993 | case IPPROTO_UDP: | 1109 | case IPPROTO_UDP: |
994 | { | 1110 | { |
995 | struct udp_packet *pkt6_udp = (struct udp_packet *) &pkt6[1]; | 1111 | struct udp_packet *pkt6_udp = (struct udp_packet *) &pkt6[1]; |
996 | 1112 | ||
997 | // FIXME: state->pt = pkt6_udp->spt; | 1113 | memcpy (&pkt6[1], payload, payload_length); |
998 | pkt6_udp->crc = 0; | 1114 | pkt6_udp->crc = 0; |
1115 | pkt6_udp->spt = htons (src_address->port); | ||
1116 | pkt6_udp->dpt = htons (dst_address->port); | ||
1117 | pkt6_udp->len = htons ((uint16_t) payload_length); | ||
1118 | |||
999 | uint32_t sum = 0; | 1119 | uint32_t sum = 0; |
1000 | sum = | 1120 | sum = GNUNET_CRYPTO_crc16_step (sum, |
1001 | GNUNET_CRYPTO_crc16_step (sum, & pkt6->source_address, | 1121 | &pkt6->source_address, |
1002 | 16 * 2); | 1122 | sizeof (struct in6_addr) * 2); |
1003 | tmp = (htons (pktlen) & 0xffff); | 1123 | uint32_t tmp = htons (len); |
1004 | sum = GNUNET_CRYPTO_crc16_step (sum, & tmp, 4); | 1124 | sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); |
1005 | tmp = htons (pkt6->next_header & 0x00ff); | 1125 | tmp = htonl (pkt6->next_header); |
1006 | sum = GNUNET_CRYPTO_crc16_step (sum, & tmp, 4); | 1126 | sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); |
1007 | sum = | 1127 | sum = GNUNET_CRYPTO_crc16_step (sum, pkt6_udp, len); |
1008 | GNUNET_CRYPTO_crc16_step (sum, pkt6_udp, | ||
1009 | ntohs (pkt6_udp->len)); | ||
1010 | pkt6_udp->crc = GNUNET_CRYPTO_crc16_finish (sum); | 1128 | pkt6_udp->crc = GNUNET_CRYPTO_crc16_finish (sum); |
1011 | } | 1129 | } |
1012 | break; | 1130 | break; |
@@ -1014,20 +1132,19 @@ prepare_ipv6_packet (size_t len, uint16_t pktlen, void *payload, | |||
1014 | { | 1132 | { |
1015 | struct tcp_packet *pkt6_tcp = (struct tcp_packet *) pkt6; | 1133 | struct tcp_packet *pkt6_tcp = (struct tcp_packet *) pkt6; |
1016 | 1134 | ||
1017 | // FIXME: state->pt = pkt6_tcp->spt; | 1135 | memcpy (pkt6_tcp, payload, payload_length); |
1018 | pkt6_tcp->crc = 0; | 1136 | pkt6_tcp->crc = 0; |
1137 | pkt6_tcp->spt = htons (src_address->port); | ||
1138 | pkt6_tcp->dpt = htons (dst_address->port); | ||
1139 | |||
1019 | uint32_t sum = 0; | 1140 | uint32_t sum = 0; |
1020 | 1141 | sum = GNUNET_CRYPTO_crc16_step (sum, &pkt6->source_address, | |
1021 | sum = | 1142 | sizeof (struct in6_addr) * 2); |
1022 | GNUNET_CRYPTO_crc16_step (sum, & pkt6->source_address, 16 * 2); | 1143 | uint32_t tmp = htonl (len); |
1023 | tmp = htonl (pktlen); | 1144 | sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); |
1024 | sum = GNUNET_CRYPTO_crc16_step (sum, & tmp, 4); | 1145 | tmp = htonl (pkt6->next_header); |
1025 | tmp = htonl (((pkt6->next_header & 0x000000ff))); | 1146 | sum = GNUNET_CRYPTO_crc16_step (sum, &tmp, sizeof (uint32_t)); |
1026 | sum = GNUNET_CRYPTO_crc16_step (sum, & tmp, 4); | 1147 | sum = GNUNET_CRYPTO_crc16_step (sum, pkt6_tcp, len); |
1027 | |||
1028 | sum = | ||
1029 | GNUNET_CRYPTO_crc16_step (sum, pkt6_tcp, | ||
1030 | ntohs (pkt6->payload_length)); | ||
1031 | pkt6_tcp->crc = GNUNET_CRYPTO_crc16_finish (sum); | 1148 | pkt6_tcp->crc = GNUNET_CRYPTO_crc16_finish (sum); |
1032 | } | 1149 | } |
1033 | break; | 1150 | break; |
@@ -1285,89 +1402,127 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1285 | return GNUNET_YES; | 1402 | return GNUNET_YES; |
1286 | } | 1403 | } |
1287 | 1404 | ||
1288 | static int | ||
1289 | receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | ||
1290 | void **tunnel_ctx GNUNET_UNUSED, | ||
1291 | const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED, | ||
1292 | const struct GNUNET_MessageHeader *message, | ||
1293 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) | ||
1294 | { | ||
1295 | // FIXME | ||
1296 | #if 0 | ||
1297 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); | ||
1298 | struct udp_packet *pkt = (struct udp_packet *) (desc + 1); | ||
1299 | struct remote_addr *s = (struct remote_addr *) desc; | ||
1300 | char *buf; | ||
1301 | size_t len; | ||
1302 | |||
1303 | GNUNET_assert (ntohs (pkt->len) == | ||
1304 | ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) - | ||
1305 | sizeof (GNUNET_HashCode)); | ||
1306 | |||
1307 | /* Prepare the state. | ||
1308 | * This will be saved in the hashmap, so that the receiving procedure knows | ||
1309 | * through which tunnel this connection has to be routed. | ||
1310 | */ | ||
1311 | struct TunnelState *state = GNUNET_malloc (sizeof (struct TunnelState)); | ||
1312 | 1405 | ||
1313 | state->tunnel = tunnel; | ||
1314 | state->hashmap = udp_connections; | ||
1315 | state->type = REMOTE; | ||
1316 | memcpy (&state->remote, s, sizeof (struct remote_addr)); | ||
1317 | 1406 | ||
1318 | len = | ||
1319 | sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) + | ||
1320 | sizeof (struct ip6_hdr) + ntohs (pkt->len); | ||
1321 | buf = alloca (len); | ||
1322 | 1407 | ||
1323 | memset (buf, 0, len); | 1408 | /** |
1409 | * FIXME: document! | ||
1410 | */ | ||
1411 | static void | ||
1412 | send_udp_packet_via_tun (const struct SocketAddress *destination_address, | ||
1413 | const struct SocketAddress *source_address, | ||
1414 | const void *payload, size_t payload_length) | ||
1415 | { | ||
1416 | size_t len; | ||
1324 | 1417 | ||
1325 | switch (s->addrlen) | 1418 | len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct tun_header); |
1419 | switch (source_address->af) | ||
1326 | { | 1420 | { |
1327 | case 4: | 1421 | case AF_INET: |
1328 | prepare_ipv4_packet (len, ntohs (pkt->len), pkt, IPPROTO_UDP, &s->addr, | 1422 | len += sizeof (struct ip4_header); |
1329 | tunnel, state, (struct ip4_header *) buf); | ||
1330 | break; | 1423 | break; |
1331 | case 16: | 1424 | case AF_INET6: |
1332 | prepare_ipv6_packet (len, ntohs (pkt->len), pkt, IPPROTO_UDP, &s->addr, | 1425 | len += sizeof (struct ip6_header); |
1333 | tunnel, state, (struct ip6_header *) buf); | ||
1334 | break; | 1426 | break; |
1335 | default: | 1427 | default: |
1336 | GNUNET_assert (0); | 1428 | GNUNET_break (0); |
1337 | break; | 1429 | return; |
1430 | } | ||
1431 | len += sizeof (struct udp_packet); | ||
1432 | len += payload_length; | ||
1433 | if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1434 | { | ||
1435 | GNUNET_break (0); | ||
1436 | return; | ||
1437 | } | ||
1438 | { | ||
1439 | char buf[len]; | ||
1440 | struct GNUNET_MessageHeader *hdr; | ||
1441 | struct tun_header *tun; | ||
1442 | |||
1443 | hdr= (struct GNUNET_MessageHeader *) buf; | ||
1444 | hdr->type = htons (42); | ||
1445 | hdr->size = htons (len); | ||
1446 | tun = (struct tun_header*) &hdr[1]; | ||
1447 | tun->flags = htons (0); | ||
1448 | switch (source_address->af) | ||
1449 | { | ||
1450 | case AF_INET: | ||
1451 | { | ||
1452 | struct ip4_header * ipv4 = (struct ip4_header*) &tun[1]; | ||
1453 | |||
1454 | tun->proto = htons (ETH_P_IPV4); | ||
1455 | prepare_ipv4_packet (payload, payload_length, IPPROTO_UDP, | ||
1456 | source_address, | ||
1457 | destination_address, | ||
1458 | ipv4); | ||
1459 | } | ||
1460 | break; | ||
1461 | case AF_INET6: | ||
1462 | { | ||
1463 | struct ip6_header * ipv6 = (struct ip6_header*) &tun[1]; | ||
1464 | |||
1465 | tun->proto = htons (ETH_P_IPV6); | ||
1466 | prepare_ipv6_packet (payload, payload_length, IPPROTO_UDP, | ||
1467 | source_address, | ||
1468 | destination_address, | ||
1469 | ipv6); | ||
1470 | } | ||
1471 | break; | ||
1472 | default: | ||
1473 | GNUNET_assert (0); | ||
1474 | break; | ||
1475 | } | ||
1476 | (void) GNUNET_HELPER_send (helper_handle, | ||
1477 | (const struct GNUNET_MessageHeader*) buf, | ||
1478 | GNUNET_YES, | ||
1479 | NULL, NULL); | ||
1338 | } | 1480 | } |
1481 | } | ||
1339 | 1482 | ||
1340 | hash_redirect_info (&state->hash, &state->redirect_info, s->addrlen); | ||
1341 | 1483 | ||
1342 | (void) GNUNET_HELPER_send (helper_handle, | ||
1343 | (const struct GNUNET_MessageHeader*) buf, | ||
1344 | GNUNET_YES, | ||
1345 | NULL, NULL); | ||
1346 | 1484 | ||
1347 | 1485 | ||
1348 | if (GNUNET_NO == | 1486 | /** |
1349 | GNUNET_CONTAINER_multihashmap_contains (udp_connections, &state->hash)) | 1487 | * FIXME: document! |
1350 | { | 1488 | */ |
1351 | GNUNET_CONTAINER_multihashmap_put (udp_connections, &state->hash, state, | 1489 | static int |
1352 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 1490 | receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, |
1491 | void **tunnel_ctx GNUNET_UNUSED, | ||
1492 | const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED, | ||
1493 | const struct GNUNET_MessageHeader *message, | ||
1494 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) | ||
1495 | { | ||
1496 | struct TunnelState *state = *tunnel_ctx; | ||
1497 | // FIXME: write proper request struct (!) | ||
1498 | const GNUNET_HashCode *desc = (const GNUNET_HashCode *) &message[1]; | ||
1499 | const struct udp_packet *pkt = (const struct udp_packet *) &desc[1]; | ||
1500 | const struct SocketAddress *s = (const struct SocketAddress *) desc; | ||
1501 | uint16_t pkt_len = ntohs (message->size); | ||
1353 | 1502 | ||
1354 | state->heap_node = | 1503 | if (pkt_len != ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) - sizeof (GNUNET_HashCode)) |
1355 | GNUNET_CONTAINER_heap_insert (udp_connections_heap, state, | 1504 | { |
1356 | GNUNET_TIME_absolute_get ().abs_value); | 1505 | GNUNET_break_op (0); |
1506 | return GNUNET_YES; | ||
1507 | } | ||
1508 | pkt_len -= (sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode)); | ||
1357 | 1509 | ||
1358 | if (GNUNET_CONTAINER_heap_get_size (udp_connections_heap) > | 1510 | if (NULL == state->heap_node) |
1359 | max_udp_connections) | 1511 | { |
1360 | GNUNET_SCHEDULER_add_now (collect_connections, udp_connections_heap); | 1512 | /* first packet, setup record */ |
1513 | state->ri.remote_address = *s; | ||
1514 | setup_state_record (state); | ||
1361 | } | 1515 | } |
1362 | else | 1516 | |
1363 | GNUNET_free (state); | 1517 | send_udp_packet_via_tun (&state->ri.remote_address, |
1364 | #endif | 1518 | &state->ri.local_address, |
1519 | &pkt[1], pkt_len - sizeof (struct udp_packet)); | ||
1365 | return GNUNET_YES; | 1520 | return GNUNET_YES; |
1366 | } | 1521 | } |
1367 | 1522 | ||
1368 | 1523 | ||
1369 | /** | 1524 | /** |
1370 | * The messages are one GNUNET_HashCode for the service, followed by a struct udp_packet | 1525 | * FIXME: document! |
1371 | */ | 1526 | */ |
1372 | static int | 1527 | static int |
1373 | receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | 1528 | receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, |
@@ -1376,16 +1531,12 @@ receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1376 | const struct GNUNET_MessageHeader *message, | 1531 | const struct GNUNET_MessageHeader *message, |
1377 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) | 1532 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) |
1378 | { | 1533 | { |
1379 | // FIXME | 1534 | struct TunnelState *state = *tunnel_ctx; |
1380 | #if 0 | 1535 | // FIXME: write proper request struct (we don't need UDP except dpt either!) |
1381 | const GNUNET_HashCode *desc = (const GNUNET_HashCode *) &message[1]; | 1536 | const GNUNET_HashCode *desc = (const GNUNET_HashCode *) &message[1]; |
1382 | const struct udp_packet *pkt = (const struct udp_packet *) &desc[1]; | 1537 | const struct udp_packet *pkt = (const struct udp_packet *) &desc[1]; |
1383 | uint16_t pkt_len = ntohs (message->size); | 1538 | uint16_t pkt_len = ntohs (message->size); |
1384 | struct LocalService *serv; | 1539 | |
1385 | struct TunnelState *state; | ||
1386 | struct tunnel_state *s; | ||
1387 | char *buf; | ||
1388 | size_t len; | ||
1389 | 1540 | ||
1390 | /* check that we got at least a valid header */ | 1541 | /* check that we got at least a valid header */ |
1391 | if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct udp_packet)) | 1542 | if (pkt_len < sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + sizeof (struct udp_packet)) |
@@ -1399,93 +1550,29 @@ receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1399 | ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) - | 1550 | ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) - |
1400 | sizeof (GNUNET_HashCode)); | 1551 | sizeof (GNUNET_HashCode)); |
1401 | 1552 | ||
1402 | if (NULL == (serv = find_service (udp_services, desc, ntohs (pkt->dpt)))) | 1553 | if (NULL == state->serv) |
1403 | { | ||
1404 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1405 | _("No service found for %s on port %d!\n"), | ||
1406 | "UDP", | ||
1407 | ntohs (pkt->dpt)); | ||
1408 | return GNUNET_YES; | ||
1409 | } | ||
1410 | pkt->dpt = htons (serv->remote_port); | ||
1411 | |||
1412 | /* At this point it would be possible to check against some kind of ACL. */ | ||
1413 | |||
1414 | s = GNUNET_MESH_tunnel_get_data (tunnel); | ||
1415 | |||
1416 | |||
1417 | /* Prepare the state. | ||
1418 | * This will be saved in the hashmap, so that the receiving procedure knows | ||
1419 | * through which tunnel this connection has to be routed. | ||
1420 | */ | ||
1421 | |||
1422 | state = GNUNET_malloc (sizeof (struct TunnelState)); | ||
1423 | |||
1424 | state->tunnel = tunnel; | ||
1425 | state->serv = serv; | ||
1426 | state->type = SERVICE; | ||
1427 | state->hashmap = udp_connections; | ||
1428 | memcpy (&state->desc, desc, sizeof (GNUNET_HashCode)); | ||
1429 | |||
1430 | len = | ||
1431 | sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) + | ||
1432 | sizeof (struct ip6_hdr) + ntohs (pkt->len); | ||
1433 | buf = alloca (len); | ||
1434 | |||
1435 | memset (buf, 0, len); | ||
1436 | |||
1437 | switch (serv->version) | ||
1438 | { | 1554 | { |
1439 | case 4: | 1555 | /* setup fresh connection */ |
1440 | prepare_ipv4_packet (len, ntohs (pkt->len), pkt, IPPROTO_UDP, | 1556 | GNUNET_assert (NULL == state->heap_node); |
1441 | &serv->v4.ip4address, tunnel, state, | 1557 | if (NULL == (state->serv = find_service (udp_services, desc, ntohs (pkt->dpt)))) |
1442 | (struct ip4_header *) buf); | 1558 | { |
1443 | break; | 1559 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1444 | case 6: | 1560 | _("No service found for %s on port %d!\n"), |
1445 | prepare_ipv6_packet (len, ntohs (pkt->len), pkt, IPPROTO_UDP, | 1561 | "UDP", |
1446 | &serv->v6.ip6address, tunnel, state, | 1562 | ntohs (pkt->dpt)); |
1447 | (struct ip6_header *) buf); | 1563 | GNUNET_MESH_tunnel_destroy (state->tunnel); |
1448 | 1564 | return GNUNET_YES; | |
1449 | break; | 1565 | } |
1450 | default: | 1566 | state->ri.remote_address = state->serv->address; |
1451 | GNUNET_assert (0); | 1567 | setup_state_record (state); |
1452 | break; | ||
1453 | } | ||
1454 | |||
1455 | hash_redirect_info (&state->hash, &state->redirect_info, | ||
1456 | serv->version == 4 ? 4 : 16); | ||
1457 | |||
1458 | if (GNUNET_NO == | ||
1459 | GNUNET_CONTAINER_multihashmap_contains (udp_connections, &state->hash)) | ||
1460 | { | ||
1461 | GNUNET_CONTAINER_multihashmap_put (udp_connections, &state->hash, state, | ||
1462 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
1463 | |||
1464 | state->heap_node = | ||
1465 | GNUNET_CONTAINER_heap_insert (udp_connections_heap, state, | ||
1466 | GNUNET_TIME_absolute_get ().abs_value); | ||
1467 | |||
1468 | if (GNUNET_CONTAINER_heap_get_size (udp_connections_heap) > | ||
1469 | max_udp_connections) | ||
1470 | GNUNET_SCHEDULER_add_now (collect_connections, udp_connections_heap); | ||
1471 | } | 1568 | } |
1472 | else | 1569 | send_udp_packet_via_tun (&state->ri.remote_address, |
1473 | GNUNET_free (state); | 1570 | &state->ri.local_address, |
1474 | 1571 | &pkt[1], pkt_len - sizeof (struct udp_packet)); | |
1475 | (void) GNUNET_HELPER_send (helper_handle, | ||
1476 | (const struct GNUNET_MessageHeader*) buf, | ||
1477 | GNUNET_YES, | ||
1478 | NULL, NULL); | ||
1479 | #endif | ||
1480 | return GNUNET_YES; | 1572 | return GNUNET_YES; |
1481 | } | 1573 | } |
1482 | 1574 | ||
1483 | 1575 | ||
1484 | |||
1485 | |||
1486 | |||
1487 | |||
1488 | |||
1489 | /** | 1576 | /** |
1490 | * Callback from GNUNET_MESH for new tunnels. | 1577 | * Callback from GNUNET_MESH for new tunnels. |
1491 | * | 1578 | * |