aboutsummaryrefslogtreecommitdiff
path: root/src/vpn
diff options
context:
space:
mode:
Diffstat (limited to 'src/vpn')
-rw-r--r--src/vpn/gnunet-service-vpn.c222
1 files changed, 120 insertions, 102 deletions
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c
index d18530dab..4c0978d5c 100644
--- a/src/vpn/gnunet-service-vpn.c
+++ b/src/vpn/gnunet-service-vpn.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2010, 2011, 2012 Christian Grothoff 3 Copyright (C) 2010, 2011, 2012, 2016 Christian Grothoff
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -377,11 +377,6 @@ static char *vpn_argv[7];
377static unsigned long long ipv6prefix; 377static unsigned long long ipv6prefix;
378 378
379/** 379/**
380 * Notification context for sending replies to clients.
381 */
382static struct GNUNET_SERVER_NotificationContext *nc;
383
384/**
385 * If there are more than this number of address-mappings, old ones 380 * If there are more than this number of address-mappings, old ones
386 * will be removed 381 * will be removed
387 */ 382 */
@@ -489,12 +484,12 @@ get_channel_key_from_ips (int af,
489 * @param addr resulting IP address 484 * @param addr resulting IP address
490 */ 485 */
491static void 486static void
492send_client_reply (struct GNUNET_SERVER_Client *client, 487send_client_reply (struct GNUNET_SERVICE_Client *client,
493 uint64_t request_id, 488 uint64_t request_id,
494 int result_af, 489 int result_af,
495 const void *addr) 490 const void *addr)
496{ 491{
497 char buf[sizeof (struct RedirectToIpResponseMessage) + sizeof (struct in6_addr)] GNUNET_ALIGN; 492 struct GNUNET_MQ_Envelope *env;
498 struct RedirectToIpResponseMessage *res; 493 struct RedirectToIpResponseMessage *res;
499 size_t rlen; 494 size_t rlen;
500 495
@@ -513,19 +508,16 @@ send_client_reply (struct GNUNET_SERVER_Client *client,
513 GNUNET_assert (0); 508 GNUNET_assert (0);
514 return; 509 return;
515 } 510 }
516 res = (struct RedirectToIpResponseMessage *) buf; 511 env = GNUNET_MQ_msg_extra (res,
517 res->header.size = htons (sizeof (struct RedirectToIpResponseMessage) + rlen); 512 rlen,
518 res->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP); 513 GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP);
519 res->result_af = htonl (result_af); 514 res->result_af = htonl (result_af);
520 res->request_id = request_id; 515 res->request_id = request_id;
521 GNUNET_memcpy (&res[1], 516 GNUNET_memcpy (&res[1],
522 addr, 517 addr,
523 rlen); 518 rlen);
524 GNUNET_SERVER_notification_context_add (nc, client); 519 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
525 GNUNET_SERVER_notification_context_unicast (nc, 520 env);
526 client,
527 &res->header,
528 GNUNET_NO);
529} 521}
530 522
531 523
@@ -2606,39 +2598,21 @@ allocate_response_ip (int *result_af,
2606 2598
2607/** 2599/**
2608 * A client asks us to setup a redirection via some exit node to a 2600 * A client asks us to setup a redirection via some exit node to a
2609 * particular IP. Setup the redirection and give the client the 2601 * particular IP. Check if @a msg is well-formed.
2610 * allocated IP. 2602 * allocated IP.
2611 * 2603 *
2612 * @param cls unused 2604 * @param cls client requesting client
2613 * @param client requesting client 2605 * @param msg redirection request
2614 * @param message redirection request (a `struct RedirectToIpRequestMessage`) 2606 * @return #GNUNET_OK if @a msg is well-formed
2615 */ 2607 */
2616static void 2608static int
2617service_redirect_to_ip (void *cls, 2609check_client_redirect_to_ip (void *cls,
2618 struct GNUNET_SERVER_Client *client, 2610 const struct RedirectToIpRequestMessage *msg)
2619 const struct GNUNET_MessageHeader *message)
2620{ 2611{
2621 size_t mlen;
2622 size_t alen; 2612 size_t alen;
2623 const struct RedirectToIpRequestMessage *msg;
2624 int addr_af; 2613 int addr_af;
2625 int result_af;
2626 struct in_addr v4;
2627 struct in6_addr v6;
2628 void *addr;
2629 struct DestinationEntry *de;
2630 struct GNUNET_HashCode key;
2631 2614
2632 /* validate and parse request */ 2615 alen = ntohs (msg->header.size) - sizeof (struct RedirectToIpRequestMessage);
2633 mlen = ntohs (message->size);
2634 if (mlen < sizeof (struct RedirectToIpRequestMessage))
2635 {
2636 GNUNET_break (0);
2637 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2638 return;
2639 }
2640 alen = mlen - sizeof (struct RedirectToIpRequestMessage);
2641 msg = (const struct RedirectToIpRequestMessage *) message;
2642 addr_af = (int) htonl (msg->addr_af); 2616 addr_af = (int) htonl (msg->addr_af);
2643 switch (addr_af) 2617 switch (addr_af)
2644 { 2618 {
@@ -2646,31 +2620,55 @@ service_redirect_to_ip (void *cls,
2646 if (alen != sizeof (struct in_addr)) 2620 if (alen != sizeof (struct in_addr))
2647 { 2621 {
2648 GNUNET_break (0); 2622 GNUNET_break (0);
2649 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 2623 return GNUNET_SYSERR;
2650 return;
2651 } 2624 }
2652 break; 2625 break;
2653 case AF_INET6: 2626 case AF_INET6:
2654 if (alen != sizeof (struct in6_addr)) 2627 if (alen != sizeof (struct in6_addr))
2655 { 2628 {
2656 GNUNET_break (0); 2629 GNUNET_break (0);
2657 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 2630 return GNUNET_SYSERR;
2658 return;
2659 } 2631 }
2660 break; 2632 break;
2661 default: 2633 default:
2662 GNUNET_break (0); 2634 GNUNET_break (0);
2663 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 2635 return GNUNET_SYSERR;
2664 return;
2665 } 2636 }
2637 return GNUNET_OK;
2638}
2639
2640
2641/**
2642 * A client asks us to setup a redirection via some exit node to a
2643 * particular IP. Setup the redirection and give the client the
2644 * allocated IP.
2645 *
2646 * @param cls client requesting client
2647 * @param msg redirection request
2648 */
2649static void
2650handle_client_redirect_to_ip (void *cls,
2651 const struct RedirectToIpRequestMessage *msg)
2652{
2653 struct GNUNET_SERVICE_Client *client = cls;
2654 size_t alen;
2655 int addr_af;
2656 int result_af;
2657 struct in_addr v4;
2658 struct in6_addr v6;
2659 void *addr;
2660 struct DestinationEntry *de;
2661 struct GNUNET_HashCode key;
2666 2662
2663 alen = ntohs (msg->header.size) - sizeof (struct RedirectToIpRequestMessage);
2664 addr_af = (int) htonl (msg->addr_af);
2667 /* allocate response IP */ 2665 /* allocate response IP */
2668 result_af = (int) htonl (msg->result_af); 2666 result_af = (int) htonl (msg->result_af);
2669 if (GNUNET_OK != allocate_response_ip (&result_af, 2667 if (GNUNET_OK != allocate_response_ip (&result_af,
2670 &addr, 2668 &addr,
2671 &v4, &v6)) 2669 &v4, &v6))
2672 { 2670 {
2673 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 2671 GNUNET_SERVICE_client_drop (client);
2674 return; 2672 return;
2675 } 2673 }
2676 /* send reply with our IP address */ 2674 /* send reply with our IP address */
@@ -2681,7 +2679,7 @@ service_redirect_to_ip (void *cls,
2681 if (result_af == AF_UNSPEC) 2679 if (result_af == AF_UNSPEC)
2682 { 2680 {
2683 /* failure, we're done */ 2681 /* failure, we're done */
2684 GNUNET_SERVER_receive_done (client, GNUNET_OK); 2682 GNUNET_SERVICE_client_continue (client);
2685 return; 2683 return;
2686 } 2684 }
2687 2685
@@ -2691,9 +2689,14 @@ service_redirect_to_ip (void *cls,
2691 2689
2692 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2690 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2693 "Allocated address %s for redirection via exit to %s\n", 2691 "Allocated address %s for redirection via exit to %s\n",
2694 inet_ntop (result_af, addr, sbuf, sizeof (sbuf)), 2692 inet_ntop (result_af,
2693 addr,
2694 sbuf,
2695 sizeof (sbuf)),
2695 inet_ntop (addr_af, 2696 inet_ntop (addr_af,
2696 &msg[1], dbuf, sizeof (dbuf))); 2697 &msg[1],
2698 dbuf,
2699 sizeof (dbuf)));
2697 } 2700 }
2698 2701
2699 /* setup destination record */ 2702 /* setup destination record */
@@ -2701,8 +2704,8 @@ service_redirect_to_ip (void *cls,
2701 de->is_service = GNUNET_NO; 2704 de->is_service = GNUNET_NO;
2702 de->details.exit_destination.af = addr_af; 2705 de->details.exit_destination.af = addr_af;
2703 GNUNET_memcpy (&de->details.exit_destination.ip, 2706 GNUNET_memcpy (&de->details.exit_destination.ip,
2704 &msg[1], 2707 &msg[1],
2705 alen); 2708 alen);
2706 get_destination_key_from_ip (result_af, 2709 get_destination_key_from_ip (result_af,
2707 addr, 2710 addr,
2708 &key); 2711 &key);
@@ -2720,7 +2723,7 @@ service_redirect_to_ip (void *cls,
2720 1, GNUNET_NO); 2723 1, GNUNET_NO);
2721 while (GNUNET_CONTAINER_multihashmap_size (destination_map) > max_destination_mappings) 2724 while (GNUNET_CONTAINER_multihashmap_size (destination_map) > max_destination_mappings)
2722 expire_destination (de); 2725 expire_destination (de);
2723 GNUNET_SERVER_receive_done (client, GNUNET_OK); 2726 GNUNET_SERVICE_client_continue (client);
2724} 2727}
2725 2728
2726 2729
@@ -2729,16 +2732,14 @@ service_redirect_to_ip (void *cls,
2729 * offering a service. Setup the redirection and give the client the 2732 * offering a service. Setup the redirection and give the client the
2730 * allocated IP. 2733 * allocated IP.
2731 * 2734 *
2732 * @param cls unused 2735 * @param cls requesting client
2733 * @param client requesting client 2736 * @param msg redirection request
2734 * @param message redirection request (a `struct RedirectToPeerRequestMessage`)
2735 */ 2737 */
2736static void 2738static void
2737service_redirect_to_service (void *cls, 2739handle_client_redirect_to_service (void *cls,
2738 struct GNUNET_SERVER_Client *client, 2740 const struct RedirectToServiceRequestMessage *msg)
2739 const struct GNUNET_MessageHeader *message)
2740{ 2741{
2741 const struct RedirectToServiceRequestMessage *msg; 2742 struct GNUNET_SERVICE_Client *client = cls;
2742 int result_af; 2743 int result_af;
2743 struct in_addr v4; 2744 struct in_addr v4;
2744 struct in6_addr v6; 2745 struct in6_addr v6;
@@ -2747,9 +2748,6 @@ service_redirect_to_service (void *cls,
2747 struct GNUNET_HashCode key; 2748 struct GNUNET_HashCode key;
2748 struct DestinationChannel *dt; 2749 struct DestinationChannel *dt;
2749 2750
2750 /* parse request */
2751 msg = (const struct RedirectToServiceRequestMessage *) message;
2752
2753 /* allocate response IP */ 2751 /* allocate response IP */
2754 result_af = (int) htonl (msg->result_af); 2752 result_af = (int) htonl (msg->result_af);
2755 if (GNUNET_OK != 2753 if (GNUNET_OK !=
@@ -2759,8 +2757,7 @@ service_redirect_to_service (void *cls,
2759 &v6)) 2757 &v6))
2760 { 2758 {
2761 GNUNET_break (0); 2759 GNUNET_break (0);
2762 GNUNET_SERVER_receive_done (client, 2760 GNUNET_SERVICE_client_drop (client);
2763 GNUNET_SYSERR);
2764 return; 2761 return;
2765 } 2762 }
2766 send_client_reply (client, 2763 send_client_reply (client,
@@ -2772,8 +2769,7 @@ service_redirect_to_service (void *cls,
2772 /* failure, we're done */ 2769 /* failure, we're done */
2773 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2770 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2774 _("Failed to allocate IP address for new destination\n")); 2771 _("Failed to allocate IP address for new destination\n"));
2775 GNUNET_SERVER_receive_done (client, 2772 GNUNET_SERVICE_client_continue (client);
2776 GNUNET_OK);
2777 return; 2773 return;
2778 } 2774 }
2779 2775
@@ -2817,8 +2813,7 @@ service_redirect_to_service (void *cls,
2817 de->dt_tail, 2813 de->dt_tail,
2818 dt); 2814 dt);
2819 /* we're done */ 2815 /* we're done */
2820 GNUNET_SERVER_receive_done (client, 2816 GNUNET_SERVICE_client_continue (client);
2821 GNUNET_OK);
2822} 2817}
2823 2818
2824 2819
@@ -2938,11 +2933,6 @@ cleanup (void *cls)
2938 GNUNET_HELPER_wait (helper_handle); 2933 GNUNET_HELPER_wait (helper_handle);
2939 helper_handle = NULL; 2934 helper_handle = NULL;
2940 } 2935 }
2941 if (NULL != nc)
2942 {
2943 GNUNET_SERVER_notification_context_destroy (nc);
2944 nc = NULL;
2945 }
2946 if (NULL != stats) 2936 if (NULL != stats)
2947 { 2937 {
2948 GNUNET_STATISTICS_destroy (stats, GNUNET_NO); 2938 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
@@ -2954,25 +2944,50 @@ cleanup (void *cls)
2954 2944
2955 2945
2956/** 2946/**
2947 * Callback called when a client connects to the service.
2948 *
2949 * @param cls closure for the service
2950 * @param c the new client that connected to the service
2951 * @param mq the message queue used to send messages to the client
2952 * @return @a c
2953 */
2954static void *
2955client_connect_cb (void *cls,
2956 struct GNUNET_SERVICE_Client *c,
2957 struct GNUNET_MQ_Handle *mq)
2958{
2959 return c;
2960}
2961
2962
2963/**
2964 * Callback called when a client disconnected from the service
2965 *
2966 * @param cls closure for the service
2967 * @param c the client that disconnected
2968 * @param internal_cls should be equal to @a c
2969 */
2970static void
2971client_disconnect_cb (void *cls,
2972 struct GNUNET_SERVICE_Client *c,
2973 void *internal_cls)
2974{
2975 GNUNET_assert (c == internal_cls);
2976}
2977
2978
2979/**
2957 * Main function that will be run by the scheduler. 2980 * Main function that will be run by the scheduler.
2958 * 2981 *
2959 * @param cls closure 2982 * @param cls closure
2960 * @param server the initialized server
2961 * @param cfg_ configuration 2983 * @param cfg_ configuration
2984 * @param service the initialized service
2962 */ 2985 */
2963static void 2986static void
2964run (void *cls, 2987run (void *cls,
2965 struct GNUNET_SERVER_Handle *server, 2988 const struct GNUNET_CONFIGURATION_Handle *cfg_,
2966 const struct GNUNET_CONFIGURATION_Handle *cfg_) 2989 struct GNUNET_SERVICE_Handle *service)
2967{ 2990{
2968 static const struct GNUNET_SERVER_MessageHandler service_handlers[] = {
2969 /* callback, cls, type, size */
2970 { &service_redirect_to_ip, NULL, GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP, 0},
2971 { &service_redirect_to_service, NULL,
2972 GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE,
2973 sizeof (struct RedirectToServiceRequestMessage) },
2974 {NULL, NULL, 0, 0}
2975 };
2976 static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { 2991 static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = {
2977 { &receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY, 0}, 2992 { &receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY, 0},
2978 { &receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN, 0}, 2993 { &receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN, 0},
@@ -3128,27 +3143,30 @@ run (void *cls,
3128 helper_handle = GNUNET_HELPER_start (GNUNET_NO, 3143 helper_handle = GNUNET_HELPER_start (GNUNET_NO,
3129 "gnunet-helper-vpn", vpn_argv, 3144 "gnunet-helper-vpn", vpn_argv,
3130 &message_token, NULL, NULL); 3145 &message_token, NULL, NULL);
3131 nc = GNUNET_SERVER_notification_context_create (server, 1);
3132 GNUNET_SERVER_add_handlers (server, service_handlers);
3133 GNUNET_SCHEDULER_add_shutdown (&cleanup, 3146 GNUNET_SCHEDULER_add_shutdown (&cleanup,
3134 NULL); 3147 NULL);
3135} 3148}
3136 3149
3137 3150
3138/** 3151/**
3139 * The main function of the VPN service. 3152 * Define "main" method using service macro.
3140 *
3141 * @param argc number of arguments from the command line
3142 * @param argv command line arguments
3143 * @return 0 ok, 1 on error
3144 */ 3153 */
3145int 3154GNUNET_SERVICE_MAIN
3146main (int argc, char *const *argv) 3155("vpn",
3147{ 3156 GNUNET_SERVICE_OPTION_NONE,
3148 return (GNUNET_OK == 3157 &run,
3149 GNUNET_SERVICE_run (argc, argv, "vpn", 3158 &client_connect_cb,
3150 GNUNET_SERVICE_OPTION_NONE, 3159 &client_disconnect_cb,
3151 &run, NULL)) ? global_ret : 1; 3160 NULL,
3152} 3161 GNUNET_MQ_hd_var_size (client_redirect_to_ip,
3162 GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP,
3163 struct RedirectToIpRequestMessage,
3164 NULL),
3165 GNUNET_MQ_hd_fixed_size (client_redirect_to_service,
3166 GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE,
3167 struct RedirectToServiceRequestMessage,
3168 NULL),
3169 GNUNET_MQ_handler_end ());
3170
3153 3171
3154/* end of gnunet-service-vpn.c */ 3172/* end of gnunet-service-vpn.c */