summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--po/POTFILES.in112
-rw-r--r--src/cadet/test_cadet.conf4
-rw-r--r--src/fs/fs_getopt.c29
-rw-r--r--src/fs/gnunet-publish.c60
-rw-r--r--src/fs/gnunet-search.c49
-rw-r--r--src/gns/gnunet-gns-proxy.c48
-rw-r--r--src/gns/test_gns_defaults.conf12
-rwxr-xr-xsrc/gns/test_gns_gns2dns_cname_lookup.sh9
-rwxr-xr-xsrc/gns/test_gns_gns2dns_lookup.sh10
-rw-r--r--src/gnsrecord/gnsrecord.c3
-rw-r--r--src/include/gnunet_configuration_lib.h31
-rw-r--r--src/include/gnunet_protocols.h19
-rw-r--r--src/include/gnunet_transport_communication_service.h10
-rw-r--r--src/namestore/gnunet-namestore.c330
-rw-r--r--src/topology/gnunet-daemon-topology.c3
-rw-r--r--src/transport/.gitignore1
-rw-r--r--src/transport/Makefile.am21
-rw-r--r--src/transport/gnunet-communicator-unix.c1148
-rw-r--r--src/transport/gnunet-service-tng.c719
-rw-r--r--src/transport/transport.h63
-rw-r--r--src/transport/transport_api2_communication.c194
-rw-r--r--src/util/configuration.c35
-rw-r--r--src/util/disk.c51
-rw-r--r--src/util/gnunet-service-resolver.c18
-rw-r--r--src/util/service.c10
26 files changed, 2679 insertions, 312 deletions
diff --git a/configure.ac b/configure.ac
index e37df28dd..3310168e0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -681,7 +681,7 @@ AC_CHECK_HEADERS([nss.h],[nss=true],[nss=false])
if test x$nss = xfalse
then
AM_CONDITIONAL(HAVE_GLIBCNSS, false)
- AC_MSG_WARN([ERROR: No GNU libc nss header, will not build NSS plugin])
+ AC_MSG_WARN([No GNU libc nss header, will not build NSS plugin])
else
AM_CONDITIONAL(HAVE_GLIBCNSS, true)
fi
diff --git a/po/POTFILES.in b/po/POTFILES.in
index caf7353be..5f4c5ee7f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -4,13 +4,21 @@ src/arm/arm_monitor_api.c
src/arm/gnunet-arm.c
src/arm/gnunet-service-arm.c
src/arm/mockup-service.c
+src/ats-tests/ats-testing-experiment.c
+src/ats-tests/ats-testing-log.c
+src/ats-tests/ats-testing-preferences.c
+src/ats-tests/ats-testing-traffic.c
+src/ats-tests/ats-testing.c
+src/ats-tests/gnunet-ats-sim.c
+src/ats-tests/gnunet-solver-eval.c
+src/ats-tool/gnunet-ats.c
src/ats/ats_api_connectivity.c
src/ats/ats_api_performance.c
src/ats/ats_api_scanner.c
src/ats/ats_api_scheduling.c
src/ats/gnunet-ats-solver-eval.c
-src/ats/gnunet-service-ats_addresses.c
src/ats/gnunet-service-ats.c
+src/ats/gnunet-service-ats_addresses.c
src/ats/gnunet-service-ats_connectivity.c
src/ats/gnunet-service-ats_normalization.c
src/ats/gnunet-service-ats_performance.c
@@ -21,14 +29,6 @@ src/ats/gnunet-service-ats_scheduling.c
src/ats/plugin_ats_mlp.c
src/ats/plugin_ats_proportional.c
src/ats/plugin_ats_ril.c
-src/ats-tests/ats-testing.c
-src/ats-tests/ats-testing-experiment.c
-src/ats-tests/ats-testing-log.c
-src/ats-tests/ats-testing-preferences.c
-src/ats-tests/ats-testing-traffic.c
-src/ats-tests/gnunet-ats-sim.c
-src/ats-tests/gnunet-solver-eval.c
-src/ats-tool/gnunet-ats.c
src/auction/gnunet-auction-create.c
src/auction/gnunet-auction-info.c
src/auction/gnunet-auction-join.c
@@ -40,8 +40,8 @@ src/block/plugin_block_test.c
src/cadet/cadet_api.c
src/cadet/cadet_test_lib.c
src/cadet/desirability_table.c
-src/cadet/gnunet-cadet.c
src/cadet/gnunet-cadet-profiler.c
+src/cadet/gnunet-cadet.c
src/cadet/gnunet-service-cadet.c
src/cadet/gnunet-service-cadet_channel.c
src/cadet/gnunet-service-cadet_connection.c
@@ -57,15 +57,15 @@ src/consensus/gnunet-service-consensus.c
src/consensus/plugin_block_consensus.c
src/conversation/conversation_api.c
src/conversation/conversation_api_call.c
-src/conversation/gnunet-conversation.c
src/conversation/gnunet-conversation-test.c
-src/conversation/gnunet_gst.c
-src/conversation/gnunet_gst_test.c
-src/conversation/gnunet-helper-audio-playback.c
+src/conversation/gnunet-conversation.c
src/conversation/gnunet-helper-audio-playback-gst.c
-src/conversation/gnunet-helper-audio-record.c
+src/conversation/gnunet-helper-audio-playback.c
src/conversation/gnunet-helper-audio-record-gst.c
+src/conversation/gnunet-helper-audio-record.c
src/conversation/gnunet-service-conversation.c
+src/conversation/gnunet_gst.c
+src/conversation/gnunet_gst_test.c
src/conversation/microphone.c
src/conversation/plugin_gnsrecord_conversation.c
src/conversation/speaker.c
@@ -101,7 +101,6 @@ src/dht/dht_api.c
src/dht/dht_test_lib.c
src/dht/gnunet-dht-get.c
src/dht/gnunet-dht-monitor.c
-src/dht/gnunet_dht_profiler.c
src/dht/gnunet-dht-put.c
src/dht/gnunet-service-dht.c
src/dht/gnunet-service-dht_clients.c
@@ -110,6 +109,7 @@ src/dht/gnunet-service-dht_hello.c
src/dht/gnunet-service-dht_neighbours.c
src/dht/gnunet-service-dht_nse.c
src/dht/gnunet-service-dht_routing.c
+src/dht/gnunet_dht_profiler.c
src/dht/plugin_block_dht.c
src/dns/dns_api.c
src/dns/gnunet-dns-monitor.c
@@ -123,8 +123,8 @@ src/dv/gnunet-dv.c
src/dv/gnunet-service-dv.c
src/dv/plugin_transport_dv.c
src/exit/gnunet-daemon-exit.c
-src/exit/gnunet-helper-exit.c
src/exit/gnunet-helper-exit-windows.c
+src/exit/gnunet-helper-exit.c
src/fragmentation/defragmentation.c
src/fragmentation/fragmentation.c
src/fs/fs_api.c
@@ -149,8 +149,8 @@ src/fs/gnunet-auto-share.c
src/fs/gnunet-daemon-fsprofiler.c
src/fs/gnunet-directory.c
src/fs/gnunet-download.c
-src/fs/gnunet-fs.c
src/fs/gnunet-fs-profiler.c
+src/fs/gnunet-fs.c
src/fs/gnunet-helper-fs-publish.c
src/fs/gnunet-publish.c
src/fs/gnunet-search.c
@@ -170,10 +170,10 @@ src/gns/gns_tld_api.c
src/gns/gnunet-bcd.c
src/gns/gnunet-dns2gns.c
src/gns/gnunet-gns-benchmark.c
-src/gns/gnunet-gns.c
src/gns/gnunet-gns-helper-service-w32.c
src/gns/gnunet-gns-import.c
src/gns/gnunet-gns-proxy.c
+src/gns/gnunet-gns.c
src/gns/gnunet-service-gns.c
src/gns/gnunet-service-gns_interceptor.c
src/gns/gnunet-service-gns_resolver.c
@@ -181,15 +181,15 @@ src/gns/nss/nss_gns.c
src/gns/nss/nss_gns_query.c
src/gns/plugin_block_gns.c
src/gns/plugin_gnsrecord_gns.c
+src/gns/w32nsp-install.c
+src/gns/w32nsp-resolve.c
+src/gns/w32nsp-uninstall.c
+src/gns/w32nsp.c
src/gnsrecord/gnsrecord.c
src/gnsrecord/gnsrecord_crypto.c
src/gnsrecord/gnsrecord_misc.c
src/gnsrecord/gnsrecord_serialization.c
src/gnsrecord/plugin_gnsrecord_dns.c
-src/gns/w32nsp.c
-src/gns/w32nsp-install.c
-src/gns/w32nsp-resolve.c
-src/gns/w32nsp-uninstall.c
src/hello/address.c
src/hello/gnunet-hello.c
src/hello/hello.c
@@ -218,8 +218,8 @@ src/namecache/namecache_api.c
src/namecache/plugin_namecache_flat.c
src/namecache/plugin_namecache_postgres.c
src/namecache/plugin_namecache_sqlite.c
-src/namestore/gnunet-namestore.c
src/namestore/gnunet-namestore-fcfsd.c
+src/namestore/gnunet-namestore.c
src/namestore/gnunet-service-namestore.c
src/namestore/gnunet-zoneimport.c
src/namestore/namestore_api.c
@@ -234,10 +234,10 @@ src/nat-auto/gnunet-service-nat-auto.c
src/nat-auto/gnunet-service-nat-auto_legacy.c
src/nat-auto/nat_auto_api.c
src/nat-auto/nat_auto_api_test.c
-src/nat/gnunet-helper-nat-client.c
src/nat/gnunet-helper-nat-client-windows.c
-src/nat/gnunet-helper-nat-server.c
+src/nat/gnunet-helper-nat-client.c
src/nat/gnunet-helper-nat-server-windows.c
+src/nat/gnunet-helper-nat-server.c
src/nat/gnunet-nat.c
src/nat/gnunet-service-nat.c
src/nat/gnunet-service-nat_externalip.c
@@ -246,15 +246,15 @@ src/nat/gnunet-service-nat_mini.c
src/nat/gnunet-service-nat_stun.c
src/nat/nat_api.c
src/nat/nat_api_stun.c
-src/nse/gnunet-nse.c
src/nse/gnunet-nse-profiler.c
+src/nse/gnunet-nse.c
src/nse/gnunet-service-nse.c
src/nse/nse_api.c
+src/peerinfo-tool/gnunet-peerinfo.c
+src/peerinfo-tool/gnunet-peerinfo_plugins.c
src/peerinfo/gnunet-service-peerinfo.c
src/peerinfo/peerinfo_api.c
src/peerinfo/peerinfo_api_notify.c
-src/peerinfo-tool/gnunet-peerinfo.c
-src/peerinfo-tool/gnunet-peerinfo_plugins.c
src/peerstore/gnunet-peerstore.c
src/peerstore/gnunet-service-peerstore.c
src/peerstore/peerstore_api.c
@@ -301,7 +301,6 @@ src/regex/regex_internal_dht.c
src/regex/regex_test_graph.c
src/regex/regex_test_lib.c
src/regex/regex_test_random.c
-src/rest/gnunet-rest-server.c
src/rest-plugins/json_reclaim.c
src/rest-plugins/oidc_helper.c
src/rest-plugins/plugin_rest_copying.c
@@ -312,27 +311,28 @@ src/rest-plugins/plugin_rest_namestore.c
src/rest-plugins/plugin_rest_openid_connect.c
src/rest-plugins/plugin_rest_peerinfo.c
src/rest-plugins/plugin_rest_reclaim.c
+src/rest/gnunet-rest-server.c
src/rest/rest.c
src/revocation/gnunet-revocation.c
src/revocation/gnunet-service-revocation.c
src/revocation/plugin_block_revocation.c
src/revocation/revocation_api.c
-src/rps/gnunet-rps.c
src/rps/gnunet-rps-profiler.c
+src/rps/gnunet-rps.c
src/rps/gnunet-service-rps.c
src/rps/gnunet-service-rps_custommap.c
src/rps/gnunet-service-rps_sampler.c
src/rps/gnunet-service-rps_sampler_elem.c
src/rps/gnunet-service-rps_view.c
-src/rps/rps_api.c
src/rps/rps-sampler_client.c
src/rps/rps-sampler_common.c
src/rps/rps-test_util.c
+src/rps/rps_api.c
src/scalarproduct/gnunet-scalarproduct.c
-src/scalarproduct/gnunet-service-scalarproduct_alice.c
-src/scalarproduct/gnunet-service-scalarproduct_bob.c
src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
+src/scalarproduct/gnunet-service-scalarproduct_alice.c
+src/scalarproduct/gnunet-service-scalarproduct_bob.c
src/scalarproduct/scalarproduct_api.c
src/secretsharing/gnunet-secretsharing-profiler.c
src/secretsharing/gnunet-service-secretsharing.c
@@ -361,15 +361,16 @@ src/statistics/gnunet-statistics.c
src/statistics/statistics_api.c
src/template/gnunet-service-template.c
src/template/gnunet-template.c
+src/testbed-logger/gnunet-service-testbed-logger.c
+src/testbed-logger/testbed_logger_api.c
src/testbed/generate-underlay-topology.c
src/testbed/gnunet-daemon-latency-logger.c
src/testbed/gnunet-daemon-testbed-blacklist.c
src/testbed/gnunet-daemon-testbed-underlay.c
src/testbed/gnunet-helper-testbed.c
-src/testbed/gnunet_mpi_test.c
src/testbed/gnunet-service-test-barriers.c
-src/testbed/gnunet-service-testbed_barriers.c
src/testbed/gnunet-service-testbed.c
+src/testbed/gnunet-service-testbed_barriers.c
src/testbed/gnunet-service-testbed_cache.c
src/testbed/gnunet-service-testbed_connectionpool.c
src/testbed/gnunet-service-testbed_cpustatus.c
@@ -377,20 +378,19 @@ src/testbed/gnunet-service-testbed_links.c
src/testbed/gnunet-service-testbed_meminfo.c
src/testbed/gnunet-service-testbed_oc.c
src/testbed/gnunet-service-testbed_peers.c
-src/testbed/gnunet_testbed_mpi_spawn.c
src/testbed/gnunet-testbed-profiler.c
-src/testbed-logger/gnunet-service-testbed-logger.c
-src/testbed-logger/testbed_logger_api.c
-src/testbed/testbed_api_barriers.c
+src/testbed/gnunet_mpi_test.c
+src/testbed/gnunet_testbed_mpi_spawn.c
src/testbed/testbed_api.c
+src/testbed/testbed_api_barriers.c
src/testbed/testbed_api_hosts.c
src/testbed/testbed_api_operations.c
src/testbed/testbed_api_peers.c
src/testbed/testbed_api_sd.c
src/testbed/testbed_api_services.c
src/testbed/testbed_api_statistics.c
-src/testbed/testbed_api_testbed.c
src/testbed/testbed_api_test.c
+src/testbed/testbed_api_testbed.c
src/testbed/testbed_api_topology.c
src/testbed/testbed_api_underlay.c
src/testing/gnunet-testing.c
@@ -398,29 +398,31 @@ src/testing/list-keys.c
src/testing/testing.c
src/topology/friends.c
src/topology/gnunet-daemon-topology.c
+src/transport/gnunet-communicator-unix.c
src/transport/gnunet-helper-transport-bluetooth.c
-src/transport/gnunet-helper-transport-wlan.c
src/transport/gnunet-helper-transport-wlan-dummy.c
-src/transport/gnunet-service-transport_ats.c
+src/transport/gnunet-helper-transport-wlan.c
+src/transport/gnunet-service-tng.c
src/transport/gnunet-service-transport.c
+src/transport/gnunet-service-transport_ats.c
src/transport/gnunet-service-transport_hello.c
src/transport/gnunet-service-transport_manipulation.c
src/transport/gnunet-service-transport_neighbours.c
src/transport/gnunet-service-transport_plugins.c
src/transport/gnunet-service-transport_validation.c
-src/transport/gnunet-transport.c
src/transport/gnunet-transport-certificate-creation.c
src/transport/gnunet-transport-profiler.c
src/transport/gnunet-transport-wlan-receiver.c
src/transport/gnunet-transport-wlan-sender.c
+src/transport/gnunet-transport.c
src/transport/plugin_transport_http_client.c
src/transport/plugin_transport_http_common.c
src/transport/plugin_transport_http_server.c
src/transport/plugin_transport_smtp.c
src/transport/plugin_transport_tcp.c
src/transport/plugin_transport_template.c
-src/transport/plugin_transport_udp_broadcasting.c
src/transport/plugin_transport_udp.c
+src/transport/plugin_transport_udp_broadcasting.c
src/transport/plugin_transport_unix.c
src/transport/plugin_transport_wlan.c
src/transport/plugin_transport_xt.c
@@ -429,6 +431,11 @@ src/transport/tcp_connection_legacy.c
src/transport/tcp_server_legacy.c
src/transport/tcp_server_mst_legacy.c
src/transport/tcp_service_legacy.c
+src/transport/transport-testing-filenames.c
+src/transport/transport-testing-loggers.c
+src/transport/transport-testing-main.c
+src/transport/transport-testing-send.c
+src/transport/transport-testing.c
src/transport/transport_api2_communication.c
src/transport/transport_api_address_to_string.c
src/transport/transport_api_blacklist.c
@@ -438,11 +445,6 @@ src/transport/transport_api_manipulation.c
src/transport/transport_api_monitor_peers.c
src/transport/transport_api_monitor_plugins.c
src/transport/transport_api_offer_hello.c
-src/transport/transport-testing.c
-src/transport/transport-testing-filenames.c
-src/transport/transport-testing-loggers.c
-src/transport/transport-testing-main.c
-src/transport/transport-testing-send.c
src/util/bandwidth.c
src/util/benchmark.c
src/util/bio.c
@@ -455,8 +457,8 @@ src/util/configuration_loader.c
src/util/container_bloomfilter.c
src/util/container_heap.c
src/util/container_meta_data.c
-src/util/container_multihashmap32.c
src/util/container_multihashmap.c
+src/util/container_multihashmap32.c
src/util/container_multipeermap.c
src/util/container_multishortmap.c
src/util/crypto_abe.c
@@ -478,15 +480,15 @@ src/util/dnsparser.c
src/util/dnsstub.c
src/util/getopt.c
src/util/getopt_helpers.c
-src/util/gnunet-config.c
src/util/gnunet-config-diff.c
+src/util/gnunet-config.c
src/util/gnunet-ecc.c
src/util/gnunet-helper-w32-console.c
src/util/gnunet-resolver.c
src/util/gnunet-scrypt.c
src/util/gnunet-service-resolver.c
-src/util/gnunet-timeout.c
src/util/gnunet-timeout-w32.c
+src/util/gnunet-timeout.c
src/util/gnunet-uri.c
src/util/helper.c
src/util/load.c
@@ -514,13 +516,13 @@ src/util/tun.c
src/util/w32cat.c
src/util/win.c
src/util/winproc.c
-src/vpn/gnunet-helper-vpn.c
src/vpn/gnunet-helper-vpn-windows.c
+src/vpn/gnunet-helper-vpn.c
src/vpn/gnunet-service-vpn.c
src/vpn/gnunet-vpn.c
src/vpn/vpn_api.c
-src/zonemaster/gnunet-service-zonemaster.c
src/zonemaster/gnunet-service-zonemaster-monitor.c
+src/zonemaster/gnunet-service-zonemaster.c
src/fs/fs_api.h
src/include/gnunet_common.h
src/include/gnunet_mq_lib.h
diff --git a/src/cadet/test_cadet.conf b/src/cadet/test_cadet.conf
index 5ad67fec2..30e496aff 100644
--- a/src/cadet/test_cadet.conf
+++ b/src/cadet/test_cadet.conf
@@ -98,3 +98,7 @@ START_ON_DEMAND = NO
[topology]
IMMEDIATE_START = NO
START_ON_DEMAND = NO
+
+[rps]
+IMMEDIATE_START = NO
+START_ON_DEMAND = NO
diff --git a/src/fs/fs_getopt.c b/src/fs/fs_getopt.c
index 7b5c2991d..cbd9339c9 100644
--- a/src/fs/fs_getopt.c
+++ b/src/fs/fs_getopt.c
@@ -38,19 +38,20 @@
* @param scls must be of type "struct GNUNET_FS_Uri **"
* @param option name of the option (typically 'k')
* @param value command line argument given
- * @return GNUNET_OK on success
+ * @return #GNUNET_OK on success
*/
static int
-getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext
- *ctx, void *scls, const char *option,
- const char *value)
+getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
+ void *scls,
+ const char *option,
+ const char *value)
{
struct GNUNET_FS_Uri **uri = scls;
struct GNUNET_FS_Uri *u = *uri;
char *val;
size_t slen;
- if (u == NULL)
+ if (NULL == u)
{
u = GNUNET_new (struct GNUNET_FS_Uri);
*uri = u;
@@ -60,10 +61,10 @@ getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext
}
else
{
- GNUNET_assert (u->type == GNUNET_FS_URI_KSK);
+ GNUNET_assert (GNUNET_FS_URI_KSK == u->type);
}
slen = strlen (value);
- if (slen == 0)
+ if (0 == slen)
return GNUNET_SYSERR; /* cannot be empty */
if (value[0] == '+')
{
@@ -75,7 +76,9 @@ getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext
/* remove the quotes, keep the '+' */
val = GNUNET_malloc (slen - 1);
val[0] = '+';
- GNUNET_memcpy (&val[1], &value[2], slen - 3);
+ GNUNET_memcpy (&val[1],
+ &value[2],
+ slen - 3);
val[slen - 2] = '\0';
}
else
@@ -91,7 +94,9 @@ getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext
/* remove the quotes, add a space */
val = GNUNET_malloc (slen);
val[0] = ' ';
- GNUNET_memcpy (&val[1], &value[1], slen - 2);
+ GNUNET_memcpy (&val[1],
+ &value[1],
+ slen - 2);
val[slen - 1] = '\0';
}
else
@@ -102,10 +107,13 @@ getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext
strcat (val, value);
}
}
- GNUNET_array_append (u->data.ksk.keywords, u->data.ksk.keywordCount, val);
+ GNUNET_array_append (u->data.ksk.keywords,
+ u->data.ksk.keywordCount,
+ val);
return GNUNET_OK;
}
+
/**
* Allow user to specify keywords.
*
@@ -135,6 +143,7 @@ GNUNET_FS_GETOPT_KEYWORDS (char shortName,
return clo;
}
+
/**
* Command-line option parser function that allows the user to specify
* one or more '-m' options with metadata. Each specified entry of
diff --git a/src/fs/gnunet-publish.c b/src/fs/gnunet-publish.c
index 999301c2f..ffcf9b5d0 100644
--- a/src/fs/gnunet-publish.c
+++ b/src/fs/gnunet-publish.c
@@ -496,21 +496,22 @@ uri_ksk_continuation (void *cls,
emsg);
ret = 1;
}
- if (NULL != namespace)
+ if (NULL == namespace)
{
- priv = GNUNET_IDENTITY_ego_get_private_key (namespace);
- GNUNET_FS_publish_sks (ctx,
- priv,
- this_id,
- next_id,
- meta,
- uri,
- &bo,
- GNUNET_FS_PUBLISH_OPTION_NONE,
- &uri_sks_continuation, NULL);
+ GNUNET_SCHEDULER_shutdown ();
return;
}
- GNUNET_SCHEDULER_shutdown ();
+ priv = GNUNET_IDENTITY_ego_get_private_key (namespace);
+ GNUNET_FS_publish_sks (ctx,
+ priv,
+ this_id,
+ next_id,
+ meta,
+ uri,
+ &bo,
+ GNUNET_FS_PUBLISH_OPTION_NONE,
+ &uri_sks_continuation,
+ NULL);
}
@@ -728,7 +729,8 @@ identity_continuation (const char *args0)
GNUNET_SCHEDULER_shutdown ();
return;
}
- GNUNET_FS_publish_ksk (ctx, topKeywords,
+ GNUNET_FS_publish_ksk (ctx,
+ topKeywords,
meta, uri,
&bo,
GNUNET_FS_PUBLISH_OPTION_NONE,
@@ -889,7 +891,8 @@ run (void *cls,
* @return 0 ok, 1 on error
*/
int
-main (int argc, char *const *argv)
+main (int argc,
+ char *const *argv)
{
struct GNUNET_GETOPT_CommandLineOption options[] = {
GNUNET_GETOPT_option_uint ('a',
@@ -922,26 +925,22 @@ main (int argc, char *const *argv)
"TYPE:VALUE",
gettext_noop ("set the meta-data for the given TYPE to the given VALUE"),
&meta),
-
GNUNET_GETOPT_option_flag ('n',
- "noindex",
- gettext_noop ("do not index, perform full insertion (stores "
- "entire file in encrypted form in GNUnet database)"),
- &do_insert),
-
+ "noindex",
+ gettext_noop ("do not index, perform full insertion (stores "
+ "entire file in encrypted form in GNUnet database)"),
+ &do_insert),
GNUNET_GETOPT_option_string ('N',
"next",
"ID",
gettext_noop ("specify ID of an updated version to be "
"published in the future (for namespace insertions only)"),
&next_id),
-
GNUNET_GETOPT_option_uint ('p',
- "priority",
- "PRIORITY",
- gettext_noop ("specify the priority of the content"),
- &bo.content_priority),
-
+ "priority",
+ "PRIORITY",
+ gettext_noop ("specify the priority of the content"),
+ &bo.content_priority),
GNUNET_GETOPT_option_string ('P',
"pseudonym",
"NAME",
@@ -964,7 +963,6 @@ main (int argc, char *const *argv)
gettext_noop ("set the ID of this version of the publication "
"(for namespace insertions only)"),
&this_id),
-
GNUNET_GETOPT_option_string ('u',
"uri",
"URI",
@@ -982,10 +980,14 @@ main (int argc, char *const *argv)
if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
return 2;
ret = (GNUNET_OK ==
- GNUNET_PROGRAM_run (argc, argv, "gnunet-publish [OPTIONS] FILENAME",
+ GNUNET_PROGRAM_run (argc,
+ argv,
+ "gnunet-publish [OPTIONS] FILENAME",
gettext_noop
("Publish a file or directory on GNUnet"),
- options, &run, NULL)) ? ret : 1;
+ options,
+ &run,
+ NULL)) ? ret : 1;
GNUNET_free ((void*) argv);
return ret;
}
diff --git a/src/fs/gnunet-search.c b/src/fs/gnunet-search.c
index 780b3c93d..2a0a153e7 100644
--- a/src/fs/gnunet-search.c
+++ b/src/fs/gnunet-search.c
@@ -304,49 +304,44 @@ int
main (int argc, char *const *argv)
{
struct GNUNET_GETOPT_CommandLineOption options[] = {
-
GNUNET_GETOPT_option_uint ('a',
- "anonymity",
- "LEVEL",
- gettext_noop ("set the desired LEVEL of receiver-anonymity"),
- &anonymity),
-
-
+ "anonymity",
+ "LEVEL",
+ gettext_noop ("set the desired LEVEL of receiver-anonymity"),
+ &anonymity),
GNUNET_GETOPT_option_flag ('n',
- "no-network",
- gettext_noop ("only search the local peer (no P2P network search)"),
- &local_only),
-
+ "no-network",
+ gettext_noop ("only search the local peer (no P2P network search)"),
+ &local_only),
GNUNET_GETOPT_option_string ('o',
"output",
"PREFIX",
gettext_noop ("write search results to file starting with PREFIX"),
&output_filename),
-
GNUNET_GETOPT_option_relative_time ('t',
- "timeout",
- "DELAY",
- gettext_noop ("automatically terminate search after DELAY"),
- &timeout),
-
-
+ "timeout",
+ "DELAY",
+ gettext_noop ("automatically terminate search after DELAY"),
+ &timeout),
GNUNET_GETOPT_option_verbose (&verbose),
-
GNUNET_GETOPT_option_uint ('N',
- "results",
- "VALUE",
- gettext_noop ("automatically terminate search "
- "after VALUE results are found"),
- &results_limit),
-
+ "results",
+ "VALUE",
+ gettext_noop ("automatically terminate search "
+ "after VALUE results are found"),
+ &results_limit),
GNUNET_GETOPT_OPTION_END
};
- if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_get_utf8_args (argc, argv,
+ &argc, &argv))
return 2;
ret = (GNUNET_OK ==
- GNUNET_PROGRAM_run (argc, argv, "gnunet-search [OPTIONS] KEYWORD",
+ GNUNET_PROGRAM_run (argc,
+ argv,
+ "gnunet-search [OPTIONS] KEYWORD",
gettext_noop
("Search GNUnet for files that were published on GNUnet"),
options, &run, NULL)) ? ret : 1;
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c
index a9013390e..e1997e215 100644
--- a/src/gns/gnunet-gns-proxy.c
+++ b/src/gns/gnunet-gns-proxy.c
@@ -59,6 +59,12 @@
#define MAX_HTTP_URI_LENGTH 2048
/**
+ * Maximum number of DANE records we support
+ * per domain name (and port and protocol).
+ */
+#define MAX_DANES 32
+
+/**
* Size of the buffer for the data upload / download. Must be
* enough for curl, thus CURL_MAX_WRITE_SIZE is needed here (16k).
*/
@@ -543,9 +549,9 @@ struct Socks5Request
char *leho;
/**
- * Payload of the (last) DANE record encountered.
+ * Payload of the DANE records encountered.
*/
- char *dane_data;
+ char *dane_data[MAX_DANES + 1];
/**
* The URL to fetch
@@ -575,7 +581,13 @@ struct Socks5Request
/**
* Number of bytes in @e dane_data.
*/
- size_t dane_data_len;
+ int dane_data_len[MAX_DANES + 1];
+
+ /**
+ * Number of entries used in @e dane_data_len
+ * and @e dane_data.
+ */
+ unsigned int num_danes;
/**
* Number of bytes already in read buffer
@@ -816,7 +828,8 @@ cleanup_s5r (struct Socks5Request *s5r)
GNUNET_free_non_null (s5r->domain);
GNUNET_free_non_null (s5r->leho);
GNUNET_free_non_null (s5r->url);
- GNUNET_free_non_null (s5r->dane_data);
+ for (unsigned int i=0;i<s5r->num_danes;i++)
+ GNUNET_free (s5r->dane_data[i]);
GNUNET_free (s5r);
}
@@ -989,10 +1002,8 @@ check_ssl_certificate (struct Socks5Request *s5r)
}
/* check for TLSA/DANE records */
#if HAVE_GNUTLS_DANE
- if (NULL != s5r->dane_data)
+ if (0 != s5r->num_danes)
{
- char *dd[] = { s5r->dane_data, NULL };
- int dlen[] = { s5r->dane_data_len, 0};
dane_state_t dane_state;
dane_query_t dane_query;
unsigned int verify;
@@ -1010,10 +1021,12 @@ check_ssl_certificate (struct Socks5Request *s5r)
gnutls_x509_crt_deinit (x509_cert);
return GNUNET_SYSERR;
}
+ s5r->dane_data[s5r->num_danes] = NULL;
+ s5r->dane_data_len[s5r->num_danes] = 0;
if (0 != (rc = dane_raw_tlsa (dane_state,
&dane_query,
- dd,
- dlen,
+ s5r->dane_data,
+ s5r->dane_data_len,
GNUNET_YES,
GNUNET_NO)))
{
@@ -3070,12 +3083,17 @@ handle_gns_result (void *cls,
(ntohs (box->protocol) != IPPROTO_TCP) ||
(ntohs (box->service) != s5r->port) )
break; /* BOX record does not apply */
- GNUNET_free_non_null (s5r->dane_data);
- s5r->dane_data_len = r->data_size - sizeof (struct GNUNET_GNSRECORD_BoxRecord);
- s5r->dane_data = GNUNET_malloc (s5r->dane_data_len);
- GNUNET_memcpy (s5r->dane_data,
- &box[1],
- s5r->dane_data_len);
+ if (s5r->num_danes >= MAX_DANES)
+ {
+ GNUNET_break (0); /* MAX_DANES too small */
+ break;
+ }
+ s5r->dane_data_len[s5r->num_danes]
+ = r->data_size - sizeof (struct GNUNET_GNSRECORD_BoxRecord);
+ s5r->dane_data[s5r->num_danes]
+ = GNUNET_memdup (&box[1],
+ s5r->dane_data_len);
+ s5r->num_danes++;
break;
}
default:
diff --git a/src/gns/test_gns_defaults.conf b/src/gns/test_gns_defaults.conf
index 19ba01ebb..80a2f3c44 100644
--- a/src/gns/test_gns_defaults.conf
+++ b/src/gns/test_gns_defaults.conf
@@ -20,3 +20,15 @@ PLUGINS = tcp
[transport-tcp]
BINDTO = 127.0.0.1
+
+[fs]
+IMMEDIATE_START = NO
+START_ON_DEMAND = NO
+
+[rps]
+IMMEDIATE_START = NO
+START_ON_DEMAND = NO
+
+[topology]
+IMMEDIATE_START = NO
+START_ON_DEMAND = NO
diff --git a/src/gns/test_gns_gns2dns_cname_lookup.sh b/src/gns/test_gns_gns2dns_cname_lookup.sh
index 84ad8549f..17196f820 100755
--- a/src/gns/test_gns_gns2dns_cname_lookup.sh
+++ b/src/gns/test_gns_gns2dns_cname_lookup.sh
@@ -43,7 +43,15 @@ MY_EGO="myego"
# various names we will use for resolution
TEST_DOMAIN="www.${TEST_RECORD_NAME}.$MY_EGO"
+which timeout &> /dev/null && DO_TIMEOUT="timeout 15"
+
+
gnunet-arm -s -c test_gns_lookup.conf
+
+echo $OUT | grep $TEST_IP - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv4 for gnunet.org not found, skipping test"; exit 77; }
+echo $OUT | grep $TEST6_IP - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv6 for gnunet.org not found, skipping test"; exit 77; }
+
+
gnunet-identity -C $MY_EGO -c test_gns_lookup.conf
# set IP address for DNS resolver for resolving in gnunet.org domain
@@ -52,7 +60,6 @@ gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECOR
gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECORD_GNS2DNS2 -e never -c test_gns_lookup.conf
gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECORD_GNS2DNS3 -e never -c test_gns_lookup.conf
-which timeout &> /dev/null && DO_TIMEOUT="timeout 15"
echo "EGOs:"
gnunet-identity -d
diff --git a/src/gns/test_gns_gns2dns_lookup.sh b/src/gns/test_gns_gns2dns_lookup.sh
index 122e45525..431f01086 100755
--- a/src/gns/test_gns_gns2dns_lookup.sh
+++ b/src/gns/test_gns_gns2dns_lookup.sh
@@ -44,8 +44,17 @@ TEST_DOMAIN="www.${TEST_RECORD_NAME}.$MY_EGO"
TEST_DOMAIN_ALT="${TEST_RECORD_NAME}.$MY_EGO"
TEST_DOMAIN_ALT2="docs.${TEST_RECORD_NAME}.$MY_EGO"
+which timeout &> /dev/null && DO_TIMEOUT="timeout 15"
+
gnunet-arm -s -c test_gns_lookup.conf
+
+OUT=`$DO_TIMEOUT gnunet-resolver -c test_gns_lookup.conf gnunet.org`
+echo $OUT | grep $TEST_IP - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv4 for gnunet.org not found, skipping test"; exit 77; }
+echo $OUT | grep $TEST6_IP - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv6 for gnunet.org not found, skipping test"; exit 77; }
+
+
+
gnunet-identity -C $MY_EGO -c test_gns_lookup.conf
# set IP address for DNS resolver for resolving in gnunet.org domain
@@ -53,7 +62,6 @@ gnunet-namestore -p -z $MY_EGO -a -n $TEST_RESOLVER_LABEL -t A -V $TEST_IP_GNS2D
# map '$TEST_RECORD_NAME.$MY_EGO' to 'gnunet.org' in DNS
gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECORD_GNS2DNS -e never -c test_gns_lookup.conf
-which timeout &> /dev/null && DO_TIMEOUT="timeout 15"
echo "EGOs:"
gnunet-identity -d
diff --git a/src/gnsrecord/gnsrecord.c b/src/gnsrecord/gnsrecord.c
index b80d86073..f0d7a839e 100644
--- a/src/gnsrecord/gnsrecord.c
+++ b/src/gnsrecord/gnsrecord.c
@@ -28,10 +28,7 @@
#include "gnunet_constants.h"
#include "gnunet_gnsrecord_lib.h"
#include "gnunet_gnsrecord_plugin.h"
-#include "gnunet_json_lib.h"
#include "gnunet_tun_lib.h"
-#include <jansson.h>
-
#define LOG(kind,...) GNUNET_log_from (kind, "gnsrecord",__VA_ARGS__)
diff --git a/src/include/gnunet_configuration_lib.h b/src/include/gnunet_configuration_lib.h
index e3eefa18d..ec3d12738 100644
--- a/src/include/gnunet_configuration_lib.h
+++ b/src/include/gnunet_configuration_lib.h
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- Copyright (C) 2006, 2008, 2009 GNUnet e.V.
+ Copyright (C) 2006, 2008, 2009, 2018 GNUnet e.V.
GNUnet is free software: you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License as published
@@ -191,6 +191,35 @@ GNUNET_CONFIGURATION_is_dirty (const struct GNUNET_CONFIGURATION_Handle *cfg);
/**
+ * Signature of a function to be run with a configuration.
+ *
+ * @param cls closure
+ * @param cfg the configuration
+ * @return status code
+ */
+typedef int
+(*GNUNET_CONFIGURATION_Callback)(void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg);
+
+
+/**
+ * Parse a configuration file @a filename and run the function
+ * @a cb with the resulting configuration object. Then free the
+ * configuration object and return the status value from @a cb.
+ *
+ * @param filename configuration to parse, NULL for "default"
+ * @param cb function to run
+ * @param cb_cls closure for @a cb
+ * @return #GNUNET_SYSERR if parsing the configuration failed,
+ * otherwise return value from @a cb.
+ */
+int
+GNUNET_CONFIGURATION_parse_and_run (const char *filename,
+ GNUNET_CONFIGURATION_Callback cb,
+ void *cb_cls);
+
+
+/**
* Function to iterate over options.
*
* @param cls closure
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 898ad6258..fbdee5415 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -3051,15 +3051,30 @@ extern "C"
#define GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE 1206
/**
+ * Response from communicator: will try to create queue.
+ */
+#define GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_OK 1207
+
+/**
+ * Response from communicator: address bogus, will not try to create queue.
+ */
+#define GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_FAIL 1208
+
+/**
* @brief transport tells communicator it wants to transmit
*/
-#define GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG 1207
+#define GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG 1209
/**
* @brief communicator tells transports that message was sent
*/
-#define GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG_ACK 1208
+#define GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG_ACK 1210
+/**
+ * Message sent to indicate to the transport which address
+ * prefix is supported by a communicator.
+ */
+#define GNUNET_MESSAGE_TYPE_TRANSPORT_NEW_COMMUNICATOR 1211
/**
* Next available: 1300
diff --git a/src/include/gnunet_transport_communication_service.h b/src/include/gnunet_transport_communication_service.h
index d93d5134e..50f94bddf 100644
--- a/src/include/gnunet_transport_communication_service.h
+++ b/src/include/gnunet_transport_communication_service.h
@@ -42,6 +42,7 @@ extern "C"
#endif
#include "gnunet_util_lib.h"
+#include "gnunet_ats_service.h"
/**
* Version number of the transport communication API.
@@ -69,7 +70,7 @@ extern "C"
typedef int
(*GNUNET_TRANSPORT_CommunicatorMqInit) (void *cls,
const struct GNUNET_PeerIdentity *peer,
- const void *address);
+ const char *address);
/**
@@ -82,7 +83,9 @@ struct GNUNET_TRANSPORT_CommunicatorHandle;
* Connect to the transport service.
*
* @param cfg configuration to use
- * @param name name of the communicator that is connecting
+ * @param config_section section of the configuration to use for options
+ * @param addr_prefix address prefix for addresses supported by this
+ * communicator, could be NULL for incoming-only communicators
* @param mtu maximum message size supported by communicator, 0 if
* sending is not supported, SIZE_MAX for no MTU
* @param mq_init function to call to initialize a message queue given
@@ -93,7 +96,8 @@ struct GNUNET_TRANSPORT_CommunicatorHandle;
*/
struct GNUNET_TRANSPORT_CommunicatorHandle *
GNUNET_TRANSPORT_communicator_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const char *name,
+ const char *config_section_name,
+ const char *addr_prefix,
size_t mtu,
GNUNET_TRANSPORT_CommunicatorMqInit mq_init,
void *mq_init_cls);
diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c
index c5f48848e..619d0c528 100644
--- a/src/namestore/gnunet-namestore.c
+++ b/src/namestore/gnunet-namestore.c
@@ -33,6 +33,24 @@
/**
+ * Entry in record set for bulk processing.
+ */
+struct RecordSetEntry
+{
+ /**
+ * Kept in a linked list.
+ */
+ struct RecordSetEntry *next;
+
+ /**
+ * The record to add/remove.
+ */
+ struct GNUNET_GNSRECORD_Data record;
+
+};
+
+
+/**
* Handle to the namestore.
*/
static struct GNUNET_NAMESTORE_Handle *ns;
@@ -173,14 +191,10 @@ static void *data;
static size_t data_size;
/**
- * Expirationstring converted to relative time.
+ * Expiration string converted to numeric value.
*/
-static struct GNUNET_TIME_Relative etime_rel;
+static uint64_t etime;
-/**
- * Expirationstring converted to absolute time.
- */
-static struct GNUNET_TIME_Absolute etime_abs;
/**
* Is expiration time relative or absolute time?
@@ -197,6 +211,11 @@ static struct GNUNET_NAMESTORE_ZoneMonitor *zm;
*/
static int monitor;
+/**
+ * Entry in record set for processing records in bulk.
+ */
+static struct RecordSetEntry *recordset;
+
/**
* Task run on shutdown. Cleans up everything.
@@ -516,6 +535,8 @@ display_record_lookup (void *cls,
unsigned int rd_len,
const struct GNUNET_GNSRECORD_Data *rd)
{
+ (void) cls;
+ (void) zone_key;
get_qe = NULL;
display_record (rname,
rd_len,
@@ -694,14 +715,10 @@ get_existing_record (void *cls,
rde->flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD;
if (1 != is_public)
rde->flags |= GNUNET_GNSRECORD_RF_PRIVATE;
+ rde->expiration_time = etime;
if (GNUNET_YES == etime_is_rel)
- {
- rde->expiration_time = etime_rel.rel_value_us;
rde->flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
- }
- else if (GNUNET_NO == etime_is_rel)
- rde->expiration_time = etime_abs.abs_value_us;
- else
+ else if (GNUNET_NO != etime_is_rel)
rde->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
GNUNET_assert (NULL != name);
add_qe = GNUNET_NAMESTORE_records_store (ns,
@@ -864,6 +881,94 @@ del_monitor (void *cls,
/**
+ * Parse expiration time.
+ *
+ * @param expirationstring text to parse
+ * @param etime_is_rel[out] set to #GNUNET_YES if time is relative
+ * @param etime[out] set to expiration time (abs or rel)
+ * @return #GNUNET_OK on success
+ */
+static int
+parse_expiration (const char *expirationstring,
+ int *etime_is_rel,
+ uint64_t *etime)
+{
+ struct GNUNET_TIME_Relative etime_rel;
+ struct GNUNET_TIME_Absolute etime_abs;
+
+ if (0 == strcmp (expirationstring,
+ "never"))
+ {
+ *etime = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
+ *etime_is_rel = GNUNET_NO;
+ return GNUNET_OK;
+ }
+ if (GNUNET_OK ==
+ GNUNET_STRINGS_fancy_time_to_relative (expirationstring,
+ &etime_rel))
+ {
+ *etime_is_rel = GNUNET_YES;
+ *etime = etime_rel.rel_value_us;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Storing record with relative expiration time of %s\n",
+ GNUNET_STRINGS_relative_time_to_string (etime_rel,
+ GNUNET_NO));
+ return GNUNET_OK;
+ }
+ if (GNUNET_OK ==
+ GNUNET_STRINGS_fancy_time_to_absolute (expirationstring,
+ &etime_abs))
+ {
+ *etime_is_rel = GNUNET_NO;
+ *etime = etime_abs.abs_value_us;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Storing record with absolute expiration time of %s\n",
+ GNUNET_STRINGS_absolute_time_to_string (etime_abs));
+ return GNUNET_OK;
+ }
+ return GNUNET_SYSERR;
+}
+
+
+#if 0
+/* globals? */
+unsigned int rd_count;
+struct GNUNET_GNSRECORD_Data *rd;
+
+
+rd_count = 0;
+for (struct RecordSetEntry *e = recordset; NULL != e; e = e->next)
+ rd_count++;
+rd = GNUNET_new_array (rd_count,
+ struct GNUNET_GNSRECORD_Data);
+rd_count = 0;
+for (struct RecordSetEntry *e = recordset; NULL != e; e = e->next)
+{
+ rd[rd_count] = e->record;
+ rd_count++;
+}
+
+/* if add: */
+qe = GNUNET_NAMESTORE_records_store (...,
+ rd_count,
+ rd,
+ &my_cont
+ ..);
+
+in 'my_cont' and/or shutdown:
+
+qe = NULL;
+GNUNET_free (rd);
+
+in shutdown:
+
+if NULL != qe NAMESTORE_cancel (qe);
+GNUNET_free (rd);
+
+#endif
+
+
+/**
* Callback invoked from identity service with ego information.
* An @a ego of NULL means the ego was not found.
*
@@ -976,32 +1081,10 @@ identity_cb (void *cls,
ret = 1;
return;
}
- if (0 == strcmp (expirationstring,
- "never"))
- {
- etime_abs = GNUNET_TIME_UNIT_FOREVER_ABS;
- etime_is_rel = GNUNET_NO;
- }
- else if (GNUNET_OK ==
- GNUNET_STRINGS_fancy_time_to_relative (expirationstring,
- &etime_rel))
- {
- etime_is_rel = GNUNET_YES;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Storing record with relative expiration time of %s\n",
- GNUNET_STRINGS_relative_time_to_string (etime_rel,
- GNUNET_NO));
- }
- else if (GNUNET_OK ==
- GNUNET_STRINGS_fancy_time_to_absolute (expirationstring,
- &etime_abs))
- {
- etime_is_rel = GNUNET_NO;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Storing record with absolute expiration time of %s\n",
- GNUNET_STRINGS_absolute_time_to_string (etime_abs));
- }
- else
+ if (GNUNET_OK !=
+ parse_expiration (expirationstring,
+ &etime_is_rel,
+ &etime))
{
fprintf (stderr,
_("Invalid time format `%s'\n"),
@@ -1106,16 +1189,9 @@ identity_cb (void *cls,
rd.data = &pkey;
rd.data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey);
rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY;
- if (GNUNET_YES == etime_is_rel)
- {
- rd.expiration_time = etime_rel.rel_value_us;
+ rd.expiration_time = etime;
+ if (GNUNET_YES == etime_is_rel)
rd.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
- }
- else if (GNUNET_NO == etime_is_rel)
- rd.expiration_time = etime_abs.abs_value_us;
- else
- rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
-
if (1 == is_shadow)
rd.flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD;
add_qe_uri = GNUNET_NAMESTORE_records_store (ns,
@@ -1247,6 +1323,161 @@ run (void *cls,
/**
+ * Command-line option parser function that allows the user to specify
+ * a complete record as one argument for adding/removing. A pointer
+ * to the head of the list of record sets must be passed as the "scls"
+ * argument.
+ *
+ * @param ctx command line processor context
+ * @param scls must be of type "struct GNUNET_FS_Uri **"
+ * @param option name of the option (typically 'R')
+ * @param value command line argument given; format is
+ * "TTL TYPE FLAGS VALUE" where TTL is an expiration time (rel or abs),
+ * TYPE is a DNS/GNS record type, FLAGS is either "n" for no flags or
+ * a combination of 's' (shadow) and 'p' (public) and VALUE is the
+ * value (in human-readable format)
+ * @return #GNUNET_OK on success
+ */
+static int
+multirecord_process (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
+ void *scls,
+ const char *option,
+ const char *value)
+{
+ struct RecordSetEntry **head = scls;
+ struct RecordSetEntry *r;
+ struct GNUNET_GNSRECORD_Data record;
+ char *cp;
+ char *tok;
+ int etime_is_rel;
+ void *raw_data;
+
+ (void) ctx;
+ (void) option;
+ cp = GNUNET_strdup (value);
+ tok = strtok (cp, " ");
+ if (NULL == tok)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ _("Empty record line argument is not allowed.\n"));
+ GNUNET_free (cp);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK !=
+ parse_expiration (tok,
+ &etime_is_rel,
+ &record.expiration_time))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ _("Invalid expiration time `%s'\n"),
+ tok);
+ GNUNET_free (cp);
+ return GNUNET_SYSERR;
+ }
+ tok = strtok (NULL, " ");
+ if (NULL == tok)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ _("Missing entries in record line `%s'.\n"),
+ value);
+ GNUNET_free (cp);
+ return GNUNET_SYSERR;
+ }
+ record.record_type = GNUNET_GNSRECORD_typename_to_number (tok);
+ if (UINT32_MAX == record.record_type)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ _("Unknown record type `%s'\n"),
+ tok);
+ GNUNET_free (cp);
+ return GNUNET_SYSERR;
+ }
+ tok = strtok (NULL, " ");
+ if (NULL == tok)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ _("Missing entries in record line `%s'.\n"),
+ value);
+ GNUNET_free (cp);
+ return GNUNET_SYSERR;
+ }
+ record.flags = GNUNET_GNSRECORD_RF_NONE;
+ if (etime_is_rel)
+ record.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+ if (NULL == strchr (tok, (unsigned char) 'p')) /* p = public */
+ record.flags |= GNUNET_GNSRECORD_RF_PRIVATE;
+ if (NULL != strchr (tok, (unsigned char) 's'))
+ record.flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD;
+ /* find beginning of record value */
+ tok = strchr (&value[tok - cp], (unsigned char) ' ');
+ if (NULL == tok)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ _("Missing entries in record line `%s'.\n"),
+ value);
+ GNUNET_free (cp);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_free (cp);
+ tok++; /* skip space */
+ if (GNUNET_OK !=
+ GNUNET_GNSRECORD_string_to_value (record.record_type,
+ tok,
+ &raw_data,
+ &record.data_size))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ _("Invalid record data for type %s: `%s'.\n"),
+ GNUNET_GNSRECORD_number_to_typename (record.record_type),
+ tok);
+ return GNUNET_SYSERR;
+ }
+
+ r = GNUNET_malloc (sizeof (struct RecordSetEntry) + record.data_size);
+ r->next = *head;
+ record.data = &r[1];
+ memcpy (&r[1],
+ raw_data,
+ record.data_size);
+ GNUNET_free (raw_data);
+ r->record = record;
+ *head = r;
+ return GNUNET_OK;
+}
+
+
+/**
+ * Allow user to specify keywords.
+ *
+ * @param shortName short name of the option
+ * @param name long name of the option
+ * @param argumentHelp help text for the option argument
+ * @param description long help text for the option
+ * @param[out] topKeywords set to the desired value
+ */
+struct GNUNET_GETOPT_CommandLineOption
+multirecord_option (char shortName,
+ const char *name,
+ const char *argumentHelp,
+ const char *description,
+ struct RecordSetEntry **rs)
+{
+ struct GNUNET_GETOPT_CommandLineOption clo = {
+ .shortName = shortName,
+ .name = name,
+ .argumentHelp = argumentHelp,
+ .description = description,
+ .require_argument = 1,
+ .processor = &multirecord_process,
+ .scls = (void *) rs
+ };
+
+ return clo;
+}
+
+
+
+/**
* The main function for gnunet-namestore.
*
* @param argc number of arguments from the command line
@@ -1294,6 +1525,11 @@ main (int argc,
"PKEY",
gettext_noop ("determine our name for the given PKEY"),
&reverse_pkey),
+ multirecord_option ('R',
+ "record",
+ "RECORDLINE",
+ gettext_noop ("complete record on one line to add/delete/display; can be specified multiple times"),
+ &recordset),
GNUNET_GETOPT_option_string ('t',
"type",
"TYPE",
diff --git a/src/topology/gnunet-daemon-topology.c b/src/topology/gnunet-daemon-topology.c
index f7a4e4525..dd384d9a1 100644
--- a/src/topology/gnunet-daemon-topology.c
+++ b/src/topology/gnunet-daemon-topology.c
@@ -1213,7 +1213,8 @@ run (void *cls,
* @return 0 ok, 1 on error
*/
int
-main (int argc, char *const *argv)
+main (int argc,
+ char *const *argv)
{
static const struct GNUNET_GETOPT_CommandLineOption options[] = {
GNUNET_GETOPT_OPTION_END
diff --git a/src/transport/.gitignore b/src/transport/.gitignore
index d035b4011..90f908a47 100644
--- a/src/transport/.gitignore
+++ b/src/transport/.gitignore
@@ -83,3 +83,4 @@ test_transport_blacklisting_outbound_bl_full
test_transport_blacklisting_outbound_bl_plugin
test_transport_testing_restart
test_transport_testing_startstop
+gnunet-communicator-unix
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index d0db6b141..92b53137f 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -140,6 +140,7 @@ endif
noinst_PROGRAMS = \
gnunet-transport-profiler \
+ gnunet-communicator-unix \
$(WLAN_BIN_SENDER) \
$(WLAN_BIN_RECEIVER)
@@ -149,6 +150,7 @@ endif
lib_LTLIBRARIES = \
libgnunettransport.la \
+ libgnunettransportcommunicator.la \
$(TESTING_LIBS)
libgnunettransporttesting_la_SOURCES = \
@@ -187,6 +189,17 @@ libgnunettransport_la_LDFLAGS = \
$(GN_LIB_LDFLAGS) $(WINFLAGS) \
-version-info 4:0:2
+
+
+libgnunettransportcommunicator_la_SOURCES = \
+ transport_api2_communication.c
+libgnunettransportcommunicator_la_LIBADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(GN_LIBINTL)
+libgnunettransportcommunicator_la_LDFLAGS = \
+ $(GN_LIB_LDFLAGS) $(WINFLAGS) \
+ -version-info 0:0:0
+
libexec_PROGRAMS = \
$(WLAN_BIN) \
$(WLAN_BIN_DUMMY) \
@@ -207,6 +220,14 @@ gnunet_transport_certificate_creation_SOURCES = \
gnunet_transport_certificate_creation_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la
+gnunet_communicator_unix_SOURCES = \
+ gnunet-communicator-unix.c
+gnunet_communicator_unix_LDADD = \
+ libgnunettransportcommunicator.la \
+ $(top_builddir)/src/statistics/libgnunetstatistics.la \
+ $(top_builddir)/src/util/libgnunetutil.la
+
+
gnunet_helper_transport_wlan_SOURCES = \
gnunet-helper-transport-wlan.c
diff --git a/src/transport/gnunet-communicator-unix.c b/src/transport/gnunet-communicator-unix.c
new file mode 100644
index 000000000..cd3ae5dce
--- /dev/null
+++ b/src/transport/gnunet-communicator-unix.c
@@ -0,0 +1,1148 @@
+/*
+ This file is part of GNUnet
+ Copyright (C) 2010-2014, 2018 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file transport/gnunet-communicator-unix.c
+ * @brief Transport plugin using unix domain sockets (!)
+ * Clearly, can only be used locally on Unix/Linux hosts...
+ * ONLY INTENDED FOR TESTING!!!
+ * @author Christian Grothoff
+ * @author Nathan Evans
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_protocols.h"
+#include "gnunet_statistics_service.h"
+#include "gnunet_transport_communication_service.h"
+
+/**
+ * How many messages do we keep at most in the queue to the
+ * transport service before we start to drop (default,
+ * can be changed via the configuration file).
+ * Should be _below_ the level of the communicator API, as
+ * otherwise we may read messages just to have them dropped
+ * by the communicator API.
+ */
+#define DEFAULT_MAX_QUEUE_LENGTH 8
+
+/**
+ * Address prefix used by the communicator.
+ */
+#define COMMUNICATOR_ADDRESS_PREFIX "unix"
+
+/**
+ * Configuration section used by the communicator.
+ */
+#define COMMUNICATOR_CONFIG_SECTION "communicator-unix"
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * UNIX Message-Packet header.
+ */
+struct UNIXMessage
+{
+ /**
+ * Message header.
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * What is the identity of the sender (GNUNET_hash of public key)
+ */
+ struct GNUNET_PeerIdentity sender;
+
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
+/**
+ * Handle for a queue.
+ */
+struct Queue
+{
+
+ /**
+ * Queues with pending messages (!) are kept in a DLL.
+ */
+ struct Queue *next;
+
+ /**
+ * Queues with pending messages (!) are kept in a DLL.
+ */
+ struct Queue *prev;
+
+ /**
+ * To whom are we talking to.
+ */
+ struct GNUNET_PeerIdentity target;
+
+ /**
+ * Address of the other peer.
+ */
+ struct sockaddr_un *address;
+
+ /**
+ * Length of the address.
+ */
+ socklen_t address_len;
+
+ /**
+ * Message currently scheduled for transmission, non-NULL if and only
+ * if this queue is in the #queue_head DLL.
+ */
+ const struct GNUNET_MessageHeader *msg;
+
+ /**
+ * Message queue we are providing for the #ch.
+ */
+ struct GNUNET_MQ_Handle *mq;
+
+ /**
+ * handle for this queue with the #ch.
+ */
+ struct GNUNET_TRANSPORT_QueueHandle *qh;
+
+ /**
+ * Number of bytes we currently have in our write queue.
+ */
+ unsigned long long bytes_in_queue;
+
+ /**
+ * Timeout for this queue.
+ */
+ struct GNUNET_TIME_Absolute timeout;
+
+ /**
+ * Queue timeout task.
+ */
+ struct GNUNET_SCHEDULER_Task *timeout_task;
+
+};
+
+
+/**
+ * ID of read task
+ */
+static struct GNUNET_SCHEDULER_Task *read_task;
+
+/**
+ * ID of write task
+ */
+static struct GNUNET_SCHEDULER_Task *write_task;
+
+/**
+ * Number of messages we currently have in our queues towards the transport service.
+ */
+static unsigned long long delivering_messages;
+
+/**
+ * Maximum queue length before we stop reading towards the transport service.
+ */
+static unsigned long long max_queue_length;
+
+/**
+ * For logging statistics.
+ */
+static struct GNUNET_STATISTICS_Handle *stats;
+
+/**
+ * Our environment.
+ */
+static struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
+
+/**
+ * Queues (map from peer identity to `struct Queue`)
+ */
+static struct GNUNET_CONTAINER_MultiPeerMap *queue_map;
+
+/**
+ * Head of queue of messages to transmit.
+ */
+static struct Queue *queue_head;
+
+/**
+ * Tail of queue of messages to transmit.
+ */
+static struct Queue *queue_tail;
+
+/**
+ * socket that we transmit all data with
+ */
+static struct GNUNET_NETWORK_Handle *unix_sock;
+
+/**
+ * Handle to the operation that publishes our address.
+ */
+static struct GNUNET_TRANSPORT_AddressIdentifier *ai;
+
+
+/**
+ * Functions with this signature are called whenever we need
+ * to close a queue due to a disconnect or failure to
+ * establish a connection.
+ *
+ * @param queue queue to close down
+ */
+static void
+queue_destroy (struct Queue *queue)
+{
+ struct GNUNET_MQ_Handle *mq;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Disconnecting queue for peer `%s'\n",
+ GNUNET_i2s (&queue->target));
+ if (0 != queue->bytes_in_queue)
+ {
+ GNUNET_CONTAINER_DLL_remove (queue_head,
+ queue_tail,
+ queue);
+ queue->bytes_in_queue = 0;
+ }
+ if (NULL != (mq = queue->mq))
+ {
+ queue->mq = NULL;
+ GNUNET_MQ_destroy (mq);
+ }
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CONTAINER_multipeermap_remove (queue_map,
+ &queue->target,
+ queue));
+ GNUNET_STATISTICS_set (stats,
+ "# UNIX queues active",
+ GNUNET_CONTAINER_multipeermap_size (queue_map),
+ GNUNET_NO);
+ if (NULL != queue->timeout_task)
+ {
+ GNUNET_SCHEDULER_cancel (queue->timeout_task);
+ queue->timeout_task = NULL;
+ }
+ GNUNET_free (queue->address);
+ GNUNET_free (queue);
+}
+
+
+/**
+ * Queue was idle for too long, so disconnect it
+ *
+ * @param cls the `struct Queue *` to disconnect
+ */
+static void
+queue_timeout (void *cls)
+{
+ struct Queue *queue = cls;
+ struct GNUNET_TIME_Relative left;
+
+ queue->timeout_task = NULL;
+ left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
+ if (0 != left.rel_value_us)
+ {
+ /* not actually our turn yet, but let's at least update
+ the monitor, it may think we're about to die ... */
+ queue->timeout_task
+ = GNUNET_SCHEDULER_add_delayed (left,
+ &queue_timeout,
+ queue);
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Queue %p was idle for %s, disconnecting\n",
+ queue,
+ GNUNET_STRINGS_relative_time_to_string (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
+ GNUNET_YES));
+ queue_destroy (queue);
+}
+
+
+/**
+ * Increment queue timeout due to activity. We do not immediately
+ * notify the monitor here as that might generate excessive
+ * signalling.
+ *
+ * @param queue queue for which the timeout should be rescheduled
+ */
+static void
+reschedule_queue_timeout (struct Queue *queue)
+{
+ GNUNET_assert (NULL != queue->timeout_task);
+ queue->timeout
+ = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
+}
+
+
+/**
+ * Convert unix path to a `struct sockaddr_un *`
+ *
+ * @param unixpath path to convert
+ * @param[out] sock_len set to the length of the address
+ * @param is_abstract is this an abstract @a unixpath
+ * @return converted unix path
+ */
+static struct sockaddr_un *
+unix_address_to_sockaddr (const char *unixpath,
+ socklen_t *sock_len)
+{
+ struct sockaddr_un *un;
+ size_t slen;
+
+ GNUNET_assert (0 < strlen (unixpath)); /* sanity check */
+ un = GNUNET_new (struct sockaddr_un);
+ un->sun_family = AF_UNIX;
+ slen = strlen (unixpath);
+ if (slen >= sizeof (un->sun_path))
+ slen = sizeof (un->sun_path) - 1;
+ GNUNET_memcpy (un->sun_path,
+ unixpath,
+ slen);
+ un->sun_path[slen] = '\0';
+ slen = sizeof (struct sockaddr_un);
+#if HAVE_SOCKADDR_UN_SUN_LEN
+ un->sun_len = (u_char) slen;
+#endif
+ (*sock_len) = slen;
+ if ('@' == un->sun_path[0])
+ un->sun_path[0] = '\0';
+ return un;
+}
+
+
+/**
+ * Closure to #lookup_queue_it().
+ */
+struct LookupCtx
+{
+ /**
+ * Location to store the queue, if found.
+ */
+ struct Queue *res;
+
+ /**
+ * Address we are looking for.
+ */
+ const struct sockaddr_un *un;
+
+ /**
+ * Number of bytes in @a un
+ */
+ socklen_t un_len;
+};
+
+
+/**
+ * Function called to find a queue by address.
+ *
+ * @param cls the `struct LookupCtx *`
+ * @param key peer we are looking for (unused)
+ * @param value a queue
+ * @return #GNUNET_YES if not found (continue looking), #GNUNET_NO on success
+ */
+static int
+lookup_queue_it (void *cls,
+ const struct GNUNET_PeerIdentity *key,
+ void *value)
+{
+ struct LookupCtx *lctx = cls;
+ struct Queue *queue = value;
+
+ if ( (queue->address_len = lctx->un_len) &&
+ (0 == memcmp (lctx->un,
+ queue->address,
+ queue->address_len)) )
+ {
+ lctx->res = queue;
+ return GNUNET_NO;
+ }
+ return GNUNET_YES;
+}
+
+
+/**
+ * Find an existing queue by address.
+ *
+ * @param plugin the plugin
+ * @param address the address to find
+ * @return NULL if queue was not found
+ */
+static struct Queue *
+lookup_queue (const struct GNUNET_PeerIdentity *peer,
+ const struct sockaddr_un *un,
+ socklen_t un_len)
+{
+ struct LookupCtx lctx;
+
+ lctx.un = un;
+ lctx.un_len = un_len;
+ GNUNET_CONTAINER_multipeermap_get_multiple (queue_map,
+ peer,
+ &lookup_queue_it,
+ &lctx);
+ return lctx.res;
+}
+
+
+/**
+ * We have been notified that our socket is ready to write.
+ * Then reschedule this function to be called again once more is available.
+ *
+ * @param cls NULL
+ */
+static void
+select_write_cb (void *cls)
+{
+ struct Queue *queue = queue_tail;
+ const struct GNUNET_MessageHeader *msg = queue->msg;
+ size_t msg_size = ntohs (msg->size);
+ ssize_t sent;
+
+ /* take queue of the ready list */
+ write_task = NULL;
+ GNUNET_CONTAINER_DLL_remove (queue_head,
+ queue_tail,
+ queue);
+ if (NULL != queue_head)
+ write_task =
+ GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
+ unix_sock,
+ &select_write_cb,
+ NULL);
+
+ /* send 'msg' */
+ queue->msg = NULL;
+ GNUNET_MQ_impl_send_continue (queue->mq);
+ resend:
+ /* Send the data */
+ sent = GNUNET_NETWORK_socket_sendto (unix_sock,
+ queue->msg,
+ msg_size,
+ (const struct sockaddr *) queue->address,
+ queue->address_len);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "UNIX transmitted message to %s (%d/%u: %s)\n",
+ GNUNET_i2s (&queue->target),
+ (int) sent,
+ (unsigned int) msg_size,
+ (sent < 0) ? STRERROR (errno) : "ok");
+ if (-1 != sent)
+ {
+ GNUNET_STATISTICS_update (stats,
+ "# bytes sent",
+ (long long) sent,
+ GNUNET_NO);
+ reschedule_queue_timeout (queue);
+ return; /* all good */
+ }
+ GNUNET_STATISTICS_update (stats,
+ "# network transmission failures",
+ 1,
+ GNUNET_NO);
+ switch (errno)
+ {
+ case EAGAIN:
+ case ENOBUFS:
+ /* We should retry later... */
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
+ "send");
+ return;
+ case EMSGSIZE:
+ {
+ socklen_t size = 0;
+ socklen_t len = sizeof (size);
+
+ GNUNET_NETWORK_socket_getsockopt (unix_sock,
+ SOL_SOCKET,
+ SO_SNDBUF,
+ &size,
+ &len);
+ if (size > ntohs (msg->size))
+ {
+ /* Buffer is bigger than message: error, no retry
+ * This should never happen!*/
+ GNUNET_break (0);
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Trying to increase socket buffer size from %u to %u for message size %u\n",
+ (unsigned int) size,
+ (unsigned int) ((msg_size / 1000) + 2) * 1000,
+ (unsigned int) msg_size);
+ size = ((msg_size / 1000) + 2) * 1000;
+ if (GNUNET_OK ==
+ GNUNET_NETWORK_socket_setsockopt (unix_sock,
+ SOL_SOCKET,
+ SO_SNDBUF,
+ &size,
+ sizeof (size)))
+ goto resend; /* Increased buffer size, retry sending */
+ /* Ok, then just try very modest increase */
+ size = msg_size;
+ if (GNUNET_OK ==
+ GNUNET_NETWORK_socket_setsockopt (unix_sock,
+ SOL_SOCKET,
+ SO_SNDBUF,
+ &size,
+ sizeof (size)))
+ goto resend; /* Increased buffer size, retry sending */
+ /* Could not increase buffer size: error, no retry */
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "setsockopt");
+ return;
+ }
+ default:
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "send");
+ return;
+ }
+}
+
+
+/**
+ * Signature of functions implementing the sending functionality of a
+ * message queue.
+ *
+ * @param mq the message queue
+ * @param msg the message to send
+ * @param impl_state our `struct Queue`
+ */
+static void
+mq_send (struct GNUNET_MQ_Handle *mq,
+ const struct GNUNET_MessageHeader *msg,
+ void *impl_state)
+{
+ struct Queue *queue = impl_state;
+
+ GNUNET_assert (mq == queue->mq);
+ GNUNET_assert (NULL == queue->msg);
+ queue->msg = msg;
+ GNUNET_CONTAINER_DLL_insert (queue_head,
+ queue_tail,
+ queue);
+ if (NULL == write_task)
+ write_task =
+ GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
+ unix_sock,
+ &select_write_cb,
+ NULL);
+}
+
+
+/**
+ * Signature of functions implementing the destruction of a message
+ * queue. Implementations must not free @a mq, but should take care
+ * of @a impl_state.
+ *
+ * @param mq the message queue to destroy
+ * @param impl_state our `struct Queue`
+ */
+static void
+mq_destroy (struct GNUNET_MQ_Handle *mq,
+ void *impl_state)
+{
+ struct Queue *queue = impl_state;
+
+ if (mq == queue->mq)
+ {
+ queue->mq = NULL;
+ queue_destroy (queue);
+ }
+}
+
+
+/**
+ * Implementation function that cancels the currently sent message.
+ *
+ * @param mq message queue
+ * @param impl_state our `struct Queue`
+ */
+static void
+mq_cancel (struct GNUNET_MQ_Handle *mq,
+ void *impl_state)
+{
+ struct Queue *queue = impl_state;
+
+ GNUNET_assert (NULL != queue->msg);
+ queue->msg = NULL;
+ GNUNET_CONTAINER_DLL_remove (queue_head,
+ queue_tail,
+ queue);
+ GNUNET_assert (NULL != write_task);
+ if (NULL == queue_head)
+ {
+ GNUNET_SCHEDULER_cancel (write_task);
+ write_task = NULL;
+ }
+}
+
+
+/**
+ * Generic error handler, called with the appropriate
+ * error code and the same closure specified at the creation of
+ * the message queue.
+ * Not every message queue implementation supports an error handler.
+ *
+ * @param cls our `struct Queue`
+ * @param error error code
+ */
+static void
+mq_error (void *cls,
+ enum GNUNET_MQ_Error error)
+{
+ struct Queue *queue = cls;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "UNIX MQ error in queue to %s: %d\n",
+ GNUNET_i2s (&queue->target),
+ (int) error);
+ queue_destroy (queue);
+}
+
+
+/**
+ * Creates a new outbound queue the transport service will use to send
+ * data to another peer.
+ *
+ * @param peer the target peer
+ * @param un the address
+ * @param un_len number of bytes in @a un
+ * @return the queue or NULL of max connections exceeded
+ */
+static struct Queue *
+setup_queue (const struct GNUNET_PeerIdentity *target,
+ const struct sockaddr_un *un,
+ socklen_t un_len)
+{
+ struct Queue *queue;
+
+ queue = GNUNET_new (struct Queue);
+ queue->target = *target;
+ queue->address = GNUNET_memdup (un,
+ un_len);
+ queue->address_len = un_len;
+ (void) GNUNET_CONTAINER_multipeermap_put (queue_map,
+ &queue->target,
+ queue,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+ GNUNET_STATISTICS_set (stats,
+ "# queues active",
+ GNUNET_CONTAINER_multipeermap_size (queue_map),
+ GNUNET_NO);
+ queue->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
+ queue->timeout_task
+ = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
+ &queue_timeout,
+ queue);
+ queue->mq
+ = GNUNET_MQ_queue_for_callbacks (&mq_send,
+ &mq_destroy,
+ &mq_cancel,
+ queue,
+ NULL,
+ &mq_error,
+ queue);
+ {
+ char *foreign_addr;
+
+ if ('\0' == un->sun_path[0])
+ GNUNET_asprintf (&foreign_addr,
+ "%s-@%s",
+ COMMUNICATOR_ADDRESS_PREFIX,
+ &un->sun_path[1]);
+ else
+ GNUNET_asprintf (&foreign_addr,
+ "%s-%s",
+ COMMUNICATOR_ADDRESS_PREFIX,
+ un->sun_path);
+ queue->qh
+ = GNUNET_TRANSPORT_communicator_mq_add (ch,
+ &queue->target,
+ foreign_addr,
+ GNUNET_ATS_NET_LOOPBACK,
+ queue->mq);
+ GNUNET_free (foreign_addr);
+ }
+ return queue;
+}
+
+
+/**
+ * We have been notified that our socket has something to read. Do the
+ * read and reschedule this function to be called again once more is
+ * available.
+ *
+ * @param cls NULL
+ */
+static void
+select_read_cb (void *cls);
+
+
+/**
+ * Function called when message was successfully passed to
+ * transport service. Continue read activity.
+ *
+ * @param cls NULL
+ * @param success #GNUNET_OK on success
+ */
+static void
+receive_complete_cb (void *cls,
+ int success)
+{
+ delivering_messages--;
+ if (GNUNET_OK != success)
+ GNUNET_STATISTICS_update (stats,
+ "# transport transmission failures",
+ 1,
+ GNUNET_NO);
+ if ( (NULL == read_task) &&
+ (delivering_messages < max_queue_length) )
+ read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
+ unix_sock,
+ &select_read_cb,
+ NULL);
+}
+
+
+/**
+ * We have been notified that our socket has something to read. Do the
+ * read and reschedule this function to be called again once more is
+ * available.
+ *
+ * @param cls NULL
+ */
+static void
+select_read_cb (void *cls)
+{
+ char buf[65536] GNUNET_ALIGN;
+ struct Queue *queue;
+ const struct UNIXMessage *msg;
+ struct sockaddr_un un;
+ socklen_t addrlen;
+ ssize_t ret;
+ uint16_t msize;
+
+ read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
+ unix_sock,
+ &select_read_cb,
+ NULL);
+ addrlen = sizeof (un);
+ memset (&un,
+ 0,
+ sizeof (un));
+ ret = GNUNET_NETWORK_socket_recvfrom (unix_sock,
+ buf,
+ sizeof (buf),
+ (struct sockaddr *) &un,
+ &addrlen);
+ if ( (-1 == ret) &&
+ ( (EAGAIN == errno) ||
+ (ENOBUFS == errno) ) )
+ return;
+ if (-1 == ret)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+ "recvfrom");
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Read %d bytes from socket %s\n",
+ (int) ret,
+ un.sun_path);
+ GNUNET_assert (AF_UNIX == (un.sun_family));
+ msg = (struct UNIXMessage *) buf;
+ msize = ntohs (msg->header.size);
+ if ( (msize < sizeof (struct UNIXMessage)) ||
+ (msize > ret) )
+ {
+ GNUNET_break_op (0);
+ return;
+ }
+ queue = lookup_queue (&msg->sender,
+ &un,
+ addrlen);
+ if (NULL == queue)
+ queue = setup_queue (&msg->sender,
+ &un,
+ addrlen);
+ else
+ reschedule_queue_timeout (queue);
+ if (NULL == queue)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Maximum number of UNIX connections exceeded, dropping incoming message\n"));
+ return;
+ }
+
+ {
+ uint16_t offset = 0;
+ uint16_t tsize = msize - sizeof (struct UNIXMessage);
+ const char *msgbuf = (const char *) &msg[1];
+
+ while (offset + sizeof (struct GNUNET_MessageHeader) <= tsize)
+ {
+ const struct GNUNET_MessageHeader *currhdr;
+ struct GNUNET_MessageHeader al_hdr;
+ uint16_t csize;
+
+ currhdr = (const struct GNUNET_MessageHeader *) &msgbuf[offset];
+ /* ensure aligned access */
+ memcpy (&al_hdr,
+ currhdr,
+ sizeof (al_hdr));
+ csize = ntohs (al_hdr.size);
+ if ( (csize < sizeof (struct GNUNET_MessageHeader)) ||
+ (csize > tsize - offset))
+ {
+ GNUNET_break_op (0);
+ break;
+ }
+ ret = GNUNET_TRANSPORT_communicator_receive (ch,
+ &msg->sender,
+ currhdr,
+ &receive_complete_cb,
+ NULL);
+ if (GNUNET_SYSERR == ret)
+ return; /* transport not up */
+ if (GNUNET_NO == ret)
+ break;
+ delivering_messages++;
+ offset += csize;
+ }
+ }
+ if (delivering_messages >= max_queue_length)
+ {
+ /* we should try to apply 'back pressure' */
+ GNUNET_SCHEDULER_cancel (read_task);
+ read_task = NULL;
+ }
+}
+
+
+/**
+ * Function called by the transport service to initialize a
+ * message queue given address information about another peer.
+ * If and when the communication channel is established, the
+ * communicator must call #GNUNET_TRANSPORT_communicator_mq_add()
+ * to notify the service that the channel is now up. It is
+ * the responsibility of the communicator to manage sane
+ * retries and timeouts for any @a peer/@a address combination
+ * provided by the transport service. Timeouts and retries
+ * do not need to be signalled to the transport service.
+ *
+ * @param cls closure
+ * @param peer identity of the other peer
+ * @param address where to send the message, human-readable
+ * communicator-specific format, 0-terminated, UTF-8
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR if the provided address is invalid
+ */
+static int
+mq_init (void *cls,
+ const struct GNUNET_PeerIdentity *peer,
+ const char *address)
+{
+ struct Queue *queue;
+ const char *path;
+ struct sockaddr_un *un;
+ socklen_t un_len;
+
+ if (0 != strncmp (address,
+ COMMUNICATOR_ADDRESS_PREFIX "-",
+ strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
+ un = unix_address_to_sockaddr (path,
+ &un_len);
+ queue = lookup_queue (peer,
+ un,
+ un_len);
+ if (NULL != queue)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Address `%s' for %s ignored, queue exists\n",
+ path,
+ GNUNET_i2s (peer));
+ GNUNET_free (un);
+ return GNUNET_OK;
+ }
+ queue = setup_queue (peer,
+ un,
+ un_len);
+ GNUNET_free (un);
+ if (NULL == queue)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Failed to setup queue to %s at `%s'\n",
+ GNUNET_i2s (peer),
+ path);
+ return GNUNET_NO;
+ }
+ return GNUNET_OK;
+}
+
+
+/**
+ * Iterator over all message queues to clean up.
+ *
+ * @param cls NULL
+ * @param target unused
+ * @param value the queue to destroy
+ * @return #GNUNET_OK to continue to iterate
+ */
+static int
+get_queue_delete_it (void *cls,
+ const struct GNUNET_PeerIdentity *target,
+ void *value)
+{
+ struct Queue *queue = value;
+
+ (void) cls;
+ (void) target;
+ queue_destroy (queue);
+ return GNUNET_OK;
+}
+
+
+/**
+ * Shutdown the UNIX communicator.
+ *
+ * @param cls NULL (always)
+ */
+static void
+do_shutdown (void *cls)
+{
+ if (NULL != read_task)
+ {
+ GNUNET_SCHEDULER_cancel (read_task);
+ read_task = NULL;
+ }
+ if (NULL != write_task)
+ {
+ GNUNET_SCHEDULER_cancel (write_task);
+ write_task = NULL;
+ }
+ if (NULL != unix_sock)
+ {
+ GNUNET_break (GNUNET_OK ==
+ GNUNET_NETWORK_socket_close (unix_sock));
+ unix_sock = NULL;
+ }
+ GNUNET_CONTAINER_multipeermap_iterate (queue_map,
+ &get_queue_delete_it,
+ NULL);
+ GNUNET_CONTAINER_multipeermap_destroy (queue_map);
+ if (NULL != ai)
+ {
+ GNUNET_TRANSPORT_communicator_address_remove (ai);
+ ai = NULL;
+ }
+ if (NULL != ch)
+ {
+ GNUNET_TRANSPORT_communicator_disconnect (ch);
+ ch = NULL;
+ }
+ if (NULL != stats)
+ {
+ GNUNET_STATISTICS_destroy (stats,
+ GNUNET_NO);
+ stats = NULL;
+ }
+}
+
+
+/**
+ * Setup communicator and launch network interactions.
+ *
+ * @param cls NULL (always)
+ * @param args remaining command-line arguments
+ * @param cfgfile name of the configuration file used (for saving, can be NULL!)
+ * @param cfg configuration
+ */
+static void
+run (void *cls,
+ char *const *args,
+ const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ char *unix_socket_path;
+ struct sockaddr_un *un;
+ socklen_t un_len;
+ char *my_addr;
+ (void) cls;
+
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_filename (cfg,
+ COMMUNICATOR_CONFIG_SECTION,
+ "UNIXPATH",
+ &unix_socket_path))
+ {
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ COMMUNICATOR_CONFIG_SECTION,
+ "UNIXPATH");
+ return;
+ }
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_number (cfg,
+ COMMUNICATOR_CONFIG_SECTION,
+ "MAX_QUEUE_LENGTH",
+ &max_queue_length))
+ max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
+
+ un = unix_address_to_sockaddr (unix_socket_path,
+ &un_len);
+ if (NULL == un)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to setup UNIX domain socket address with path `%s'\n",
+ unix_socket_path);
+ GNUNET_free (unix_socket_path);
+ return;
+ }
+ unix_sock = GNUNET_NETWORK_socket_create (AF_UNIX,
+ SOCK_DGRAM,
+ 0);
+ if (NULL == unix_sock)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "socket");
+ GNUNET_free (un);
+ GNUNET_free (unix_socket_path);
+ return;
+ }
+ if ( ('\0' != un->sun_path[0]) &&
+ (GNUNET_OK !=
+ GNUNET_DISK_directory_create_for_file (un->sun_path)) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Cannot create path to `%s'\n"),
+ un->sun_path);
+ GNUNET_NETWORK_socket_close (unix_sock);
+ unix_sock = NULL;
+ GNUNET_free (un);
+ GNUNET_free (unix_socket_path);
+ return;
+ }
+ if (GNUNET_OK !=
+ GNUNET_NETWORK_socket_bind (unix_sock,
+ (const struct sockaddr *) un,
+ un_len))
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
+ "bind",
+ un->sun_path);
+ GNUNET_NETWORK_socket_close (unix_sock);
+ unix_sock = NULL;
+ GNUNET_free (un);
+ GNUNET_free (unix_socket_path);
+ return;
+ }
+ GNUNET_free (un);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Bound to `%s'\n",
+ unix_socket_path);
+ stats = GNUNET_STATISTICS_create ("C-UNIX",
+ cfg);
+ GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
+ NULL);
+ read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
+ unix_sock,
+ &select_read_cb,
+ NULL);
+ queue_map = GNUNET_CONTAINER_multipeermap_create (10,
+ GNUNET_NO);
+ ch = GNUNET_TRANSPORT_communicator_connect (cfg,
+ COMMUNICATOR_CONFIG_SECTION,
+ COMMUNICATOR_ADDRESS_PREFIX,
+ 65535,
+ &mq_init,
+ NULL);
+ if (NULL == ch)
+ {
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_shutdown ();
+ GNUNET_free (unix_socket_path);
+ return;
+ }
+ GNUNET_asprintf (&my_addr,
+ "%s-%s",
+ COMMUNICATOR_ADDRESS_PREFIX,
+ unix_socket_path);
+ ai = GNUNET_TRANSPORT_communicator_address_add (ch,
+ my_addr,
+ GNUNET_ATS_NET_LOOPBACK,
+ GNUNET_TIME_UNIT_FOREVER_REL);
+ GNUNET_free (my_addr);
+ GNUNET_free (unix_socket_path);
+ read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
+ unix_sock,
+ &select_read_cb,
+ NULL);
+}
+
+
+/**
+ * The main function for the UNIX communicator.
+ *
+ * @param argc number of arguments from the command line
+ * @param argv command line arguments
+ * @return 0 ok, 1 on error
+ */
+int
+main (int argc,
+ char *const *argv)
+{
+ static const struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+ int ret;
+
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_get_utf8_args (argc, argv,
+ &argc, &argv))
+ return 2;
+
+ ret =
+ (GNUNET_OK ==
+ GNUNET_PROGRAM_run (argc, argv,
+ "gnunet-communicator-unix",
+ _("GNUnet UNIX domain socket communicator"),
+ options,
+ &run,
+ NULL)) ? 0 : 1;
+ GNUNET_free ((void*) argv);
+ return ret;
+}
+
+
+#if defined(LINUX) && defined(__GLIBC__)
+#include <malloc.h>
+
+/**
+ * MINIMIZE heap size (way below 128k) since this process doesn't need much.
+ */
+void __attribute__ ((constructor))
+GNUNET_ARM_memory_init ()
+{
+ mallopt (M_TRIM_THRESHOLD, 4 * 1024);
+ mallopt (M_TOP_PAD, 1 * 1024);
+ malloc_trim (0);
+}
+#endif
+
+/* end of gnunet-communicator-unix.c */
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
new file mode 100644
index 000000000..8cbca3188
--- /dev/null
+++ b/src/transport/gnunet-service-tng.c
@@ -0,0 +1,719 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2010-2016, 2018 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+/**
+ * @file transport/gnunet-service-transport.c
+ * @brief main for gnunet-service-transport
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_statistics_service.h"
+#include "gnunet_transport_service.h"
+#include "gnunet_peerinfo_service.h"
+#include "gnunet_ats_service.h"
+#include "gnunet-service-transport.h"
+#include "transport.h"
+
+
+/**
+ * How many messages can we have pending for a given client process
+ * before we start to drop incoming messages? We typically should
+ * have only one client and so this would be the primary buffer for
+ * messages, so the number should be chosen rather generously.
+ *
+ * The expectation here is that most of the time the queue is large
+ * enough so that a drop is virtually never required. Note that
+ * this value must be about as large as 'TOTAL_MSGS' in the
+ * 'test_transport_api_reliability.c', otherwise that testcase may
+ * fail.
+ */
+#define MAX_PENDING (128 * 1024)
+
+
+/**
+ * What type of client is the `struct TransportClient` about?
+ */
+enum ClientType
+{
+ /**
+ * We do not know yet (client is fresh).
+ */
+ CT_NONE = 0,
+
+ /**
+ * Is the CORE service, we need to forward traffic to it.
+ */
+ CT_CORE = 1,
+
+ /**
+ * It is a monitor, forward monitor data.
+ */
+ CT_MONITOR = 2,
+
+ /**
+ * It is a communicator, use for communication.
+ */
+ CT_COMMUNICATOR = 3
+};
+
+
+/**
+ * Client connected to the transport service.
+ */
+struct TransportClient
+{
+
+ /**
+ * Kept in a DLL.
+ */
+ struct TransportClient *next;
+
+ /**
+ * Kept in a DLL.
+ */
+ struct TransportClient *prev;
+
+ /**
+ * Handle to the client.
+ */
+ struct GNUNET_SERVICE_Client *client;
+
+ /**
+ * Message queue to the client.
+ */
+ struct GNUNET_MQ_Handle *mq;
+
+ /**
+ * What type of client is this?
+ */
+ enum ClientType type;
+
+ union
+ {
+
+ /**
+ * Peer identity to monitor the addresses of.
+ * Zero to monitor all neighbours. Valid if
+ * @e type is #CT_MONITOR.
+ */
+ struct GNUNET_PeerIdentity monitor_peer;
+
+ /**
+ * If @e type is #CT_COMMUNICATOR, this communicator
+ * supports communicating using these addresses.
+ */
+ const char *address_prefix;
+
+ } details;
+
+};
+
+
+/**
+ * Head of linked list of all clients to this service.
+ */
+static struct TransportClient *clients_head;
+
+/**
+ * Tail of linked list of all clients to this service.
+ */
+static struct TransportClient *clients_tail;
+
+/**
+ * Statistics handle.
+ */
+struct GNUNET_STATISTICS_Handle *GST_stats;
+
+/**
+ * Configuration handle.
+ */
+const struct GNUNET_CONFIGURATION_Handle *GST_cfg;
+
+/**
+ * Configuration handle.
+ */
+struct GNUNET_PeerIdentity GST_my_identity;
+
+/**
+ * Handle to peerinfo service.
+ */
+struct GNUNET_PEERINFO_Handle *GST_peerinfo;
+
+/**
+ * Our private key.
+ */
+struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key;
+
+
+/**
+ * Called whenever a client connects. Allocates our
+ * data structures associated with that client.
+ *
+ * @param cls closure, NULL
+ * @param client identification of the client
+ * @param mq message queue for the client
+ * @return our `struct TransportClient`
+ */
+static void *
+client_connect_cb (void *cls,
+ struct GNUNET_SERVICE_Client *client,
+ struct GNUNET_MQ_Handle *mq)
+{
+ struct TransportClient *tc;
+
+ tc = GNUNET_new (struct TransportClient);
+ tc->client = client;
+ tc->mq = mq;
+ GNUNET_CONTAINER_DLL_insert (clients_head,
+ clients_tail,
+ tc);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client %p connected\n",
+ tc);
+ return tc;
+}
+
+
+/**
+ * Called whenever a client is disconnected. Frees our
+ * resources associated with that client.
+ *
+ * @param cls closure, NULL
+ * @param client identification of the client
+ * @param app_ctx our `struct TransportClient`
+ */
+static void
+client_disconnect_cb (void *cls,
+ struct GNUNET_SERVICE_Client *client,
+ void *app_ctx)
+{
+ struct TransportClient *tc = app_ctx;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client %p disconnected, cleaning up.\n",
+ tc);
+ GNUNET_CONTAINER_DLL_remove (clients_head,
+ clients_tail,
+ tc);
+ switch (tc->type)
+ {
+ case CT_NONE:
+ break;
+ case CT_CORE:
+ break;
+ case CT_MONITOR:
+ break;
+ case CT_COMMUNICATOR:
+ break;
+ }
+ GNUNET_free (tc);
+}
+
+
+/**
+ * Initialize a "CORE" client. We got a start message from this
+ * client, so add it to the list of clients for broadcasting of
+ * inbound messages.
+ *
+ * @param cls the client
+ * @param start the start message that was sent
+ */
+static void
+handle_client_start (void *cls,
+ const struct StartMessage *start)
+{
+ struct TransportClient *tc = cls;
+ const struct GNUNET_MessageHeader *hello;
+ uint32_t options;
+
+ options = ntohl (start->options);
+ if ( (0 != (1 & options)) &&
+ (0 !=
+ memcmp (&start->self,
+ &GST_my_identity,
+ sizeof (struct GNUNET_PeerIdentity)) ) )
+ {
+ /* client thinks this is a different peer, reject */
+ GNUNET_break (0);
+ GNUNET_SERVICE_client_drop (tc->client);
+ return;
+ }
+ if (CT_NONE != tc->type)
+ {
+ GNUNET_break (0);
+ GNUNET_SERVICE_client_drop (tc->client);
+ return;
+ }
+ tc->type = CT_CORE;
+#if 0
+ hello = GST_hello_get ();
+ if (NULL != hello)
+ unicast (tc,
+ hello,
+ GNUNET_NO);
+#endif
+ GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * Client sent us a HELLO. Check the request.
+ *
+ * @param cls the client
+ * @param message the HELLO message
+ */
+static int
+check_client_hello (void *cls,
+ const struct GNUNET_MessageHeader *message)
+{
+ (void) cls;
+ return GNUNET_OK; /* FIXME: check here? */
+}
+
+
+/**
+ * Client sent us a HELLO. Process the request.
+ *
+ * @param cls the client
+ * @param message the HELLO message
+ */
+static void
+handle_client_hello (void *cls,
+ const struct GNUNET_MessageHeader *message)
+{
+ struct TransportClient *tc = cls;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Received HELLO message\n");
+ GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * Client asked for transmission to a peer. Process the request.
+ *
+ * @param cls the client
+ * @param obm the send message that was sent
+ */
+static int
+check_client_send (void *cls,
+ const struct OutboundMessage *obm)
+{
+ uint16_t size;
+ const struct GNUNET_MessageHeader *obmm;
+
+ (void) cls;
+ size = ntohs (obm->header.size) - sizeof (struct OutboundMessage);
+ if (size < sizeof (struct GNUNET_MessageHeader))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ obmm = (const struct GNUNET_MessageHeader *) &obm[1];
+ if (size != ntohs (obmm->size))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
+/**
+ * Client asked for transmission to a peer. Process the request.
+ *
+ * @param cls the client
+ * @param obm the send message that was sent
+ */
+static void
+handle_client_send (void *cls,
+ const struct OutboundMessage *obm)
+{
+ struct TransportClient *tc = cls;
+ const struct GNUNET_MessageHeader *obmm;
+
+ obmm = (const struct GNUNET_MessageHeader *) &obm[1];
+}
+
+
+/**
+ * Communicator started. Test message is well-formed.
+ *
+ * @param cls the client
+ * @param cam the send message that was sent
+ */
+static int
+check_communicator_available (void *cls,
+ const struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam)
+{
+ const char *addr;
+ uint16_t size;
+
+ (void) cls;
+ size = ntohs (cam->header.size) - sizeof (*cam);
+ if (0 == size)
+ return GNUNET_OK; /* receive-only communicator */
+ addr = (const char *) &cam[1];
+ if ('\0' != addr[size-1])
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
+/**
+ * Communicator started. Process the request.
+ *
+ * @param cls the client
+ * @param cam the send message that was sent
+ */
+static void
+handle_communicator_available (void *cls,
+ const struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam)
+{
+ struct TransportClient *tc = cls;
+ uint16_t size;
+
+ if (CT_NONE != tc->type)
+ {
+ GNUNET_break (0);
+ GNUNET_SERVICE_client_drop (tc->client);
+ return;
+ }
+ tc->type = CT_COMMUNICATOR;
+ size = ntohs (cam->header.size) - sizeof (*cam);
+ if (0 == size)
+ return GNUNET_OK; /* receive-only communicator */
+ tc->details.address_prefix = GNUNET_strdup ((const char *) &cam[1]);
+ GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * Address of our peer added. Test message is well-formed.
+ *
+ * @param cls the client
+ * @param aam the send message that was sent
+ */
+static int
+check_add_address (void *cls,
+ const struct GNUNET_TRANSPORT_AddAddressMessage *aam)
+{
+ const char *addr;
+ uint16_t size;
+
+ (void) cls;
+ size = ntohs (aam->header.size) - sizeof (*aam);
+ if (0 == size)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ addr = (const char *) &cam[1];
+ if ('\0' != addr[size-1])
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
+/**
+ * Address of our peer added. Process the request.
+ *
+ * @param cls the client
+ * @param aam the send message that was sent
+ */
+static void
+handle_add_address (void *cls,
+ const struct GNUNET_TRANSPORT_AddAddressMessage *aam)
+{
+ struct TransportClient *tc = cls;
+
+ GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * Address of our peer deleted. Process the request.
+ *
+ * @param cls the client
+ * @param dam the send message that was sent
+ */
+static void
+handle_del_address (void *cls,
+ const struct GNUNET_TRANSPORT_DelAddressMessage *dam)
+{
+ struct TransportClient *tc = cls;
+
+ GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * Client asked for transmission to a peer. Process the request.
+ *
+ * @param cls the client
+ * @param obm the send message that was sent
+ */
+static int
+check_incoming_msg (void *cls,
+ const struct GNUNET_TRANSPORT_IncomingMessage *im)
+{
+ uint16_t size;
+ const struct GNUNET_MessageHeader *obmm;
+
+ (void) cls;
+ size = ntohs (im->header.size) - sizeof (*im);
+ if (size < sizeof (struct GNUNET_MessageHeader))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ obmm = (const struct GNUNET_MessageHeader *) &im[1];
+ if (size != ntohs (obmm->size))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
+/**
+ * Incoming meessage. Process the request.
+ *
+ * @param cls the client
+ * @param im the send message that was received
+ */
+static void
+handle_incoming_msg (void *cls,
+ const struct GNUNET_TRANSPORT_IncomingMessage *im)
+{
+ struct TransportClient *tc = cls;
+
+ GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * New queue became available. Check message.
+ *
+ * @param cls the client
+ * @param aqm the send message that was sent
+ */
+static int
+check_add_queue_message (void *cls,
+ const struct GNUNET_TRANSPORT_AddQueueMessage *aqm)
+{
+ const char *addr;
+ uint16_t size;
+
+ (void) cls;
+ size = ntohs (aqm->header.size) - sizeof (*aqm);
+ if (0 == size)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ addr = (const char *) &aqm[1];
+ if ('\0' != addr[size-1])
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
+/**
+ * New queue became available. Process the request.
+ *
+ * @param cls the client
+ * @param aqm the send message that was sent
+ */
+static void
+handle_add_queue_message (void *cls,
+ const struct GNUNET_TRANSPORT_AddQueueMessage *aqm)
+{
+ struct TransportClient *tc = cls;
+
+ GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * Queue to a peer went down. Process the request.
+ *
+ * @param cls the client
+ * @param dqm the send message that was sent
+ */
+static void
+handle_del_queue_message (void *cls,
+ const struct GNUNET_TRANSPORT_DelQueueMessage *dqm)
+{
+ struct TransportClient *tc = cls;
+
+ GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * Message was transmitted. Process the request.
+ *
+ * @param cls the client
+ * @param sma the send message that was sent
+ */
+static void
+handle_send_message_ack (void *cls,
+ const struct GNUNET_TRANSPORT_SendMessageToAck *sma)
+{
+ struct TransportClient *tc = cls;
+
+ GNUNET_SERVICE_client_continue (tc->client);
+}
+
+
+/**
+ * Function called when the service shuts down. Unloads our plugins
+ * and cancels pending validations.
+ *
+ * @param cls closure, unused
+ */
+static void
+shutdown_task (void *cls)
+{
+ (void) cls;
+
+ if (NULL != GST_stats)
+ {
+ GNUNET_STATISTICS_destroy (GST_stats,
+ GNUNET_NO);
+ GST_stats = NULL;
+ }
+ if (NULL != GST_my_private_key)
+ {
+ GNUNET_free (GST_my_private_key);
+ GST_my_private_key = NULL;
+ }
+}
+
+
+/**
+ * Initiate transport service.
+ *
+ * @param cls closure
+ * @param c configuration to use
+ * @param service the initialized service
+ */
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *c,
+ struct GNUNET_SERVICE_Handle *service)
+{
+ /* setup globals */
+ GST_cfg = c;
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_time (c,
+ "transport",
+ "HELLO_EXPIRATION",
+ &hello_expiration))
+ {
+ hello_expiration = GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION;
+ }
+ GST_my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
+ if (NULL == GST_my_private_key)
+ {
+ GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
+ _("Transport service is lacking key configuration settings. Exiting.\n"));
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ GNUNET_CRYPTO_eddsa_key_get_public (GST_my_private_key,
+ &GST_my_identity.public_key);
+ GNUNET_log(GNUNET_ERROR_TYPE_INFO,
+ "My identity is `%s'\n",
+ GNUNET_i2s_full (&GST_my_identity));
+
+ GST_stats = GNUNET_STATISTICS_create ("transport",
+ GST_cfg);
+ GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
+ NULL);
+ /* start subsystems */
+}
+
+
+/**
+ * Define "main" method using service macro.
+ */
+GNUNET_SERVICE_MAIN
+("transport",
+ GNUNET_SERVICE_OPTION_NONE,
+ &run,
+ &client_connect_cb,
+ &client_disconnect_cb,
+ NULL,
+ /* communication with core */
+ GNUNET_MQ_hd_fixed_size (client_start,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_START,
+ struct StartMessage,
+ NULL),
+ GNUNET_MQ_hd_var_size (client_hello,
+ GNUNET_MESSAGE_TYPE_HELLO,
+ struct GNUNET_MessageHeader,
+ NULL),
+ GNUNET_MQ_hd_var_size (client_send,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_SEND,
+ struct OutboundMessage,
+ NULL),
+ /* communication with communicators */
+ GNUNET_MQ_hd_var_size (communicator_available,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_NEW_COMMUNICATOR,
+ struct GNUNET_TRANSPORT_CommunicatorAvailableMessage,
+ NULL),
+ GNUNET_MQ_hd_var_size (add_address,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_ADDRESS,
+ struct GNUNET_TRANSPORT_AddAddressMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (del_address,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_ADDRESS,
+ struct GNUNET_TRANSPORT_DelAddressMessage,
+ NULL),
+ GNUNET_MQ_hd_var_size (incoming_msg,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG,
+ struct GNUNET_TRANSPORT_IncomingMessage,
+ NULL),
+ GNUNET_MQ_hd_var_size (add_queue_message,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_SETUP,
+ struct GNUNET_TRANSPORT_AddQueueMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (del_queue_message,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_TEARDOWN,
+ struct GNUNET_TRANSPORT_DelQueueMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (send_message_ack,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG_ACK,
+ struct GNUNET_TRANSPORT_SendMessageToAck,
+ NULL),
+ GNUNET_MQ_handler_end ());
+
+
+/* end of file gnunet-service-transport.c */
diff --git a/src/transport/transport.h b/src/transport/transport.h
index e68536bcc..1b46213cf 100644
--- a/src/transport/transport.h
+++ b/src/transport/transport.h
@@ -11,7 +11,7 @@
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -94,7 +94,7 @@ struct StartMessage
/**
* 0: no options
- * 1: The 'self' field should be checked
+ * 1: The @e self field should be checked
* 2: this client is interested in payload traffic
*/
uint32_t options;
@@ -404,6 +404,7 @@ struct ValidationIterateResponseMessage
struct GNUNET_TIME_AbsoluteNBO next_validation;
};
+
/**
* Message from the library to the transport service
* asking for binary addresses known for a peer.
@@ -654,6 +655,22 @@ struct TransportPluginMonitorMessage
/* *********************** TNG messages ***************** */
/**
+ * Communicator goes online. Note which addresses it can
+ * work with.
+ */
+struct GNUNET_TRANSPORT_CommunicatorAvailableMessage
+{
+
+ /**
+ * Type will be #GNUNET_MESSAGE_TYPE_TRANSPORT_NEW_COMMUNICATOR.
+ */
+ struct GNUNET_MessageHeader header;
+
+ /* Followed by the address prefix of the communicator */
+};
+
+
+/**
* Add address to the list.
*/
struct GNUNET_TRANSPORT_AddAddressMessage
@@ -678,7 +695,7 @@ struct GNUNET_TRANSPORT_AddAddressMessage
* An `enum GNUNET_ATS_Network_Type` in NBO.
*/
uint32_t nt;
-
+
/* followed by UTF-8 encoded, 0-terminated human-readable address */
};
@@ -717,12 +734,12 @@ struct GNUNET_TRANSPORT_IncomingMessage
* Do we use flow control or not?
*/
uint32_t fc_on GNUNET_PACKED;
-
+
/**
* 64-bit number to identify the matching ACK.
*/
uint64_t fc_id GNUNET_PACKED;
-
+
/**
* Sender identifier.
*/
@@ -748,12 +765,12 @@ struct GNUNET_TRANSPORT_IncomingMessageAck
* Reserved (0)
*/
uint32_t reserved GNUNET_PACKED;
-
+
/**
* Which message is being ACKed?
*/
uint64_t fc_id GNUNET_PACKED;
-
+
/**
* Sender identifier of the original message.
*/
@@ -769,7 +786,7 @@ struct GNUNET_TRANSPORT_AddQueueMessage
{
/**
- * Type will be #GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_QUEUE.
+ * Type will be #GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_SETUP.
*/
struct GNUNET_MessageHeader header;
@@ -787,7 +804,7 @@ struct GNUNET_TRANSPORT_AddQueueMessage
* An `enum GNUNET_ATS_Network_Type` in NBO.
*/
uint32_t nt;
-
+
/* followed by UTF-8 encoded, 0-terminated human-readable address */
};
@@ -799,7 +816,7 @@ struct GNUNET_TRANSPORT_DelQueueMessage
{
/**
- * Type will be #GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_QUEUE.
+ * Type will be #GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_TEARDOWN.
*/
struct GNUNET_MessageHeader header;
@@ -828,9 +845,9 @@ struct GNUNET_TRANSPORT_CreateQueue
struct GNUNET_MessageHeader header;
/**
- * Always zero.
+ * Unique ID for the request.
*/
- uint32_t reserved GNUNET_PACKED;
+ uint32_t request_id GNUNET_PACKED;
/**
* Receiver that can be addressed via the queue.
@@ -842,6 +859,24 @@ struct GNUNET_TRANSPORT_CreateQueue
/**
+ * Transport tells communicator that it wants a new queue.
+ */
+struct GNUNET_TRANSPORT_CreateQueueResponse
+{
+
+ /**
+ * Type will be #GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_OK or #GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_FAIL.
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Unique ID for the request.
+ */
+ uint32_t request_id GNUNET_PACKED;
+};
+
+
+/**
* Inform communicator about transport's desire to send a message.
*/
struct GNUNET_TRANSPORT_SendMessageTo
@@ -861,7 +896,7 @@ struct GNUNET_TRANSPORT_SendMessageTo
* Message ID, used for flow control.
*/
uint64_t mid GNUNET_PACKED;
-
+
/**
* Receiver identifier.
*/
@@ -891,7 +926,7 @@ struct GNUNET_TRANSPORT_SendMessageToAck
* Message ID of the original message.
*/
uint64_t mid GNUNET_PACKED;
-
+
/**
* Receiver identifier.
*/
diff --git a/src/transport/transport_api2_communication.c b/src/transport/transport_api2_communication.c
index d446516bd..3a68c6eba 100644
--- a/src/transport/transport_api2_communication.c
+++ b/src/transport/transport_api2_communication.c
@@ -90,6 +90,11 @@ struct AckPending
struct AckPending *prev;
/**
+ * Communicator this entry belongs to.
+ */
+ struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
+
+ /**
* Which peer is this about?
*/
struct GNUNET_PeerIdentity receiver;
@@ -134,17 +139,17 @@ struct GNUNET_TRANSPORT_CommunicatorHandle
/**
* DLL of messages awaiting transmission confirmation (ack).
*/
- struct AckPending *ac_tail;
+ struct AckPending *ap_tail;
/**
* DLL of queues we offer.
*/
- struct QueueHandle *queue_head;
+ struct GNUNET_TRANSPORT_QueueHandle *queue_head;
/**
* DLL of queues we offer.
*/
- struct QueueHandle *queue_tail;
+ struct GNUNET_TRANSPORT_QueueHandle *queue_tail;
/**
* Our configuration.
@@ -152,9 +157,14 @@ struct GNUNET_TRANSPORT_CommunicatorHandle
const struct GNUNET_CONFIGURATION_Handle *cfg;
/**
- * Name of the communicator.
+ * Config section to use.
+ */
+ const char *config_section;
+
+ /**
+ * Address prefix to use.
*/
- const char *name;
+ const char *addr_prefix;
/**
* Function to call when the transport service wants us to initiate
@@ -168,6 +178,11 @@ struct GNUNET_TRANSPORT_CommunicatorHandle
void *mq_init_cls;
/**
+ * Queue to talk to the transport service.
+ */
+ struct GNUNET_MQ_Handle *mq;
+
+ /**
* Maximum permissable queue length.
*/
unsigned long long max_queue_length;
@@ -202,6 +217,17 @@ struct GNUNET_TRANSPORT_CommunicatorHandle
*/
struct GNUNET_TRANSPORT_QueueHandle
{
+
+ /**
+ * Kept in a DLL.
+ */
+ struct GNUNET_TRANSPORT_QueueHandle *next;
+
+ /**
+ * Kept in a DLL.
+ */
+ struct GNUNET_TRANSPORT_QueueHandle *prev;
+
/**
* Handle this queue belongs to.
*/
@@ -308,7 +334,7 @@ send_add_address (struct GNUNET_TRANSPORT_AddressIdentifier *ai)
env = GNUNET_MQ_msg_extra (aam,
strlen (ai->address) + 1,
GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_ADDRESS);
- aam->expiration = GNUNET_TIME_relative_to_nbo (ai->expiration);
+ aam->expiration = GNUNET_TIME_relative_hton (ai->expiration);
aam->nt = htonl ((uint32_t) ai->nt);
memcpy (&aam[1],
ai->address,
@@ -334,7 +360,7 @@ send_del_address (struct GNUNET_TRANSPORT_AddressIdentifier *ai)
return;
env = GNUNET_MQ_msg (dam,
GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_ADDRESS);
- dam.aid = htonl (ai->aid);
+ dam->aid = htonl (ai->aid);
GNUNET_MQ_send (ai->ch->mq,
env);
}
@@ -352,18 +378,18 @@ send_add_queue (struct GNUNET_TRANSPORT_QueueHandle *qh)
struct GNUNET_MQ_Envelope *env;
struct GNUNET_TRANSPORT_AddQueueMessage *aqm;
- if (NULL == ai->ch->mq)
+ if (NULL == qh->ch->mq)
return;
env = GNUNET_MQ_msg_extra (aqm,
- strlen (ai->address) + 1,
- GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_QUEUE);
- aqm.receiver = qh->peer;
- aqm.nt = htonl ((uint32_t) qh->nt);
- aqm.qid = htonl (qh->qid);
+ strlen (qh->address) + 1,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_SETUP);
+ aqm->receiver = qh->peer;
+ aqm->nt = htonl ((uint32_t) qh->nt);
+ aqm->qid = htonl (qh->queue_id);
memcpy (&aqm[1],
- ai->address,
- strlen (ai->address) + 1);
- GNUNET_MQ_send (ai->ch->mq,
+ qh->address,
+ strlen (qh->address) + 1);
+ GNUNET_MQ_send (qh->ch->mq,
env);
}
@@ -380,13 +406,13 @@ send_del_queue (struct GNUNET_TRANSPORT_QueueHandle *qh)
struct GNUNET_MQ_Envelope *env;
struct GNUNET_TRANSPORT_DelQueueMessage *dqm;
- if (NULL == ai->ch->mq)
+ if (NULL == qh->ch->mq)
return;
env = GNUNET_MQ_msg (dqm,
- GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_QUEUE);
- dqm.qid = htonl (qh->qid);
- dqm.receiver = qh->peer;
- GNUNET_MQ_send (ai->ch->mq,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_TEARDOWN);
+ dqm->qid = htonl (qh->queue_id);
+ dqm->receiver = qh->peer;
+ GNUNET_MQ_send (qh->ch->mq,
env);
}
@@ -444,7 +470,8 @@ error_handler (void *cls,
struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "MQ failure, reconnecting to transport service.\n");
+ "MQ failure %d, reconnecting to transport service.\n",
+ error);
disconnect (ch);
/* TODO: maybe do this with exponential backoff/delay */
reconnect (ch);
@@ -460,7 +487,7 @@ error_handler (void *cls,
*/
static void
handle_incoming_ack (void *cls,
- struct GNUNET_TRANSPORT_IncomingMessageAck *incoming_ack)
+ const struct GNUNET_TRANSPORT_IncomingMessageAck *incoming_ack)
{
struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
@@ -470,7 +497,7 @@ handle_incoming_ack (void *cls,
{
if ( (fc->id == incoming_ack->fc_id) &&
(0 == memcmp (&fc->sender,
- incoming_ack->sender,
+ &incoming_ack->sender,
sizeof (struct GNUNET_PeerIdentity))) )
{
GNUNET_CONTAINER_DLL_remove (ch->fc_head,
@@ -499,11 +526,12 @@ handle_incoming_ack (void *cls,
*/
static int
check_create_queue (void *cls,
- struct GNUNET_TRANSPORT_CreateQueue *cq)
+ const struct GNUNET_TRANSPORT_CreateQueue *cq)
{
uint16_t len = ntohs (cq->header.size) - sizeof (*cq);
const char *addr = (const char *) &cq[1];
+ (void) cls;
if ( (0 == len) ||
('\0' != addr[len-1]) )
{
@@ -522,11 +550,13 @@ check_create_queue (void *cls,
*/
static void
handle_create_queue (void *cls,
- struct GNUNET_TRANSPORT_CreateQueue *cq)
+ const struct GNUNET_TRANSPORT_CreateQueue *cq)
{
struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
const char *addr = (const char *) &cq[1];
-
+ struct GNUNET_TRANSPORT_CreateQueueResponse *cqr;
+ struct GNUNET_MQ_Envelope *env;
+
if (GNUNET_OK !=
ch->mq_init (ch->mq_init_cls,
&cq->receiver,
@@ -535,8 +565,17 @@ handle_create_queue (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Address `%s' invalid for this communicator\n",
addr);
- // TODO: do we notify the transport!?
+ env = GNUNET_MQ_msg (cqr,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_FAIL);
}
+ else
+ {
+ env = GNUNET_MQ_msg (cqr,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_OK);
+ }
+ cqr->request_id = cq->request_id;
+ GNUNET_MQ_send (ch->mq,
+ env);
}
@@ -550,11 +589,12 @@ handle_create_queue (void *cls,
*/
static int
check_send_msg (void *cls,
- struct GNUNET_TRANSPORT_SendMessageTo *smt)
+ const struct GNUNET_TRANSPORT_SendMessageTo *smt)
{
uint16_t len = ntohs (smt->header.size) - sizeof (*smt);
const struct GNUNET_MessageHeader *mh = (const struct GNUNET_MessageHeader *) &smt[1];
+ (void) cls;
if (ntohs (mh->size) != len)
{
GNUNET_break (0);
@@ -584,9 +624,9 @@ send_ack (struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
env = GNUNET_MQ_msg (ack,
GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG_ACK);
- ack->status = htonl (GNUNET_OK);
- ack->mid = ap->mid;
- ack->receiver = ap->receiver;
+ ack->status = htonl (status);
+ ack->mid = mid;
+ ack->receiver = *receiver;
GNUNET_MQ_send (ch->mq,
env);
}
@@ -623,18 +663,18 @@ send_ack_cb (void *cls)
*/
static void
handle_send_msg (void *cls,
- struct GNUNET_TRANSPORT_SendMessageTo *smt)
+ const struct GNUNET_TRANSPORT_SendMessageTo *smt)
{
struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls;
const struct GNUNET_MessageHeader *mh;
struct GNUNET_MQ_Envelope *env;
struct AckPending *ap;
- struct QueueHandle *qh;
+ struct GNUNET_TRANSPORT_QueueHandle *qh;
for (qh = ch->queue_head;NULL != qh; qh = qh->next)
if ( (qh->queue_id == smt->qid) &&
(0 == memcmp (&qh->peer,
- &smt->target,
+ &smt->receiver,
sizeof (struct GNUNET_PeerIdentity))) )
break;
if (NULL == qh)
@@ -653,7 +693,7 @@ handle_send_msg (void *cls,
ap->receiver = smt->receiver;
ap->mid = smt->mid;
GNUNET_CONTAINER_DLL_insert (ch->ap_head,
- cp->ap_tail,
+ ch->ap_tail,
ap);
mh = (const struct GNUNET_MessageHeader *) &smt[1];
env = GNUNET_MQ_msg_copy (mh);
@@ -679,7 +719,7 @@ reconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
struct GNUNET_TRANSPORT_IncomingMessageAck,
ch),
GNUNET_MQ_hd_var_size (create_queue,
- GNUNET_MESSAGE_TYPE_TRANSPORT_CREATE_QUEUE,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE,
struct GNUNET_TRANSPORT_CreateQueue,
ch),
GNUNET_MQ_hd_var_size (send_msg,
@@ -688,12 +728,24 @@ reconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
ch),
GNUNET_MQ_handler_end()
};
+ struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam;
+ struct GNUNET_MQ_Envelope *env;
- ch->mq = GNUNET_CLIENT_connect (cfg,
+ ch->mq = GNUNET_CLIENT_connect (ch->cfg,
"transport",
handlers,
&error_handler,
ch);
+ if (NULL == ch->mq)
+ return;
+ env = GNUNET_MQ_msg_extra (cam,
+ strlen (ch->addr_prefix) + 1,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_NEW_COMMUNICATOR);
+ memcpy (&cam[1],
+ ch->addr_prefix,
+ strlen (ch->addr_prefix) + 1);
+ GNUNET_MQ_send (ch->mq,
+ env);
for (struct GNUNET_TRANSPORT_AddressIdentifier *ai = ch->ai_head;
NULL != ai;
ai = ai->next)
@@ -709,7 +761,9 @@ reconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
* Connect to the transport service.
*
* @param cfg configuration to use
- * @param name name of the communicator that is connecting
+ * @param config_section section of the configuration to use for options
+ * @param addr_prefix address prefix for addresses supported by this
+ * communicator, could be NULL for incoming-only communicators
* @param mtu maximum message size supported by communicator, 0 if
* sending is not supported, SIZE_MAX for no MTU
* @param mq_init function to call to initialize a message queue given
@@ -720,7 +774,8 @@ reconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
*/
struct GNUNET_TRANSPORT_CommunicatorHandle *
GNUNET_TRANSPORT_communicator_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const char *name,
+ const char *config_section,
+ const char *addr_prefix,
size_t mtu,
GNUNET_TRANSPORT_CommunicatorMqInit mq_init,
void *mq_init_cls)
@@ -729,14 +784,15 @@ GNUNET_TRANSPORT_communicator_connect (const struct GNUNET_CONFIGURATION_Handle
ch = GNUNET_new (struct GNUNET_TRANSPORT_CommunicatorHandle);
ch->cfg = cfg;
- ch->name = name;
+ ch->config_section = config_section;
+ ch->addr_prefix = addr_prefix;
ch->mtu = mtu;
ch->mq_init = mq_init;
ch->mq_init_cls = mq_init_cls;
reconnect (ch);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_number (cfg,
- name,
+ config_section,
"MAX_QUEUE_LENGTH",
&ch->max_queue_length))
ch->max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
@@ -798,32 +854,15 @@ GNUNET_TRANSPORT_communicator_receive (struct GNUNET_TRANSPORT_CommunicatorHandl
struct GNUNET_TRANSPORT_IncomingMessage *im;
uint16_t msize;
- if (NULL == ai->ch->mq)
+ if (NULL == ch->mq)
return GNUNET_SYSERR;
- if (NULL != cb)
+ if ( (NULL == cb) &&
+ (GNUNET_MQ_get_length (ch->mq) >= ch->max_queue_length) )
{
- struct FlowControl *fc;
-
- im->fc_on = htonl (GNUNET_YES);
- im->fc_id = ai->ch->fc_gen++;
- fc = GNUNET_new (struct FlowControl);
- fc->sender = *sender;
- fc->id = im->fc_id;
- fc->cb = cb;
- fc->cb_cls = cb_cls;
- GNUNET_CONTAINER_DLL_insert (ch->fc_head,
- ch->fc_tail,
- fc);
- }
- else
- {
- if (GNUNET_MQ_get_length (ch->mq) >= ch->max_queue_length)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Dropping message: transprot is too slow, queue length %u exceeded\n",
- ch->max_queue_length);
- return GNUNET_NO;
- }
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Dropping message: transprot is too slow, queue length %llu exceeded\n",
+ ch->max_queue_length);
+ return GNUNET_NO;
}
msize = ntohs (msg->size);
@@ -839,7 +878,22 @@ GNUNET_TRANSPORT_communicator_receive (struct GNUNET_TRANSPORT_CommunicatorHandl
memcpy (&im[1],
msg,
msize);
- GNUNET_MQ_send (ai->ch->mq,
+ if (NULL != cb)
+ {
+ struct FlowControl *fc;
+
+ im->fc_on = htonl (GNUNET_YES);
+ im->fc_id = ch->fc_gen++;
+ fc = GNUNET_new (struct FlowControl);
+ fc->sender = *sender;
+ fc->id = im->fc_id;
+ fc->cb = cb;
+ fc->cb_cls = cb_cls;
+ GNUNET_CONTAINER_DLL_insert (ch->fc_head,
+ ch->fc_tail,
+ fc);
+ }
+ GNUNET_MQ_send (ch->mq,
env);
return GNUNET_OK;
}
@@ -927,9 +981,9 @@ GNUNET_TRANSPORT_communicator_address_add (struct GNUNET_TRANSPORT_CommunicatorH
ai->address = GNUNET_strdup (address);
ai->nt = nt;
ai->expiration = expiration;
- ai->aid = handle->aid_gen++;
- GNUNET_CONTAINER_DLL_insert (handle->ai_head,
- handle->ai_tail,
+ ai->aid = ch->aid_gen++;
+ GNUNET_CONTAINER_DLL_insert (ch->ai_head,
+ ch->ai_tail,
ai);
send_add_address (ai);
return ai;
diff --git a/src/util/configuration.c b/src/util/configuration.c
index 312e0acd3..197c664db 100644
--- a/src/util/configuration.c
+++ b/src/util/configuration.c
@@ -138,6 +138,41 @@ GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg)
/**
+ * Parse a configuration file @a filename and run the function
+ * @a cb with the resulting configuration object. Then free the
+ * configuration object and return the status value from @a cb.
+ *
+ * @param filename configuration to parse, NULL for "default"
+ * @param cb function to run
+ * @param cb_cls closure for @a cb
+ * @return #GNUNET_SYSERR if parsing the configuration failed,
+ * otherwise return value from @a cb.
+ */
+int
+GNUNET_CONFIGURATION_parse_and_run (const char *filename,
+ GNUNET_CONFIGURATION_Callback cb,
+ void *cb_cls)
+{
+ struct GNUNET_CONFIGURATION_Handle *cfg;
+ int ret;
+
+ cfg = GNUNET_CONFIGURATION_create ();
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_load (cfg,
+ filename))
+ {
+ GNUNET_break (0);
+ GNUNET_CONFIGURATION_destroy (cfg);
+ return GNUNET_SYSERR;
+ }
+ ret = cb (cb_cls,
+ cfg);
+ GNUNET_CONFIGURATION_destroy (cfg);
+ return ret;
+}
+
+
+/**
* De-serializes configuration
*
* @param cfg configuration to update
diff --git a/src/util/disk.c b/src/util/disk.c
index e0227be70..dc38d1137 100644
--- a/src/util/disk.c
+++ b/src/util/disk.c
@@ -2668,28 +2668,19 @@ GNUNET_DISK_internal_file_handle_ (const struct GNUNET_DISK_FileHandle *fh,
/**
- * Remove the directory given under @a option in
- * section [PATHS] in configuration under @a cfg_filename
+ * Helper function for #GNUNET_DISK_purge_cfg_dir.
*
- * @param cfg_filename configuration file to parse
- * @param option option with the dir name to purge
+ * @param cls a `const char *` with the option to purge
+ * @param cfg our configuration
+ * @return #GNUNET_OK on success
*/
-void
-GNUNET_DISK_purge_cfg_dir (const char *cfg_filename,
- const char *option)
+static int
+purge_cfg_dir (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
{
- struct GNUNET_CONFIGURATION_Handle *cfg;
+ const char *option = cls;
char *tmpname;
-
- cfg = GNUNET_CONFIGURATION_create ();
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_load (cfg,
- cfg_filename))
- {
- GNUNET_break (0);
- GNUNET_CONFIGURATION_destroy (cfg);
- return;
- }
+
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_filename (cfg,
"PATHS",
@@ -2699,10 +2690,8 @@ GNUNET_DISK_purge_cfg_dir (const char *cfg_filename,
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"PATHS",
option);
- GNUNET_CONFIGURATION_destroy (cfg);
- return;
+ return GNUNET_NO;
}
- GNUNET_CONFIGURATION_destroy (cfg);
if (GNUNET_SYSERR ==
GNUNET_DISK_directory_remove (tmpname))
{
@@ -2710,11 +2699,29 @@ GNUNET_DISK_purge_cfg_dir (const char *cfg_filename,
"remove",
tmpname);
GNUNET_free (tmpname);
- return;
+ return GNUNET_OK;
}
GNUNET_free (tmpname);
+ return GNUNET_OK;
}
+/**
+ * Remove the directory given under @a option in
+ * section [PATHS] in configuration under @a cfg_filename
+ *
+ * @param cfg_filename configuration file to parse
+ * @param option option with the dir name to purge
+ */
+void
+GNUNET_DISK_purge_cfg_dir (const char *cfg_filename,
+ const char *option)
+{
+ GNUNET_break (GNUNET_OK ==
+ GNUNET_CONFIGURATION_parse_and_run (cfg_filename,
+ &purge_cfg_dir,
+ (void *) option));
+}
+
/* end of disk.c */
diff --git a/src/util/gnunet-service-resolver.c b/src/util/gnunet-service-resolver.c
index d907bd8d9..3b871ce33 100644
--- a/src/util/gnunet-service-resolver.c
+++ b/src/util/gnunet-service-resolver.c
@@ -364,7 +364,7 @@ lookup_dns_servers (char ***server_addrs)
GNUNET_DISK_file_close (fh);
return -1;
}
- if (bytes_read > SIZE_MAX)
+ if ((size_t) bytes_read > SIZE_MAX)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"/etc/resolv.conf file too large to mmap. "
@@ -379,7 +379,7 @@ lookup_dns_servers (char ***server_addrs)
*server_addrs = NULL;
read_offset = 0;
num_dns_servers = 0;
- while (read_offset < bytes_read)
+ while (read_offset < (size_t) bytes_read)
{
const char *newline;
size_t line_len;
@@ -648,11 +648,16 @@ try_cache (const char *hostname,
struct ResolveCache *pos;
struct ResolveCache *next;
int found;
+ int in_hosts;
+ in_hosts = GNUNET_NO;
for (pos = hosts_head; NULL != pos; pos = pos->next)
if (0 == strcmp (pos->hostname,
hostname))
+ {
+ in_hosts = GNUNET_YES;
break;
+ }
if (NULL == pos)
{
next = cache_head;
@@ -673,7 +678,8 @@ try_cache (const char *hostname,
hostname);
return GNUNET_NO;
}
- if (cache_head != pos)
+ if ( (GNUNET_NO == in_hosts) &&
+ (cache_head != pos) )
{
/* move result to head to achieve LRU for cache eviction */
GNUNET_CONTAINER_DLL_remove (cache_head,
@@ -1313,7 +1319,7 @@ extract_hosts (const char *line,
if (NULL != c)
line_len = c - line;
/* ignore leading whitespace */
- while ( (0 > line_len) &&
+ while ( (0 < line_len) &&
isspace ((unsigned char) *line) )
{
line++;
@@ -1382,7 +1388,7 @@ load_etc_hosts (void)
GNUNET_DISK_file_close (fh);
return;
}
- if (bytes_read > SIZE_MAX)
+ if ((size_t) bytes_read > SIZE_MAX)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"/etc/hosts file too large to mmap. "
@@ -1395,7 +1401,7 @@ load_etc_hosts (void)
GNUNET_DISK_MAP_TYPE_READ,
(size_t) bytes_read);
read_offset = 0;
- while (read_offset < bytes_read)
+ while (read_offset < (size_t) bytes_read)
{
const char *newline;
size_t line_len;
diff --git a/src/util/service.c b/src/util/service.c
index ea34abc6c..b61168570 100644
--- a/src/util/service.c
+++ b/src/util/service.c
@@ -1815,8 +1815,9 @@ GNUNET_SERVICE_run_ (int argc,
opt_cfg_filename = GNUNET_strdup (cfg_filename);
if (GNUNET_YES == GNUNET_DISK_file_test (opt_cfg_filename))
{
- if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg,
- opt_cfg_filename))
+ if (GNUNET_SYSERR ==
+ GNUNET_CONFIGURATION_load (cfg,
+ opt_cfg_filename))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Malformed configuration file `%s', exit ...\n"),
@@ -1826,8 +1827,9 @@ GNUNET_SERVICE_run_ (int argc,
}
else
{
- if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg,
- NULL))
+ if (GNUNET_SYSERR ==
+ GNUNET_CONFIGURATION_load (cfg,
+ NULL))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Malformed configuration, exit ...\n"));