* IP traffic received on those IPs via the GNUnet mesh
* @author Philipp Toelke
* @author Christian Grothoff
- *
- * TODO:
- * Basics:
- * - test!
- *
- * Features:
- * - add back ICMP support (especially needed for IPv6)
*/
#include "platform.h"
#include "gnunet_util_lib.h"
};
+/**
+ * Return value from 'main'.
+ */
+static int global_ret;
+
/**
* Configuration we use.
*/
* 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,
GNUNET_CONTAINER_DLL_remove (ts->tmq_head,
ts->tmq_tail,
dq);
+ ts->tmq_length--;
GNUNET_MESH_notify_transmit_ready_cancel (ts->th);
ts->th = NULL;
GNUNET_STATISTICS_update (stats,
*
* @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
*/
static struct TunnelState *
create_tunnel_to_destination (struct DestinationEntry *de,
struct GNUNET_SERVER_Client *client,
+ int client_af,
uint64_t request_id)
{
struct TunnelState *ts;
1, GNUNET_NO);
GNUNET_assert (NULL == de->ts);
ts = GNUNET_malloc (sizeof (struct TunnelState));
+ ts->af = client_af;
if (NULL != client)
{
ts->request_id = request_id;
ts->destination.heap_node = NULL; /* copy is NOT in destination heap */
de->ts = ts;
ts->destination_container = de; /* we are referenced from de */
- ts->af = AF_UNSPEC; /* so far, unknown */
ts->tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
ts,
&tunnel_peer_connect_handler,
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);
available) or create a fresh one */
is_new = GNUNET_YES;
if (NULL == destination->ts)
- ts = create_tunnel_to_destination (destination, NULL, 0);
+ ts = create_tunnel_to_destination (destination, NULL, af, 0);
else
ts = destination->ts;
if (NULL == ts)
struct GNUNET_TUN_IPv4Header *ipp,
struct GNUNET_TUN_UdpHeader *udp)
{
- /* FIXME */
- GNUNET_break (0);
+ GNUNET_TUN_initialize_ipv4_header (ipp,
+ ts->protocol,
+ 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->len = htons (0);
+ udp->crc = htons (0);
}
struct GNUNET_TUN_IPv6Header *ipp,
struct GNUNET_TUN_UdpHeader *udp)
{
- /* FIXME */
- GNUNET_break (0);
+ GNUNET_TUN_initialize_ipv6_header (ipp,
+ ts->protocol,
+ 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->len = htons (0);
+ udp->crc = htons (0);
}
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);
void *addr;
struct DestinationEntry *de;
GNUNET_HashCode key;
+ struct TunnelState *ts;
/* validate and parse request */
mlen = ntohs (message->size);
1, GNUNET_NO);
while (GNUNET_CONTAINER_multihashmap_size (destination_map) > max_destination_mappings)
expire_destination (de);
-
+
/* setup tunnel to destination */
- (void) create_tunnel_to_destination (de,
- (GNUNET_NO == ntohl (msg->nac)) ? NULL : client,
- msg->request_id);
+ ts = create_tunnel_to_destination (de,
+ (GNUNET_NO == ntohl (msg->nac)) ? NULL : client,
+ result_af,
+ msg->request_id);
+ switch (result_af)
+ {
+ case AF_INET:
+ ts->destination_ip.v4 = v4;
+ break;
+ case AF_INET6:
+ ts->destination_ip.v6 = v6;
+ break;
+ default:
+ GNUNET_assert (0);
+ }
/* we're done */
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
void *addr;
struct DestinationEntry *de;
GNUNET_HashCode key;
+ struct TunnelState *ts;
/* parse request */
msg = (const struct RedirectToServiceRequestMessage *) message;
GNUNET_TIME_absolute_ntoh (msg->expiration_time).abs_value);
while (GNUNET_CONTAINER_multihashmap_size (destination_map) > max_destination_mappings)
expire_destination (de);
- (void) create_tunnel_to_destination (de,
- (GNUNET_NO == ntohl (msg->nac)) ? NULL : client,
- msg->request_id);
+ ts = create_tunnel_to_destination (de,
+ (GNUNET_NO == ntohl (msg->nac)) ? NULL : client,
+ result_af,
+ msg->request_id);
+ switch (result_af)
+ {
+ case AF_INET:
+ ts->destination_ip.v4 = v4;
+ break;
+ case AF_INET6:
+ ts->destination_ip.v6 = v6;
+ break;
+ default:
+ GNUNET_assert (0);
+ }
/* we're done */
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
}
if (stats != NULL)
{
- GNUNET_STATISTICS_destroy (stats, GNUNET_YES);
+ GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
stats = NULL;
}
for (i=0;i<5;i++)
struct in_addr v4;
struct in6_addr v6;
+ if (GNUNET_YES !=
+ GNUNET_OS_check_helper_binary ("gnunet-helper-vpn"))
+ {
+ fprintf (stderr,
+ "`%s' is not SUID, refusing to run.\n",
+ "gnunet-helper-vpn");
+ global_ret = 1;
+ return;
+ }
cfg = cfg_;
stats = GNUNET_STATISTICS_create ("vpn", cfg);
if (GNUNET_OK !=
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 */