aboutsummaryrefslogtreecommitdiff
path: root/src/exit/gnunet-daemon-exit.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-06 01:02:51 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-06 01:02:51 +0000
commite7708b300114cd6612d2d643d3291324515a1e46 (patch)
tree43edae76860c432a074d2ecf009bd59d01653df6 /src/exit/gnunet-daemon-exit.c
parentcdfe91f4823e6733e588acd1bbc5cb6c1a197938 (diff)
downloadgnunet-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.c577
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 */
482struct LocalService * 483static struct LocalService *
483find_service (struct GNUNET_CONTAINER_MultiHashMap *service_map, 484find_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 */
887static void
888setup_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 */
936static void
937setup_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
882void 977/**
883prepare_ipv4_packet (size_t len, 978 * FIXME: document
884 uint16_t pktlen, void *payload, 979 */
885 uint8_t protocol, 980static void
886 void *ipaddress, void *tunnel, 981prepare_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
954void 1064/**
955prepare_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) 1067static void
1068prepare_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
1288static int
1289receive_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 */
1411static void
1412send_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, 1489static int
1352 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); 1490receive_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 */
1372static int 1527static int
1373receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, 1528receive_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 *