diff options
-rw-r--r-- | src/exit/gnunet-daemon-exit.c | 7 | ||||
-rw-r--r-- | src/gns/gns.conf.in | 3 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns.c | 3 | ||||
-rw-r--r-- | src/gns/test_gns_proxy.conf | 2 | ||||
-rw-r--r-- | src/include/gnunet_testing_lib.h | 34 | ||||
-rw-r--r-- | src/pt/Makefile.am | 3 | ||||
-rw-r--r-- | src/pt/test_gns_vpn.c | 294 | ||||
-rw-r--r-- | src/pt/test_gns_vpn.conf | 11 |
8 files changed, 262 insertions, 95 deletions
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c index 1afa292008..2a4d126518 100644 --- a/src/exit/gnunet-daemon-exit.c +++ b/src/exit/gnunet-daemon-exit.c @@ -3394,7 +3394,8 @@ add_services (int proto, * @param section name of section in config, equal to hostname */ static void -read_service_conf (void *cls, const char *section) +read_service_conf (void *cls, + const char *section) { char *cpy; @@ -3402,7 +3403,9 @@ read_service_conf (void *cls, const char *section) (0 != strcmp (".gnunet.", section + (strlen (section) - 8)))) return; if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (cfg, section, "UDP_REDIRECTS", + GNUNET_CONFIGURATION_get_value_string (cfg, + section, + "UDP_REDIRECTS", &cpy)) { add_services (IPPROTO_UDP, cpy, section); diff --git a/src/gns/gns.conf.in b/src/gns/gns.conf.in index 34eda3ac56..7fbd572abe 100644 --- a/src/gns/gns.conf.in +++ b/src/gns/gns.conf.in @@ -25,6 +25,9 @@ ZONE_PUBLISH_TIME_WINDOW = 4 h # PREFIX = valgrind --leak-check=full --track-origins=yes +# Setting this option enables hijacking DNS queries using iptables. +# DNS_ROOT = KEY + [gns-proxy] BINARY = gnunet-gns-proxy AUTOSTART = NO diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c index 092da35774..60c277561c 100644 --- a/src/gns/gnunet-service-gns.c +++ b/src/gns/gnunet-service-gns.c @@ -917,7 +917,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, &dns_root)) { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, - "gns", "DNS_ROOT", + "gns", + "DNS_ROOT", _("valid public key required")); GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); GNUNET_free (dns_root_name); diff --git a/src/gns/test_gns_proxy.conf b/src/gns/test_gns_proxy.conf index 973c0257ef..fb1b0c7c8e 100644 --- a/src/gns/test_gns_proxy.conf +++ b/src/gns/test_gns_proxy.conf @@ -14,7 +14,7 @@ HOSTKEYSFILE = ${DATADIR}/testing_hostkeys.dat [gns] AUTOSTART = YES -ZONEKEY = $GNUNET_TEST_HOME/.hostkey +ZONEKEY = $GNUNET_TEST_HOME/.zonekey HIJACK_DNS = YES [gns-proxy] diff --git a/src/include/gnunet_testing_lib.h b/src/include/gnunet_testing_lib.h index 4cb518dc3c..04975d0774 100644 --- a/src/include/gnunet_testing_lib.h +++ b/src/include/gnunet_testing_lib.h @@ -226,7 +226,8 @@ GNUNET_TESTING_release_port (struct GNUNET_TESTING_System *system, * * @param system system to use to coordinate resource usage * @param cfg template configuration to update - * @return GNUNET_OK on success, GNUNET_SYSERR on error - the configuration will + * @return #GNUNET_OK on success, + * #GNUNET_SYSERR on error - the configuration will * be incomplete and should not be used there upon */ int @@ -271,7 +272,8 @@ GNUNET_TESTING_peer_get_identity (struct GNUNET_TESTING_Peer *peer, * Start the peer. * * @param peer peer to start - * @return GNUNET_OK on success, GNUNET_SYSERR on error (i.e. peer already running) + * @return #GNUNET_OK on success, + * #GNUNET_SYSERR on error (i.e. peer already running) */ int GNUNET_TESTING_peer_start (struct GNUNET_TESTING_Peer *peer); @@ -283,7 +285,8 @@ GNUNET_TESTING_peer_start (struct GNUNET_TESTING_Peer *peer); * GNUNET_TESTING_peer_stop_async(). * * @param peer peer to stop - * @return GNUNET_OK on success, GNUNET_SYSERR on error (i.e. peer not running) + * @return #GNUNET_OK on success, + * #GNUNET_SYSERR on error (i.e. peer not running) */ int GNUNET_TESTING_peer_stop (struct GNUNET_TESTING_Peer *peer); @@ -304,7 +307,7 @@ GNUNET_TESTING_peer_destroy (struct GNUNET_TESTING_Peer *peer); * Sends SIGTERM to the peer's main process * * @param peer the handle to the peer - * @return GNUNET_OK if successful; GNUNET_SYSERR if the main process is NULL + * @return #GNUNET_OK if successful; #GNUNET_SYSERR if the main process is NULL * or upon any error while sending SIGTERM */ int @@ -315,7 +318,7 @@ GNUNET_TESTING_peer_kill (struct GNUNET_TESTING_Peer *peer); * Waits for a peer to terminate. The peer's main process will also be destroyed. * * @param peer the handle to the peer - * @return GNUNET_OK if successful; GNUNET_SYSERR if the main process is NULL + * @return #GNUNET_OK if successful; #GNUNET_SYSERR if the main process is NULL * or upon any error while waiting */ int @@ -327,13 +330,13 @@ GNUNET_TESTING_peer_wait (struct GNUNET_TESTING_Peer *peer); * * @param cls the closure given to GNUNET_TESTING_peer_stop_async() * @param peer the respective peer whose status is being reported - * @param success GNUNET_YES if the peer is stopped; GNUNET_SYSERR upon any + * @param success #GNUNET_YES if the peer is stopped; #GNUNET_SYSERR upon any * error */ -typedef void (*GNUNET_TESTING_PeerStopCallback) (void *cls, - struct GNUNET_TESTING_Peer * - peer, - int success); +typedef void +(*GNUNET_TESTING_PeerStopCallback) (void *cls, + struct GNUNET_TESTING_Peer *peer, + int success); /** @@ -368,15 +371,16 @@ GNUNET_TESTING_peer_stop_async_cancel (struct GNUNET_TESTING_Peer *peer); /** * Signature of the 'main' function for a (single-peer) testcase that - * is run using 'GNUNET_TESTING_peer_run'. + * is run using #GNUNET_TESTING_peer_run(). * * @param cls closure * @param cfg configuration of the peer that was started * @param peer identity of the peer that was created */ -typedef void (*GNUNET_TESTING_TestMain) (void *cls, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Peer *peer); +typedef void +(*GNUNET_TESTING_TestMain) (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer); /** @@ -420,7 +424,7 @@ GNUNET_TESTING_peer_run (const char *testdir, * @param cfgfilename name of the configuration file to use; * use NULL to only run with defaults * @param tm main function of the testcase - * @param tm_cls closure for 'tm' + * @param tm_cls closure for @a tm * @return 0 on success, 1 on error */ int diff --git a/src/pt/Makefile.am b/src/pt/Makefile.am index 7ce3f182f1..e56990f08a 100644 --- a/src/pt/Makefile.am +++ b/src/pt/Makefile.am @@ -96,6 +96,7 @@ test_gns_vpn_SOURCES = \ test_gns_vpn.c test_gns_vpn_LDADD = -lmicrohttpd $(LIB_GNURL) \ $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -137,5 +138,3 @@ test_gnunet_vpn_6_to_4_LDADD = -lmicrohttpd $(LIB_GNURL) \ $(top_builddir)/src/util/libgnunetutil.la test_gnunet_vpn_6_to_4_CPPFLAGS = \ $(CPP_GNURL) $(AM_CPPFLAGS) - - diff --git a/src/pt/test_gns_vpn.c b/src/pt/test_gns_vpn.c index 3661b2ed62..c426aa43cf 100644 --- a/src/pt/test_gns_vpn.c +++ b/src/pt/test_gns_vpn.c @@ -26,6 +26,7 @@ #include "platform.h" #include <curl/curl.h> #include <microhttpd.h> +#include "gnunet_identity_service.h" #include "gnunet_namestore_service.h" #include "gnunet_gnsrecord_lib.h" #include "gnunet_gns_service.h" @@ -45,9 +46,13 @@ static struct GNUNET_NAMESTORE_Handle *namestore; static struct MHD_Daemon *mhd; -static struct GNUNET_SCHEDULER_Task * mhd_task_id; +static struct GNUNET_SCHEDULER_Task *mhd_task_id; -static struct GNUNET_SCHEDULER_Task * curl_task_id; +static struct GNUNET_SCHEDULER_Task *curl_task_id; + +static struct GNUNET_IDENTITY_Handle *identity; + +static struct GNUNET_NAMESTORE_QueueEntry *qe; static CURL *curl; @@ -55,6 +60,8 @@ static CURLM *multi; static char *url; +static struct GNUNET_PeerIdentity id; + /** * IP address of the ultimate destination. */ @@ -129,7 +136,8 @@ mhd_ahc (void *cls, static void -do_shutdown () +do_shutdown (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *c) { if (mhd_task_id != NULL) { @@ -146,6 +154,16 @@ do_shutdown () MHD_stop_daemon (mhd); mhd = NULL; } + if (NULL != identity) + { + GNUNET_IDENTITY_disconnect (identity); + identity = NULL; + } + if (NULL != qe) + { + GNUNET_NAMESTORE_cancel (qe); + qe = NULL; + } GNUNET_free_non_null (url); url = NULL; } @@ -217,7 +235,7 @@ curl_main () global_ret = 3; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download complete, shutting down!\n"); - do_shutdown (); + GNUNET_SCHEDULER_shutdown (); return; } GNUNET_assert (CURLM_OK == curl_multi_fdset (multi, &rs, &ws, &es, &max)); @@ -253,13 +271,15 @@ start_curl (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) curl_easy_setopt (curl, CURLOPT_WRITEDATA, &cbc); curl_easy_setopt (curl, CURLOPT_FAILONERROR, 1); curl_easy_setopt (curl, CURLOPT_TIMEOUT, 150L); - curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT, 15L); + curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT, 150L); curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1); multi = curl_multi_init (); GNUNET_assert (multi != NULL); GNUNET_assert (CURLM_OK == curl_multi_add_handle (multi, curl)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Beginning HTTP download from `%s'\n", url); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Beginning HTTP download from `%s'\n", + url); curl_main (); } @@ -292,11 +312,15 @@ commence_testing (void *cls, int32_t success, const char *emsg) if ((emsg != NULL) && (GNUNET_YES != success)) { fprintf (stderr, - "NS failed to create record %s\n", emsg); + "NS failed to create record %s\n", + emsg); GNUNET_SCHEDULER_shutdown (); return; } - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10), &start_curl, NULL); + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 10), + &start_curl, + NULL); } @@ -356,70 +380,6 @@ mhd_main () } -static void -run (void *cls, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Peer *peer) -{ - enum MHD_FLAG flags; - struct GNUNET_PeerIdentity id; - char *peername; - struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key; - struct GNUNET_GNSRECORD_Data rd; - char *rd_string; - char *zone_keyfile; - - GNUNET_TESTING_peer_get_identity (peer, &id); - peername = GNUNET_strdup (GNUNET_i2s_full (&id)); - - namestore = GNUNET_NAMESTORE_connect (cfg); - GNUNET_assert (NULL != namestore); - flags = MHD_USE_DEBUG; - if (GNUNET_YES == use_v6) - flags |= MHD_USE_IPv6; - mhd = MHD_start_daemon (flags, - PORT, - NULL, NULL, - &mhd_ahc, NULL, - MHD_OPTION_END); - GNUNET_assert (NULL != mhd); - mhd_main (); - - if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns", - "ZONEKEY", - &zone_keyfile)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to get key from cfg\n"); - GNUNET_free (peername); - return; - } - - zone_key = GNUNET_CRYPTO_ecdsa_key_create_from_file (zone_keyfile); - rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; - GNUNET_asprintf (&rd_string, - "6 %s %s", - peername, - "www.gnu."); - GNUNET_free (peername); - GNUNET_assert (GNUNET_OK == - GNUNET_GNSRECORD_string_to_value (GNUNET_GNSRECORD_TYPE_VPN, - rd_string, - (void**) &rd.data, - &rd.data_size)); - rd.record_type = GNUNET_GNSRECORD_TYPE_VPN; - - GNUNET_NAMESTORE_records_store (namestore, - zone_key, - "www", - 1, &rd, - &commence_testing, - NULL); - GNUNET_free ((void**)rd.data); - GNUNET_free (rd_string); - GNUNET_free (zone_keyfile); - GNUNET_free (zone_key); -} /** @@ -505,6 +465,194 @@ fork_and_exec (const char *file, return 0; } + + +/** + * Method called to inform about the egos of this peer. + * + * When used with #GNUNET_IDENTITY_connect, this function is + * initially called for all egos and then again whenever a + * ego's name changes or if it is deleted. At the end of + * the initial pass over all egos, the function is once called + * with 'NULL' for @a ego. That does NOT mean that the callback won't + * be invoked in the future or that there was an error. + * + * When used with #GNUNET_IDENTITY_create or #GNUNET_IDENTITY_get, + * this function is only called ONCE, and 'NULL' being passed in + * @a ego does indicate an error (i.e. name is taken or no default + * value is known). If @a ego is non-NULL and if '*ctx' + * is set in those callbacks, the value WILL be passed to a subsequent + * call to the identity callback of #GNUNET_IDENTITY_connect (if + * that one was not NULL). + * + * When an identity is renamed, this function is called with the + * (known) @a ego but the NEW @a name. + * + * When an identity is deleted, this function is called with the + * (known) ego and "NULL" for the @a name. In this case, + * the @a ego is henceforth invalid (and the @a ctx should also be + * cleaned up). + * + * @param cls closure + * @param ego ego handle + * @param ctx context for application to store data for this ego + * (during the lifetime of this process, initially NULL) + * @param name name assigned by the user for this ego, + * NULL if the user just deleted the ego and it + * must thus no longer be used + */ +static void +identity_cb (void *cls, + struct GNUNET_IDENTITY_Ego *ego, + void **ctx, + const char *name) +{ + const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key; + struct GNUNET_GNSRECORD_Data rd; + char *rd_string; + char *peername; + + if (NULL == name) + return; + if (NULL == ego) + { + if (NULL == qe) + { + fprintf (stderr, + "Failed to find master-zone ego\n"); + GNUNET_SCHEDULER_shutdown (); + return; + } + GNUNET_IDENTITY_disconnect (identity); + identity = NULL; + return; + } + GNUNET_assert (NULL != name); + if (0 != strcmp (name, + "master-zone")) + { + fprintf (stderr, + "Unexpected name %s\n", + name); + return; + } + /* FIXME: we somehow need to get this zone-key into + the 'DNS_ROOT' option of the 'gns' service. This + is currently why the test fails... */ + zone_key = GNUNET_IDENTITY_ego_get_private_key (ego); + rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; + peername = GNUNET_strdup (GNUNET_i2s_full (&id)); + GNUNET_asprintf (&rd_string, + "6 %s %s", + peername, + "www.gnu."); + GNUNET_free (peername); + GNUNET_assert (GNUNET_OK == + GNUNET_GNSRECORD_string_to_value (GNUNET_GNSRECORD_TYPE_VPN, + rd_string, + (void**) &rd.data, + &rd.data_size)); + rd.record_type = GNUNET_GNSRECORD_TYPE_VPN; + + qe = GNUNET_NAMESTORE_records_store (namestore, + zone_key, + "www", + 1, &rd, + &commence_testing, + NULL); + GNUNET_free ((void**)rd.data); + GNUNET_free (rd_string); +} + + +static void +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer) +{ + enum MHD_FLAG flags; + + char *bin; + char *bin_identity; + char *config; + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + "arm", + "CONFIG", + &config)) + { + fprintf (stderr, + "Failed to locate configuration file. Skipping test.\n"); + GNUNET_SCHEDULER_shutdown (); + return; + } + + char *const identity_args[] = + { + "gnunet-identity", + "-C", "master-zone", + "-c", config, + NULL + }; + char *const identity2_args[] = + { + "gnunet-identity", + "-e", "master-zone", + "-s", "gns-master", + "-c", config, + NULL + }; + GNUNET_TESTING_peer_get_identity (peer, &id); + GNUNET_SCHEDULER_add_delayed (TIMEOUT, + &do_shutdown, + NULL); + bin = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_BINDIR); + GNUNET_asprintf (&bin_identity, + "%s/%s", + bin, + "gnunet-identity"); + GNUNET_free (bin); + if (0 != fork_and_exec (bin_identity, identity_args)) + { + fprintf (stderr, + "Failed to run `gnunet-identity -C. Skipping test.\n"); + GNUNET_SCHEDULER_shutdown (); + GNUNET_free (bin_identity); + GNUNET_free (config); + return; + } + if (0 != fork_and_exec (bin_identity, identity2_args)) + { + fprintf (stderr, + "Failed to run `gnunet-identity -e. Skipping test.\n"); + GNUNET_SCHEDULER_shutdown (); + GNUNET_free (bin_identity); + GNUNET_free (config); + return; + } + GNUNET_free (bin_identity); + GNUNET_free (config); + + namestore = GNUNET_NAMESTORE_connect (cfg); + GNUNET_assert (NULL != namestore); + flags = MHD_USE_DEBUG; + if (GNUNET_YES == use_v6) + flags |= MHD_USE_IPv6; + mhd = MHD_start_daemon (flags, + PORT, + NULL, NULL, + &mhd_ahc, NULL, + MHD_OPTION_END); + GNUNET_assert (NULL != mhd); + mhd_main (); + + identity = GNUNET_IDENTITY_connect (cfg, + &identity_cb, + NULL); +} + + int main (int argc, char *const *argv) { @@ -591,6 +739,8 @@ main (int argc, char *const *argv) fprintf (stderr, "failed to initialize curl\n"); return 2; } + + if (0 != GNUNET_TESTING_peer_run ("test-gnunet-vpn", "test_gns_vpn.conf", &run, NULL)) diff --git a/src/pt/test_gns_vpn.conf b/src/pt/test_gns_vpn.conf index b0ed23176f..78dbdc700f 100644 --- a/src/pt/test_gns_vpn.conf +++ b/src/pt/test_gns_vpn.conf @@ -7,6 +7,8 @@ PLUGINS = tcp [arm] PORT = 0 ALLOW_SHUTDOWN = YES +SYSTEM_ONLY = NO +USER_ONLY = NO [exit] FORCESTART = YES @@ -23,6 +25,11 @@ EXIT_IFNAME = eth1 [dns] DNS_EXIT = 8.8.8.8 +FORCESTART = YES + +[identity] +AUTOSTART = YES +FORCESTART = YES [hostlist] AUTOSTART = NO @@ -46,8 +53,8 @@ TTL = 3600000 [gns] AUTOSTART = YES -ZONEKEY = $GNUNET_TEST_HOME/.hostkey -HIJACK_DNS = YES +ZONEKEY = $GNUNET_TEST_HOME/.zonekey +DNS_ROOT = FIXME [namestore] AUTOSTART = YES |