aboutsummaryrefslogtreecommitdiff
path: root/src/exit
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-09-21 20:13:25 +0000
committerChristian Grothoff <christian@grothoff.org>2013-09-21 20:13:25 +0000
commit59c2e2ae2391c2678ce54af52b19862b9d01a3fc (patch)
treea18c95a71548b8b61f6f6c50a0fc342ce0e9f96a /src/exit
parent04bb54e0efe6f6770c016aedbb776dd4ae801972 (diff)
downloadgnunet-59c2e2ae2391c2678ce54af52b19862b9d01a3fc.tar.gz
gnunet-59c2e2ae2391c2678ce54af52b19862b9d01a3fc.zip
advertise DNS exit capability in DHT
Diffstat (limited to 'src/exit')
-rw-r--r--src/exit/Makefile.am2
-rw-r--r--src/exit/gnunet-daemon-exit.c193
2 files changed, 169 insertions, 26 deletions
diff --git a/src/exit/Makefile.am b/src/exit/Makefile.am
index aa46c35cc..3d221f0c6 100644
--- a/src/exit/Makefile.am
+++ b/src/exit/Makefile.am
@@ -49,7 +49,7 @@ gnunet_daemon_exit_SOURCES = \
49 gnunet-daemon-exit.c exit.h 49 gnunet-daemon-exit.c exit.h
50gnunet_daemon_exit_LDADD = \ 50gnunet_daemon_exit_LDADD = \
51 $(top_builddir)/src/dns/libgnunetdnsstub.la \ 51 $(top_builddir)/src/dns/libgnunetdnsstub.la \
52 $(top_builddir)/src/core/libgnunetcore.la \ 52 $(top_builddir)/src/dht/libgnunetdht.la \
53 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 53 $(top_builddir)/src/statistics/libgnunetstatistics.la \
54 $(top_builddir)/src/tun/libgnunettun.la \ 54 $(top_builddir)/src/tun/libgnunettun.la \
55 $(top_builddir)/src/util/libgnunetutil.la \ 55 $(top_builddir)/src/util/libgnunetutil.la \
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c
index 751907d8d..6f6e71362 100644
--- a/src/exit/gnunet-daemon-exit.c
+++ b/src/exit/gnunet-daemon-exit.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2010, 2012 Christian Grothoff 3 (C) 2010-2013 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
@@ -38,14 +38,18 @@
38#include "gnunet_util_lib.h" 38#include "gnunet_util_lib.h"
39#include "gnunet_protocols.h" 39#include "gnunet_protocols.h"
40#include "gnunet_applications.h" 40#include "gnunet_applications.h"
41#include "gnunet_dht_service.h"
41#include "gnunet_mesh_service.h" 42#include "gnunet_mesh_service.h"
42#include "gnunet_dnsparser_lib.h" 43#include "gnunet_dnsparser_lib.h"
43#include "gnunet_dnsstub_lib.h" 44#include "gnunet_dnsstub_lib.h"
44#include "gnunet_statistics_service.h" 45#include "gnunet_statistics_service.h"
45#include "gnunet_constants.h" 46#include "gnunet_constants.h"
47#include "gnunet_signatures.h"
46#include "gnunet_tun_lib.h" 48#include "gnunet_tun_lib.h"
47#include "gnunet_regex_service.h" 49#include "gnunet_regex_service.h"
48#include "exit.h" 50#include "exit.h"
51#include "block_dns.h"
52
49 53
50/** 54/**
51 * Maximum path compression length for mesh regex announcing for IPv4 address 55 * Maximum path compression length for mesh regex announcing for IPv4 address
@@ -65,6 +69,17 @@
65#define REGEX_REFRESH_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30) 69#define REGEX_REFRESH_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30)
66 70
67/** 71/**
72 * How frequently do we re-announce the DNS exit in the DHT?
73 */
74#define DHT_PUT_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
75
76/**
77 * How long do we typically sign the DNS exit advertisement for?
78 */
79#define DNS_ADVERTISEMENT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 3)
80
81
82/**
68 * Generic logging shorthand 83 * Generic logging shorthand
69 */ 84 */
70#define LOG(kind, ...) \ 85#define LOG(kind, ...) \
@@ -220,9 +235,9 @@ struct TunnelState
220 struct GNUNET_MESH_TransmitHandle *th; 235 struct GNUNET_MESH_TransmitHandle *th;
221 236
222 /** 237 /**
223 * GNUNET_NO if this is a tunnel for TCP/UDP, 238 * #GNUNET_NO if this is a tunnel for TCP/UDP,
224 * GNUNET_YES if this is a tunnel for DNS, 239 * #GNUNET_YES if this is a tunnel for DNS,
225 * GNUNET_SYSERR if the tunnel is not yet initialized. 240 * #GNUNET_SYSERR if the tunnel is not yet initialized.
226 */ 241 */
227 int is_dns; 242 int is_dns;
228 243
@@ -395,6 +410,37 @@ static struct TunnelState *tunnels[UINT16_MAX + 1];
395static struct GNUNET_DNSSTUB_Context *dnsstub; 410static struct GNUNET_DNSSTUB_Context *dnsstub;
396 411
397/** 412/**
413 * Handle for ongoing DHT PUT operations to advertise exit service.
414 */
415static struct GNUNET_DHT_PutHandle *dht_put;
416
417/**
418 * Handle to the DHT.
419 */
420static struct GNUNET_DHT_Handle *dht;
421
422/**
423 * Task for doing DHT PUTs to advertise exit service.
424 */
425static GNUNET_SCHEDULER_TaskIdentifier dht_task;
426
427/**
428 * Advertisement message we put into the DHT to advertise us
429 * as a DNS exit.
430 */
431static struct GNUNET_DNS_Advertisement dns_advertisement;
432
433/**
434 * Key we store the DNS advertismenet under.
435 */
436static struct GNUNET_HashCode dht_put_key;
437
438/**
439 * Private key for this peer.
440 */
441static struct GNUNET_CRYPTO_EccPrivateKey *peer_key;
442
443/**
398 * Are we an IPv4-exit? 444 * Are we an IPv4-exit?
399 */ 445 */
400static int ipv4_exit; 446static int ipv4_exit;
@@ -510,11 +556,11 @@ process_dns_result (void *cls,
510 * 556 *
511 * @param cls closure, NULL 557 * @param cls closure, NULL
512 * @param tunnel connection to the other end 558 * @param tunnel connection to the other end
513 * @param tunnel_ctx pointer to our 'struct TunnelState *' 559 * @param tunnel_ctx pointer to our `struct TunnelState *`
514 * @param message the actual message 560 * @param message the actual message
515 * 561 *
516 * @return GNUNET_OK to keep the connection open, 562 * @return #GNUNET_OK to keep the connection open,
517 * GNUNET_SYSERR to close it (signal serious error) 563 * #GNUNET_SYSERR to close it (signal serious error)
518 */ 564 */
519static int 565static int
520receive_dns_request (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, 566receive_dns_request (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
@@ -2969,7 +3015,7 @@ static void *
2969new_tunnel (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, 3015new_tunnel (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2970 const struct GNUNET_PeerIdentity *initiator, uint32_t port) 3016 const struct GNUNET_PeerIdentity *initiator, uint32_t port)
2971{ 3017{
2972 struct TunnelState *s = GNUNET_malloc (sizeof (struct TunnelState)); 3018 struct TunnelState *s = GNUNET_new (struct TunnelState);
2973 3019
2974 s->is_dns = GNUNET_SYSERR; 3020 s->is_dns = GNUNET_SYSERR;
2975 s->peer = *initiator; 3021 s->peer = *initiator;
@@ -3117,7 +3163,27 @@ cleanup (void *cls GNUNET_UNUSED,
3117 GNUNET_DNSSTUB_stop (dnsstub); 3163 GNUNET_DNSSTUB_stop (dnsstub);
3118 dnsstub = NULL; 3164 dnsstub = NULL;
3119 } 3165 }
3120 if (stats != NULL) 3166 if (NULL != peer_key)
3167 {
3168 GNUNET_free (peer_key);
3169 peer_key = NULL;
3170 }
3171 if (GNUNET_SCHEDULER_NO_TASK != dht_task)
3172 {
3173 GNUNET_SCHEDULER_cancel (dht_task);
3174 dht_task = GNUNET_SCHEDULER_NO_TASK;
3175 }
3176 if (NULL != dht_put)
3177 {
3178 GNUNET_DHT_put_cancel (dht_put);
3179 dht_put = NULL;
3180 }
3181 if (NULL != dht)
3182 {
3183 GNUNET_DHT_disconnect (dht);
3184 dht = NULL;
3185 }
3186 if (NULL != stats)
3121 { 3187 {
3122 GNUNET_STATISTICS_destroy (stats, GNUNET_NO); 3188 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
3123 stats = NULL; 3189 stats = NULL;
@@ -3186,7 +3252,7 @@ add_services (int proto,
3186 continue; 3252 continue;
3187 } 3253 }
3188 3254
3189 serv = GNUNET_malloc (sizeof (struct LocalService)); 3255 serv = GNUNET_new (struct LocalService);
3190 serv->address.proto = proto; 3256 serv->address.proto = proto;
3191 serv->my_port = (uint16_t) local_port; 3257 serv->my_port = (uint16_t) local_port;
3192 serv->address.port = remote_port; 3258 serv->address.port = remote_port;
@@ -3298,6 +3364,75 @@ read_service_conf (void *cls GNUNET_UNUSED, const char *section)
3298 3364
3299 3365
3300/** 3366/**
3367 * We are running a DNS exit service, advertise it in the
3368 * DHT. This task is run periodically to do the DHT PUT.
3369 *
3370 * @param cls closure
3371 * @param tc scheduler context
3372 */
3373static void
3374do_dht_put (void *cls,
3375 const struct GNUNET_SCHEDULER_TaskContext *tc);
3376
3377
3378/**
3379 * Function called when the DHT PUT operation is complete.
3380 * Schedules the next PUT.
3381 *
3382 * @param cls closure, NULL
3383 * @param success #GNUNET_OK if the operation worked (unused)
3384 */
3385static void
3386dht_put_cont (void *cls,
3387 int success)
3388{
3389 dht_put = NULL;
3390 dht_task = GNUNET_SCHEDULER_add_delayed (DHT_PUT_FREQUENCY,
3391 &do_dht_put,
3392 NULL);
3393}
3394
3395
3396/**
3397 * We are running a DNS exit service, advertise it in the
3398 * DHT. This task is run periodically to do the DHT PUT.
3399 *
3400 * @param cls closure
3401 * @param tc scheduler context
3402 */
3403static void
3404do_dht_put (void *cls,
3405 const struct GNUNET_SCHEDULER_TaskContext *tc)
3406{
3407 struct GNUNET_TIME_Absolute expiration;
3408
3409 dht_task = GNUNET_SCHEDULER_NO_TASK;
3410 expiration = GNUNET_TIME_absolute_ntoh (dns_advertisement.expiration_time);
3411 if (GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us <
3412 GNUNET_TIME_UNIT_HOURS.rel_value_us)
3413 {
3414 /* refresh advertisement */
3415 expiration = GNUNET_TIME_relative_to_absolute (DNS_ADVERTISEMENT_TIMEOUT);
3416 dns_advertisement.expiration_time = GNUNET_TIME_absolute_hton (expiration);
3417 GNUNET_assert (GNUNET_OK ==
3418 GNUNET_CRYPTO_ecc_sign (peer_key,
3419 &dns_advertisement.purpose,
3420 &dns_advertisement.signature));
3421 }
3422 dht_put = GNUNET_DHT_put (dht,
3423 &dht_put_key,
3424 1 /* replication */,
3425 GNUNET_DHT_RO_NONE,
3426 GNUNET_BLOCK_TYPE_DNS,
3427 sizeof (struct GNUNET_DNS_Advertisement),
3428 &dns_advertisement,
3429 expiration,
3430 GNUNET_TIME_UNIT_FOREVER_REL,
3431 &dht_put_cont, NULL);
3432}
3433
3434
3435/**
3301 * @brief Main function that will be run by the scheduler. 3436 * @brief Main function that will be run by the scheduler.
3302 * 3437 *
3303 * @param cls closure 3438 * @param cls closure
@@ -3411,8 +3546,9 @@ run (void *cls, char *const *args GNUNET_UNUSED,
3411 ( (1 != inet_pton (AF_INET, dns_exit, &dns_exit4)) && 3546 ( (1 != inet_pton (AF_INET, dns_exit, &dns_exit4)) &&
3412 (1 != inet_pton (AF_INET6, dns_exit, &dns_exit6)) ) ) ) 3547 (1 != inet_pton (AF_INET6, dns_exit, &dns_exit6)) ) ) )
3413 { 3548 {
3414 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "dns", "DNS_RESOLVER", 3549 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
3415 _("need a valid IPv4 or IPv6 address\n")); 3550 "dns", "DNS_RESOLVER",
3551 _("need a valid IPv4 or IPv6 address\n"));
3416 GNUNET_free_non_null (dns_exit); 3552 GNUNET_free_non_null (dns_exit);
3417 dns_exit = NULL; 3553 dns_exit = NULL;
3418 } 3554 }
@@ -3435,7 +3571,18 @@ run (void *cls, char *const *args GNUNET_UNUSED,
3435 } 3571 }
3436 if (NULL != dns_exit) 3572 if (NULL != dns_exit)
3437 { 3573 {
3438 // FIXME use regex to put info 3574 dht = GNUNET_DHT_connect (cfg, 1);
3575 peer_key = GNUNET_CRYPTO_ecc_key_create_from_configuration (cfg);
3576 GNUNET_CRYPTO_ecc_key_get_public_for_signature (peer_key,
3577 &dns_advertisement.peer);
3578 dns_advertisement.purpose.size = htonl (sizeof (struct GNUNET_DNS_Advertisement) -
3579 sizeof (struct GNUNET_CRYPTO_EccSignature));
3580 dns_advertisement.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DNS_RECORD);
3581 GNUNET_CRYPTO_hash ("dns",
3582 strlen ("dns"),
3583 &dht_put_key);
3584 dht_task = GNUNET_SCHEDULER_add_now (&do_dht_put,
3585 NULL);
3439 apptypes[app_idx] = GNUNET_APPLICATION_TYPE_INTERNET_RESOLVER; 3586 apptypes[app_idx] = GNUNET_APPLICATION_TYPE_INTERNET_RESOLVER;
3440 app_idx++; 3587 app_idx++;
3441 } 3588 }
@@ -3450,8 +3597,7 @@ run (void *cls, char *const *args GNUNET_UNUSED,
3450 if (GNUNET_SYSERR == 3597 if (GNUNET_SYSERR ==
3451 GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "TUN_IFNAME", &tun_ifname)) 3598 GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "TUN_IFNAME", &tun_ifname))
3452 { 3599 {
3453 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3600 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "TUN_IFNAME");
3454 "No entry 'TUN_IFNAME' in configuration!\n");
3455 GNUNET_SCHEDULER_shutdown (); 3601 GNUNET_SCHEDULER_shutdown ();
3456 return; 3602 return;
3457 } 3603 }
@@ -3461,8 +3607,7 @@ run (void *cls, char *const *args GNUNET_UNUSED,
3461 if (GNUNET_SYSERR == 3607 if (GNUNET_SYSERR ==
3462 GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "EXIT_IFNAME", &exit_ifname)) 3608 GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "EXIT_IFNAME", &exit_ifname))
3463 { 3609 {
3464 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3610 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "EXIT_IFNAME");
3465 "No entry 'EXIT_IFNAME' in configuration!\n");
3466 GNUNET_SCHEDULER_shutdown (); 3611 GNUNET_SCHEDULER_shutdown ();
3467 return; 3612 return;
3468 } 3613 }
@@ -3481,8 +3626,7 @@ run (void *cls, char *const *args GNUNET_UNUSED,
3481 &ipv6addr) || 3626 &ipv6addr) ||
3482 (1 != inet_pton (AF_INET6, ipv6addr, &exit_ipv6addr))) ) 3627 (1 != inet_pton (AF_INET6, ipv6addr, &exit_ipv6addr))) )
3483 { 3628 {
3484 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3629 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "IPV6ADDR");
3485 "No valid entry 'IPV6ADDR' in configuration!\n");
3486 GNUNET_SCHEDULER_shutdown (); 3630 GNUNET_SCHEDULER_shutdown ();
3487 return; 3631 return;
3488 } 3632 }
@@ -3491,8 +3635,7 @@ run (void *cls, char *const *args GNUNET_UNUSED,
3491 GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6PREFIX", 3635 GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6PREFIX",
3492 &ipv6prefix_s)) 3636 &ipv6prefix_s))
3493 { 3637 {
3494 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3638 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "IPV6PREFIX");
3495 "No entry 'IPV6PREFIX' in configuration!\n");
3496 GNUNET_SCHEDULER_shutdown (); 3639 GNUNET_SCHEDULER_shutdown ();
3497 return; 3640 return;
3498 } 3641 }
@@ -3503,6 +3646,8 @@ run (void *cls, char *const *args GNUNET_UNUSED,
3503 &ipv6prefix)) || 3646 &ipv6prefix)) ||
3504 (ipv6prefix >= 127) ) 3647 (ipv6prefix >= 127) )
3505 { 3648 {
3649 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "EXIT", "IPV6PREFIX",
3650 _("Must be a number"));
3506 GNUNET_SCHEDULER_shutdown (); 3651 GNUNET_SCHEDULER_shutdown ();
3507 return; 3652 return;
3508 } 3653 }
@@ -3520,8 +3665,7 @@ run (void *cls, char *const *args GNUNET_UNUSED,
3520 &ipv4addr) || 3665 &ipv4addr) ||
3521 (1 != inet_pton (AF_INET, ipv4addr, &exit_ipv4addr))) ) 3666 (1 != inet_pton (AF_INET, ipv4addr, &exit_ipv4addr))) )
3522 { 3667 {
3523 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3668 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "IPV4ADDR");
3524 "No valid entry for 'IPV4ADDR' in configuration!\n");
3525 GNUNET_SCHEDULER_shutdown (); 3669 GNUNET_SCHEDULER_shutdown ();
3526 return; 3670 return;
3527 } 3671 }
@@ -3531,8 +3675,7 @@ run (void *cls, char *const *args GNUNET_UNUSED,
3531 &ipv4mask) || 3675 &ipv4mask) ||
3532 (1 != inet_pton (AF_INET, ipv4mask, &exit_ipv4mask))) ) 3676 (1 != inet_pton (AF_INET, ipv4mask, &exit_ipv4mask))) )
3533 { 3677 {
3534 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3678 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "EXIT", "IPV4MASK");
3535 "No valid entry 'IPV4MASK' in configuration!\n");
3536 GNUNET_SCHEDULER_shutdown (); 3679 GNUNET_SCHEDULER_shutdown ();
3537 return; 3680 return;
3538 } 3681 }