aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-07 23:38:44 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-07 23:38:44 +0000
commit41d3e0863d932024f76d9085b53b84232efdf380 (patch)
tree40e23b7197629ea89e18351950276e521593d3eb /src
parent6429f7e56bcbe50863e05e284c0174f252ca1d5b (diff)
downloadgnunet-41d3e0863d932024f76d9085b53b84232efdf380.tar.gz
gnunet-41d3e0863d932024f76d9085b53b84232efdf380.zip
-implement local address allocation
Diffstat (limited to 'src')
-rw-r--r--src/vpn/gnunet-service-vpn.c99
1 files changed, 92 insertions, 7 deletions
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c
index 5ad5ff1db..f405bab78 100644
--- a/src/vpn/gnunet-service-vpn.c
+++ b/src/vpn/gnunet-service-vpn.c
@@ -27,7 +27,6 @@
27 * @author Christian Grothoff 27 * @author Christian Grothoff
28 * 28 *
29 * TODO: 29 * TODO:
30 * - implement service message handlers
31 * - define mesh message formats between VPN and EXIT! 30 * - define mesh message formats between VPN and EXIT!
32 * - build mesh messages 31 * - build mesh messages
33 * - parse mesh replies 32 * - parse mesh replies
@@ -297,6 +296,11 @@ static struct GNUNET_HELPER_Handle *helper_handle;
297static char *vpn_argv[7]; 296static char *vpn_argv[7];
298 297
299/** 298/**
299 * Length of the prefix of the VPN's IPv6 network.
300 */
301static unsigned long long ipv6prefix;
302
303/**
300 * Notification context for sending replies to clients. 304 * Notification context for sending replies to clients.
301 */ 305 */
302static struct GNUNET_SERVER_NotificationContext *nc; 306static struct GNUNET_SERVER_NotificationContext *nc;
@@ -1116,8 +1120,43 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1116static int 1120static int
1117allocate_v4_address (struct in_addr *v4) 1121allocate_v4_address (struct in_addr *v4)
1118{ 1122{
1119 // FIXME: implement! 1123 const char *ipv4addr = vpn_argv[4];
1120 return GNUNET_SYSERR; 1124 const char *ipv4mask = vpn_argv[5];
1125 struct in_addr addr;
1126 struct in_addr mask;
1127 struct in_addr rnd;
1128 GNUNET_HashCode key;
1129 unsigned int tries;
1130
1131 GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &addr));
1132 GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &mask));
1133 /* Given 192.168.0.1/255.255.0.0, we want a mask
1134 of '192.168.255.255', thus: */
1135 mask.s_addr = addr.s_addr | ~mask.s_addr;
1136 tries = 0;
1137 do
1138 {
1139 tries++;
1140 if (tries > 16)
1141 {
1142 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1143 _("Failed to find unallocated IPv4 address in VPN's range\n"));
1144 return GNUNET_SYSERR;
1145 }
1146 /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
1147 rnd.s_addr = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1148 UINT32_MAX);
1149 v4->s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
1150 get_destination_key_from_ip (AF_INET,
1151 v4,
1152 &key);
1153 }
1154 while ( (GNUNET_YES ==
1155 GNUNET_CONTAINER_multihashmap_contains (destination_map,
1156 &key)) ||
1157 (v4->s_addr == addr.s_addr) ||
1158 (v4->s_addr == mask.s_addr) );
1159 return GNUNET_OK;
1121} 1160}
1122 1161
1123 1162
@@ -1130,10 +1169,57 @@ allocate_v4_address (struct in_addr *v4)
1130 * GNUNET_SYSERR on error 1169 * GNUNET_SYSERR on error
1131 */ 1170 */
1132static int 1171static int
1133allocate_v6_address (struct in6_addr *v4) 1172allocate_v6_address (struct in6_addr *v6)
1134{ 1173{
1135 // FIXME: implement! 1174 const char *ipv6addr = vpn_argv[2];
1136 return GNUNET_SYSERR; 1175 struct in6_addr addr;
1176 struct in6_addr mask;
1177 struct in6_addr rnd;
1178 int i;
1179 GNUNET_HashCode key;
1180 unsigned int tries;
1181
1182 GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr));
1183 GNUNET_assert (ipv6prefix < 128);
1184 /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
1185 thus: */
1186 mask = addr;
1187 for (i=127;i>=128-ipv6prefix;i--)
1188 mask.s6_addr[i / 8] |= (1 << (i % 8));
1189
1190 /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
1191 tries = 0;
1192 do
1193 {
1194 tries++;
1195 if (tries > 16)
1196 {
1197 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1198 _("Failed to find unallocated IPv6 address in VPN's range\n"));
1199 return GNUNET_SYSERR;
1200
1201 }
1202 for (i=0;i<16;i++)
1203 {
1204 rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1205 256);
1206 v6->s6_addr[i]
1207 = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
1208 }
1209 get_destination_key_from_ip (AF_INET6,
1210 v6,
1211 &key);
1212 }
1213 while ( (GNUNET_YES ==
1214 GNUNET_CONTAINER_multihashmap_contains (destination_map,
1215 &key)) ||
1216 (0 == memcmp (v6,
1217 &addr,
1218 sizeof (struct in6_addr))) ||
1219 (0 == memcmp (v6,
1220 &mask,
1221 sizeof (struct in6_addr))) );
1222 return GNUNET_OK;
1137} 1223}
1138 1224
1139 1225
@@ -1640,7 +1726,6 @@ run (void *cls,
1640 char *ipv4mask; 1726 char *ipv4mask;
1641 struct in_addr v4; 1727 struct in_addr v4;
1642 struct in6_addr v6; 1728 struct in6_addr v6;
1643 unsigned long long ipv6prefix;
1644 1729
1645 cfg = cfg_; 1730 cfg = cfg_;
1646 if (GNUNET_OK != 1731 if (GNUNET_OK !=