aboutsummaryrefslogtreecommitdiff
path: root/src/exit/gnunet-daemon-exit.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-06 22:25:49 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-06 22:25:49 +0000
commit7e9b91392479f94df116717c3594b56f93a50b02 (patch)
treee5ca49de1ca3d5761f6186657fbd2fb30aa63aa3 /src/exit/gnunet-daemon-exit.c
parent7557eb23b2d2e1a8a73b49dd7d6e6c9783416571 (diff)
downloadgnunet-7e9b91392479f94df116717c3594b56f93a50b02.tar.gz
gnunet-7e9b91392479f94df116717c3594b56f93a50b02.zip
-finshing first round of re-implementation; missing structs should be done together with entry-component
Diffstat (limited to 'src/exit/gnunet-daemon-exit.c')
-rw-r--r--src/exit/gnunet-daemon-exit.c92
1 files changed, 68 insertions, 24 deletions
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c
index a3e8636d2..fe533ee9e 100644
--- a/src/exit/gnunet-daemon-exit.c
+++ b/src/exit/gnunet-daemon-exit.c
@@ -25,7 +25,6 @@
25 * @author Christian Grothoff 25 * @author Christian Grothoff
26 * 26 *
27 * TODO: 27 * TODO:
28 * - setup_fresh_address is not implemented
29 * - need proper message headers for mesh P2P messages 28 * - need proper message headers for mesh P2P messages
30 * - factor out crc computations from DNS/EXIT into shared library? 29 * - factor out crc computations from DNS/EXIT into shared library?
31 */ 30 */
@@ -891,42 +890,87 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
891 */ 890 */
892static void 891static void
893setup_fresh_address (int af, 892setup_fresh_address (int af,
894 int proto, 893 uint8_t proto,
895 struct SocketAddress *local_address) 894 struct SocketAddress *local_address)
896{ 895{
896 local_address->af = af;
897 local_address->proto = (uint8_t) proto;
898 /* default "local" port range is often 32768--61000,
899 so we pick a random value in that range */
900 local_address->port
901 = (uint16_t) 32768 + GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
902 28232);
897 switch (af) 903 switch (af)
898 { 904 {
899 case AF_INET: 905 case AF_INET:
900 { 906 {
901 const char *ipv4addr = exit_argv[4]; 907 const char *ipv4addr = exit_argv[4];
902 const char *ipv4mask = exit_argv[5]; 908 const char *ipv4mask = exit_argv[5];
903 uint32_t tmp; 909 struct in_addr addr;
904 uint32_t tmp2; 910 struct in_addr mask;
905 911 struct in_addr rnd;
906 GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &tmp)); 912
907 GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &tmp2)); 913 GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &addr));
908 // FIXME 914 GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &mask));
909 /* This should be a noop */ 915 if (0 == ~mask.s_addr)
910 tmp = tmp & tmp2; 916 {
911 tmp |= ntohl (*((uint32_t *) /*tunnel*/ 42)) & (~tmp2); 917 /* only one valid IP anyway */
912 918 local_address->address.ipv4 = addr;
913 // pkt4->source_address.s_addr = tmp; 919 return;
920 }
921 /* Given 192.168.0.1/255.255.0.0, we want a mask
922 of '192.168.255.255', thus: */
923 mask.s_addr = addr.s_addr | ~mask.s_addr;
924 /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
925 do
926 {
927 rnd.s_addr = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
928 UINT32_MAX);
929 local_address->address.ipv4.s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
930 }
931 while ( (local_address->address.ipv4.s_addr == addr.s_addr) ||
932 (local_address->address.ipv4.s_addr == mask.s_addr) );
914 } 933 }
915 break; 934 break;
916 case AF_INET6: 935 case AF_INET6:
917 { 936 {
918 const char *ipv6addr = exit_argv[2]; 937 const char *ipv6addr = exit_argv[2];
919 /* Generate a new src-address 938 struct in6_addr addr;
920 * This takes as much from the address of the tunnel as fits into 939 struct in6_addr mask;
921 * the host-mask*/ 940 struct in6_addr rnd;
922 unsigned long long ipv6prefix_r = (ipv6prefix + 7) / 8; 941 int i;
923 inet_pton (AF_INET6, ipv6addr, &local_address->address.ipv6); 942
924 if (ipv6prefix_r < (16 - sizeof (void *))) 943 GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr));
925 ipv6prefix_r = 16 - sizeof (void *); 944 GNUNET_assert (ipv6prefix < 128);
945 if (ipv6prefix == 127)
946 {
947 /* only one valid IP anyway */
948 local_address->address.ipv6 = addr;
949 return;
950 }
951 /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
952 thus: */
953 mask = addr;
954 for (i=127;i>=128-ipv6prefix;i--)
955 mask.s6_addr[i / 8] |= (1 << (i % 8));
926 956
927 unsigned int offset = ipv6prefix_r - (16 - sizeof (void *)); 957 /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
928 // memcpy ((((char *) &pkt6->source_address)) + ipv6prefix_r, ((char *) &tunnel) + offset, 16 - ipv6prefix_r); 958 do
929 offset++; 959 {
960 for (i=0;i<16;i++)
961 {
962 rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
963 256);
964 local_address->address.ipv6.s6_addr[i]
965 = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
966 }
967 }
968 while ( (0 == memcmp (&local_address->address.ipv6,
969 &addr,
970 sizeof (struct in6_addr))) ||
971 (0 == memcmp (&local_address->address.ipv6,
972 &mask,
973 sizeof (struct in6_addr))) );
930 } 974 }
931 break; 975 break;
932 default: 976 default:
@@ -1052,7 +1096,7 @@ prepare_ipv4_packet (const void *payload, size_t payload_length,
1052 pkt4->diff_serv = 0; 1096 pkt4->diff_serv = 0;
1053 pkt4->total_length = htons ((uint16_t) (sizeof (struct ip4_header) + len)); 1097 pkt4->total_length = htons ((uint16_t) (sizeof (struct ip4_header) + len));
1054 pkt4->identification = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1098 pkt4->identification = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1055 65536); 1099 UINT16_MAX + 1);
1056 pkt4->flags = 0; 1100 pkt4->flags = 0;
1057 pkt4->fragmentation_offset = 0; 1101 pkt4->fragmentation_offset = 0;
1058 pkt4->ttl = 255; 1102 pkt4->ttl = 255;