From 6610dea80399451f4eae448c001bf8e425d6e5ab Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 7 Jan 2012 19:26:53 +0000 Subject: [PATCH] -defining IPC messages for VPN --- src/vpn/gnunet-service-vpn.c | 113 +++++++++++++++++++++++++--------- src/vpn/vpn.h | 115 +++++++++++++++++++++++++++++++++++ src/vpn/vpn_api.c | 15 +++-- 3 files changed, 211 insertions(+), 32 deletions(-) diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index 8f0236846..e736b7746 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c @@ -44,13 +44,14 @@ #include "gnunet_mesh_service.h" #include "gnunet_constants.h" #include "tcpip_tun.h" +#include "vpn.h" /** * Information we track for each IP address to determine which tunnel * to send the traffic over to the destination. */ -struct destination_entry +struct DestinationEntry { /** * Information about the tunnel to use, NULL if no tunnel @@ -108,17 +109,17 @@ struct destination_entry /** * A messages we have in queue for a particular tunnel. */ -struct tunnel_notify_queue +struct TunnelMessageQueueEntry { /** * This is a doubly-linked list. */ - struct tunnel_notify_queue *next; + struct TunnelMessageQueueEntry *next; /** * This is a doubly-linked list. */ - struct tunnel_notify_queue *prev; + struct TunnelMessageQueueEntry *prev; /** * Number of bytes in 'msg'. @@ -135,7 +136,7 @@ struct tunnel_notify_queue /** * State we keep for each of our tunnels. */ -struct tunnel_state +struct TunnelState { /** * Active transmission handle, NULL for none. @@ -150,12 +151,12 @@ struct tunnel_state /** * Head of list of messages scheduled for transmission. */ - struct tunnel_notify_queue *head; + struct TunnelMessageQueueEntry *head; /** * Tail of list of messages scheduled for transmission. */ - struct tunnel_notify_queue *tail; + struct TunnelMessageQueueEntry *tail; /** * Destination to which this tunnel leads. Note that @@ -163,7 +164,7 @@ struct tunnel_state * local copy) and that the 'heap_node' should always * be NULL. */ - struct destination_entry destination; + struct DestinationEntry destination; /** * GNUNET_NO if this is a tunnel to an Internet-exit, @@ -362,7 +363,7 @@ get_tunnel_key_from_ips (int af, /** * Send a message from the message queue via mesh. * - * @param cls the 'struct tunnel_state' with the message queue + * @param cls the 'struct TunnelState' with the message queue * @param size number of bytes available in buf * @param buf where to copy the message * @return number of bytes copied to buf @@ -370,8 +371,8 @@ get_tunnel_key_from_ips (int af, static size_t send_to_peer_notify_callback (void *cls, size_t size, void *buf) { - struct tunnel_state *ts = cls; - struct tunnel_notify_queue *tnq; + struct TunnelState *ts = cls; + struct TunnelMessageQueueEntry *tnq; size_t ret; ts->th = NULL; @@ -407,8 +408,8 @@ send_to_peer_notify_callback (void *cls, size_t size, void *buf) * @param ts tunnel to queue the message for */ static void -send_to_tunnel (struct tunnel_notify_queue *tnq, - struct tunnel_state *ts) +send_to_tunnel (struct TunnelMessageQueueEntry *tnq, + struct TunnelState *ts) { GNUNET_CONTAINER_DLL_insert_tail (ts->head, ts->tail, @@ -437,7 +438,7 @@ send_to_tunnel (struct tunnel_notify_queue *tnq, * @param payload_length number of bytes in payload */ static void -route_packet (struct destination_entry *destination, +route_packet (struct DestinationEntry *destination, int af, uint8_t protocol, const void *source_ip, @@ -446,8 +447,8 @@ route_packet (struct destination_entry *destination, size_t payload_length) { GNUNET_HashCode key; - struct tunnel_state *ts; - struct tunnel_notify_queue *tnq; + struct TunnelState *ts; + struct TunnelMessageQueueEntry *tnq; switch (protocol) { @@ -524,24 +525,24 @@ route_packet (struct destination_entry *destination, case IPPROTO_UDP: if (destination->is_service) { - tnq = GNUNET_malloc (sizeof (struct tunnel_notify_queue) + 42); + tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + 42); // FIXME: build message! } else { - tnq = GNUNET_malloc (sizeof (struct tunnel_notify_queue) + 42); + tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + 42); // FIXME: build message! } break; case IPPROTO_TCP: if (destination->is_service) { - tnq = GNUNET_malloc (sizeof (struct tunnel_notify_queue) + 42); + tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + 42); // FIXME: build message! } else { - tnq = GNUNET_malloc (sizeof (struct tunnel_notify_queue) + 42); + tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + 42); // FIXME: build message! } break; @@ -572,7 +573,7 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, const struct tun_header *tun; size_t mlen; GNUNET_HashCode key; - struct destination_entry *de; + struct DestinationEntry *de; mlen = ntohs (message->size); if ( (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) || @@ -699,7 +700,7 @@ receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, struct remote_addr *s = (struct remote_addr *) desc; struct udp_pkt *pkt = (struct udp_pkt *) (desc + 1); const struct GNUNET_PeerIdentity *other = sender; - struct tunnel_state *ts = *tunnel_ctx; + struct TunnelState *ts = *tunnel_ctx; if (16 == ts->addrlen) { @@ -887,7 +888,7 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, struct remote_addr *s = (struct remote_addr *) desc; struct tcp_pkt *pkt = (struct tcp_pkt *) (desc + 1); const struct GNUNET_PeerIdentity *other = sender; - struct tunnel_state *ts = *tunnel_ctx; + struct TunnelState *ts = *tunnel_ctx; size_t pktlen = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) - @@ -1064,6 +1065,41 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, } +/** + * A client asks us to setup a redirection via some exit + * node to a particular IP. Setup the redirection and + * give the client the allocated IP. + * + * @param cls unused + * @param client requesting client + * @param message redirection request (a 'struct RedirectToIpRequestMessage') + */ +static void +service_redirect_to_ip (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); +} + + +/** + * A client asks us to setup a redirection to a particular peer + * offering a service. Setup the redirection and give the client the + * allocated IP. + * + * @param cls unused + * @param client requesting client + * @param message redirection request (a 'struct RedirectToPeerRequestMessage') + */ +static void +service_redirect_to_service (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); +} + + + /** * FIXME: document. */ @@ -1115,6 +1151,20 @@ cleanup (void *cls GNUNET_UNUSED, } +/** + * A client has disconnected from us. If we are currently building + * a tunnel for it, cancel the operation. + * + * @param cls unused + * @param client handle to the client that disconnected + */ +static void +client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) +{ + // FIXME +} + + /** * Main function that will be run by the scheduler. * @@ -1127,7 +1177,15 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *cfg_) { - static const struct GNUNET_MESH_MessageHandler handlers[] = { + static const struct GNUNET_SERVER_MessageHandler service_handlers[] = { + /* callback, cls, type, size */ + {&service_redirect_to_ip, NULL, GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP, 0}, + {&service_redirect_to_service, NULL, + GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE, + sizeof (struct RedirectToServiceRequestMessage) }, + {NULL, NULL, 0, 0} + }; + static const struct GNUNET_MESH_MessageHandler mesh_handlers[] = { {receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP_BACK, 0}, {receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP_BACK, 0}, {receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP_BACK, 0}, @@ -1231,13 +1289,12 @@ run (void *cls, GNUNET_MESH_connect (cfg_, 42 /* queue length */, NULL, &new_tunnel, &tunnel_cleaner, - handlers, + mesh_handlers, types); - // FIXME: register service handlers to allow destination mappings to - // be created! - helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", vpn_argv, &message_token, NULL); + GNUNET_SERVER_add_handlers (server, service_handlers); + GNUNET_SERVER_disconnect_notify (server, &client_disconnect, NULL); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls); } diff --git a/src/vpn/vpn.h b/src/vpn/vpn.h index da7fa6eb8..90bcdaa61 100644 --- a/src/vpn/vpn.h +++ b/src/vpn/vpn.h @@ -28,8 +28,123 @@ #include "gnunet_util_lib.h" +/** + * Message send by the VPN client to the VPN service requesting + * the setup of a redirection from some IP via an exit node to + * some global Internet address. + */ +struct RedirectToIpRequestMessage +{ + /** + * Type is GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP + */ + struct GNUNET_MessageHeader header; + + /** + * GNUNET_YES to notify only after completion of the mesh-level connection, + * GNUNET_NO to notify as soon as an address was allocated (in nbo). + */ + int32_t nac; + + /** + * How long should the redirection be maintained at most? + */ + struct GNUNET_TIME_AbsoluteNBO expiration_time; + + /** + * Address family desired for the result (AF_INET or AF_INET6 or AF_UNSPEC, in nbo) + */ + int32_t result_af; + + /** + * Address family used for the destination address (AF_INET or AF_INET6, in nbo) + */ + int32_t addr_af; + + /** + * Unique ID to match a future response to this request. + * Picked by the client. + */ + uint64_t request_id; + + /* followed by destination address ('struct in_addr' or 'struct in6_addr') */ + +}; + + +/** + * Message send by the VPN client to the VPN service requesting + * the setup of a redirection from some IP to a service running + * at a particular peer. + */ +struct RedirectToServiceRequestMessage +{ + /** + * Type is GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP + */ + struct GNUNET_MessageHeader header; + + /** + * GNUNET_YES to notify only after completion of the mesh-level connection, + * GNUNET_NO to notify as soon as an address was allocated (in nbo). + */ + int32_t nac; + + /** + * How long should the redirection be maintained at most? + */ + struct GNUNET_TIME_AbsoluteNBO expiration_time; + + /** + * Desired protocol (IPPROTO_UDP or IPPROTO_TCP) + */ + int32_t protocol; + + /** + * Address family desired for the result (AF_INET or AF_INET6 or AF_UNSPEC, in nbo) + */ + int32_t result_af; + + /** + * Target peer offering the service. + */ + struct GNUNET_PeerIdentity target; + + /** + * Service descriptor identifying the service. + */ + struct GNUNET_PeerIdentity desc; + + /** + * Unique ID to match a future response to this request. + * Picked by the client. + */ + uint64_t request_id; + +}; + + +/** + * Response from the VPN service to a VPN client informing about + * the IP that was assigned for the requested redirection. + */ +struct RedirectToIpResponseMessage +{ + + /** + * Type is GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP + */ + struct GNUNET_MessageHeader header; + /** + * Address family of the allocated address that follows; will match + * "result_af" from the request, of be "AF_UNSPEC" on errors. + */ + int32_t result_af; + /* followed by destination address ('struct in_addr' or 'struct in6_addr') */ + +}; #endif diff --git a/src/vpn/vpn_api.c b/src/vpn/vpn_api.c index 5c351a190..b6fab37bf 100644 --- a/src/vpn/vpn_api.c +++ b/src/vpn/vpn_api.c @@ -107,9 +107,14 @@ struct GNUNET_VPN_RedirectionRequest struct GNUNET_TIME_Absolute expiration_time; /** - * AF_INET or AF_INET6. + * Desired address family for the result. */ - int af; + int result_af; + + /** + * Address family of 'addr'. AF_INET or AF_INET6. + */ + int addr_af; /** * GNUNET_YES if we are to call the callback only after successful @@ -192,7 +197,8 @@ GNUNET_VPN_redirect_to_peer (struct GNUNET_VPN_Handle *rh, * limitations, the longest inactive mappings will be destroyed. * * @param vh VPN handle - * @param af address family, AF_INET or AF_INET6 + * @param result_af desired address family for the returned allocation + * @param addr_af address family for 'addr', AF_INET or AF_INET6 * @param addr destination IP address on the Internet; destination * port is to be taken from the VPN packet itself * @param nac GNUNET_YES to notify via callback only after completion of @@ -208,7 +214,8 @@ GNUNET_VPN_redirect_to_peer (struct GNUNET_VPN_Handle *rh, */ struct GNUNET_VPN_RedirectionRequest * GNUNET_VPN_redirect_to_ip (struct GNUNET_VPN_Handle *rh, - int af, + int result_af, + int addr_af, const void *addr, int nac, struct GNUNET_TIME_Absolute expiration_time, -- 2.25.1