[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r19063 - gnunet/src/vpn
From: |
gnunet |
Subject: |
[GNUnet-SVN] r19063 - gnunet/src/vpn |
Date: |
Sun, 8 Jan 2012 00:38:44 +0100 |
Author: grothoff
Date: 2012-01-08 00:38:44 +0100 (Sun, 08 Jan 2012)
New Revision: 19063
Modified:
gnunet/src/vpn/gnunet-service-vpn.c
Log:
-implement local address allocation
Modified: gnunet/src/vpn/gnunet-service-vpn.c
===================================================================
--- gnunet/src/vpn/gnunet-service-vpn.c 2012-01-07 23:28:50 UTC (rev 19062)
+++ gnunet/src/vpn/gnunet-service-vpn.c 2012-01-07 23:38:44 UTC (rev 19063)
@@ -27,7 +27,6 @@
* @author Christian Grothoff
*
* TODO:
- * - implement service message handlers
* - define mesh message formats between VPN and EXIT!
* - build mesh messages
* - parse mesh replies
@@ -297,6 +296,11 @@
static char *vpn_argv[7];
/**
+ * Length of the prefix of the VPN's IPv6 network.
+ */
+static unsigned long long ipv6prefix;
+
+/**
* Notification context for sending replies to clients.
*/
static struct GNUNET_SERVER_NotificationContext *nc;
@@ -1116,8 +1120,43 @@
static int
allocate_v4_address (struct in_addr *v4)
{
- // FIXME: implement!
- return GNUNET_SYSERR;
+ const char *ipv4addr = vpn_argv[4];
+ const char *ipv4mask = vpn_argv[5];
+ struct in_addr addr;
+ struct in_addr mask;
+ struct in_addr rnd;
+ GNUNET_HashCode key;
+ unsigned int tries;
+
+ GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &addr));
+ GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &mask));
+ /* Given 192.168.0.1/255.255.0.0, we want a mask
+ of '192.168.255.255', thus: */
+ mask.s_addr = addr.s_addr | ~mask.s_addr;
+ tries = 0;
+ do
+ {
+ tries++;
+ if (tries > 16)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Failed to find unallocated IPv4 address in VPN's
range\n"));
+ return GNUNET_SYSERR;
+ }
+ /* Pick random IPv4 address within the subnet, except 'addr' or 'mask'
itself */
+ rnd.s_addr = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
+ UINT32_MAX);
+ v4->s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
+ get_destination_key_from_ip (AF_INET,
+ v4,
+ &key);
+ }
+ while ( (GNUNET_YES ==
+ GNUNET_CONTAINER_multihashmap_contains (destination_map,
+ &key)) ||
+ (v4->s_addr == addr.s_addr) ||
+ (v4->s_addr == mask.s_addr) );
+ return GNUNET_OK;
}
@@ -1130,10 +1169,57 @@
* GNUNET_SYSERR on error
*/
static int
-allocate_v6_address (struct in6_addr *v4)
+allocate_v6_address (struct in6_addr *v6)
{
- // FIXME: implement!
- return GNUNET_SYSERR;
+ const char *ipv6addr = vpn_argv[2];
+ struct in6_addr addr;
+ struct in6_addr mask;
+ struct in6_addr rnd;
+ int i;
+ GNUNET_HashCode key;
+ unsigned int tries;
+
+ GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr));
+ GNUNET_assert (ipv6prefix < 128);
+ /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
+ thus: */
+ mask = addr;
+ for (i=127;i>=128-ipv6prefix;i--)
+ mask.s6_addr[i / 8] |= (1 << (i % 8));
+
+ /* Pick random IPv6 address within the subnet, except 'addr' or 'mask'
itself */
+ tries = 0;
+ do
+ {
+ tries++;
+ if (tries > 16)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Failed to find unallocated IPv6 address in VPN's
range\n"));
+ return GNUNET_SYSERR;
+
+ }
+ for (i=0;i<16;i++)
+ {
+ rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32
(GNUNET_CRYPTO_QUALITY_WEAK,
+ 256);
+ v6->s6_addr[i]
+ = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
+ }
+ get_destination_key_from_ip (AF_INET6,
+ v6,
+ &key);
+ }
+ while ( (GNUNET_YES ==
+ GNUNET_CONTAINER_multihashmap_contains (destination_map,
+ &key)) ||
+ (0 == memcmp (v6,
+ &addr,
+ sizeof (struct in6_addr))) ||
+ (0 == memcmp (v6,
+ &mask,
+ sizeof (struct in6_addr))) );
+ return GNUNET_OK;
}
@@ -1640,7 +1726,6 @@
char *ipv4mask;
struct in_addr v4;
struct in6_addr v6;
- unsigned long long ipv6prefix;
cfg = cfg_;
if (GNUNET_OK !=
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r19063 - gnunet/src/vpn,
gnunet <=