#include "gnunet_statistics_service.h"
#include "gnunet_constants.h"
#include "gnunet_tun_lib.h"
+#include "gnunet_regex_lib.h"
#include "vpn.h"
#include "exit.h"
* Key under which this entry is in the 'destination_map' (only valid
* if 'heap_node != NULL').
*/
- GNUNET_HashCode key;
+ struct GNUNET_HashCode key;
/**
* Pre-allocated tunnel for this destination, or NULL for none.
/**
* The description of the service (only used for service tunnels).
*/
- GNUNET_HashCode service_descriptor;
+ struct GNUNET_HashCode service_descriptor;
/**
* Peer offering the service.
};
+/**
+ * Return value from 'main'.
+ */
+static int global_ret;
+
/**
* Configuration we use.
*/
static void
get_destination_key_from_ip (int af,
const void *address,
- GNUNET_HashCode *key)
+ struct GNUNET_HashCode *key)
{
switch (af)
{
uint16_t source_port,
const void *destination_ip,
uint16_t destination_port,
- GNUNET_HashCode *key)
+ struct GNUNET_HashCode *key)
{
char *off;
- memset (key, 0, sizeof (GNUNET_HashCode));
+ memset (key, 0, sizeof (struct GNUNET_HashCode));
/* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
so we put the ports in there (and hope for few collisions) */
off = (char*) key;
int result_af,
const void *addr)
{
- char buf[sizeof (struct RedirectToIpResponseMessage) + sizeof (struct in6_addr)];
+ char buf[sizeof (struct RedirectToIpResponseMessage) + sizeof (struct in6_addr)] GNUNET_ALIGN;
struct RedirectToIpResponseMessage *res;
size_t rlen;
static void
free_tunnel_state (struct TunnelState *ts)
{
- GNUNET_HashCode key;
+ struct GNUNET_HashCode key;
struct TunnelMessageQueueEntry *tnq;
struct GNUNET_MESH_Tunnel *tunnel;
* Destroy the mesh tunnel.
*
* @param cls the 'struct TunnelState' with the tunnel to destroy
- * @param ts schedule context
+ * @param tc scheduler context
*/
static void
destroy_tunnel_task (void *cls,
"Peer %s disconnected from tunnel.\n",
GNUNET_i2s (peer));
GNUNET_STATISTICS_update (stats,
- gettext_noop ("# Peers connected to mesh tunnels"),
+ gettext_noop ("# peers connected to mesh tunnels"),
-1, GNUNET_NO);
if (NULL != ts->th)
{
"Peer %s connected to tunnel.\n",
GNUNET_i2s (peer));
GNUNET_STATISTICS_update (stats,
- gettext_noop ("# Peers connected to mesh tunnels"),
+ gettext_noop ("# peers connected to mesh tunnels"),
1, GNUNET_NO);
if (NULL == ts->client)
return; /* nothing to do */
if (NULL != (tnq = ts->tmq_head))
ts->th = GNUNET_MESH_notify_transmit_ready (ts->tunnel,
GNUNET_NO /* cork */,
- 42 /* priority */,
GNUNET_TIME_UNIT_FOREVER_REL,
NULL,
tnq->len,
if (NULL == ts->th)
ts->th = GNUNET_MESH_notify_transmit_ready (ts->tunnel,
GNUNET_NO /* cork */,
- 42 /* priority */,
GNUNET_TIME_UNIT_FOREVER_REL,
NULL,
tnq->len,
*
* @param de destination entry for which we need to setup a tunnel
* @param client client to notify on successful tunnel setup, or NULL for none
+ * @param client_af address family of the address returned to the client
* @param request_id request ID to send in client notification (unused if client is NULL)
* @return tunnel state of the tunnel that was created
*/
}
else
{
+ char *policy;
+
switch (de->details.exit_destination.af)
{
case AF_INET:
- GNUNET_MESH_peer_request_connect_by_type (ts->tunnel,
- GNUNET_APPLICATION_TYPE_IPV4_GATEWAY);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Creating tunnel to exit peer for %s\n",
- "IPv4");
- break;
+ {
+ char address[GNUNET_REGEX_IPV4_REGEXLEN];
+ GNUNET_REGEX_ipv4toregex (&de->details.exit_destination.ip.v4,
+ "255.255.255.255", address);
+ GNUNET_asprintf (&policy, "%s%s%s",
+ GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX,
+ "4",
+ address);
+ break;
+ }
case AF_INET6:
- GNUNET_MESH_peer_request_connect_by_type (ts->tunnel,
- GNUNET_APPLICATION_TYPE_IPV6_GATEWAY);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Creating tunnel to exit peer for %s\n",
- "IPv6");
+ {
+ char address[GNUNET_REGEX_IPV6_REGEXLEN];
+ GNUNET_REGEX_ipv6toregex (&de->details.exit_destination.ip.v6,
+ 128, address);
+ GNUNET_asprintf (&policy, "%s%s%s",
+ GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX,
+ "6",
+ address);
break;
+ }
default:
GNUNET_assert (0);
break;
}
- }
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Requesting connect by string: %s\n", policy);
+
+ GNUNET_MESH_peer_request_connect_by_string (ts->tunnel, policy);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Creating tunnel to exit peer for policy `%s'\n",
+ policy);
+ GNUNET_free (policy);
+ }
return ts;
}
struct TunnelState *ts;
ts = GNUNET_CONTAINER_heap_peek (tunnel_heap);
+ GNUNET_assert (NULL != ts);
if (except == ts)
return; /* can't do this */
free_tunnel_state (ts);
*
* @param destination description of the destination
* @param af address family on this end (AF_INET or AF_INET6)
- * @param protocol IPPROTO_TCP or IPPROTO_UDP
+ * @param protocol IPPROTO_TCP or IPPROTO_UDP or IPPROTO_ICMP or IPPROTO_ICMPV6
* @param source_ip source IP used by the sender (struct in_addr or struct in6_addr)
* @param destination_ip destination IP used by the sender (struct in_addr or struct in6_addr)
* @param payload payload of the packet after the IP header
const void *payload,
size_t payload_length)
{
- GNUNET_HashCode key;
+ struct GNUNET_HashCode key;
struct TunnelState *ts;
struct TunnelMessageQueueEntry *tnq;
size_t alen;
const struct GNUNET_TUN_UdpHeader *udp;
const struct GNUNET_TUN_TcpHeader *tcp;
const struct GNUNET_TUN_IcmpHeader *icmp;
- uint16_t spt;
- uint16_t dpt;
+ uint16_t source_port;
+ uint16_t destination_port;
switch (protocol)
{
GNUNET_break (0);
return;
}
+ tcp = NULL; /* make compiler happy */
+ icmp = NULL; /* make compiler happy */
udp = payload;
- spt = ntohs (udp->spt);
- dpt = ntohs (udp->dpt);
+ if (udp->len < sizeof (struct GNUNET_TUN_UdpHeader))
+ {
+ GNUNET_break_op (0);
+ return;
+ }
+ source_port = ntohs (udp->source_port);
+ destination_port = ntohs (udp->destination_port);
get_tunnel_key_from_ips (af,
IPPROTO_UDP,
source_ip,
- spt,
+ source_port,
destination_ip,
- dpt,
+ destination_port,
&key);
}
break;
/* blame kernel? */
GNUNET_break (0);
return;
- }
+ }
+ udp = NULL; /* make compiler happy */
+ icmp = NULL; /* make compiler happy */
tcp = payload;
- spt = ntohs (tcp->spt);
- dpt = ntohs (tcp->dpt);
+ if (tcp->off * 4 < sizeof (struct GNUNET_TUN_TcpHeader))
+ {
+ GNUNET_break_op (0);
+ return;
+ }
+ source_port = ntohs (tcp->source_port);
+ destination_port = ntohs (tcp->destination_port);
get_tunnel_key_from_ips (af,
IPPROTO_TCP,
source_ip,
- spt,
+ source_port,
destination_ip,
- dpt,
+ destination_port,
&key);
}
break;
- case IPPROTO_ICMP:
+ case IPPROTO_ICMP:
+ case IPPROTO_ICMPV6:
{
+ if ( (AF_INET == af) ^ (protocol == IPPROTO_ICMP) )
+ {
+ GNUNET_break (0);
+ return;
+ }
if (payload_length < sizeof (struct GNUNET_TUN_IcmpHeader))
{
/* blame kernel? */
GNUNET_break (0);
return;
}
+ tcp = NULL; /* make compiler happy */
+ udp = NULL; /* make compiler happy */
icmp = payload;
- spt = 0;
- dpt = 0;
+ source_port = 0;
+ destination_port = 0;
get_tunnel_key_from_ips (af,
- IPPROTO_ICMP,
+ protocol,
source_ip,
0,
destination_ip,
"Routing %s packet from %s:%u -> %s:%u to destination %s:%u\n",
(protocol == IPPROTO_TCP) ? "TCP" : "UDP",
inet_ntop (af, source_ip, sbuf, sizeof (sbuf)),
- spt,
+ source_port,
inet_ntop (af, destination_ip, dbuf, sizeof (dbuf)),
- dpt,
+ destination_port,
inet_ntop (destination->details.exit_destination.af,
&destination->details.exit_destination.ip,
xbuf, sizeof (xbuf)),
- dpt);
+ destination_port);
}
}
else
"Routing %s packet from %s:%u -> %s:%u to service %s at peer %s\n",
(protocol == IPPROTO_TCP) ? "TCP" : "UDP",
inet_ntop (af, source_ip, sbuf, sizeof (sbuf)),
- spt,
+ source_port,
inet_ntop (af, destination_ip, dbuf, sizeof (dbuf)),
- dpt,
+ destination_port,
GNUNET_h2s (&destination->details.service_destination.service_descriptor),
GNUNET_i2s (&destination->details.service_destination.target));
}
ts->source_ip.v6 = * (const struct in6_addr *) source_ip;
ts->destination_ip.v6 = * (const struct in6_addr *) destination_ip;
}
- ts->source_port = spt;
- ts->destination_port = dpt;
+ ts->source_port = source_port;
+ ts->destination_port = destination_port;
ts->heap_node = GNUNET_CONTAINER_heap_insert (tunnel_heap,
ts,
GNUNET_TIME_absolute_get ().abs_value);
usm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE);
/* if the source port is below 32000, we assume it has a special
meaning; if not, we pick a random port (this is a heuristic) */
- usm->source_port = (ntohs (udp->spt) < 32000) ? udp->spt : 0;
- usm->destination_port = udp->dpt;
+ usm->source_port = (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
+ usm->destination_port = udp->destination_port;
usm->service_descriptor = destination->details.service_destination.service_descriptor;
memcpy (&usm[1],
&udp[1],
uim->header.size = htons ((uint16_t) mlen);
uim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET);
uim->af = htonl (destination->details.exit_destination.af);
- uim->source_port = (ntohs (udp->spt) < 32000) ? udp->spt : 0;
- uim->destination_port = udp->dpt;
+ uim->source_port = (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
+ uim->destination_port = udp->destination_port;
switch (destination->details.exit_destination.af)
{
case AF_INET:
}
break;
case IPPROTO_ICMP:
+ case IPPROTO_ICMPV6:
if (destination->is_service)
{
struct GNUNET_EXIT_IcmpServiceMessage *ism;
* @param client NULL
* @param message message we got from the client (VPN tunnel interface)
*/
-static void
+static int
message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
const struct GNUNET_MessageHeader *message)
{
const struct GNUNET_TUN_Layer2PacketHeader *tun;
size_t mlen;
- GNUNET_HashCode key;
+ struct GNUNET_HashCode key;
struct DestinationEntry *de;
GNUNET_STATISTICS_update (stats,
(mlen < sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader)) )
{
GNUNET_break (0);
- return;
+ return GNUNET_OK;
}
tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
mlen -= (sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader));
{
/* blame kernel */
GNUNET_break (0);
- return;
+ return GNUNET_OK;
}
pkt6 = (const struct GNUNET_TUN_IPv6Header *) &tun[1];
get_destination_key_from_ip (AF_INET6,
&pkt6->destination_address,
buf,
sizeof (buf)));
- return;
+ return GNUNET_OK;
}
route_packet (de,
AF_INET6,
{
/* blame kernel */
GNUNET_break (0);
- return;
+ return GNUNET_OK;
}
pkt4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
get_destination_key_from_ip (AF_INET,
&pkt4->destination_address,
buf,
sizeof (buf)));
- return;
+ return GNUNET_OK;
}
if (pkt4->header_length * 4 != sizeof (struct GNUNET_TUN_IPv4Header))
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
_("Received IPv4 packet with options (dropping it)\n"));
- return;
+ return GNUNET_OK;
}
route_packet (de,
AF_INET,
(unsigned int) ntohs (tun->proto));
break;
}
+ return GNUNET_OK;
}
sizeof (struct GNUNET_TUN_TcpHeader),
&ts->source_ip.v4,
&ts->destination_ip.v4);
- udp->spt = htons (ts->source_port);
- udp->dpt = htons (ts->destination_port);
+ udp->source_port = htons (ts->source_port);
+ udp->destination_port = htons (ts->destination_port);
udp->len = htons (0);
udp->crc = htons (0);
}
sizeof (struct GNUNET_TUN_TcpHeader),
&ts->source_ip.v6,
&ts->destination_ip.v6);
- udp->spt = htons (ts->source_port);
- udp->dpt = htons (ts->destination_port);
+ udp->source_port = htons (ts->source_port);
+ udp->destination_port = htons (ts->destination_port);
udp->len = htons (0);
udp->crc = htons (0);
}
{
/* reserve some extra space in case we have an ICMP type here where
we will need to make up the payload ourselves */
- char buf[size + sizeof (struct GNUNET_TUN_IPv4Header) + 8];
+ char buf[size + sizeof (struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN;
struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
mlen;
{
- char buf[size + sizeof (struct GNUNET_TUN_IPv6Header) + 8];
+ char buf[size + sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1];
tun->flags = htons (0);
tun->proto = htons (ETH_P_IPV6);
GNUNET_TUN_initialize_ipv6_header (ipv6,
- IPPROTO_ICMP,
+ IPPROTO_ICMPV6,
sizeof (struct GNUNET_TUN_IcmpHeader) + mlen,
&ts->destination_ip.v6,
&ts->source_ip.v6);
sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
mlen;
{
- char buf[size];
+ char buf[size] GNUNET_ALIGN;
struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
&ts->destination_ip.v4,
&ts->source_ip.v4);
if (0 == ntohs (reply->source_port))
- udp->spt = htons (ts->destination_port);
+ udp->source_port = htons (ts->destination_port);
else
- udp->spt = reply->source_port;
+ udp->source_port = reply->source_port;
if (0 == ntohs (reply->destination_port))
- udp->dpt = htons (ts->source_port);
+ udp->destination_port = htons (ts->source_port);
else
- udp->dpt = reply->destination_port;
+ udp->destination_port = reply->destination_port;
udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader));
GNUNET_TUN_calculate_udp4_checksum (ipv4,
udp,
sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
mlen;
{
- char buf[size];
+ char buf[size] GNUNET_ALIGN;
struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1];
&ts->destination_ip.v6,
&ts->source_ip.v6);
if (0 == ntohs (reply->source_port))
- udp->spt = htons (ts->destination_port);
+ udp->source_port = htons (ts->destination_port);
else
- udp->spt = reply->source_port;
+ udp->source_port = reply->source_port;
if (0 == ntohs (reply->destination_port))
- udp->dpt = htons (ts->source_port);
+ udp->destination_port = htons (ts->source_port);
else
- udp->dpt = reply->destination_port;
+ udp->destination_port = reply->destination_port;
udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader));
GNUNET_TUN_calculate_udp6_checksum (ipv6,
udp,
inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)),
ts->source_port);
}
+ if (data->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
switch (ts->af)
{
case AF_INET:
sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
mlen;
{
- char buf[size];
+ char buf[size] GNUNET_ALIGN;
struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
&ts->destination_ip.v4,
&ts->source_ip.v4);
*tcp = data->tcp_header;
- tcp->spt = htons (ts->destination_port);
- tcp->dpt = htons (ts->source_port);
+ tcp->source_port = htons (ts->destination_port);
+ tcp->destination_port = htons (ts->source_port);
GNUNET_TUN_calculate_tcp4_checksum (ipv4,
tcp,
&data[1],
sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
mlen;
{
- char buf[size];
+ char buf[size] GNUNET_ALIGN;
struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1];
sizeof (struct GNUNET_TUN_TcpHeader) + mlen,
&ts->destination_ip.v6,
&ts->source_ip.v6);
- tcp->spt = htons (ts->destination_port);
- tcp->dpt = htons (ts->source_port);
+ *tcp = data->tcp_header;
+ tcp->source_port = htons (ts->destination_port);
+ tcp->destination_port = htons (ts->source_port);
GNUNET_TUN_calculate_tcp6_checksum (ipv6,
tcp,
- &tcp[1],
+ &data[1],
mlen);
+ memcpy (&tcp[1],
+ &data[1],
+ mlen);
(void) GNUNET_HELPER_send (helper_handle,
msg,
GNUNET_YES,
struct in_addr addr;
struct in_addr mask;
struct in_addr rnd;
- GNUNET_HashCode key;
+ struct GNUNET_HashCode key;
unsigned int tries;
GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &addr));
struct in6_addr mask;
struct in6_addr rnd;
int i;
- GNUNET_HashCode key;
+ struct GNUNET_HashCode key;
unsigned int tries;
GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr));
/* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
thus: */
mask = addr;
- for (i=127;i>=128-ipv6prefix;i--)
+ for (i=127;i>=ipv6prefix;i--)
mask.s6_addr[i / 8] |= (1 << (i % 8));
/* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
struct DestinationEntry *de;
de = GNUNET_CONTAINER_heap_peek (destination_heap);
+ GNUNET_assert (NULL != de);
if (except == de)
return; /* can't do this */
free_destination_entry (de);
}
+/**
+ * Allocate an IP address for the response.
+ *
+ * @param result_af desired address family; set to the actual
+ * address family; can initially be AF_UNSPEC if there
+ * is no preference; will be set to AF_UNSPEC if the
+ * allocation failed
+ * @param addr set to either v4 or v6 depending on which
+ * storage location was used; set to NULL if allocation failed
+ * @param v4 storage space for an IPv4 address
+ * @param v6 storage space for an IPv6 address
+ * @return GNUNET_OK normally, GNUNET_SYSERR if '*result_af' was
+ * an unsupported address family (not AF_INET, AF_INET6 or AF_UNSPEC)
+ */
+static int
+allocate_response_ip (int *result_af,
+ void **addr,
+ struct in_addr *v4,
+ struct in6_addr *v6)
+{
+ *addr = NULL;
+ switch (*result_af)
+ {
+ case AF_INET:
+ if (GNUNET_OK !=
+ allocate_v4_address (v4))
+ *result_af = AF_UNSPEC;
+ else
+ *addr = v4;
+ break;
+ case AF_INET6:
+ if (GNUNET_OK !=
+ allocate_v6_address (v6))
+ *result_af = AF_UNSPEC;
+ else
+ *addr = v6;
+ break;
+ case AF_UNSPEC:
+ if (GNUNET_OK ==
+ allocate_v4_address (v4))
+ {
+ *addr = v4;
+ *result_af = AF_INET;
+ }
+ else if (GNUNET_OK ==
+ allocate_v6_address (v6))
+ {
+ *addr = v6;
+ *result_af = AF_INET6;
+ }
+ break;
+ default:
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
/**
* A client asks us to setup a redirection via some exit
* node to a particular IP. Setup the redirection and
struct in6_addr v6;
void *addr;
struct DestinationEntry *de;
- GNUNET_HashCode key;
+ struct GNUNET_HashCode key;
struct TunnelState *ts;
/* validate and parse request */
}
/* allocate response IP */
- addr = NULL;
result_af = (int) htonl (msg->result_af);
- switch (result_af)
+ if (GNUNET_OK != allocate_response_ip (&result_af,
+ &addr,
+ &v4, &v6))
{
- case AF_INET:
- if (GNUNET_OK !=
- allocate_v4_address (&v4))
- result_af = AF_UNSPEC;
- else
- addr = &v4;
- break;
- case AF_INET6:
- if (GNUNET_OK !=
- allocate_v6_address (&v6))
- result_af = AF_UNSPEC;
- else
- addr = &v6;
- break;
- case AF_UNSPEC:
- if (GNUNET_OK ==
- allocate_v4_address (&v4))
- {
- addr = &v4;
- result_af = AF_INET;
- }
- else if (GNUNET_OK ==
- allocate_v6_address (&v6))
- {
- addr = &v6;
- result_af = AF_INET6;
- }
- break;
- default:
- GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
struct in6_addr v6;
void *addr;
struct DestinationEntry *de;
- GNUNET_HashCode key;
+ struct GNUNET_HashCode key;
struct TunnelState *ts;
/* parse request */
msg = (const struct RedirectToServiceRequestMessage *) message;
/* allocate response IP */
- addr = NULL;
result_af = (int) htonl (msg->result_af);
- switch (result_af)
+ if (GNUNET_OK != allocate_response_ip (&result_af,
+ &addr,
+ &v4, &v6))
{
- case AF_INET:
- if (GNUNET_OK !=
- allocate_v4_address (&v4))
- result_af = AF_UNSPEC;
- else
- addr = &v4;
- break;
- case AF_INET6:
- if (GNUNET_OK !=
- allocate_v6_address (&v6))
- result_af = AF_UNSPEC;
- else
- addr = &v6;
- break;
- case AF_UNSPEC:
- if (GNUNET_OK ==
- allocate_v4_address (&v4))
- {
- addr = &v4;
- result_af = AF_INET;
- }
- else if (GNUNET_OK ==
- allocate_v6_address (&v6))
- {
- addr = &v6;
- result_af = AF_INET6;
- }
- break;
- default:
- GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
*/
static int
cleanup_destination (void *cls,
- const GNUNET_HashCode *key,
+ const struct GNUNET_HashCode *key,
void *value)
{
struct DestinationEntry *de = value;
*/
static int
cleanup_tunnel (void *cls,
- const GNUNET_HashCode *key,
+ const struct GNUNET_HashCode *key,
void *value)
{
struct TunnelState *ts = value;
}
if (stats != NULL)
{
- GNUNET_STATISTICS_destroy (stats, GNUNET_YES);
+ GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
stats = NULL;
}
for (i=0;i<5;i++)
*/
static int
cleanup_tunnel_client (void *cls,
- const GNUNET_HashCode *key,
+ const struct GNUNET_HashCode *key,
void *value)
{
struct GNUNET_SERVER_Client *client = cls;
*/
static int
cleanup_destination_client (void *cls,
- const GNUNET_HashCode *key,
+ const struct GNUNET_HashCode *key,
void *value)
{
struct GNUNET_SERVER_Client *client = cls;
char *ipv4mask;
struct in_addr v4;
struct in6_addr v6;
+ char *binary;
+ binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-vpn");
+
+ if (GNUNET_YES !=
+ GNUNET_OS_check_helper_binary (binary))
+ {
+ fprintf (stderr,
+ "`%s' is not SUID, refusing to run.\n",
+ "gnunet-helper-vpn");
+ GNUNET_free (binary);
+ global_ret = 1;
+ return;
+ }
+ GNUNET_free (binary);
cfg = cfg_;
stats = GNUNET_STATISTICS_create ("vpn", cfg);
if (GNUNET_OK !=
&max_tunnel_mappings))
max_tunnel_mappings = 200;
- destination_map = GNUNET_CONTAINER_multihashmap_create (max_destination_mappings * 2);
+ destination_map = GNUNET_CONTAINER_multihashmap_create (max_destination_mappings * 2, GNUNET_NO);
destination_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
- tunnel_map = GNUNET_CONTAINER_multihashmap_create (max_tunnel_mappings * 2);
+ tunnel_map = GNUNET_CONTAINER_multihashmap_create (max_tunnel_mappings * 2, GNUNET_NO);
tunnel_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
return;
}
vpn_argv[1] = ifname;
- if ( (GNUNET_SYSERR ==
- GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR",
- &ipv6addr) ||
- (1 != inet_pton (AF_INET6, ipv6addr, &v6))) )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "No valid entry 'IPV6ADDR' in configuration!\n");
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- vpn_argv[2] = ipv6addr;
- if (GNUNET_SYSERR ==
- GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6PREFIX",
- &ipv6prefix_s))
+ if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET6))
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "No entry 'IPV6PREFIX' in configuration!\n");
- GNUNET_SCHEDULER_shutdown ();
- return;
+ if ( (GNUNET_SYSERR ==
+ GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR",
+ &ipv6addr) ||
+ (1 != inet_pton (AF_INET6, ipv6addr, &v6))) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No valid entry 'IPV6ADDR' in configuration!\n");
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ vpn_argv[2] = ipv6addr;
+ if (GNUNET_SYSERR ==
+ GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6PREFIX",
+ &ipv6prefix_s))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No entry 'IPV6PREFIX' in configuration!\n");
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ vpn_argv[3] = ipv6prefix_s;
+ if ( (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_number (cfg, "vpn",
+ "IPV6PREFIX",
+ &ipv6prefix)) ||
+ (ipv6prefix >= 127) )
+ {
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
}
- vpn_argv[3] = ipv6prefix_s;
- if ( (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (cfg, "vpn",
- "IPV6PREFIX",
- &ipv6prefix)) ||
- (ipv6prefix >= 127) )
+ else
{
- GNUNET_SCHEDULER_shutdown ();
- return;
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ _("IPv6 support disabled as this system does not support IPv6\n"));
+ vpn_argv[2] = GNUNET_strdup ("-");
+ vpn_argv[3] = GNUNET_strdup ("-");
}
-
- if ( (GNUNET_SYSERR ==
- GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR",
- &ipv4addr) ||
- (1 != inet_pton (AF_INET, ipv4addr, &v4))) )
+ if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET))
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "No valid entry for 'IPV4ADDR' in configuration!\n");
- GNUNET_SCHEDULER_shutdown ();
- return;
+ if ( (GNUNET_SYSERR ==
+ GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR",
+ &ipv4addr) ||
+ (1 != inet_pton (AF_INET, ipv4addr, &v4))) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No valid entry for 'IPV4ADDR' in configuration!\n");
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ vpn_argv[4] = ipv4addr;
+ if ( (GNUNET_SYSERR ==
+ GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK",
+ &ipv4mask) ||
+ (1 != inet_pton (AF_INET, ipv4mask, &v4))) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No valid entry 'IPV4MASK' in configuration!\n");
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ vpn_argv[5] = ipv4mask;
}
- vpn_argv[4] = ipv4addr;
- if ( (GNUNET_SYSERR ==
- GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK",
- &ipv4mask) ||
- (1 != inet_pton (AF_INET, ipv4mask, &v4))) )
+ else
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "No valid entry 'IPV4MASK' in configuration!\n");
- GNUNET_SCHEDULER_shutdown ();
- return;
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ _("IPv4 support disabled as this system does not support IPv4\n"));
+ vpn_argv[4] = GNUNET_strdup ("-");
+ vpn_argv[5] = GNUNET_strdup ("-");
}
- vpn_argv[5] = ipv4mask;
vpn_argv[6] = NULL;
mesh_handle =
- GNUNET_MESH_connect (cfg_, 42 /* queue length */, NULL,
+ GNUNET_MESH_connect (cfg_, NULL,
&inbound_tunnel_cb,
&tunnel_cleaner,
mesh_handlers,
types);
- helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", vpn_argv,
- &message_token, NULL);
+ helper_handle = GNUNET_HELPER_start (GNUNET_NO,
+ "gnunet-helper-vpn", vpn_argv,
+ &message_token, NULL, NULL);
nc = GNUNET_SERVER_notification_context_create (server, 1);
GNUNET_SERVER_add_handlers (server, service_handlers);
GNUNET_SERVER_disconnect_notify (server, &client_disconnect, NULL);
return (GNUNET_OK ==
GNUNET_SERVICE_run (argc, argv, "vpn",
GNUNET_SERVICE_OPTION_NONE,
- &run, NULL)) ? 0 : 1;
+ &run, NULL)) ? global_ret : 1;
}
/* end of gnunet-service-vpn.c */