X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=inline;f=src%2Fvpn%2Fgnunet-service-vpn.c;h=796a4a6e109e0eaa0ef701f5b91768a40a0542c4;hb=dd61bcd68f58de56d7e0d5e8773017af1cebd966;hp=12b4eef4a776317b0376cce0b48ceb57fc9e54b1;hpb=b53c68458d1b7daa7a4320adb401daac62c4daed;p=oweals%2Fgnunet.git diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index 12b4eef4a..796a4a6e1 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c @@ -25,13 +25,6 @@ * 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" @@ -291,6 +284,11 @@ struct TunnelState }; +/** + * Return value from 'main'. + */ +static int global_ret; + /** * Configuration we use. */ @@ -572,7 +570,7 @@ free_tunnel_state (struct TunnelState *ts) * 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, @@ -732,6 +730,7 @@ send_to_tunnel (struct TunnelMessageQueueEntry *tnq, 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, @@ -757,12 +756,14 @@ send_to_tunnel (struct TunnelMessageQueueEntry *tnq, * * @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; @@ -772,6 +773,7 @@ create_tunnel_to_destination (struct DestinationEntry *de, 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; @@ -782,7 +784,6 @@ create_tunnel_to_destination (struct DestinationEntry *de, 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, @@ -844,6 +845,7 @@ expire_tunnel (struct TunnelState *except) 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); @@ -1013,7 +1015,7 @@ route_packet (struct DestinationEntry *destination, 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) @@ -1613,8 +1615,15 @@ make_up_icmpv4_payload (struct TunnelState *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); } @@ -1632,8 +1641,15 @@ make_up_icmpv6_payload (struct TunnelState *ts, 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); } @@ -2427,6 +2443,7 @@ expire_destination (struct DestinationEntry *except) 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); @@ -2456,6 +2473,7 @@ service_redirect_to_ip (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Client *cl void *addr; struct DestinationEntry *de; GNUNET_HashCode key; + struct TunnelState *ts; /* validate and parse request */ mlen = ntohs (message->size); @@ -2581,11 +2599,23 @@ service_redirect_to_ip (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Client *cl 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); } @@ -2611,6 +2641,7 @@ service_redirect_to_service (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Clien void *addr; struct DestinationEntry *de; GNUNET_HashCode key; + struct TunnelState *ts; /* parse request */ msg = (const struct RedirectToServiceRequestMessage *) message; @@ -2700,9 +2731,21 @@ service_redirect_to_service (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Clien 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); } @@ -2845,7 +2888,7 @@ cleanup (void *cls GNUNET_UNUSED, } if (stats != NULL) { - GNUNET_STATISTICS_destroy (stats, GNUNET_YES); + GNUNET_STATISTICS_destroy (stats, GNUNET_NO); stats = NULL; } for (i=0;i<5;i++) @@ -2964,6 +3007,15 @@ run (void *cls, 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 != @@ -3074,7 +3126,7 @@ main (int argc, char *const *argv) 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 */