aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorxrs <xrs@mail36.net>2017-03-24 15:31:29 +0100
committerxrs <xrs@mail36.net>2017-03-24 15:31:29 +0100
commit03512957fb04969d08fb7eac0952a747aa9596ae (patch)
treeb130b8fbab45a8d4fb9a801ece7a7df13fa46b94 /src
parent633c9ed2d8392f0620dee12513f65a4cc602ea60 (diff)
parent7307d73db807dd1fa295629d2b89c70cf603aeb4 (diff)
downloadgnunet-03512957fb04969d08fb7eac0952a747aa9596ae.tar.gz
gnunet-03512957fb04969d08fb7eac0952a747aa9596ae.zip
Merge branch 'master' of ssh://gnunet.org/gnunet
Diffstat (limited to 'src')
-rw-r--r--src/arm/arm_api.c2
-rw-r--r--src/arm/gnunet-arm.c97
-rw-r--r--src/arm/gnunet-service-arm.c2
-rw-r--r--src/ats-tests/gnunet-solver-eval.c29
-rw-r--r--src/ats-tool/gnunet-ats.c84
-rw-r--r--src/ats/ats_api_scheduling.c6
-rw-r--r--src/ats/gnunet-ats-solver-eval.c45
-rw-r--r--src/ats/gnunet-service-ats_addresses.c2
-rw-r--r--src/ats/gnunet-service-ats_performance.c2
-rw-r--r--src/ats/perf_ats_solver.c57
-rw-r--r--src/auction/Makefile.am62
-rw-r--r--src/auction/gnunet-auction-create.c67
-rw-r--r--src/cadet/Makefile.am2
-rw-r--r--src/cadet/gnunet-cadet.c72
-rw-r--r--src/cadet/test_cadet.c26
-rw-r--r--src/consensus/consensus_protocol.h6
-rw-r--r--src/consensus/gnunet-consensus-profiler.c74
-rw-r--r--src/conversation/gnunet-conversation.c21
-rw-r--r--src/conversation/gnunet-helper-audio-playback.c15
-rw-r--r--src/conversation/microphone.c2
-rw-r--r--src/core/core_api.c4
-rw-r--r--src/core/gnunet-core.c9
-rw-r--r--src/core/gnunet-service-core.c2
-rw-r--r--src/core/gnunet-service-core_kx.c152
-rw-r--r--src/datastore/datastore.h24
-rw-r--r--src/datastore/datastore_api.c53
-rw-r--r--src/datastore/gnunet-datastore.c50
-rw-r--r--src/datastore/gnunet-service-datastore.c60
-rw-r--r--src/datastore/plugin_datastore_heap.c296
-rw-r--r--src/datastore/plugin_datastore_mysql.c306
-rw-r--r--src/datastore/plugin_datastore_postgres.c345
-rw-r--r--src/datastore/plugin_datastore_sqlite.c323
-rw-r--r--src/datastore/plugin_datastore_template.c43
-rw-r--r--src/datastore/test_datastore_api.c47
-rw-r--r--src/datastore/test_datastore_api_management.c44
-rw-r--r--src/datastore/test_plugin_datastore.c14
-rw-r--r--src/dht/dht_api.c14
-rw-r--r--src/dht/gnunet-dht-get.c68
-rw-r--r--src/dht/gnunet-dht-monitor.c50
-rw-r--r--src/dht/gnunet-dht-put.c84
-rw-r--r--src/dht/gnunet-service-dht_clients.c2
-rw-r--r--src/dht/gnunet-service-dht_datacache.c2
-rw-r--r--src/dht/gnunet-service-dht_neighbours.c16
-rw-r--r--src/dht/gnunet_dht_profiler.c73
-rw-r--r--src/dns/dns_api.c2
-rw-r--r--src/dns/gnunet-dns-monitor.c21
-rw-r--r--src/dns/gnunet-dns-redirector.c22
-rw-r--r--src/dns/gnunet-helper-dns.c2
-rw-r--r--src/dns/gnunet-service-dns.c7
-rw-r--r--src/dv/dv_api.c2
-rw-r--r--src/dv/gnunet-dv.c10
-rw-r--r--src/dv/gnunet-service-dv.c4
-rw-r--r--src/exit/gnunet-daemon-exit.c10
-rw-r--r--src/exit/gnunet-helper-exit-windows.c2
-rw-r--r--src/exit/gnunet-helper-exit.c2
-rw-r--r--src/fs/fs_api.h10
-rw-r--r--src/fs/fs_dirmetascan.c2
-rw-r--r--src/fs/fs_getopt.c79
-rw-r--r--src/fs/fs_publish.c4
-rw-r--r--src/fs/fs_search.c2
-rw-r--r--src/fs/fs_unindex.c58
-rw-r--r--src/fs/gnunet-auto-share.c54
-rw-r--r--src/fs/gnunet-download.c74
-rw-r--r--src/fs/gnunet-fs-profiler.c30
-rw-r--r--src/fs/gnunet-fs.c13
-rw-r--r--src/fs/gnunet-publish.c151
-rw-r--r--src/fs/gnunet-search.c58
-rw-r--r--src/fs/gnunet-service-fs_cadet_server.c50
-rw-r--r--src/fs/gnunet-service-fs_cp.c4
-rw-r--r--src/fs/gnunet-service-fs_indexing.c5
-rw-r--r--src/fs/gnunet-service-fs_indexing.h11
-rw-r--r--src/fs/gnunet-service-fs_pr.c420
-rw-r--r--src/fs/gnunet-service-fs_push.c6
-rw-r--r--src/fs/gnunet-service-fs_put.c46
-rw-r--r--src/fs/gnunet-unindex.c10
-rw-r--r--src/gns/gns_api.c2
-rw-r--r--src/gns/gnunet-bcd.c12
-rw-r--r--src/gns/gnunet-dns2gns.c48
-rw-r--r--src/gns/gnunet-gns-proxy.c25
-rw-r--r--src/gns/gnunet-gns.c56
-rw-r--r--src/hello/hello.c2
-rw-r--r--src/hostlist/gnunet-daemon-hostlist.c31
-rw-r--r--src/hostlist/gnunet-daemon-hostlist_client.c6
-rw-r--r--src/hostlist/gnunet-daemon-hostlist_server.c2
-rw-r--r--src/identity-provider/gnunet-identity-token.c19
-rw-r--r--src/identity-provider/identity_provider_api.c4
-rw-r--r--src/identity/gnunet-identity.c54
-rw-r--r--src/identity/identity_api.c14
-rw-r--r--src/include/Makefile.am2
-rw-r--r--src/include/gnunet_bandwidth_lib.h14
-rw-r--r--src/include/gnunet_connection_lib.h400
-rw-r--r--src/include/gnunet_constants.h2
-rw-r--r--src/include/gnunet_datastore_plugin.h85
-rw-r--r--src/include/gnunet_datastore_service.h22
-rw-r--r--src/include/gnunet_fs_service.h47
-rw-r--r--src/include/gnunet_getopt_lib.h349
-rw-r--r--src/include/gnunet_helper_lib.h8
-rw-r--r--src/include/gnunet_json_lib.h20
-rw-r--r--src/include/gnunet_mq_lib.h1
-rw-r--r--src/include/gnunet_server_lib.h887
-rw-r--r--src/include/gnunet_service_lib.h107
-rw-r--r--src/include/gnunet_util_lib.h17
-rw-r--r--src/include/platform.h1
-rw-r--r--src/json/json.c73
-rw-r--r--src/multicast/.gitignore1
-rw-r--r--src/multicast/gnunet-service-multicast.c3
-rw-r--r--src/namecache/gnunet-namecache.c20
-rw-r--r--src/namestore/gnunet-namestore.c125
-rw-r--r--src/namestore/gnunet-service-namestore.c2
-rw-r--r--src/nat-auto/Makefile.am5
-rw-r--r--src/nat-auto/gnunet-nat-auto.c44
-rw-r--r--src/nat-auto/gnunet-nat-server.c212
-rw-r--r--src/nat-auto/nat_auto_api.c2
-rw-r--r--src/nat/gnunet-nat.c65
-rw-r--r--src/nat/nat_api.c2
-rw-r--r--src/nse/gnunet-nse-profiler.c65
-rw-r--r--src/peerinfo-tool/gnunet-peerinfo.c67
-rw-r--r--src/peerinfo/gnunet-service-peerinfo.c8
-rw-r--r--src/pq/pq.c7
-rw-r--r--src/psyc/.gitignore1
-rw-r--r--src/psyc/psyc_api.c4
-rw-r--r--src/psycstore/.gitignore4
-rw-r--r--src/psycstore/gnunet-service-psycstore.c2
-rw-r--r--src/psycstore/psycstore_api.c4
-rw-r--r--src/psycutil/.gitignore1
-rw-r--r--src/regex/gnunet-regex-profiler.c49
-rw-r--r--src/regex/gnunet-regex-simulation-profiler.c21
-rw-r--r--src/regex/gnunet-service-regex.c323
-rw-r--r--src/regex/regex_api_announce.c2
-rw-r--r--src/regex/regex_api_search.c2
-rw-r--r--src/rest/gnunet-rest-server.c14
-rw-r--r--src/revocation/gnunet-revocation.c38
-rw-r--r--src/rps/gnunet-rps.c57
-rw-r--r--src/rps/gnunet-service-rps.c4
-rw-r--r--src/rps/rps_api.c8
-rw-r--r--src/rps/test_rps.c6
-rw-r--r--src/scalarproduct/gnunet-scalarproduct.c36
-rw-r--r--src/scalarproduct/scalarproduct_api.c8
-rw-r--r--src/secretsharing/gnunet-secretsharing-profiler.c59
-rw-r--r--src/secretsharing/gnunet-service-secretsharing.c27
-rw-r--r--src/set/gnunet-set-ibf-profiler.c49
-rw-r--r--src/set/gnunet-set-profiler.c86
-rw-r--r--src/social/.gitignore1
-rw-r--r--src/social/gnunet-social.c277
-rw-r--r--src/social/social_api.c10
-rw-r--r--src/statistics/gnunet-service-statistics.c2
-rw-r--r--src/statistics/gnunet-statistics.c60
-rw-r--r--src/statistics/statistics_api.c6
-rw-r--r--src/testbed-logger/gnunet-service-testbed-logger.c179
-rw-r--r--src/testbed-logger/test_testbed_logger_api.c4
-rw-r--r--src/testbed-logger/testbed_logger_api.c2
-rw-r--r--src/testbed/generate-underlay-topology.c12
-rw-r--r--src/testbed/gnunet-helper-testbed.c2
-rw-r--r--src/testbed/gnunet-service-testbed_barriers.c4
-rw-r--r--src/testbed/gnunet-testbed-profiler.c43
-rw-r--r--src/testbed/test_gnunet_helper_testbed.c18
-rw-r--r--src/testbed/testbed_api_hosts.c5
-rw-r--r--src/testbed/testbed_api_peers.c2
-rw-r--r--src/testing/gnunet-testing.c40
-rw-r--r--src/testing/list-keys.c15
-rw-r--r--src/topology/gnunet-daemon-topology.c2
-rw-r--r--src/transport/Makefile.am4
-rw-r--r--src/transport/gnunet-helper-transport-wlan-dummy.c30
-rw-r--r--src/transport/gnunet-service-transport_validation.c2
-rw-r--r--src/transport/gnunet-transport-profiler.c54
-rw-r--r--src/transport/gnunet-transport.c120
-rw-r--r--src/transport/plugin_transport_http_client.c25
-rw-r--r--src/transport/plugin_transport_http_server.c25
-rw-r--r--src/transport/plugin_transport_tcp.c587
-rw-r--r--src/transport/plugin_transport_udp.c41
-rw-r--r--src/transport/plugin_transport_udp.h12
-rw-r--r--src/transport/plugin_transport_udp_broadcasting.c30
-rw-r--r--src/transport/plugin_transport_wlan.c31
-rw-r--r--src/transport/tcp_connection_legacy.c (renamed from src/util/connection.c)24
-rw-r--r--src/transport/tcp_server_legacy.c (renamed from src/util/server.c)12
-rw-r--r--src/transport/tcp_server_mst_legacy.c (renamed from src/util/server_mst.c)6
-rw-r--r--src/transport/tcp_service_legacy.c1688
-rw-r--r--src/transport/test_plugin_transport.c2
-rw-r--r--src/transport/test_transport_api_reliability.c2
-rw-r--r--src/transport/transport_api_address_to_string.c6
-rw-r--r--src/transport/transport_api_core.c2
-rw-r--r--src/util/Makefile.am96
-rw-r--r--src/util/bandwidth.c20
-rw-r--r--src/util/client.c13
-rw-r--r--src/util/getopt.c72
-rw-r--r--src/util/getopt_helpers.c634
-rw-r--r--src/util/gnunet-config.c58
-rw-r--r--src/util/gnunet-ecc.c56
-rw-r--r--src/util/gnunet-resolver.c9
-rw-r--r--src/util/gnunet-scrypt.c41
-rw-r--r--src/util/helper.c25
-rw-r--r--src/util/mq.c104
-rw-r--r--src/util/mst.c4
-rw-r--r--src/util/resolver_api.c2
-rw-r--r--src/util/server_nc.c472
-rw-r--r--src/util/server_tc.c242
-rw-r--r--src/util/service.c2401
-rw-r--r--src/util/service_new.c2615
-rw-r--r--src/util/test_client.c2
-rw-r--r--src/util/test_connection.c167
-rw-r--r--src/util/test_connection_addressing.c186
-rw-r--r--src/util/test_connection_receive_cancel.c160
-rw-r--r--src/util/test_connection_timeout.c129
-rw-r--r--src/util/test_connection_timeout_no_connect.c76
-rw-r--r--src/util/test_connection_transmit_cancel.c76
-rw-r--r--src/util/test_getopt.c43
-rw-r--r--src/util/test_program.c129
-rw-r--r--src/util/test_server.c302
-rw-r--r--src/util/test_server_disconnect.c166
-rw-r--r--src/util/test_server_mst_interrupt.c60
-rw-r--r--src/util/test_server_with_client.c198
-rw-r--r--src/util/test_server_with_client_unix.c176
-rw-r--r--src/util/test_service.c2
-rw-r--r--src/vpn/gnunet-helper-vpn-windows.c2
-rw-r--r--src/vpn/gnunet-helper-vpn.c2
-rw-r--r--src/vpn/gnunet-service-vpn.c16
-rw-r--r--src/vpn/gnunet-vpn.c72
217 files changed, 8832 insertions, 11051 deletions
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c
index a61343833..56af544b1 100644
--- a/src/arm/arm_api.c
+++ b/src/arm/arm_api.c
@@ -753,7 +753,7 @@ change_service (struct GNUNET_ARM_Handle *h,
753 753
754 slen = strlen (service_name) + 1; 754 slen = strlen (service_name) + 1;
755 if (slen + sizeof (struct GNUNET_ARM_Message) >= 755 if (slen + sizeof (struct GNUNET_ARM_Message) >=
756 GNUNET_SERVER_MAX_MESSAGE_SIZE) 756 GNUNET_MAX_MESSAGE_SIZE)
757 { 757 {
758 GNUNET_break (0); 758 GNUNET_break (0);
759 return NULL; 759 return NULL;
diff --git a/src/arm/gnunet-arm.c b/src/arm/gnunet-arm.c
index 49886eb56..78c78738a 100644
--- a/src/arm/gnunet-arm.c
+++ b/src/arm/gnunet-arm.c
@@ -121,12 +121,12 @@ static struct GNUNET_SCHEDULER_Task *timeout_task;
121/** 121/**
122 * Do we want to give our stdout to gnunet-service-arm? 122 * Do we want to give our stdout to gnunet-service-arm?
123 */ 123 */
124static unsigned int no_stdout; 124static int no_stdout;
125 125
126/** 126/**
127 * Do we want to give our stderr to gnunet-service-arm? 127 * Do we want to give our stderr to gnunet-service-arm?
128 */ 128 */
129static unsigned int no_stderr; 129static int no_stderr;
130 130
131/** 131/**
132 * Handle for the task running the #action_loop(). 132 * Handle for the task running the #action_loop().
@@ -762,35 +762,70 @@ run (void *cls,
762int 762int
763main (int argc, char *const *argv) 763main (int argc, char *const *argv)
764{ 764{
765 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 765 struct GNUNET_GETOPT_CommandLineOption options[] = {
766 {'e', "end", NULL, gettext_noop ("stop all GNUnet services"), 766
767 GNUNET_NO, &GNUNET_GETOPT_set_one, &end}, 767 GNUNET_GETOPT_OPTION_SET_ONE ('e',
768 {'i', "init", "SERVICE", gettext_noop ("start a particular service"), 768 "end",
769 GNUNET_YES, &GNUNET_GETOPT_set_string, &init}, 769 gettext_noop ("stop all GNUnet services"),
770 {'k', "kill", "SERVICE", gettext_noop ("stop a particular service"), 770 &end),
771 GNUNET_YES, &GNUNET_GETOPT_set_string, &term}, 771
772 {'s', "start", NULL, gettext_noop ("start all GNUnet default services"), 772 GNUNET_GETOPT_OPTION_STRING ('i',
773 GNUNET_NO, &GNUNET_GETOPT_set_one, &start}, 773 "init",
774 {'r', "restart", NULL, 774 "SERVICE",
775 gettext_noop ("stop and start all GNUnet default services"), 775 gettext_noop ("start a particular service"),
776 GNUNET_NO, &GNUNET_GETOPT_set_one, &restart}, 776 &init),
777 {'d', "delete", NULL, 777
778 gettext_noop ("delete config file and directory on exit"), 778 GNUNET_GETOPT_OPTION_STRING ('k',
779 GNUNET_NO, &GNUNET_GETOPT_set_one, &delete}, 779 "kill",
780 {'m', "monitor", NULL, 780 "SERVICE",
781 gettext_noop ("monitor ARM activities"), 781 gettext_noop ("stop a particular service"),
782 GNUNET_NO, &GNUNET_GETOPT_set_one, &monitor}, 782 &term),
783 {'q', "quiet", NULL, gettext_noop ("don't print status messages"), 783
784 GNUNET_NO, &GNUNET_GETOPT_set_one, &quiet}, 784 GNUNET_GETOPT_OPTION_SET_ONE ('s',
785 {'T', "timeout", "DELAY", 785 "start",
786 gettext_noop ("exit with error status if operation does not finish after DELAY"), 786 gettext_noop ("start all GNUnet default services"),
787 GNUNET_YES, &GNUNET_GETOPT_set_relative_time, &timeout}, 787 &start),
788 {'I', "info", NULL, gettext_noop ("list currently running services"), 788
789 GNUNET_NO, &GNUNET_GETOPT_set_one, &list}, 789 GNUNET_GETOPT_OPTION_SET_ONE ('r',
790 {'O', "no-stdout", NULL, gettext_noop ("don't let gnunet-service-arm inherit standard output"), 790 "restart",
791 GNUNET_NO, &GNUNET_GETOPT_set_one, &no_stdout}, 791 gettext_noop ("stop and start all GNUnet default services"),
792 {'E', "no-stderr", NULL, gettext_noop ("don't let gnunet-service-arm inherit standard error"), 792 &restart),
793 GNUNET_NO, &GNUNET_GETOPT_set_one, &no_stderr}, 793 GNUNET_GETOPT_OPTION_SET_ONE ('d',
794 "delete",
795 gettext_noop ("delete config file and directory on exit"),
796 &delete),
797
798 GNUNET_GETOPT_OPTION_SET_ONE ('m',
799 "monitor",
800 gettext_noop ("monitor ARM activities"),
801 &monitor),
802
803 GNUNET_GETOPT_OPTION_SET_ONE ('q',
804 "quiet",
805 gettext_noop ("don't print status messages"),
806 &quiet),
807
808 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('T',
809 "timeout",
810 "DELAY",
811 gettext_noop ("exit with error status if operation does not finish after DELAY"),
812 &timeout),
813
814 GNUNET_GETOPT_OPTION_SET_ONE ('I',
815 "info",
816 gettext_noop ("list currently running services"),
817 &list),
818
819 GNUNET_GETOPT_OPTION_SET_ONE ('O',
820 "no-stdout",
821 gettext_noop ("don't let gnunet-service-arm inherit standard output"),
822 &no_stdout),
823
824 GNUNET_GETOPT_OPTION_SET_ONE ('E',
825 "no-stderr",
826 gettext_noop ("don't let gnunet-service-arm inherit standard error"),
827 &no_stderr),
828
794 GNUNET_GETOPT_OPTION_END 829 GNUNET_GETOPT_OPTION_END
795 }; 830 };
796 831
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c
index cc23ef1f6..19088c5cb 100644
--- a/src/arm/gnunet-service-arm.c
+++ b/src/arm/gnunet-service-arm.c
@@ -2225,7 +2225,7 @@ main (int argc,
2225 shc_chld = 2225 shc_chld =
2226 GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, 2226 GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD,
2227 &sighandler_child_death); 2227 &sighandler_child_death);
2228 ret = GNUNET_SERVICE_ruN_ (argc, 2228 ret = GNUNET_SERVICE_run_ (argc,
2229 argv, 2229 argv,
2230 "arm", 2230 "arm",
2231 GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN, 2231 GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN,
diff --git a/src/ats-tests/gnunet-solver-eval.c b/src/ats-tests/gnunet-solver-eval.c
index c19afe895..1bb7fdee7 100644
--- a/src/ats-tests/gnunet-solver-eval.c
+++ b/src/ats-tests/gnunet-solver-eval.c
@@ -931,17 +931,24 @@ main (int argc, char *argv[])
931 opt_log = GNUNET_NO; 931 opt_log = GNUNET_NO;
932 opt_plot = GNUNET_NO; 932 opt_plot = GNUNET_NO;
933 933
934 static struct GNUNET_GETOPT_CommandLineOption options[] = 934 struct GNUNET_GETOPT_CommandLineOption options[] =
935 { 935 {
936 { 's', "solver", NULL, 936 GNUNET_GETOPT_OPTION_STRING ('s',
937 gettext_noop ("solver to use"), 937 "solver",
938 1, &GNUNET_GETOPT_set_string, &opt_solver}, 938 NULL,
939 { 'e', "experiment", NULL, 939 gettext_noop ("solver to use"),
940 gettext_noop ("experiment to use"), 940 &opt_solver),
941 1, &GNUNET_GETOPT_set_string, &opt_exp_file}, 941
942 { 'e', "experiment", NULL, 942 GNUNET_GETOPT_OPTION_STRING ('e',
943 gettext_noop ("experiment to use"), 943 "experiment",
944 1, &GNUNET_GETOPT_set_one, &opt_verbose}, 944 NULL,
945 gettext_noop ("experiment to use"),
946 &opt_exp_file),
947
948 GNUNET_GETOPT_OPTION_SET_ONE ('e',
949 "experiment",
950 gettext_noop ("experiment to use"),
951 &opt_verbose),
945 GNUNET_GETOPT_OPTION_END 952 GNUNET_GETOPT_OPTION_END
946 }; 953 };
947 954
diff --git a/src/ats-tool/gnunet-ats.c b/src/ats-tool/gnunet-ats.c
index 5fc1d6e92..f645ba56d 100644
--- a/src/ats-tool/gnunet-ats.c
+++ b/src/ats-tool/gnunet-ats.c
@@ -944,34 +944,62 @@ main (int argc,
944 stat_receive_done = GNUNET_NO; 944 stat_receive_done = GNUNET_NO;
945 opt_type_str = NULL; 945 opt_type_str = NULL;
946 946
947 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 947 struct GNUNET_GETOPT_CommandLineOption options[] = {
948 { 'u', "used", NULL, 948 GNUNET_GETOPT_OPTION_SET_ONE ('u',
949 gettext_noop ("get list of active addresses currently used"), 0, 949 "used",
950 &GNUNET_GETOPT_set_one, &opt_list_used }, 950 gettext_noop ("get list of active addresses currently used"),
951 { 'a', "all", NULL, gettext_noop ("get list of all active addresses"), 0, 951 &opt_list_used),
952 &GNUNET_GETOPT_set_one, &opt_list_all }, 952 GNUNET_GETOPT_OPTION_SET_ONE ('a',
953 { 'C', "connect", "PEER", 953 "all",
954 gettext_noop ("connect to PEER"), 1, 954 gettext_noop ("get list of all active addresses"),
955 &GNUNET_GETOPT_set_string, &cpid_str }, 955 &opt_list_all),
956 { 'n', "numeric", NULL, 956
957 gettext_noop ("do not resolve IP addresses to hostnames"), 0, 957 GNUNET_GETOPT_OPTION_STRING ('C',
958 &GNUNET_GETOPT_set_one, &opt_resolve_addresses_numeric }, 958 "connect",
959 { 'm', "monitor", NULL, gettext_noop ("monitor mode"), 0, 959 NULL,
960 &GNUNET_GETOPT_set_one, &opt_monitor }, 960 gettext_noop ("connect to PEER"),
961 { 'p', "preference", NULL, gettext_noop ("set preference for the given peer"), 961 &cpid_str),
962 0, &GNUNET_GETOPT_set_one, &opt_set_pref }, 962 GNUNET_GETOPT_OPTION_SET_ONE ('n',
963 { 'q', "quotas", NULL, gettext_noop ("print all configured quotas"), 0, 963 "numeric",
964 &GNUNET_GETOPT_set_one, &opt_print_quotas }, 964 gettext_noop ("do not resolve IP addresses to hostnames"),
965 { 'i', "id", "TYPE", gettext_noop ("peer id"), 1, &GNUNET_GETOPT_set_string, 965 &opt_resolve_addresses_numeric),
966 &opt_pid_str }, 966
967 { 't', "type", "TYPE", 967 GNUNET_GETOPT_OPTION_SET_ONE ('m',
968 gettext_noop ("preference type to set: latency | bandwidth"), 1, 968 "monitor",
969 &GNUNET_GETOPT_set_string, &opt_type_str }, 969 gettext_noop ("monitor mode"),
970 { 'k', "value", "VALUE", gettext_noop ("preference value"), 1, 970 &opt_monitor),
971 &GNUNET_GETOPT_set_uint, &opt_pref_value }, 971
972 { 'V', "verbose", NULL, 972 GNUNET_GETOPT_OPTION_SET_ONE ('p',
973 gettext_noop ("verbose output (include ATS address properties)"), 0, 973 "preference",
974 &GNUNET_GETOPT_set_one, &opt_verbose }, 974 gettext_noop ("set preference for the given peer"),
975 &opt_set_pref),
976
977 GNUNET_GETOPT_OPTION_SET_ONE ('q',
978 "quotas",
979 gettext_noop ("print all configured quotas"),
980 &opt_print_quotas),
981 GNUNET_GETOPT_OPTION_STRING ('i',
982 "id",
983 "TYPE",
984 gettext_noop ("peer id"),
985 &opt_pid_str),
986
987 GNUNET_GETOPT_OPTION_STRING ('t',
988 "type",
989 "TYPE",
990 gettext_noop ("preference type to set: latency | bandwidth"),
991 &opt_type_str),
992
993 GNUNET_GETOPT_OPTION_SET_UINT ('k',
994 "value",
995 "VALUE",
996 gettext_noop ("preference value"),
997 &opt_pref_value),
998
999 GNUNET_GETOPT_OPTION_SET_ONE ('V',
1000 "verbose",
1001 gettext_noop ("verbose output (include ATS address properties)"),
1002 &opt_verbose),
975 GNUNET_GETOPT_OPTION_END 1003 GNUNET_GETOPT_OPTION_END
976 }; 1004 };
977 1005
diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c
index faeeb6081..81ae01b6a 100644
--- a/src/ats/ats_api_scheduling.c
+++ b/src/ats/ats_api_scheduling.c
@@ -657,9 +657,9 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
657 GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope); 657 GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope);
658 namelen = strlen (address->transport_name) + 1; 658 namelen = strlen (address->transport_name) + 1;
659 msize = address->address_length + namelen; 659 msize = address->address_length + namelen;
660 if ((msize + sizeof (struct AddressUpdateMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || 660 if ((msize + sizeof (struct AddressUpdateMessage) >= GNUNET_MAX_MESSAGE_SIZE) ||
661 (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || 661 (address->address_length >= GNUNET_MAX_MESSAGE_SIZE) ||
662 (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ) 662 (namelen >= GNUNET_MAX_MESSAGE_SIZE) )
663 { 663 {
664 /* address too large for us, this should not happen */ 664 /* address too large for us, this should not happen */
665 GNUNET_break (0); 665 GNUNET_break (0);
diff --git a/src/ats/gnunet-ats-solver-eval.c b/src/ats/gnunet-ats-solver-eval.c
index e2e68562c..597285f5e 100644
--- a/src/ats/gnunet-ats-solver-eval.c
+++ b/src/ats/gnunet-ats-solver-eval.c
@@ -3289,24 +3289,33 @@ main (int argc, char *argv[])
3289 3289
3290 static struct GNUNET_GETOPT_CommandLineOption options[] = 3290 static struct GNUNET_GETOPT_CommandLineOption options[] =
3291 { 3291 {
3292 { 's', "solver", NULL, 3292 GNUNET_GETOPT_OPTION_STRING ('s',
3293 gettext_noop ("solver to use"), 3293 "solver",
3294 1, &GNUNET_GETOPT_set_string, &opt_solver}, 3294 gettext_noop ("solver to use"),
3295 { 'e', "experiment", NULL, 3295 &opt_solver),
3296 gettext_noop ("experiment to use"), 3296
3297 1, &GNUNET_GETOPT_set_string, &opt_exp_file}, 3297 GNUNET_GETOPT_OPTION_STRING ('e',
3298 { 'V', "verbose", NULL, 3298 "experiment"
3299 gettext_noop ("be verbose"), 3299 gettext_noop ("experiment to use"),
3300 0, &GNUNET_GETOPT_set_one, &opt_verbose}, 3300 &opt_exp_file),
3301 { 'p', "print", NULL, 3301
3302 gettext_noop ("print logging"), 3302 GNUNET_GETOPT_OPTION_VERBOSE (&opt_verbose),
3303 0, &GNUNET_GETOPT_set_one, &opt_print}, 3303
3304 { 'f', "file", NULL, 3304 GNUNET_GETOPT_OPTION_SET_ONE ('p',
3305 gettext_noop ("save logging to disk"), 3305 "print",
3306 0, &GNUNET_GETOPT_set_one, &opt_save}, 3306 gettext_noop ("print logging"),
3307 { 'd', "dn", NULL, 3307 &opt_print),
3308 gettext_noop ("disable normalization"), 3308
3309 0, &GNUNET_GETOPT_set_one, &opt_disable_normalization}, 3309 GNUNET_GETOPT_OPTION_SET_ONE ('f',
3310 "file",
3311 gettext_noop ("save logging to disk"),
3312 &opt_save),
3313
3314 GNUNET_GETOPT_OPTION_SET_ONE ('d',
3315 "dn",
3316 gettext_noop ("disable normalization"),
3317 &opt_disable_normalization),
3318
3310 GNUNET_GETOPT_OPTION_END 3319 GNUNET_GETOPT_OPTION_END
3311 }; 3320 };
3312 3321
diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c
index 1a4a33206..ba34cbacb 100644
--- a/src/ats/gnunet-service-ats_addresses.c
+++ b/src/ats/gnunet-service-ats_addresses.c
@@ -571,7 +571,7 @@ transmit_req_addr (struct AddressIteration *ai,
571 msize = plugin_addr_len + plugin_name_length; 571 msize = plugin_addr_len + plugin_name_length;
572 572
573 GNUNET_assert (sizeof (struct PeerInformationMessage) + msize 573 GNUNET_assert (sizeof (struct PeerInformationMessage) + msize
574 < GNUNET_SERVER_MAX_MESSAGE_SIZE); 574 < GNUNET_MAX_MESSAGE_SIZE);
575 env = GNUNET_MQ_msg_extra (msg, 575 env = GNUNET_MQ_msg_extra (msg,
576 msize, 576 msize,
577 GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_RESPONSE); 577 GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_RESPONSE);
diff --git a/src/ats/gnunet-service-ats_performance.c b/src/ats/gnunet-service-ats_performance.c
index 5252a71bc..07ddf0531 100644
--- a/src/ats/gnunet-service-ats_performance.c
+++ b/src/ats/gnunet-service-ats_performance.c
@@ -85,7 +85,7 @@ notify_client (struct GNUNET_SERVICE_Client *client,
85 85
86 if (NULL != prop) 86 if (NULL != prop)
87 GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope); 87 GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope);
88 GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE); 88 GNUNET_assert (msize < GNUNET_MAX_MESSAGE_SIZE);
89 msg = (struct PeerInformationMessage *) buf; 89 msg = (struct PeerInformationMessage *) buf;
90 msg->header.size = htons (msize); 90 msg->header.size = htons (msize);
91 msg->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_PEER_INFORMATION); 91 msg->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_PEER_INFORMATION);
diff --git a/src/ats/perf_ats_solver.c b/src/ats/perf_ats_solver.c
index f05668e9b..855899b36 100644
--- a/src/ats/perf_ats_solver.c
+++ b/src/ats/perf_ats_solver.c
@@ -1404,27 +1404,42 @@ main (int argc, char *argv[])
1404 ph.total_iterations = 1; 1404 ph.total_iterations = 1;
1405 1405
1406 static struct GNUNET_GETOPT_CommandLineOption options[] = { 1406 static struct GNUNET_GETOPT_CommandLineOption options[] = {
1407 { 'a', "addresses", NULL, 1407
1408 gettext_noop ("addresses to use"), 1408 GNUNET_GETOPT_OPTION_SET_UINT ('a',
1409 1, &GNUNET_GETOPT_set_uint, &ph.N_address }, 1409 "addresses",
1410 { 's', "start", NULL, 1410 gettext_noop ("addresses to use"),
1411 gettext_noop ("start with peer"), 1411 &ph.N_address),
1412 1, &GNUNET_GETOPT_set_uint, &ph.N_peers_start }, 1412
1413 { 'e', "end", NULL, 1413 GNUNET_GETOPT_OPTION_SET_UINT ('s',
1414 gettext_noop ("end with peer"), 1414 "start",
1415 1, &GNUNET_GETOPT_set_uint, &ph.N_peers_end }, 1415 gettext_noop ("start with peer"),
1416 { 'i', "iterations", NULL, 1416 &ph.N_peers_start),
1417 gettext_noop ("number of iterations used for averaging (default: 1)"), 1417
1418 1, &GNUNET_GETOPT_set_uint, &ph.total_iterations }, 1418 GNUNET_GETOPT_OPTION_SET_UINT ('e',
1419 { 'p', "percentage", NULL, 1419 "end",
1420 gettext_noop ("update a fix percentage of addresses"), 1420 gettext_noop ("end with peer"),
1421 1, &GNUNET_GETOPT_set_uint, &ph.opt_update_percent }, 1421 &ph.N_peers_end),
1422 { 'd', "data", NULL, 1422
1423 gettext_noop ("create data file"), 1423 GNUNET_GETOPT_OPTION_SET_UINT ('i',
1424 0, &GNUNET_GETOPT_set_one, &ph.create_datafile}, 1424 "iterations",
1425 { 'u', "update", NULL, 1425 gettext_noop ("number of iterations used for averaging (default: 1)"),
1426 gettext_noop ("measure updates"), 1426 &ph.total_iterations),
1427 0, &GNUNET_GETOPT_set_one, &ph.measure_updates}, 1427
1428 GNUNET_GETOPT_OPTION_SET_UINT ('p',
1429 "percentage",
1430 gettext_noop ("update a fix percentage of addresses"),
1431 &ph.opt_update_percent),
1432
1433 GNUNET_GETOPT_OPTION_SET_ONE ('d',
1434 "data",
1435 gettext_noop ("create data file"),
1436 &ph.create_datafile),
1437
1438 GNUNET_GETOPT_OPTION_SET_ONE ('u',
1439 "update",
1440 gettext_noop ("measure updates"),
1441 &ph.measure_updates),
1442
1428 GNUNET_GETOPT_OPTION_END 1443 GNUNET_GETOPT_OPTION_END
1429 }; 1444 };
1430 1445
diff --git a/src/auction/Makefile.am b/src/auction/Makefile.am
index 28b52f3d5..bdede0ce0 100644
--- a/src/auction/Makefile.am
+++ b/src/auction/Makefile.am
@@ -1,74 +1,74 @@
1# This Makefile.am is in the public domain 1# This Makefile.am is in the public domain
2AM_CPPFLAGS = -I$(top_srcdir)/src/include 2AM_CPPFLAGS = -I$(top_srcdir)/src/include
3 3
4pkgcfgdir= $(pkgdatadir)/config.d/ 4pkgcfgdir = $(pkgdatadir)/config.d/
5 5
6libexecdir= $(pkglibdir)/libexec/ 6libexecdir = $(pkglibdir)/libexec/
7 7
8 8
9pkgcfg_DATA = \ 9pkgcfg_DATA = \
10 auction.conf 10 auction.conf
11 11
12if MINGW 12if MINGW
13 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols 13 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
14endif 14endif
15 15
16if USE_COVERAGE 16if USE_COVERAGE
17 AM_CFLAGS = -fprofile-arcs -ftest-coverage 17 AM_CFLAGS = -fprofile-arcs -ftest-coverage
18endif 18endif
19 19
20 20
21libexec_PROGRAMS = \ 21libexec_PROGRAMS = \
22 gnunet-service-auction 22 gnunet-service-auction
23 23
24gnunet_service_auction_SOURCES = \ 24gnunet_service_auction_SOURCES = \
25 gnunet-service-auction.c 25 gnunet-service-auction.c
26gnunet_service_auction_LDADD = \ 26gnunet_service_auction_LDADD = \
27 $(top_builddir)/src/util/libgnunetutil.la \ 27 $(top_builddir)/src/util/libgnunetutil.la \
28 -ljansson \ 28 -ljansson \
29 $(GN_LIBINTL) 29 $(GN_LIBINTL)
30 30
31 31
32bin_PROGRAMS = \ 32bin_PROGRAMS = \
33 gnunet-auction-create \ 33 gnunet-auction-create \
34 gnunet-auction-info \ 34 gnunet-auction-info \
35 gnunet-auction-join 35 gnunet-auction-join
36 36
37gnunet_auction_create_SOURCES = \ 37gnunet_auction_create_SOURCES = \
38 gnunet-auction-create.c 38 gnunet-auction-create.c
39gnunet_auction_create_LDADD = \ 39gnunet_auction_create_LDADD = \
40 $(top_builddir)/src/util/libgnunetutil.la \ 40 $(top_builddir)/src/util/libgnunetutil.la \
41 -ljansson \ 41 -ljansson \
42 $(GN_LIBINTL) 42 $(GN_LIBINTL)
43 43
44gnunet_auction_info_SOURCES = \ 44gnunet_auction_info_SOURCES = \
45 gnunet-auction-info.c 45 gnunet-auction-info.c
46gnunet_auction_info_LDADD = \ 46gnunet_auction_info_LDADD = \
47 $(top_builddir)/src/util/libgnunetutil.la \ 47 $(top_builddir)/src/util/libgnunetutil.la \
48 -ljansson \ 48 -ljansson \
49 $(GN_LIBINTL) 49 $(GN_LIBINTL)
50 50
51gnunet_auction_join_SOURCES = \ 51gnunet_auction_join_SOURCES = \
52 gnunet-auction-join.c 52 gnunet-auction-join.c
53gnunet_auction_join_LDADD = \ 53gnunet_auction_join_LDADD = \
54 $(top_builddir)/src/util/libgnunetutil.la \ 54 $(top_builddir)/src/util/libgnunetutil.la \
55 -ljansson \ 55 -ljansson \
56 $(GN_LIBINTL) 56 $(GN_LIBINTL)
57 57
58 58
59check_PROGRAMS = \ 59check_PROGRAMS = \
60 test_auction_api 60 test_auction_api
61 61
62test_auction_api_SOURCES = \ 62test_auction_api_SOURCES = \
63 test_auction_api.c 63 test_auction_api.c
64test_auction_api_LDADD = \ 64test_auction_api_LDADD = \
65 $(top_builddir)/src/util/libgnunetutil.la 65 $(top_builddir)/src/util/libgnunetutil.la
66 66
67 67
68check_SCRIPTS = \ 68check_SCRIPTS = \
69 test_auction_create.sh 69 test_auction_create.sh
70 70
71if ENABLE_TEST_RUN 71if ENABLE_TEST_RUN
72AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; 72 AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
73TESTS = $(check_PROGRAMS) $(check_SCRIPTS) 73 TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
74endif 74endif
diff --git a/src/auction/gnunet-auction-create.c b/src/auction/gnunet-auction-create.c
index a4c029572..e6fcab097 100644
--- a/src/auction/gnunet-auction-create.c
+++ b/src/auction/gnunet-auction-create.c
@@ -155,30 +155,49 @@ fail:
155int 155int
156main (int argc, char *const *argv) 156main (int argc, char *const *argv)
157{ 157{
158 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 158 struct GNUNET_GETOPT_CommandLineOption options[] = {
159 {'d', "description", "FILE", 159
160 gettext_noop ("description of the item to be sold"), 160 GNUNET_GETOPT_OPTION_FILENAME ('d',
161 1, &GNUNET_GETOPT_set_filename, &fndesc}, 161 "description",
162 {'p', "pricemap", "FILE", 162 "FILE",
163 gettext_noop ("mapping of possible prices"), 163 gettext_noop ("description of the item to be sold"),
164 1, &GNUNET_GETOPT_set_filename, &fnprices}, 164 &fndesc),
165 {'r', "roundtime", "DURATION", 165
166 gettext_noop ("max duration per round"), 166 GNUNET_GETOPT_OPTION_FILENAME ('p',
167 1, &GNUNET_GETOPT_set_relative_time, &dround}, 167 "pricemap",
168 {'s', "regtime", "DURATION", 168 "FILE",
169 gettext_noop ("duration until auction starts"), 169 gettext_noop ("mapping of possible prices"),
170 1, &GNUNET_GETOPT_set_relative_time, &dstart}, 170 &fnprices),
171 {'m', "m", "NUMBER", 171
172 gettext_noop ("number of items to sell\n" 172 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('r',
173 "0 for first price auction\n" 173 "roundtime",
174 ">0 for vickrey/M+1st price auction"), 174 "DURATION",
175 1, &GNUNET_GETOPT_set_uint, &m}, 175 gettext_noop ("max duration per round"),
176 {'u', "public", NULL, 176 &dround),
177 gettext_noop ("public auction outcome"), 177
178 0, &GNUNET_GETOPT_set_one, &outcome}, 178 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('s',
179 {'i', "interactive", NULL, 179 "regtime",
180 gettext_noop ("keep running in foreground until auction completes"), 180 "DURATION",
181 0, &GNUNET_GETOPT_set_one, &interactive}, 181 gettext_noop ("duration until auction starts"),
182 &dstart),
183 GNUNET_GETOPT_OPTION_SET_UINT ('m',
184 "m",
185 "NUMBER",
186 gettext_noop ("number of items to sell\n"
187 "0 for first price auction\n"
188 ">0 for vickrey/M+1st price auction"),
189 &m),
190
191 GNUNET_GETOPT_OPTION_SET_ONE ('u',
192 "public",
193 gettext_noop ("public auction outcome"),
194 &outcome),
195
196 GNUNET_GETOPT_OPTION_SET_ONE ('i',
197 "interactive",
198 gettext_noop ("keep running in foreground until auction completes"),
199 &interactive),
200
182 GNUNET_GETOPT_OPTION_END 201 GNUNET_GETOPT_OPTION_END
183 }; 202 };
184 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 203 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
diff --git a/src/cadet/Makefile.am b/src/cadet/Makefile.am
index af1a6720c..ce30ebe46 100644
--- a/src/cadet/Makefile.am
+++ b/src/cadet/Makefile.am
@@ -69,7 +69,7 @@ gnunet_service_cadet_LDADD = \
69 $(top_builddir)/src/hello/libgnunethello.la \ 69 $(top_builddir)/src/hello/libgnunethello.la \
70 $(top_builddir)/src/block/libgnunetblock.la 70 $(top_builddir)/src/block/libgnunetblock.la
71if LINUX 71if LINUX
72 gnunet_service_cadet_new_LDFLAGS = -lrt 72 gnunet_service_cadet_LDFLAGS = -lrt
73endif 73endif
74 74
75 75
diff --git a/src/cadet/gnunet-cadet.c b/src/cadet/gnunet-cadet.c
index 1556f7d86..57eeac735 100644
--- a/src/cadet/gnunet-cadet.c
+++ b/src/cadet/gnunet-cadet.c
@@ -920,32 +920,54 @@ main (int argc,
920{ 920{
921 int res; 921 int res;
922 const char helpstr[] = "Create tunnels and retrieve info about CADET's status."; 922 const char helpstr[] = "Create tunnels and retrieve info about CADET's status.";
923 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 923 struct GNUNET_GETOPT_CommandLineOption options[] = {
924 /* I would use the terminology 'circuit' here... --lynX */ 924 /* I would use the terminology 'circuit' here... --lynX */
925 {'C', "connection", "CONNECTION_ID", 925 GNUNET_GETOPT_OPTION_STRING ('C',
926 gettext_noop ("Provide information about a particular connection"), 926 "connection",
927 GNUNET_YES, &GNUNET_GETOPT_set_string, &conn_id}, 927 "CONNECTION_ID",
928 {'e', "echo", NULL, 928 gettext_noop ("Provide information about a particular connection"),
929 gettext_noop ("Activate echo mode"), 929 &conn_id),
930 GNUNET_NO, &GNUNET_GETOPT_set_one, &echo}, 930
931 {'d', "dump", NULL, 931 GNUNET_GETOPT_OPTION_SET_ONE ('e',
932 gettext_noop ("Dump debug information to STDERR"), 932 "echo",
933 GNUNET_NO, &GNUNET_GETOPT_set_one, &dump}, 933 gettext_noop ("Activate echo mode"),
934 {'o', "open-port", "SHARED_SECRET", 934 &echo),
935 gettext_noop ("Listen for connections using a shared secret among sender and recipient"), 935
936 GNUNET_YES, &GNUNET_GETOPT_set_string, &listen_port}, 936 GNUNET_GETOPT_OPTION_SET_ONE ('d',
937 {'p', "peer", "PEER_ID", 937 "dump",
938 gettext_noop ("Provide information about a patricular peer"), 938 gettext_noop ("Dump debug information to STDERR"),
939 GNUNET_YES, &GNUNET_GETOPT_set_string, &peer_id}, 939 &dump),
940 {'P', "peers", NULL, 940
941 gettext_noop ("Provide information about all peers"), 941 GNUNET_GETOPT_OPTION_STRING ('o',
942 GNUNET_NO, &GNUNET_GETOPT_set_one, &request_peers}, 942 "open-port",
943 {'t', "tunnel", "TUNNEL_ID", 943 "SHARED_SECRET",
944 gettext_noop ("Provide information about a particular tunnel"), 944 gettext_noop ("Listen for connections using a shared secret among sender and recipient"),
945 GNUNET_YES, &GNUNET_GETOPT_set_string, &tunnel_id}, 945 &listen_port),
946 {'T', "tunnels", NULL, 946
947 gettext_noop ("Provide information about all tunnels"), 947
948 GNUNET_NO, &GNUNET_GETOPT_set_one, &request_tunnels}, 948 GNUNET_GETOPT_OPTION_STRING ('p',
949 "peer",
950 "PEER_ID",
951 gettext_noop ("Provide information about a patricular peer"),
952 &peer_id),
953
954
955 GNUNET_GETOPT_OPTION_SET_ONE ('P',
956 "peers",
957 gettext_noop ("Provide information about all peers"),
958 &request_peers),
959
960 GNUNET_GETOPT_OPTION_STRING ('t',
961 "tunnel",
962 "TUNNEL_ID",
963 gettext_noop ("Provide information about a particular tunnel"),
964 &tunnel_id),
965
966
967 GNUNET_GETOPT_OPTION_SET_ONE ('T',
968 "tunnels",
969 gettext_noop ("Provide information about all tunnels"),
970 &request_tunnels),
949 971
950 GNUNET_GETOPT_OPTION_END 972 GNUNET_GETOPT_OPTION_END
951 }; 973 };
diff --git a/src/cadet/test_cadet.c b/src/cadet/test_cadet.c
index 3586b26ac..8963d97c9 100644
--- a/src/cadet/test_cadet.c
+++ b/src/cadet/test_cadet.c
@@ -948,6 +948,7 @@ tmain (void *cls,
948int 948int
949main (int argc, char *argv[]) 949main (int argc, char *argv[])
950{ 950{
951 static const struct GNUNET_HashCode *ports[2];
951 struct GNUNET_MQ_MessageHandler handlers[] = { 952 struct GNUNET_MQ_MessageHandler handlers[] = {
952 GNUNET_MQ_hd_var_size (data, 953 GNUNET_MQ_hd_var_size (data,
953 GNUNET_MESSAGE_TYPE_DUMMY, 954 GNUNET_MESSAGE_TYPE_DUMMY,
@@ -955,23 +956,26 @@ main (int argc, char *argv[])
955 NULL), 956 NULL),
956 GNUNET_MQ_handler_end () 957 GNUNET_MQ_handler_end ()
957 }; 958 };
958
959 initialized = GNUNET_NO;
960 static const struct GNUNET_HashCode *ports[2];
961 const char *config_file; 959 const char *config_file;
962 char port_id[] = "test port"; 960 char port_id[] = "test port";
963 961 struct GNUNET_GETOPT_CommandLineOption options[] = {
964 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 962 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('t',
965 {'t', "time", "short_time", 963 "time",
966 gettext_noop ("set short timeout"), 964 "short_time",
967 GNUNET_YES, &GNUNET_GETOPT_set_relative_time, &short_time}, 965 gettext_noop ("set short timeout"),
968 {'m', "messages", "NUM_MESSAGES", 966 &short_time),
969 gettext_noop ("set number of messages to send"), 967
970 GNUNET_YES, &GNUNET_GETOPT_set_uint, &total_packets}, 968 GNUNET_GETOPT_OPTION_SET_UINT ('m',
969 "messages",
970 "NUM_MESSAGES",
971 gettext_noop ("set number of messages to send"),
972 &total_packets),
971 973
972 GNUNET_GETOPT_OPTION_END 974 GNUNET_GETOPT_OPTION_END
973 }; 975 };
974 976
977
978 initialized = GNUNET_NO;
975 GNUNET_log_setup ("test", "DEBUG", NULL); 979 GNUNET_log_setup ("test", "DEBUG", NULL);
976 980
977 total_packets = TOTAL_PACKETS; 981 total_packets = TOTAL_PACKETS;
diff --git a/src/consensus/consensus_protocol.h b/src/consensus/consensus_protocol.h
index 320d460c7..f2933ed6f 100644
--- a/src/consensus/consensus_protocol.h
+++ b/src/consensus/consensus_protocol.h
@@ -109,7 +109,7 @@ struct ConsensusElement
109 /** 109 /**
110 * Is this a marker element? 110 * Is this a marker element?
111 */ 111 */
112 uint8_t marker GNUNET_PACKED; 112 uint8_t marker;
113 113
114 /* rest: element data */ 114 /* rest: element data */
115}; 115};
@@ -117,7 +117,7 @@ struct ConsensusElement
117 117
118struct ConsensusSizeElement 118struct ConsensusSizeElement
119{ 119{
120 struct ConsensusElement ce GNUNET_PACKED; 120 struct ConsensusElement ce;
121 121
122 uint64_t size GNUNET_PACKED; 122 uint64_t size GNUNET_PACKED;
123 uint8_t sender_index; 123 uint8_t sender_index;
@@ -125,7 +125,7 @@ struct ConsensusSizeElement
125 125
126struct ConsensusStuffedElement 126struct ConsensusStuffedElement
127{ 127{
128 struct ConsensusElement ce GNUNET_PACKED; 128 struct ConsensusElement ce;
129 struct GNUNET_HashCode rand GNUNET_PACKED; 129 struct GNUNET_HashCode rand GNUNET_PACKED;
130}; 130};
131 131
diff --git a/src/consensus/gnunet-consensus-profiler.c b/src/consensus/gnunet-consensus-profiler.c
index 65542f4cd..8cc1b3512 100644
--- a/src/consensus/gnunet-consensus-profiler.c
+++ b/src/consensus/gnunet-consensus-profiler.c
@@ -515,31 +515,55 @@ run (void *cls, char *const *args, const char *cfgfile,
515int 515int
516main (int argc, char **argv) 516main (int argc, char **argv)
517{ 517{
518 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 518 struct GNUNET_GETOPT_CommandLineOption options[] = {
519 { 'n', "num-peers", NULL, 519
520 gettext_noop ("number of peers in consensus"), 520 GNUNET_GETOPT_OPTION_SET_UINT ('n',
521 GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_peers }, 521 "num-peers",
522 { 'k', "value-replication", NULL, 522 NULL,
523 gettext_noop ("how many peers (random selection without replacement) receive one value?"), 523 gettext_noop ("number of peers in consensus"),
524 GNUNET_YES, &GNUNET_GETOPT_set_uint, &replication }, 524 &num_peers),
525 { 'x', "num-values", NULL, 525
526 gettext_noop ("number of values"), 526 GNUNET_GETOPT_OPTION_SET_UINT ('k',
527 GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_values }, 527 "value-replication",
528 { 't', "timeout", NULL, 528 NULL,
529 gettext_noop ("consensus timeout"), 529 gettext_noop ("how many peers (random selection without replacement) receive one value?"),
530 GNUNET_YES, &GNUNET_GETOPT_set_relative_time, &conclude_timeout }, 530 &replication),
531 { 'd', "delay", NULL, 531
532 gettext_noop ("delay until consensus starts"), 532 GNUNET_GETOPT_OPTION_SET_UINT ('x',
533 GNUNET_YES, &GNUNET_GETOPT_set_relative_time, &consensus_delay }, 533 "num-values",
534 { 's', "statistics", NULL, 534 NULL,
535 gettext_noop ("write statistics to file"), 535 gettext_noop ("number of values"),
536 GNUNET_YES, &GNUNET_GETOPT_set_filename, &statistics_filename }, 536 &num_values),
537 { 'S', "dist-static", NULL, 537
538 gettext_noop ("distribute elements to a static subset of good peers"), 538 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('t',
539 GNUNET_YES, &GNUNET_GETOPT_set_one, &dist_static }, 539 "timeout",
540 { 'V', "verbose", NULL, 540 NULL,
541 gettext_noop ("be more verbose (print received values)"), 541 gettext_noop ("consensus timeout"),
542 GNUNET_NO, &GNUNET_GETOPT_set_one, &verbose }, 542 &conclude_timeout),
543
544
545 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('d',
546 "delay",
547 NULL,
548 gettext_noop ("delay until consensus starts"),
549 &consensus_delay),
550
551 GNUNET_GETOPT_OPTION_FILENAME ('s',
552 "statistics",
553 "FILENAME",
554 gettext_noop ("write statistics to file"),
555 &statistics_filename),
556
557 GNUNET_GETOPT_OPTION_SET_ONE ('S',
558 "dist-static",
559 gettext_noop ("distribute elements to a static subset of good peers"),
560 &dist_static),
561
562 GNUNET_GETOPT_OPTION_SET_ONE ('V',
563 "verbose",
564 gettext_noop ("be more verbose (print received values)"),
565 &verbose),
566
543 GNUNET_GETOPT_OPTION_END 567 GNUNET_GETOPT_OPTION_END
544 }; 568 };
545 conclude_timeout = GNUNET_TIME_UNIT_SECONDS; 569 conclude_timeout = GNUNET_TIME_UNIT_SECONDS;
diff --git a/src/conversation/gnunet-conversation.c b/src/conversation/gnunet-conversation.c
index 925db4665..c5275c0de 100644
--- a/src/conversation/gnunet-conversation.c
+++ b/src/conversation/gnunet-conversation.c
@@ -1265,13 +1265,20 @@ run (void *cls,
1265int 1265int
1266main (int argc, char *const *argv) 1266main (int argc, char *const *argv)
1267{ 1267{
1268 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 1268 struct GNUNET_GETOPT_CommandLineOption options[] = {
1269 {'e', "ego", "NAME", 1269
1270 gettext_noop ("sets the NAME of the ego to use for the phone (and name resolution)"), 1270 GNUNET_GETOPT_OPTION_STRING ('e',
1271 1, &GNUNET_GETOPT_set_string, &ego_name}, 1271 "ego",
1272 {'p', "phone", "LINE", 1272 "NAME",
1273 gettext_noop ("sets the LINE to use for the phone"), 1273 gettext_noop ("sets the NAME of the ego to use for the phone (and name resolution)"),
1274 1, &GNUNET_GETOPT_set_string, &line}, 1274 &ego_name),
1275
1276 GNUNET_GETOPT_OPTION_STRING ('p',
1277 "phone",
1278 "LINE",
1279 gettext_noop ("sets the LINE to use for the phone"),
1280 &line),
1281
1275 GNUNET_GETOPT_OPTION_END 1282 GNUNET_GETOPT_OPTION_END
1276 }; 1283 };
1277 int ret; 1284 int ret;
diff --git a/src/conversation/gnunet-helper-audio-playback.c b/src/conversation/gnunet-helper-audio-playback.c
index e965cb2aa..4344e1d41 100644
--- a/src/conversation/gnunet-helper-audio-playback.c
+++ b/src/conversation/gnunet-helper-audio-playback.c
@@ -549,7 +549,6 @@ ogg_demux_and_decode ()
549 */ 549 */
550static int 550static int
551stdin_receiver (void *cls, 551stdin_receiver (void *cls,
552 void *client,
553 const struct GNUNET_MessageHeader *msg) 552 const struct GNUNET_MessageHeader *msg)
554{ 553{
555 struct AudioMessage *audio; 554 struct AudioMessage *audio;
@@ -727,12 +726,14 @@ ogg_init ()
727 ogg_sync_init (&oy); 726 ogg_sync_init (&oy);
728} 727}
729 728
729
730static void 730static void
731drain_callback (pa_stream*s, int success, void *userdata) 731drain_callback (pa_stream*s, int success, void *userdata)
732{ 732{
733 pa_threaded_mainloop_signal (m, 0); 733 pa_threaded_mainloop_signal (m, 0);
734} 734}
735 735
736
736/** 737/**
737 * The main function for the playback helper. 738 * The main function for the playback helper.
738 * 739 *
@@ -746,7 +747,7 @@ main (int argc, char *argv[])
746 static unsigned long long toff; 747 static unsigned long long toff;
747 748
748 char readbuf[MAXLINE]; 749 char readbuf[MAXLINE];
749 struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst; 750 struct GNUNET_MessageStreamTokenizer *stdin_mst;
750 char c; 751 char c;
751 ssize_t ret; 752 ssize_t ret;
752#ifdef DEBUG_READ_PURE_OGG 753#ifdef DEBUG_READ_PURE_OGG
@@ -762,7 +763,7 @@ main (int argc, char *argv[])
762 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "pipe"); 763 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "pipe");
763 return 1; 764 return 1;
764 } 765 }
765 stdin_mst = GNUNET_SERVER_mst_create (&stdin_receiver, NULL); 766 stdin_mst = GNUNET_MST_create (&stdin_receiver, NULL);
766 ogg_init (); 767 ogg_init ();
767 pa_init (); 768 pa_init ();
768 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 769 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -802,11 +803,11 @@ main (int argc, char *argv[])
802 } 803 }
803 else 804 else
804#endif 805#endif
805 GNUNET_SERVER_mst_receive (stdin_mst, NULL, 806 GNUNET_MST_from_buffer (stdin_mst,
806 readbuf, ret, 807 readbuf, ret,
807 GNUNET_NO, GNUNET_NO); 808 GNUNET_NO, GNUNET_NO);
808 } 809 }
809 GNUNET_SERVER_mst_destroy (stdin_mst); 810 GNUNET_MST_destroy (stdin_mst);
810 if (stream_out) 811 if (stream_out)
811 { 812 {
812 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 813 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
diff --git a/src/conversation/microphone.c b/src/conversation/microphone.c
index 94f52f8dc..7871433a3 100644
--- a/src/conversation/microphone.c
+++ b/src/conversation/microphone.c
@@ -64,13 +64,11 @@ struct Microphone
64 * Function to process the audio from the record helper 64 * Function to process the audio from the record helper
65 * 65 *
66 * @param cls clsoure with our `struct Microphone` 66 * @param cls clsoure with our `struct Microphone`
67 * @param client NULL
68 * @param msg the message from the helper 67 * @param msg the message from the helper
69 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 68 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
70 */ 69 */
71static int 70static int
72process_record_messages (void *cls, 71process_record_messages (void *cls,
73 void *client,
74 const struct GNUNET_MessageHeader *msg) 72 const struct GNUNET_MessageHeader *msg)
75{ 73{
76 struct Microphone *mic = cls; 74 struct Microphone *mic = cls;
diff --git a/src/core/core_api.c b/src/core/core_api.c
index fd789295d..ed8ce364d 100644
--- a/src/core/core_api.c
+++ b/src/core/core_api.c
@@ -321,7 +321,7 @@ core_mq_send_impl (struct GNUNET_MQ_Handle *mq,
321 321
322 /* check message size for sanity */ 322 /* check message size for sanity */
323 msize = ntohs (msg->size); 323 msize = ntohs (msg->size);
324 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct SendMessage)) 324 if (msize >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct SendMessage))
325 { 325 {
326 GNUNET_break (0); 326 GNUNET_break (0);
327 GNUNET_MQ_impl_send_continue (mq); 327 GNUNET_MQ_impl_send_continue (mq);
@@ -796,7 +796,7 @@ GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
796 h->handlers = GNUNET_MQ_copy_handlers (handlers); 796 h->handlers = GNUNET_MQ_copy_handlers (handlers);
797 h->hcnt = GNUNET_MQ_count_handlers (handlers); 797 h->hcnt = GNUNET_MQ_count_handlers (handlers);
798 GNUNET_assert (h->hcnt < 798 GNUNET_assert (h->hcnt <
799 (GNUNET_SERVER_MAX_MESSAGE_SIZE - 799 (GNUNET_MAX_MESSAGE_SIZE -
800 sizeof (struct InitMessage)) / sizeof (uint16_t)); 800 sizeof (struct InitMessage)) / sizeof (uint16_t));
801 LOG (GNUNET_ERROR_TYPE_DEBUG, 801 LOG (GNUNET_ERROR_TYPE_DEBUG,
802 "Connecting to CORE service\n"); 802 "Connecting to CORE service\n");
diff --git a/src/core/gnunet-core.c b/src/core/gnunet-core.c
index d91dc304d..ed89b1946 100644
--- a/src/core/gnunet-core.c
+++ b/src/core/gnunet-core.c
@@ -171,10 +171,11 @@ main (int argc,
171 char *const *argv) 171 char *const *argv)
172{ 172{
173 int res; 173 int res;
174 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 174 struct GNUNET_GETOPT_CommandLineOption options[] = {
175 {'m', "monitor", NULL, 175 GNUNET_GETOPT_OPTION_SET_ONE ('m',
176 gettext_noop ("provide information about all current connections (continuously)"), 176 "monitor",
177 0, &GNUNET_GETOPT_set_one, &monitor_connections}, 177 gettext_noop ("provide information about all current connections (continuously)"),
178 &monitor_connections),
178 GNUNET_GETOPT_OPTION_END 179 GNUNET_GETOPT_OPTION_END
179 }; 180 };
180 181
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index 31b91f12f..625bf9655 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -807,7 +807,7 @@ GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender,
807{ 807{
808 size_t size = msize + sizeof (struct NotifyTrafficMessage); 808 size_t size = msize + sizeof (struct NotifyTrafficMessage);
809 809
810 if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 810 if (size >= GNUNET_MAX_MESSAGE_SIZE)
811 { 811 {
812 GNUNET_break (0); 812 GNUNET_break (0);
813 return; 813 return;
diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c
index 906898512..8a7cada5c 100644
--- a/src/core/gnunet-service-core_kx.c
+++ b/src/core/gnunet-service-core_kx.c
@@ -263,6 +263,11 @@ struct GSC_KeyExchangeInfo
263 struct GNUNET_MQ_Handle *mq; 263 struct GNUNET_MQ_Handle *mq;
264 264
265 /** 265 /**
266 * Our message stream tokenizer (for encrypted payload).
267 */
268 struct GNUNET_MessageStreamTokenizer *mst;
269
270 /**
266 * PING message we transmit to the other peer. 271 * PING message we transmit to the other peer.
267 */ 272 */
268 struct PingMessage ping; 273 struct PingMessage ping;
@@ -370,11 +375,6 @@ static struct GNUNET_CRYPTO_EcdhePrivateKey *my_ephemeral_key;
370static struct EphemeralKeyMessage current_ekm; 375static struct EphemeralKeyMessage current_ekm;
371 376
372/** 377/**
373 * Our message stream tokenizer (for encrypted payload).
374 */
375static struct GNUNET_SERVER_MessageStreamTokenizer *mst;
376
377/**
378 * DLL head. 378 * DLL head.
379 */ 379 */
380static struct GSC_KeyExchangeInfo *kx_head; 380static struct GSC_KeyExchangeInfo *kx_head;
@@ -702,6 +702,55 @@ setup_fresh_ping (struct GSC_KeyExchangeInfo *kx)
702 702
703 703
704/** 704/**
705 * Deliver P2P message to interested clients. Invokes send twice,
706 * once for clients that want the full message, and once for clients
707 * that only want the header
708 *
709 * @param cls the `struct GSC_KeyExchangeInfo`
710 * @param m the message
711 */
712static int
713deliver_message (void *cls,
714 const struct GNUNET_MessageHeader *m)
715{
716 struct GSC_KeyExchangeInfo *kx = cls;
717
718 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
719 "Decrypted message of type %d from %s\n",
720 ntohs (m->type),
721 GNUNET_i2s (kx->peer));
722 if (GNUNET_CORE_KX_STATE_UP != kx->status)
723 {
724 GNUNET_STATISTICS_update (GSC_stats,
725 gettext_noop ("# PAYLOAD dropped (out of order)"),
726 1,
727 GNUNET_NO);
728 return GNUNET_OK;
729 }
730 switch (ntohs (m->type))
731 {
732 case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
733 case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
734 GSC_SESSIONS_set_typemap (kx->peer, m);
735 return GNUNET_OK;
736 case GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP:
737 GSC_SESSIONS_confirm_typemap (kx->peer, m);
738 return GNUNET_OK;
739 default:
740 GSC_CLIENTS_deliver_message (kx->peer,
741 m,
742 ntohs (m->size),
743 GNUNET_CORE_OPTION_SEND_FULL_INBOUND);
744 GSC_CLIENTS_deliver_message (kx->peer,
745 m,
746 sizeof (struct GNUNET_MessageHeader),
747 GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
748 }
749 return GNUNET_OK;
750}
751
752
753/**
705 * Function called by transport to notify us that 754 * Function called by transport to notify us that
706 * a peer connected to us (on the network level). 755 * a peer connected to us (on the network level).
707 * Starts the key exchange with the given peer. 756 * Starts the key exchange with the given peer.
@@ -727,6 +776,8 @@ handle_transport_notify_connect (void *cls,
727 1, 776 1,
728 GNUNET_NO); 777 GNUNET_NO);
729 kx = GNUNET_new (struct GSC_KeyExchangeInfo); 778 kx = GNUNET_new (struct GSC_KeyExchangeInfo);
779 kx->mst = GNUNET_MST_create (&deliver_message,
780 kx);
730 kx->mq = mq; 781 kx->mq = mq;
731 kx->peer = pid; 782 kx->peer = pid;
732 kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY; 783 kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
@@ -801,6 +852,7 @@ handle_transport_notify_disconnect (void *cls,
801 GNUNET_CONTAINER_DLL_remove (kx_head, 852 GNUNET_CONTAINER_DLL_remove (kx_head,
802 kx_tail, 853 kx_tail,
803 kx); 854 kx);
855 GNUNET_MST_destroy (kx->mst);
804 GNUNET_free (kx); 856 GNUNET_free (kx);
805} 857}
806 858
@@ -1417,24 +1469,6 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
1417 1469
1418 1470
1419/** 1471/**
1420 * Closure for #deliver_message()
1421 */
1422struct DeliverMessageContext
1423{
1424
1425 /**
1426 * Key exchange context.
1427 */
1428 struct GSC_KeyExchangeInfo *kx;
1429
1430 /**
1431 * Sender of the message.
1432 */
1433 const struct GNUNET_PeerIdentity *peer;
1434};
1435
1436
1437/**
1438 * We received an encrypted message. Check that it is 1472 * We received an encrypted message. Check that it is
1439 * well-formed (size-wise). 1473 * well-formed (size-wise).
1440 * 1474 *
@@ -1475,7 +1509,6 @@ handle_encrypted (void *cls,
1475 struct GNUNET_TIME_Absolute t; 1509 struct GNUNET_TIME_Absolute t;
1476 struct GNUNET_CRYPTO_SymmetricInitializationVector iv; 1510 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1477 struct GNUNET_CRYPTO_AuthKey auth_key; 1511 struct GNUNET_CRYPTO_AuthKey auth_key;
1478 struct DeliverMessageContext dmc;
1479 uint16_t size = ntohs (m->header.size); 1512 uint16_t size = ntohs (m->header.size);
1480 char buf[size] GNUNET_ALIGN; 1513 char buf[size] GNUNET_ALIGN;
1481 1514
@@ -1620,15 +1653,12 @@ handle_encrypted (void *cls,
1620 gettext_noop ("# bytes of payload decrypted"), 1653 gettext_noop ("# bytes of payload decrypted"),
1621 size - sizeof (struct EncryptedMessage), 1654 size - sizeof (struct EncryptedMessage),
1622 GNUNET_NO); 1655 GNUNET_NO);
1623 dmc.kx = kx;
1624 dmc.peer = kx->peer;
1625 if (GNUNET_OK != 1656 if (GNUNET_OK !=
1626 GNUNET_SERVER_mst_receive (mst, 1657 GNUNET_MST_from_buffer (kx->mst,
1627 &dmc, 1658 &buf[sizeof (struct EncryptedMessage)],
1628 &buf[sizeof (struct EncryptedMessage)], 1659 size - sizeof (struct EncryptedMessage),
1629 size - sizeof (struct EncryptedMessage), 1660 GNUNET_YES,
1630 GNUNET_YES, 1661 GNUNET_NO))
1631 GNUNET_NO))
1632 GNUNET_break_op (0); 1662 GNUNET_break_op (0);
1633} 1663}
1634 1664
@@ -1656,57 +1686,6 @@ handle_transport_notify_excess_bw (void *cls,
1656 1686
1657 1687
1658/** 1688/**
1659 * Deliver P2P message to interested clients. Invokes send twice,
1660 * once for clients that want the full message, and once for clients
1661 * that only want the header
1662 *
1663 * @param cls always NULL
1664 * @param client who sent us the message (struct GSC_KeyExchangeInfo)
1665 * @param m the message
1666 */
1667static int
1668deliver_message (void *cls,
1669 void *client,
1670 const struct GNUNET_MessageHeader *m)
1671{
1672 struct DeliverMessageContext *dmc = client;
1673
1674 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1675 "Decrypted message of type %d from %s\n",
1676 ntohs (m->type),
1677 GNUNET_i2s (dmc->peer));
1678 if (GNUNET_CORE_KX_STATE_UP != dmc->kx->status)
1679 {
1680 GNUNET_STATISTICS_update (GSC_stats,
1681 gettext_noop ("# PAYLOAD dropped (out of order)"),
1682 1,
1683 GNUNET_NO);
1684 return GNUNET_OK;
1685 }
1686 switch (ntohs (m->type))
1687 {
1688 case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
1689 case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
1690 GSC_SESSIONS_set_typemap (dmc->peer, m);
1691 return GNUNET_OK;
1692 case GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP:
1693 GSC_SESSIONS_confirm_typemap (dmc->peer, m);
1694 return GNUNET_OK;
1695 default:
1696 GSC_CLIENTS_deliver_message (dmc->peer,
1697 m,
1698 ntohs (m->size),
1699 GNUNET_CORE_OPTION_SEND_FULL_INBOUND);
1700 GSC_CLIENTS_deliver_message (dmc->peer,
1701 m,
1702 sizeof (struct GNUNET_MessageHeader),
1703 GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
1704 }
1705 return GNUNET_OK;
1706}
1707
1708
1709/**
1710 * Setup the message that links the ephemeral key to our persistent 1689 * Setup the message that links the ephemeral key to our persistent
1711 * public key and generate the appropriate signature. 1690 * public key and generate the appropriate signature.
1712 */ 1691 */
@@ -1829,8 +1808,6 @@ GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
1829 rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY, 1808 rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY,
1830 &do_rekey, 1809 &do_rekey,
1831 NULL); 1810 NULL);
1832 mst = GNUNET_SERVER_mst_create (&deliver_message,
1833 NULL);
1834 transport 1811 transport
1835 = GNUNET_TRANSPORT_core_connect (GSC_cfg, 1812 = GNUNET_TRANSPORT_core_connect (GSC_cfg,
1836 &GSC_my_identity, 1813 &GSC_my_identity,
@@ -1874,11 +1851,6 @@ GSC_KX_done ()
1874 GNUNET_free (my_private_key); 1851 GNUNET_free (my_private_key);
1875 my_private_key = NULL; 1852 my_private_key = NULL;
1876 } 1853 }
1877 if (NULL != mst)
1878 {
1879 GNUNET_SERVER_mst_destroy (mst);
1880 mst = NULL;
1881 }
1882 if (NULL != nc) 1854 if (NULL != nc)
1883 { 1855 {
1884 GNUNET_notification_context_destroy (nc); 1856 GNUNET_notification_context_destroy (nc);
diff --git a/src/datastore/datastore.h b/src/datastore/datastore.h
index 9de72f064..98f8b82ef 100644
--- a/src/datastore/datastore.h
+++ b/src/datastore/datastore.h
@@ -119,9 +119,14 @@ struct GetKeyMessage
119 uint32_t type GNUNET_PACKED; 119 uint32_t type GNUNET_PACKED;
120 120
121 /** 121 /**
122 * Offset of the result. 122 * UID at which to start the search
123 */ 123 */
124 uint64_t offset GNUNET_PACKED; 124 uint64_t next_uid GNUNET_PACKED;
125
126 /**
127 * If true return a random result
128 */
129 uint32_t random GNUNET_PACKED;
125 130
126 /** 131 /**
127 * Desired key. 132 * Desired key.
@@ -148,9 +153,14 @@ struct GetMessage
148 uint32_t type GNUNET_PACKED; 153 uint32_t type GNUNET_PACKED;
149 154
150 /** 155 /**
151 * Offset of the result. 156 * UID at which to start the search
157 */
158 uint64_t next_uid GNUNET_PACKED;
159
160 /**
161 * If true return a random result
152 */ 162 */
153 uint64_t offset GNUNET_PACKED; 163 uint32_t random GNUNET_PACKED;
154 164
155}; 165};
156 166
@@ -172,9 +182,9 @@ struct GetZeroAnonymityMessage
172 uint32_t type GNUNET_PACKED; 182 uint32_t type GNUNET_PACKED;
173 183
174 /** 184 /**
175 * Offset of the result. 185 * UID at which to start the search
176 */ 186 */
177 uint64_t offset GNUNET_PACKED; 187 uint64_t next_uid GNUNET_PACKED;
178 188
179}; 189};
180 190
@@ -219,7 +229,7 @@ struct DataMessage
219 uint32_t anonymity GNUNET_PACKED; 229 uint32_t anonymity GNUNET_PACKED;
220 230
221 /** 231 /**
222 * Desired replication level. 0 from service to API. 232 * Desired replication level.
223 */ 233 */
224 uint32_t replication GNUNET_PACKED; 234 uint32_t replication GNUNET_PACKED;
225 235
diff --git a/src/datastore/datastore_api.c b/src/datastore/datastore_api.c
index ef7cd7532..31f7a997f 100644
--- a/src/datastore/datastore_api.c
+++ b/src/datastore/datastore_api.c
@@ -352,7 +352,11 @@ mq_error_handler (void *cls,
352 qc.rc.proc (qc.rc.proc_cls, 352 qc.rc.proc (qc.rc.proc_cls,
353 NULL, 353 NULL,
354 0, 354 0,
355 NULL, 0, 0, 0, 355 NULL,
356 0,
357 0,
358 0,
359 0,
356 GNUNET_TIME_UNIT_ZERO_ABS, 360 GNUNET_TIME_UNIT_ZERO_ABS,
357 0); 361 0);
358 break; 362 break;
@@ -468,7 +472,11 @@ GNUNET_DATASTORE_disconnect (struct GNUNET_DATASTORE_Handle *h,
468 qe->qc.rc.proc (qe->qc.rc.proc_cls, 472 qe->qc.rc.proc (qe->qc.rc.proc_cls,
469 NULL, 473 NULL,
470 0, 474 0,
471 NULL, 0, 0, 0, 475 NULL,
476 0,
477 0,
478 0,
479 0,
472 GNUNET_TIME_UNIT_ZERO_ABS, 480 GNUNET_TIME_UNIT_ZERO_ABS,
473 0); 481 0);
474 break; 482 break;
@@ -825,6 +833,7 @@ handle_data (void *cls,
825 ntohl (dm->type), 833 ntohl (dm->type),
826 ntohl (dm->priority), 834 ntohl (dm->priority),
827 ntohl (dm->anonymity), 835 ntohl (dm->anonymity),
836 ntohl (dm->replication),
828 GNUNET_TIME_absolute_ntoh (dm->expiration), 837 GNUNET_TIME_absolute_ntoh (dm->expiration),
829 GNUNET_ntohll (dm->uid)); 838 GNUNET_ntohll (dm->uid));
830} 839}
@@ -887,6 +896,7 @@ handle_data_end (void *cls,
887 0, 896 0,
888 0, 897 0,
889 0, 898 0,
899 0,
890 GNUNET_TIME_UNIT_ZERO_ABS, 900 GNUNET_TIME_UNIT_ZERO_ABS,
891 0); 901 0);
892} 902}
@@ -1001,7 +1011,7 @@ GNUNET_DATASTORE_put (struct GNUNET_DATASTORE_Handle *h,
1001 struct DataMessage *dm; 1011 struct DataMessage *dm;
1002 union QueueContext qc; 1012 union QueueContext qc;
1003 1013
1004 if (size + sizeof (*dm) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 1014 if (size + sizeof (*dm) >= GNUNET_MAX_MESSAGE_SIZE)
1005 { 1015 {
1006 GNUNET_break (0); 1016 GNUNET_break (0);
1007 return NULL; 1017 return NULL;
@@ -1022,8 +1032,6 @@ GNUNET_DATASTORE_put (struct GNUNET_DATASTORE_Handle *h,
1022 dm->priority = htonl (priority); 1032 dm->priority = htonl (priority);
1023 dm->anonymity = htonl (anonymity); 1033 dm->anonymity = htonl (anonymity);
1024 dm->replication = htonl (replication); 1034 dm->replication = htonl (replication);
1025 dm->reserved = htonl (0);
1026 dm->uid = GNUNET_htonll (0);
1027 dm->expiration = GNUNET_TIME_absolute_hton (expiration); 1035 dm->expiration = GNUNET_TIME_absolute_hton (expiration);
1028 dm->key = *key; 1036 dm->key = *key;
1029 GNUNET_memcpy (&dm[1], 1037 GNUNET_memcpy (&dm[1],
@@ -1212,7 +1220,7 @@ GNUNET_DATASTORE_remove (struct GNUNET_DATASTORE_Handle *h,
1212 struct GNUNET_MQ_Envelope *env; 1220 struct GNUNET_MQ_Envelope *env;
1213 union QueueContext qc; 1221 union QueueContext qc;
1214 1222
1215 if (sizeof (*dm) + size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 1223 if (sizeof (*dm) + size >= GNUNET_MAX_MESSAGE_SIZE)
1216 { 1224 {
1217 GNUNET_break (0); 1225 GNUNET_break (0);
1218 return NULL; 1226 return NULL;
@@ -1226,13 +1234,7 @@ GNUNET_DATASTORE_remove (struct GNUNET_DATASTORE_Handle *h,
1226 env = GNUNET_MQ_msg_extra (dm, 1234 env = GNUNET_MQ_msg_extra (dm,
1227 size, 1235 size,
1228 GNUNET_MESSAGE_TYPE_DATASTORE_REMOVE); 1236 GNUNET_MESSAGE_TYPE_DATASTORE_REMOVE);
1229 dm->rid = htonl (0);
1230 dm->size = htonl (size); 1237 dm->size = htonl (size);
1231 dm->type = htonl (0);
1232 dm->priority = htonl (0);
1233 dm->anonymity = htonl (0);
1234 dm->uid = GNUNET_htonll (0);
1235 dm->expiration = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_ZERO_ABS);
1236 dm->key = *key; 1238 dm->key = *key;
1237 GNUNET_memcpy (&dm[1], 1239 GNUNET_memcpy (&dm[1],
1238 data, 1240 data,
@@ -1325,10 +1327,7 @@ GNUNET_DATASTORE_get_for_replication (struct GNUNET_DATASTORE_Handle *h,
1325 * Get a single zero-anonymity value from the datastore. 1327 * Get a single zero-anonymity value from the datastore.
1326 * 1328 *
1327 * @param h handle to the datastore 1329 * @param h handle to the datastore
1328 * @param offset offset of the result (modulo num-results); set to 1330 * @param next_uid return the result with lowest uid >= next_uid
1329 * a random 64-bit value initially; then increment by
1330 * one each time; detect that all results have been found by uid
1331 * being again the first uid ever returned.
1332 * @param queue_priority ranking of this request in the priority queue 1331 * @param queue_priority ranking of this request in the priority queue
1333 * @param max_queue_size at what queue size should this request be dropped 1332 * @param max_queue_size at what queue size should this request be dropped
1334 * (if other requests of higher priority are in the queue) 1333 * (if other requests of higher priority are in the queue)
@@ -1342,7 +1341,7 @@ GNUNET_DATASTORE_get_for_replication (struct GNUNET_DATASTORE_Handle *h,
1342 */ 1341 */
1343struct GNUNET_DATASTORE_QueueEntry * 1342struct GNUNET_DATASTORE_QueueEntry *
1344GNUNET_DATASTORE_get_zero_anonymity (struct GNUNET_DATASTORE_Handle *h, 1343GNUNET_DATASTORE_get_zero_anonymity (struct GNUNET_DATASTORE_Handle *h,
1345 uint64_t offset, 1344 uint64_t next_uid,
1346 unsigned int queue_priority, 1345 unsigned int queue_priority,
1347 unsigned int max_queue_size, 1346 unsigned int max_queue_size,
1348 enum GNUNET_BLOCK_Type type, 1347 enum GNUNET_BLOCK_Type type,
@@ -1357,13 +1356,12 @@ GNUNET_DATASTORE_get_zero_anonymity (struct GNUNET_DATASTORE_Handle *h,
1357 GNUNET_assert (NULL != proc); 1356 GNUNET_assert (NULL != proc);
1358 GNUNET_assert (type != GNUNET_BLOCK_TYPE_ANY); 1357 GNUNET_assert (type != GNUNET_BLOCK_TYPE_ANY);
1359 LOG (GNUNET_ERROR_TYPE_DEBUG, 1358 LOG (GNUNET_ERROR_TYPE_DEBUG,
1360 "Asked to get %llu-th zero-anonymity entry of type %d\n", 1359 "Asked to get a zero-anonymity entry of type %d\n",
1361 (unsigned long long) offset,
1362 type); 1360 type);
1363 env = GNUNET_MQ_msg (m, 1361 env = GNUNET_MQ_msg (m,
1364 GNUNET_MESSAGE_TYPE_DATASTORE_GET_ZERO_ANONYMITY); 1362 GNUNET_MESSAGE_TYPE_DATASTORE_GET_ZERO_ANONYMITY);
1365 m->type = htonl ((uint32_t) type); 1363 m->type = htonl ((uint32_t) type);
1366 m->offset = GNUNET_htonll (offset); 1364 m->next_uid = GNUNET_htonll (next_uid);
1367 qc.rc.proc = proc; 1365 qc.rc.proc = proc;
1368 qc.rc.proc_cls = proc_cls; 1366 qc.rc.proc_cls = proc_cls;
1369 qe = make_queue_entry (h, 1367 qe = make_queue_entry (h,
@@ -1392,10 +1390,8 @@ GNUNET_DATASTORE_get_zero_anonymity (struct GNUNET_DATASTORE_Handle *h,
1392 * will only be called once. 1390 * will only be called once.
1393 * 1391 *
1394 * @param h handle to the datastore 1392 * @param h handle to the datastore
1395 * @param offset offset of the result (modulo num-results); set to 1393 * @param next_uid return the result with lowest uid >= next_uid
1396 * a random 64-bit value initially; then increment by 1394 * @param random if true, return a random result instead of using next_uid
1397 * one each time; detect that all results have been found by uid
1398 * being again the first uid ever returned.
1399 * @param key maybe NULL (to match all entries) 1395 * @param key maybe NULL (to match all entries)
1400 * @param type desired type, 0 for any 1396 * @param type desired type, 0 for any
1401 * @param queue_priority ranking of this request in the priority queue 1397 * @param queue_priority ranking of this request in the priority queue
@@ -1409,7 +1405,8 @@ GNUNET_DATASTORE_get_zero_anonymity (struct GNUNET_DATASTORE_Handle *h,
1409 */ 1405 */
1410struct GNUNET_DATASTORE_QueueEntry * 1406struct GNUNET_DATASTORE_QueueEntry *
1411GNUNET_DATASTORE_get_key (struct GNUNET_DATASTORE_Handle *h, 1407GNUNET_DATASTORE_get_key (struct GNUNET_DATASTORE_Handle *h,
1412 uint64_t offset, 1408 uint64_t next_uid,
1409 bool random,
1413 const struct GNUNET_HashCode *key, 1410 const struct GNUNET_HashCode *key,
1414 enum GNUNET_BLOCK_Type type, 1411 enum GNUNET_BLOCK_Type type,
1415 unsigned int queue_priority, 1412 unsigned int queue_priority,
@@ -1433,14 +1430,16 @@ GNUNET_DATASTORE_get_key (struct GNUNET_DATASTORE_Handle *h,
1433 env = GNUNET_MQ_msg (gm, 1430 env = GNUNET_MQ_msg (gm,
1434 GNUNET_MESSAGE_TYPE_DATASTORE_GET); 1431 GNUNET_MESSAGE_TYPE_DATASTORE_GET);
1435 gm->type = htonl (type); 1432 gm->type = htonl (type);
1436 gm->offset = GNUNET_htonll (offset); 1433 gm->next_uid = GNUNET_htonll (next_uid);
1434 gm->random = random;
1437 } 1435 }
1438 else 1436 else
1439 { 1437 {
1440 env = GNUNET_MQ_msg (gkm, 1438 env = GNUNET_MQ_msg (gkm,
1441 GNUNET_MESSAGE_TYPE_DATASTORE_GET_KEY); 1439 GNUNET_MESSAGE_TYPE_DATASTORE_GET_KEY);
1442 gkm->type = htonl (type); 1440 gkm->type = htonl (type);
1443 gkm->offset = GNUNET_htonll (offset); 1441 gkm->next_uid = GNUNET_htonll (next_uid);
1442 gkm->random = random;
1444 gkm->key = *key; 1443 gkm->key = *key;
1445 } 1444 }
1446 qc.rc.proc = proc; 1445 qc.rc.proc = proc;
diff --git a/src/datastore/gnunet-datastore.c b/src/datastore/gnunet-datastore.c
index b3d14c43c..7caf5d175 100644
--- a/src/datastore/gnunet-datastore.c
+++ b/src/datastore/gnunet-datastore.c
@@ -130,20 +130,23 @@ do_finish (void *cls,
130 * @param type type of the content 130 * @param type type of the content
131 * @param priority priority of the content 131 * @param priority priority of the content
132 * @param anonymity anonymity-level for the content 132 * @param anonymity anonymity-level for the content
133 * @param replication replication-level for the content
133 * @param expiration expiration time for the content 134 * @param expiration expiration time for the content
134 * @param uid unique identifier for the datum; 135 * @param uid unique identifier for the datum;
135 * maybe 0 if no unique identifier is available 136 * maybe 0 if no unique identifier is available
136 */ 137 */
137static void 138static void
138do_put (void *cls, 139do_put (void *cls,
139 const struct GNUNET_HashCode *key, 140 const struct GNUNET_HashCode *key,
140 size_t size, 141 size_t size,
141 const void *data, 142 const void *data,
142 enum GNUNET_BLOCK_Type type, 143 enum GNUNET_BLOCK_Type type,
143 uint32_t priority, 144 uint32_t priority,
144 uint32_t anonymity, 145 uint32_t anonymity,
145 struct GNUNET_TIME_Absolute 146 uint32_t replication,
146 expiration, uint64_t uid) 147 struct GNUNET_TIME_Absolute
148 expiration,
149 uint64_t uid)
147{ 150{
148 qe = NULL; 151 qe = NULL;
149 if ( (0 != offset) && 152 if ( (0 != offset) &&
@@ -154,13 +157,20 @@ do_put (void *cls,
154 } 157 }
155 if (0 == offset) 158 if (0 == offset)
156 first_uid = uid; 159 first_uid = uid;
157 qe = GNUNET_DATASTORE_put (db_dst, 0, 160 qe = GNUNET_DATASTORE_put (db_dst,
158 key, size, data, type, 161 0,
159 priority, anonymity, 162 key,
160 0 /* FIXME: replication is lost... */, 163 size,
161 expiration, 164 data,
162 0, 1, 165 type,
163 &do_finish, NULL); 166 priority,
167 anonymity,
168 replication,
169 expiration,
170 0,
171 1,
172 &do_finish,
173 NULL);
164} 174}
165 175
166 176
@@ -171,7 +181,7 @@ static void
171do_get () 181do_get ()
172{ 182{
173 qe = GNUNET_DATASTORE_get_key (db_src, 183 qe = GNUNET_DATASTORE_get_key (db_src,
174 offset, 184 0, false,
175 NULL, GNUNET_BLOCK_TYPE_ANY, 185 NULL, GNUNET_BLOCK_TYPE_ANY,
176 0, 1, 186 0, 1,
177 &do_put, NULL); 187 &do_put, NULL);
@@ -239,10 +249,12 @@ run (void *cls, char *const *args, const char *cfgfile,
239int 249int
240main (int argc, char *const *argv) 250main (int argc, char *const *argv)
241{ 251{
242 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 252 struct GNUNET_GETOPT_CommandLineOption options[] = {
243 { 's', "sourcecfg", "FILENAME", 253 GNUNET_GETOPT_OPTION_FILENAME ('s',
244 gettext_noop ("specifies the configuration to use to access an alternative datastore; will merge that datastore into our current datastore"), 254 "sourcecfg",
245 1, &GNUNET_GETOPT_set_filename, &alternative_cfg }, 255 "FILENAME",
256 gettext_noop ("specifies the configuration to use to access an alternative datastore; will merge that datastore into our current datastore"),
257 &alternative_cfg),
246 GNUNET_GETOPT_OPTION_END 258 GNUNET_GETOPT_OPTION_END
247 }; 259 };
248 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 260 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c
index bde2843a6..277530843 100644
--- a/src/datastore/gnunet-service-datastore.c
+++ b/src/datastore/gnunet-service-datastore.c
@@ -286,6 +286,7 @@ delete_expired (void *cls);
286 * @param type type of the content 286 * @param type type of the content
287 * @param priority priority of the content 287 * @param priority priority of the content
288 * @param anonymity anonymity-level for the content 288 * @param anonymity anonymity-level for the content
289 * @param replication replication-level for the content
289 * @param expiration expiration time for the content 290 * @param expiration expiration time for the content
290 * @param uid unique identifier for the datum; 291 * @param uid unique identifier for the datum;
291 * maybe 0 if no unique identifier is available 292 * maybe 0 if no unique identifier is available
@@ -302,6 +303,7 @@ expired_processor (void *cls,
302 enum GNUNET_BLOCK_Type type, 303 enum GNUNET_BLOCK_Type type,
303 uint32_t priority, 304 uint32_t priority,
304 uint32_t anonymity, 305 uint32_t anonymity,
306 uint32_t replication,
305 struct GNUNET_TIME_Absolute expiration, 307 struct GNUNET_TIME_Absolute expiration,
306 uint64_t uid) 308 uint64_t uid)
307{ 309{
@@ -374,6 +376,7 @@ delete_expired (void *cls)
374 * @param type type of the content 376 * @param type type of the content
375 * @param priority priority of the content 377 * @param priority priority of the content
376 * @param anonymity anonymity-level for the content 378 * @param anonymity anonymity-level for the content
379 * @param replication replication-level for the content
377 * @param expiration expiration time for the content 380 * @param expiration expiration time for the content
378 * @param uid unique identifier for the datum; 381 * @param uid unique identifier for the datum;
379 * maybe 0 if no unique identifier is available 382 * maybe 0 if no unique identifier is available
@@ -389,6 +392,7 @@ quota_processor (void *cls,
389 enum GNUNET_BLOCK_Type type, 392 enum GNUNET_BLOCK_Type type,
390 uint32_t priority, 393 uint32_t priority,
391 uint32_t anonymity, 394 uint32_t anonymity,
395 uint32_t replication,
392 struct GNUNET_TIME_Absolute expiration, 396 struct GNUNET_TIME_Absolute expiration,
393 uint64_t uid) 397 uint64_t uid)
394{ 398{
@@ -495,6 +499,7 @@ transmit_status (struct GNUNET_SERVICE_Client *client,
495 * @param type type of the content 499 * @param type type of the content
496 * @param priority priority of the content 500 * @param priority priority of the content
497 * @param anonymity anonymity-level for the content 501 * @param anonymity anonymity-level for the content
502 * @param replication replication-level for the content
498 * @param expiration expiration time for the content 503 * @param expiration expiration time for the content
499 * @param uid unique identifier for the datum; 504 * @param uid unique identifier for the datum;
500 * maybe 0 if no unique identifier is available 505 * maybe 0 if no unique identifier is available
@@ -509,6 +514,7 @@ transmit_item (void *cls,
509 enum GNUNET_BLOCK_Type type, 514 enum GNUNET_BLOCK_Type type,
510 uint32_t priority, 515 uint32_t priority,
511 uint32_t anonymity, 516 uint32_t anonymity,
517 uint32_t replication,
512 struct GNUNET_TIME_Absolute expiration, 518 struct GNUNET_TIME_Absolute expiration,
513 uint64_t uid) 519 uint64_t uid)
514{ 520{
@@ -529,7 +535,7 @@ transmit_item (void *cls,
529 return GNUNET_OK; 535 return GNUNET_OK;
530 } 536 }
531 GNUNET_assert (sizeof (struct DataMessage) + size < 537 GNUNET_assert (sizeof (struct DataMessage) + size <
532 GNUNET_SERVER_MAX_MESSAGE_SIZE); 538 GNUNET_MAX_MESSAGE_SIZE);
533 env = GNUNET_MQ_msg_extra (dm, 539 env = GNUNET_MQ_msg_extra (dm,
534 size, 540 size,
535 GNUNET_MESSAGE_TYPE_DATASTORE_DATA); 541 GNUNET_MESSAGE_TYPE_DATASTORE_DATA);
@@ -538,8 +544,7 @@ transmit_item (void *cls,
538 dm->type = htonl (type); 544 dm->type = htonl (type);
539 dm->priority = htonl (priority); 545 dm->priority = htonl (priority);
540 dm->anonymity = htonl (anonymity); 546 dm->anonymity = htonl (anonymity);
541 dm->replication = htonl (0); 547 dm->replication = htonl (replication);
542 dm->reserved = htonl (0);
543 dm->expiration = GNUNET_TIME_absolute_hton (expiration); 548 dm->expiration = GNUNET_TIME_absolute_hton (expiration);
544 dm->uid = GNUNET_htonll (uid); 549 dm->uid = GNUNET_htonll (uid);
545 dm->key = *key; 550 dm->key = *key;
@@ -848,6 +853,7 @@ check_present_continuation (void *cls,
848 * @param type type of the content 853 * @param type type of the content
849 * @param priority priority of the content 854 * @param priority priority of the content
850 * @param anonymity anonymity-level for the content 855 * @param anonymity anonymity-level for the content
856 * @param replication replication-level for the content
851 * @param expiration expiration time for the content 857 * @param expiration expiration time for the content
852 * @param uid unique identifier for the datum; 858 * @param uid unique identifier for the datum;
853 * maybe 0 if no unique identifier is available 859 * maybe 0 if no unique identifier is available
@@ -856,13 +862,14 @@ check_present_continuation (void *cls,
856 */ 862 */
857static int 863static int
858check_present (void *cls, 864check_present (void *cls,
859 const struct GNUNET_HashCode *key, 865 const struct GNUNET_HashCode *key,
860 uint32_t size, 866 uint32_t size,
861 const void *data, 867 const void *data,
862 enum GNUNET_BLOCK_Type type, 868 enum GNUNET_BLOCK_Type type,
863 uint32_t priority, 869 uint32_t priority,
864 uint32_t anonymity, 870 uint32_t anonymity,
865 struct GNUNET_TIME_Absolute expiration, 871 uint32_t replication,
872 struct GNUNET_TIME_Absolute expiration,
866 uint64_t uid) 873 uint64_t uid)
867{ 874{
868 struct PutContext *pc = cls; 875 struct PutContext *pc = cls;
@@ -883,16 +890,17 @@ check_present (void *cls,
883 { 890 {
884 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 891 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
885 "Result already present in datastore\n"); 892 "Result already present in datastore\n");
886 /* FIXME: change API to allow increasing 'replication' counter */ 893 if ( (ntohl (dm->priority) > 0) ||
887 if ((ntohl (dm->priority) > 0) || 894 (ntohl (dm->replication) > 0) ||
888 (GNUNET_TIME_absolute_ntoh (dm->expiration).abs_value_us > 895 (GNUNET_TIME_absolute_ntoh (dm->expiration).abs_value_us >
889 expiration.abs_value_us)) 896 expiration.abs_value_us) )
890 plugin->api->update (plugin->api->cls, 897 plugin->api->update (plugin->api->cls,
891 uid, 898 uid,
892 ntohl (dm->priority), 899 ntohl (dm->priority),
900 ntohl (dm->replication),
893 GNUNET_TIME_absolute_ntoh (dm->expiration), 901 GNUNET_TIME_absolute_ntoh (dm->expiration),
894 &check_present_continuation, 902 &check_present_continuation,
895 pc->client); 903 pc->client);
896 else 904 else
897 { 905 {
898 transmit_status (pc->client, 906 transmit_status (pc->client,
@@ -984,12 +992,13 @@ handle_put (void *cls,
984 size, 992 size,
985 &vhash); 993 &vhash);
986 plugin->api->get_key (plugin->api->cls, 994 plugin->api->get_key (plugin->api->cls,
987 0, 995 0,
988 &dm->key, 996 false,
989 &vhash, 997 &dm->key,
998 &vhash,
990 ntohl (dm->type), 999 ntohl (dm->type),
991 &check_present, 1000 &check_present,
992 pc); 1001 pc);
993 GNUNET_SERVICE_client_continue (client); 1002 GNUNET_SERVICE_client_continue (client);
994 return; 1003 return;
995 } 1004 }
@@ -1018,7 +1027,8 @@ handle_get (void *cls,
1018 1, 1027 1,
1019 GNUNET_NO); 1028 GNUNET_NO);
1020 plugin->api->get_key (plugin->api->cls, 1029 plugin->api->get_key (plugin->api->cls,
1021 GNUNET_ntohll (msg->offset), 1030 GNUNET_ntohll (msg->next_uid),
1031 msg->random,
1022 NULL, 1032 NULL,
1023 NULL, 1033 NULL,
1024 ntohl (msg->type), 1034 ntohl (msg->type),
@@ -1062,14 +1072,15 @@ handle_get_key (void *cls,
1062 1, 1072 1,
1063 GNUNET_NO); 1073 GNUNET_NO);
1064 transmit_item (client, 1074 transmit_item (client,
1065 NULL, 0, NULL, 0, 0, 0, 1075 NULL, 0, NULL, 0, 0, 0, 0,
1066 GNUNET_TIME_UNIT_ZERO_ABS, 1076 GNUNET_TIME_UNIT_ZERO_ABS,
1067 0); 1077 0);
1068 GNUNET_SERVICE_client_continue (client); 1078 GNUNET_SERVICE_client_continue (client);
1069 return; 1079 return;
1070 } 1080 }
1071 plugin->api->get_key (plugin->api->cls, 1081 plugin->api->get_key (plugin->api->cls,
1072 GNUNET_ntohll (msg->offset), 1082 GNUNET_ntohll (msg->next_uid),
1083 msg->random,
1073 &msg->key, 1084 &msg->key,
1074 NULL, 1085 NULL,
1075 ntohl (msg->type), 1086 ntohl (msg->type),
@@ -1131,7 +1142,7 @@ handle_get_zero_anonymity (void *cls,
1131 1, 1142 1,
1132 GNUNET_NO); 1143 GNUNET_NO);
1133 plugin->api->get_zero_anonymity (plugin->api->cls, 1144 plugin->api->get_zero_anonymity (plugin->api->cls,
1134 GNUNET_ntohll (msg->offset), 1145 GNUNET_ntohll (msg->next_uid),
1135 type, 1146 type,
1136 &transmit_item, 1147 &transmit_item,
1137 client); 1148 client);
@@ -1150,6 +1161,7 @@ handle_get_zero_anonymity (void *cls,
1150 * @param type type of the content 1161 * @param type type of the content
1151 * @param priority priority of the content 1162 * @param priority priority of the content
1152 * @param anonymity anonymity-level for the content 1163 * @param anonymity anonymity-level for the content
1164 * @param replication replication-level for the content
1153 * @param expiration expiration time for the content 1165 * @param expiration expiration time for the content
1154 * @param uid unique identifier for the datum 1166 * @param uid unique identifier for the datum
1155 * @return #GNUNET_OK to keep the item 1167 * @return #GNUNET_OK to keep the item
@@ -1163,6 +1175,7 @@ remove_callback (void *cls,
1163 enum GNUNET_BLOCK_Type type, 1175 enum GNUNET_BLOCK_Type type,
1164 uint32_t priority, 1176 uint32_t priority,
1165 uint32_t anonymity, 1177 uint32_t anonymity,
1178 uint32_t replication,
1166 struct GNUNET_TIME_Absolute expiration, 1179 struct GNUNET_TIME_Absolute expiration,
1167 uint64_t uid) 1180 uint64_t uid)
1168{ 1181{
@@ -1241,6 +1254,7 @@ handle_remove (void *cls,
1241 (uint32_t) ntohl (dm->type)); 1254 (uint32_t) ntohl (dm->type));
1242 plugin->api->get_key (plugin->api->cls, 1255 plugin->api->get_key (plugin->api->cls,
1243 0, 1256 0,
1257 false,
1244 &dm->key, 1258 &dm->key,
1245 &vhash, 1259 &vhash,
1246 (enum GNUNET_BLOCK_Type) ntohl (dm->type), 1260 (enum GNUNET_BLOCK_Type) ntohl (dm->type),
diff --git a/src/datastore/plugin_datastore_heap.c b/src/datastore/plugin_datastore_heap.c
index 199c03a50..d04c1cf60 100644
--- a/src/datastore/plugin_datastore_heap.c
+++ b/src/datastore/plugin_datastore_heap.c
@@ -323,19 +323,19 @@ struct GetContext
323{ 323{
324 324
325 /** 325 /**
326 * Desired result offset / number of results. 326 * Lowest uid to consider.
327 */ 327 */
328 uint64_t offset; 328 uint64_t next_uid;
329 329
330 /** 330 /**
331 * The plugin. 331 * Value with lowest uid >= next_uid found so far.
332 */ 332 */
333 struct Plugin *plugin; 333 struct Value *value;
334 334
335 /** 335 /**
336 * Requested value hash. 336 * Requested value hash.
337 */ 337 */
338 const struct GNUNET_HashCode * vhash; 338 const struct GNUNET_HashCode *vhash;
339 339
340 /** 340 /**
341 * Requested type. 341 * Requested type.
@@ -343,68 +343,15 @@ struct GetContext
343 enum GNUNET_BLOCK_Type type; 343 enum GNUNET_BLOCK_Type type;
344 344
345 /** 345 /**
346 * Function to call with the result. 346 * If true, return a random value
347 */ 347 */
348 PluginDatumProcessor proc; 348 bool random;
349 349
350 /**
351 * Closure for 'proc'.
352 */
353 void *proc_cls;
354}; 350};
355 351
356 352
357/** 353/**
358 * Test if a value matches the specification from the 'get' context 354 * Obtain the matching value with the lowest uid >= next_uid.
359 *
360 * @param gc query
361 * @param value the value to check against the query
362 * @return GNUNET_YES if the value matches
363 */
364static int
365match (const struct GetContext *gc,
366 struct Value *value)
367{
368 struct GNUNET_HashCode vh;
369
370 if ( (gc->type != GNUNET_BLOCK_TYPE_ANY) &&
371 (gc->type != value->type) )
372 return GNUNET_NO;
373 if (NULL != gc->vhash)
374 {
375 GNUNET_CRYPTO_hash (&value[1], value->size, &vh);
376 if (0 != memcmp (&vh, gc->vhash, sizeof (struct GNUNET_HashCode)))
377 return GNUNET_NO;
378 }
379 return GNUNET_YES;
380}
381
382
383/**
384 * Count number of matching values.
385 *
386 * @param cls the 'struct GetContext'
387 * @param key unused
388 * @param val the 'struct Value'
389 * @return GNUNET_YES (continue iteration)
390 */
391static int
392count_iterator (void *cls,
393 const struct GNUNET_HashCode *key,
394 void *val)
395{
396 struct GetContext *gc = cls;
397 struct Value *value = val;
398
399 if (GNUNET_NO == match (gc, value))
400 return GNUNET_OK;
401 gc->offset++;
402 return GNUNET_OK;
403}
404
405
406/**
407 * Obtain matching value at 'offset'.
408 * 355 *
409 * @param cls the 'struct GetContext' 356 * @param cls the 'struct GetContext'
410 * @param key unused 357 * @param key unused
@@ -418,23 +365,29 @@ get_iterator (void *cls,
418{ 365{
419 struct GetContext *gc = cls; 366 struct GetContext *gc = cls;
420 struct Value *value = val; 367 struct Value *value = val;
368 struct GNUNET_HashCode vh;
421 369
422 if (GNUNET_NO == match (gc, value)) 370 if ( (gc->type != GNUNET_BLOCK_TYPE_ANY) &&
371 (gc->type != value->type) )
423 return GNUNET_OK; 372 return GNUNET_OK;
424 if (0 != gc->offset--) 373 if (NULL != gc->vhash)
374 {
375 GNUNET_CRYPTO_hash (&value[1], value->size, &vh);
376 if (0 != memcmp (&vh, gc->vhash, sizeof (struct GNUNET_HashCode)))
377 return GNUNET_OK;
378 }
379 if (gc->random)
380 {
381 gc->value = value;
382 return GNUNET_NO;
383 }
384 if ( (uint64_t) (intptr_t) value < gc->next_uid)
425 return GNUNET_OK; 385 return GNUNET_OK;
426 if (GNUNET_NO == 386 if ( (NULL != gc->value) &&
427 gc->proc (gc->proc_cls, 387 (value > gc->value) )
428 key, 388 return GNUNET_OK;
429 value->size, 389 gc->value = value;
430 &value[1], 390 return GNUNET_OK;
431 value->type,
432 value->priority,
433 value->anonymity,
434 value->expiration,
435 (uint64_t) (long) value))
436 delete_value (gc->plugin, value);
437 return GNUNET_NO;
438} 391}
439 392
440 393
@@ -442,8 +395,8 @@ get_iterator (void *cls,
442 * Get one of the results for a particular key in the datastore. 395 * Get one of the results for a particular key in the datastore.
443 * 396 *
444 * @param cls closure 397 * @param cls closure
445 * @param offset offset of the result (modulo num-results); 398 * @param next_uid return the result with lowest uid >= next_uid
446 * specific ordering does not matter for the offset 399 * @param random if true, return a random result instead of using next_uid
447 * @param key maybe NULL (to match all entries) 400 * @param key maybe NULL (to match all entries)
448 * @param vhash hash of the value, maybe NULL (to 401 * @param vhash hash of the value, maybe NULL (to
449 * match all values that have the right key). 402 * match all values that have the right key).
@@ -457,7 +410,7 @@ get_iterator (void *cls,
457 * @param proc_cls closure for proc 410 * @param proc_cls closure for proc
458 */ 411 */
459static void 412static void
460heap_plugin_get_key (void *cls, uint64_t offset, 413heap_plugin_get_key (void *cls, uint64_t next_uid, bool random,
461 const struct GNUNET_HashCode *key, 414 const struct GNUNET_HashCode *key,
462 const struct GNUNET_HashCode *vhash, 415 const struct GNUNET_HashCode *vhash,
463 enum GNUNET_BLOCK_Type type, PluginDatumProcessor proc, 416 enum GNUNET_BLOCK_Type type, PluginDatumProcessor proc,
@@ -466,25 +419,14 @@ heap_plugin_get_key (void *cls, uint64_t offset,
466 struct Plugin *plugin = cls; 419 struct Plugin *plugin = cls;
467 struct GetContext gc; 420 struct GetContext gc;
468 421
469 gc.plugin = plugin; 422 gc.value = NULL;
470 gc.offset = 0; 423 gc.next_uid = next_uid;
424 gc.random = random;
471 gc.vhash = vhash; 425 gc.vhash = vhash;
472 gc.type = type; 426 gc.type = type;
473 gc.proc = proc;
474 gc.proc_cls = proc_cls;
475 if (NULL == key) 427 if (NULL == key)
476 { 428 {
477 GNUNET_CONTAINER_multihashmap_iterate (plugin->keyvalue, 429 GNUNET_CONTAINER_multihashmap_iterate (plugin->keyvalue,
478 &count_iterator,
479 &gc);
480 if (0 == gc.offset)
481 {
482 proc (proc_cls,
483 NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
484 return;
485 }
486 gc.offset = offset % gc.offset;
487 GNUNET_CONTAINER_multihashmap_iterate (plugin->keyvalue,
488 &get_iterator, 430 &get_iterator,
489 &gc); 431 &gc);
490 } 432 }
@@ -492,20 +434,28 @@ heap_plugin_get_key (void *cls, uint64_t offset,
492 { 434 {
493 GNUNET_CONTAINER_multihashmap_get_multiple (plugin->keyvalue, 435 GNUNET_CONTAINER_multihashmap_get_multiple (plugin->keyvalue,
494 key, 436 key,
495 &count_iterator,
496 &gc);
497 if (0 == gc.offset)
498 {
499 proc (proc_cls,
500 NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
501 return;
502 }
503 gc.offset = offset % gc.offset;
504 GNUNET_CONTAINER_multihashmap_get_multiple (plugin->keyvalue,
505 key,
506 &get_iterator, 437 &get_iterator,
507 &gc); 438 &gc);
508 } 439 }
440 if (NULL == gc.value)
441 {
442 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
443 return;
444 }
445 if (GNUNET_NO ==
446 proc (proc_cls,
447 &gc.value->key,
448 gc.value->size,
449 &gc.value[1],
450 gc.value->type,
451 gc.value->priority,
452 gc.value->anonymity,
453 gc.value->replication,
454 gc.value->expiration,
455 (uint64_t) (intptr_t) gc.value))
456 {
457 delete_value (plugin, gc.value);
458 }
509} 459}
510 460
511 461
@@ -531,8 +481,7 @@ heap_plugin_get_replication (void *cls,
531 value = GNUNET_CONTAINER_heap_remove_root (plugin->by_replication); 481 value = GNUNET_CONTAINER_heap_remove_root (plugin->by_replication);
532 if (NULL == value) 482 if (NULL == value)
533 { 483 {
534 proc (proc_cls, 484 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
535 NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
536 return; 485 return;
537 } 486 }
538 if (value->replication > 0) 487 if (value->replication > 0)
@@ -552,14 +501,15 @@ heap_plugin_get_replication (void *cls,
552 } 501 }
553 if (GNUNET_NO == 502 if (GNUNET_NO ==
554 proc (proc_cls, 503 proc (proc_cls,
555 &value->key, 504 &value->key,
556 value->size, 505 value->size,
557 &value[1], 506 &value[1],
558 value->type, 507 value->type,
559 value->priority, 508 value->priority,
560 value->anonymity, 509 value->anonymity,
561 value->expiration, 510 value->replication,
562 (uint64_t) (long) value)) 511 value->expiration,
512 (uint64_t) (intptr_t) value))
563 delete_value (plugin, value); 513 delete_value (plugin, value);
564} 514}
565 515
@@ -582,35 +532,36 @@ heap_plugin_get_expiration (void *cls, PluginDatumProcessor proc,
582 value = GNUNET_CONTAINER_heap_peek (plugin->by_expiration); 532 value = GNUNET_CONTAINER_heap_peek (plugin->by_expiration);
583 if (NULL == value) 533 if (NULL == value)
584 { 534 {
585 proc (proc_cls, 535 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
586 NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
587 return; 536 return;
588 } 537 }
589 if (GNUNET_NO == 538 if (GNUNET_NO ==
590 proc (proc_cls, 539 proc (proc_cls,
591 &value->key, 540 &value->key,
592 value->size, 541 value->size,
593 &value[1], 542 &value[1],
594 value->type, 543 value->type,
595 value->priority, 544 value->priority,
596 value->anonymity, 545 value->anonymity,
597 value->expiration, 546 value->replication,
598 (uint64_t) (long) value)) 547 value->expiration,
548 (uint64_t) (intptr_t) value))
599 delete_value (plugin, value); 549 delete_value (plugin, value);
600} 550}
601 551
602 552
603/** 553/**
604 * Update the priority for a particular key in the datastore. If 554 * Update the priority, replication and expiration for a particular
605 * the expiration time in value is different than the time found in 555 * unique ID in the datastore. If the expiration time in value is
606 * the datastore, the higher value should be kept. For the 556 * different than the time found in the datastore, the higher value
607 * anonymity level, the lower value is to be used. The specified 557 * should be kept. The specified priority and replication is added
608 * priority should be added to the existing priority, ignoring the 558 * to the existing value.
609 * priority in value.
610 * 559 *
611 * @param cls our `struct Plugin *` 560 * @param cls our `struct Plugin *`
612 * @param uid unique identifier of the datum 561 * @param uid unique identifier of the datum
613 * @param delta by how much should the priority 562 * @param priority by how much should the priority
563 * change?
564 * @param replication by how much should the replication
614 * change? 565 * change?
615 * @param expire new expiration time should be the 566 * @param expire new expiration time should be the
616 * MAX of any existing expiration time and 567 * MAX of any existing expiration time and
@@ -620,15 +571,16 @@ heap_plugin_get_expiration (void *cls, PluginDatumProcessor proc,
620 */ 571 */
621static void 572static void
622heap_plugin_update (void *cls, 573heap_plugin_update (void *cls,
623 uint64_t uid, 574 uint64_t uid,
624 uint32_t delta, 575 uint32_t priority,
625 struct GNUNET_TIME_Absolute expire, 576 uint32_t replication,
626 PluginUpdateCont cont, 577 struct GNUNET_TIME_Absolute expire,
627 void *cont_cls) 578 PluginUpdateCont cont,
579 void *cont_cls)
628{ 580{
629 struct Value *value; 581 struct Value *value;
630 582
631 value = (struct Value*) (long) uid; 583 value = (struct Value*) (intptr_t) uid;
632 GNUNET_assert (NULL != value); 584 GNUNET_assert (NULL != value);
633 if (value->expiration.abs_value_us != expire.abs_value_us) 585 if (value->expiration.abs_value_us != expire.abs_value_us)
634 { 586 {
@@ -636,11 +588,15 @@ heap_plugin_update (void *cls,
636 GNUNET_CONTAINER_heap_update_cost (value->expire_heap, 588 GNUNET_CONTAINER_heap_update_cost (value->expire_heap,
637 expire.abs_value_us); 589 expire.abs_value_us);
638 } 590 }
639 /* Saturating add, don't overflow */ 591 /* Saturating adds, don't overflow */
640 if (value->priority > UINT32_MAX - delta) 592 if (value->priority > UINT32_MAX - priority)
641 value->priority = UINT32_MAX; 593 value->priority = UINT32_MAX;
642 else 594 else
643 value->priority += delta; 595 value->priority += priority;
596 if (value->replication > UINT32_MAX - replication)
597 value->replication = UINT32_MAX;
598 else
599 value->replication += replication;
644 cont (cont_cls, GNUNET_OK, NULL); 600 cont (cont_cls, GNUNET_OK, NULL);
645} 601}
646 602
@@ -649,63 +605,53 @@ heap_plugin_update (void *cls,
649 * Call the given processor on an item with zero anonymity. 605 * Call the given processor on an item with zero anonymity.
650 * 606 *
651 * @param cls our "struct Plugin*" 607 * @param cls our "struct Plugin*"
652 * @param offset offset of the result (modulo num-results); 608 * @param next_uid return the result with lowest uid >= next_uid
653 * specific ordering does not matter for the offset
654 * @param type entries of which type should be considered? 609 * @param type entries of which type should be considered?
655 * Use 0 for any type. 610 * Must not be zero (ANY).
656 * @param proc function to call on each matching value; 611 * @param proc function to call on each matching value;
657 * will be called with NULL if no value matches 612 * will be called with NULL if no value matches
658 * @param proc_cls closure for proc 613 * @param proc_cls closure for proc
659 */ 614 */
660static void 615static void
661heap_plugin_get_zero_anonymity (void *cls, uint64_t offset, 616heap_plugin_get_zero_anonymity (void *cls, uint64_t next_uid,
662 enum GNUNET_BLOCK_Type type, 617 enum GNUNET_BLOCK_Type type,
663 PluginDatumProcessor proc, void *proc_cls) 618 PluginDatumProcessor proc, void *proc_cls)
664{ 619{
665 struct Plugin *plugin = cls; 620 struct Plugin *plugin = cls;
666 struct ZeroAnonByType *zabt; 621 struct ZeroAnonByType *zabt;
667 struct Value *value; 622 struct Value *value = NULL;
668 uint64_t count;
669 623
670 count = 0;
671 for (zabt = plugin->zero_head; NULL != zabt; zabt = zabt->next) 624 for (zabt = plugin->zero_head; NULL != zabt; zabt = zabt->next)
672 { 625 {
673 if ( (type != GNUNET_BLOCK_TYPE_ANY) && 626 if ( (type != GNUNET_BLOCK_TYPE_ANY) &&
674 (type != zabt->type) ) 627 (type != zabt->type) )
675 continue; 628 continue;
676 count += zabt->array_pos; 629 for (int i = 0; i < zabt->array_pos; ++i)
630 {
631 if ( (uint64_t) (intptr_t) zabt->array[i] < next_uid)
632 continue;
633 if ( (NULL != value) &&
634 (zabt->array[i] > value) )
635 continue;
636 value = zabt->array[i];
637 }
677 } 638 }
678 if (0 == count) 639 if (NULL == value)
679 { 640 {
680 proc (proc_cls, 641 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
681 NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
682 return; 642 return;
683 } 643 }
684 offset = offset % count;
685 for (zabt = plugin->zero_head; NULL != zabt; zabt = zabt->next)
686 {
687 if ( (type != GNUNET_BLOCK_TYPE_ANY) &&
688 (type != zabt->type) )
689 continue;
690 if (offset >= zabt->array_pos)
691 {
692 offset -= zabt->array_pos;
693 continue;
694 }
695 break;
696 }
697 GNUNET_assert (NULL != zabt);
698 value = zabt->array[offset];
699 if (GNUNET_NO == 644 if (GNUNET_NO ==
700 proc (proc_cls, 645 proc (proc_cls,
701 &value->key, 646 &value->key,
702 value->size, 647 value->size,
703 &value[1], 648 &value[1],
704 value->type, 649 value->type,
705 value->priority, 650 value->priority,
706 value->anonymity, 651 value->anonymity,
707 value->expiration, 652 value->replication,
708 (uint64_t) (long) value)) 653 value->expiration,
654 (uint64_t) (intptr_t) value))
709 delete_value (plugin, value); 655 delete_value (plugin, value);
710} 656}
711 657
diff --git a/src/datastore/plugin_datastore_mysql.c b/src/datastore/plugin_datastore_mysql.c
index 1067064aa..6f2a76499 100644
--- a/src/datastore/plugin_datastore_mysql.c
+++ b/src/datastore/plugin_datastore_mysql.c
@@ -150,31 +150,56 @@ struct Plugin
150#define DELETE_ENTRY_BY_UID "DELETE FROM gn090 WHERE uid=?" 150#define DELETE_ENTRY_BY_UID "DELETE FROM gn090 WHERE uid=?"
151 struct GNUNET_MYSQL_StatementHandle *delete_entry_by_uid; 151 struct GNUNET_MYSQL_StatementHandle *delete_entry_by_uid;
152 152
153#define COUNT_ENTRY_BY_HASH "SELECT count(*) FROM gn090 FORCE INDEX (idx_hash) WHERE hash=?" 153#define RESULT_COLUMNS "repl, type, prio, anonLevel, expire, hash, value, uid"
154 struct GNUNET_MYSQL_StatementHandle *count_entry_by_hash; 154
155 155#define SELECT_ENTRY "SELECT " RESULT_COLUMNS " FROM gn090 "\
156#define SELECT_ENTRY_BY_HASH "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_hash) WHERE hash=? ORDER BY uid LIMIT 1 OFFSET ?" 156 "WHERE uid >= ? AND "\
157 "(rvalue >= ? OR 0 = ?) "\
158 "ORDER BY uid LIMIT 1"
159 struct GNUNET_MYSQL_StatementHandle *select_entry;
160
161#define SELECT_ENTRY_BY_HASH "SELECT " RESULT_COLUMNS " FROM gn090 "\
162 "FORCE INDEX (idx_hash) "\
163 "WHERE hash=? AND "\
164 "uid >= ? AND "\
165 "(rvalue >= ? OR 0 = ?) "\
166 "ORDER BY uid LIMIT 1"
157 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash; 167 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash;
158 168
159#define COUNT_ENTRY_BY_HASH_AND_VHASH "SELECT count(*) FROM gn090 FORCE INDEX (idx_hash_vhash) WHERE hash=? AND vhash=?" 169#define SELECT_ENTRY_BY_HASH_AND_VHASH "SELECT " RESULT_COLUMNS " FROM gn090 "\
160 struct GNUNET_MYSQL_StatementHandle *count_entry_by_hash_and_vhash; 170 "FORCE INDEX (idx_hash_vhash) "\
161 171 "WHERE hash = ? AND "\
162#define SELECT_ENTRY_BY_HASH_AND_VHASH "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_hash_vhash) WHERE hash=? AND vhash=? ORDER BY uid LIMIT 1 OFFSET ?" 172 "vhash = ? AND "\
173 "uid >= ? AND "\
174 "(rvalue >= ? OR 0 = ?) "\
175 "ORDER BY uid LIMIT 1"
163 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_and_vhash; 176 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_and_vhash;
164 177
165#define COUNT_ENTRY_BY_HASH_AND_TYPE "SELECT count(*) FROM gn090 FORCE INDEX (idx_hash_type_uid) WHERE hash=? AND type=?" 178#define SELECT_ENTRY_BY_HASH_AND_TYPE "SELECT " RESULT_COLUMNS " FROM gn090 "\
166 struct GNUNET_MYSQL_StatementHandle *count_entry_by_hash_and_type; 179 "FORCE INDEX (idx_hash_type_uid) "\
167 180 "WHERE hash = ? AND "\
168#define SELECT_ENTRY_BY_HASH_AND_TYPE "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_hash_type_uid) WHERE hash=? AND type=? ORDER BY uid LIMIT 1 OFFSET ?" 181 "type = ? AND "\
182 "uid >= ? AND "\
183 "(rvalue >= ? OR 0 = ?) "\
184 "ORDER BY uid LIMIT 1"
169 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_and_type; 185 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_and_type;
170 186
171#define COUNT_ENTRY_BY_HASH_VHASH_AND_TYPE "SELECT count(*) FROM gn090 FORCE INDEX (idx_hash_vhash) WHERE hash=? AND vhash=? AND type=?" 187#define SELECT_ENTRY_BY_HASH_VHASH_AND_TYPE "SELECT " RESULT_COLUMNS " "\
172 struct GNUNET_MYSQL_StatementHandle *count_entry_by_hash_vhash_and_type; 188 "FROM gn090 "\
173 189 "FORCE INDEX (idx_hash_vhash) "\
174#define SELECT_ENTRY_BY_HASH_VHASH_AND_TYPE "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_hash_vhash) WHERE hash=? AND vhash=? AND type=? ORDER BY uid ASC LIMIT 1 OFFSET ?" 190 "WHERE hash = ? AND "\
191 "vhash = ? AND "\
192 "type = ? AND "\
193 "uid >= ? AND "\
194 "(rvalue >= ? OR 0 = ?) "\
195 "ORDER BY uid LIMIT 1"
175 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_vhash_and_type; 196 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_vhash_and_type;
176 197
177#define UPDATE_ENTRY "UPDATE gn090 SET prio=prio+?,expire=IF(expire>=?,expire,?) WHERE uid=?" 198#define UPDATE_ENTRY "UPDATE gn090 SET "\
199 "prio = prio + ?, "\
200 "repl = repl + ?, "\
201 "expire = IF(expire >= ?, expire, ?) "\
202 "WHERE uid = ?"
178 struct GNUNET_MYSQL_StatementHandle *update_entry; 203 struct GNUNET_MYSQL_StatementHandle *update_entry;
179 204
180#define DEC_REPL "UPDATE gn090 SET repl=GREATEST (1, repl) - 1 WHERE uid=?" 205#define DEC_REPL "UPDATE gn090 SET repl=GREATEST (1, repl) - 1 WHERE uid=?"
@@ -183,22 +208,27 @@ struct Plugin
183#define SELECT_SIZE "SELECT SUM(LENGTH(value)+256) FROM gn090" 208#define SELECT_SIZE "SELECT SUM(LENGTH(value)+256) FROM gn090"
184 struct GNUNET_MYSQL_StatementHandle *get_size; 209 struct GNUNET_MYSQL_StatementHandle *get_size;
185 210
186#define SELECT_IT_NON_ANONYMOUS "SELECT type,prio,anonLevel,expire,hash,value,uid "\ 211#define SELECT_IT_NON_ANONYMOUS "SELECT " RESULT_COLUMNS " FROM gn090 "\
187 "FROM gn090 FORCE INDEX (idx_anonLevel_type_rvalue) "\ 212 "FORCE INDEX (idx_anonLevel_type_rvalue) "\
188 "WHERE anonLevel=0 AND type=? AND "\ 213 "WHERE anonLevel=0 AND "\
189 "(rvalue >= ? OR"\ 214 "type=? AND "\
190 " NOT EXISTS (SELECT 1 FROM gn090 FORCE INDEX (idx_anonLevel_type_rvalue) WHERE anonLevel=0 AND type=? AND rvalue>=?)) "\ 215 "uid >= ? "\
191 "ORDER BY rvalue ASC LIMIT 1" 216 "ORDER BY uid LIMIT 1"
192 struct GNUNET_MYSQL_StatementHandle *zero_iter; 217 struct GNUNET_MYSQL_StatementHandle *zero_iter;
193 218
194#define SELECT_IT_EXPIRATION "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_expire) WHERE expire < ? ORDER BY expire ASC LIMIT 1" 219#define SELECT_IT_EXPIRATION "SELECT " RESULT_COLUMNS " FROM gn090 "\
220 "FORCE INDEX (idx_expire) "\
221 "WHERE expire < ? "\
222 "ORDER BY expire ASC LIMIT 1"
195 struct GNUNET_MYSQL_StatementHandle *select_expiration; 223 struct GNUNET_MYSQL_StatementHandle *select_expiration;
196 224
197#define SELECT_IT_PRIORITY "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_prio) ORDER BY prio ASC LIMIT 1" 225#define SELECT_IT_PRIORITY "SELECT " RESULT_COLUMNS " FROM gn090 "\
226 "FORCE INDEX (idx_prio) "\
227 "ORDER BY prio ASC LIMIT 1"
198 struct GNUNET_MYSQL_StatementHandle *select_priority; 228 struct GNUNET_MYSQL_StatementHandle *select_priority;
199 229
200#define SELECT_IT_REPLICATION "SELECT type,prio,anonLevel,expire,hash,value,uid "\ 230#define SELECT_IT_REPLICATION "SELECT " RESULT_COLUMNS " FROM gn090 "\
201 "FROM gn090 FORCE INDEX (idx_repl_rvalue) "\ 231 "FORCE INDEX (idx_repl_rvalue) "\
202 "WHERE repl=? AND "\ 232 "WHERE repl=? AND "\
203 " (rvalue>=? OR"\ 233 " (rvalue>=? OR"\
204 " NOT EXISTS (SELECT 1 FROM gn090 FORCE INDEX (idx_repl_rvalue) WHERE repl=? AND rvalue>=?)) "\ 234 " NOT EXISTS (SELECT 1 FROM gn090 FORCE INDEX (idx_repl_rvalue) WHERE repl=? AND rvalue>=?)) "\
@@ -382,19 +412,17 @@ mysql_plugin_put (void *cls,
382 412
383 413
384/** 414/**
385 * Update the priority for a particular key in the datastore. If 415 * Update the priority, replication and expiration for a particular
386 * the expiration time in value is different than the time found in 416 * unique ID in the datastore. If the expiration time in value is
387 * the datastore, the higher value should be kept. For the 417 * different than the time found in the datastore, the higher value
388 * anonymity level, the lower value is to be used. The specified 418 * should be kept. The specified priority and replication is added
389 * priority should be added to the existing priority, ignoring the 419 * to the existing value.
390 * priority in value.
391 *
392 * Note that it is possible for multiple values to match this put.
393 * In that case, all of the respective values are updated.
394 * 420 *
395 * @param cls our "struct Plugin*" 421 * @param cls our "struct Plugin*"
396 * @param uid unique identifier of the datum 422 * @param uid unique identifier of the datum
397 * @param delta by how much should the priority 423 * @param priority by how much should the priority
424 * change?
425 * @param replication by how much should the replication
398 * change? 426 * change?
399 * @param expire new expiration time should be the 427 * @param expire new expiration time should be the
400 * MAX of any existing expiration time and 428 * MAX of any existing expiration time and
@@ -405,7 +433,8 @@ mysql_plugin_put (void *cls,
405static void 433static void
406mysql_plugin_update (void *cls, 434mysql_plugin_update (void *cls,
407 uint64_t uid, 435 uint64_t uid,
408 uint32_t delta, 436 uint32_t priority,
437 uint32_t replication,
409 struct GNUNET_TIME_Absolute expire, 438 struct GNUNET_TIME_Absolute expire,
410 PluginUpdateCont cont, 439 PluginUpdateCont cont,
411 void *cont_cls) 440 void *cont_cls)
@@ -415,13 +444,15 @@ mysql_plugin_update (void *cls,
415 int ret; 444 int ret;
416 445
417 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 446 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
418 "Updating value %llu adding %d to priority and maxing exp at %s\n", 447 "Updating value %llu adding %d to priority %d to replication and maxing exp at %s\n",
419 (unsigned long long) uid, 448 (unsigned long long) uid,
420 delta, 449 priority,
421 GNUNET_STRINGS_absolute_time_to_string (expire)); 450 replication,
451 GNUNET_STRINGS_absolute_time_to_string (expire));
422 452
423 struct GNUNET_MY_QueryParam params_update[] = { 453 struct GNUNET_MY_QueryParam params_update[] = {
424 GNUNET_MY_query_param_uint32 (&delta), 454 GNUNET_MY_query_param_uint32 (&priority),
455 GNUNET_MY_query_param_uint32 (&replication),
425 GNUNET_MY_query_param_uint64 (&lexpire), 456 GNUNET_MY_query_param_uint64 (&lexpire),
426 GNUNET_MY_query_param_uint64 (&lexpire), 457 GNUNET_MY_query_param_uint64 (&lexpire),
427 GNUNET_MY_query_param_uint64 (&uid), 458 GNUNET_MY_query_param_uint64 (&uid),
@@ -468,6 +499,7 @@ execute_select (struct Plugin *plugin,
468 struct GNUNET_MY_QueryParam *params_select) 499 struct GNUNET_MY_QueryParam *params_select)
469{ 500{
470 int ret; 501 int ret;
502 uint32_t replication;
471 uint32_t type; 503 uint32_t type;
472 uint32_t priority; 504 uint32_t priority;
473 uint32_t anonymity; 505 uint32_t anonymity;
@@ -477,6 +509,7 @@ execute_select (struct Plugin *plugin,
477 struct GNUNET_HashCode key; 509 struct GNUNET_HashCode key;
478 struct GNUNET_TIME_Absolute expiration; 510 struct GNUNET_TIME_Absolute expiration;
479 struct GNUNET_MY_ResultSpec results_select[] = { 511 struct GNUNET_MY_ResultSpec results_select[] = {
512 GNUNET_MY_result_spec_uint32 (&replication),
480 GNUNET_MY_result_spec_uint32 (&type), 513 GNUNET_MY_result_spec_uint32 (&type),
481 GNUNET_MY_result_spec_uint32 (&priority), 514 GNUNET_MY_result_spec_uint32 (&priority),
482 GNUNET_MY_result_spec_uint32 (&anonymity), 515 GNUNET_MY_result_spec_uint32 (&anonymity),
@@ -493,7 +526,7 @@ execute_select (struct Plugin *plugin,
493 if (GNUNET_OK != ret) 526 if (GNUNET_OK != ret)
494 { 527 {
495 proc (proc_cls, 528 proc (proc_cls,
496 NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 529 NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
497 return; 530 return;
498 } 531 }
499 532
@@ -502,7 +535,7 @@ execute_select (struct Plugin *plugin,
502 if (GNUNET_OK != ret) 535 if (GNUNET_OK != ret)
503 { 536 {
504 proc (proc_cls, 537 proc (proc_cls,
505 NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 538 NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
506 return; 539 return;
507 } 540 }
508 541
@@ -524,6 +557,7 @@ execute_select (struct Plugin *plugin,
524 type, 557 type,
525 priority, 558 priority,
526 anonymity, 559 anonymity,
560 replication,
527 expiration, 561 expiration,
528 uid); 562 uid);
529 GNUNET_MY_cleanup_result (results_select); 563 GNUNET_MY_cleanup_result (results_select);
@@ -541,8 +575,8 @@ execute_select (struct Plugin *plugin,
541 * Get one of the results for a particular key in the datastore. 575 * Get one of the results for a particular key in the datastore.
542 * 576 *
543 * @param cls closure 577 * @param cls closure
544 * @param offset offset of the result (modulo num-results); 578 * @param next_uid return the result with lowest uid >= next_uid
545 * specific ordering does not matter for the offset 579 * @param random if true, return a random result instead of using next_uid
546 * @param key key to match, never NULL 580 * @param key key to match, never NULL
547 * @param vhash hash of the value, maybe NULL (to 581 * @param vhash hash of the value, maybe NULL (to
548 * match all values that have the right key). 582 * match all values that have the right key).
@@ -557,7 +591,8 @@ execute_select (struct Plugin *plugin,
557 */ 591 */
558static void 592static void
559mysql_plugin_get_key (void *cls, 593mysql_plugin_get_key (void *cls,
560 uint64_t offset, 594 uint64_t next_uid,
595 bool random,
561 const struct GNUNET_HashCode *key, 596 const struct GNUNET_HashCode *key,
562 const struct GNUNET_HashCode *vhash, 597 const struct GNUNET_HashCode *vhash,
563 enum GNUNET_BLOCK_Type type, 598 enum GNUNET_BLOCK_Type type,
@@ -565,121 +600,33 @@ mysql_plugin_get_key (void *cls,
565 void *proc_cls) 600 void *proc_cls)
566{ 601{
567 struct Plugin *plugin = cls; 602 struct Plugin *plugin = cls;
568 int ret; 603 uint64_t rvalue;
569 uint64_t total;
570 struct GNUNET_MY_ResultSpec results_get[] = {
571 GNUNET_MY_result_spec_uint64 (&total),
572 GNUNET_MY_result_spec_end
573 };
574 604
575 total = UINT64_MAX; 605 if (random)
576 if (0 != type)
577 { 606 {
578 if (NULL != vhash) 607 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
579 { 608 UINT64_MAX);
580 struct GNUNET_MY_QueryParam params_get[] = { 609 next_uid = 0;
581 GNUNET_MY_query_param_auto_from_type (key),
582 GNUNET_MY_query_param_auto_from_type (vhash),
583 GNUNET_MY_query_param_uint32 (&type),
584 GNUNET_MY_query_param_end
585 };
586
587 ret =
588 GNUNET_MY_exec_prepared (plugin->mc,
589 plugin->count_entry_by_hash_vhash_and_type,
590 params_get);
591 GNUNET_break (GNUNET_OK == ret);
592 if (GNUNET_OK == ret)
593 ret =
594 GNUNET_MY_extract_result (plugin->count_entry_by_hash_vhash_and_type,
595 results_get);
596 if (GNUNET_OK == ret)
597 GNUNET_break (GNUNET_NO ==
598 GNUNET_MY_extract_result (plugin->count_entry_by_hash_vhash_and_type,
599 NULL));
600 }
601 else
602 {
603 struct GNUNET_MY_QueryParam params_get[] = {
604 GNUNET_MY_query_param_auto_from_type (key),
605 GNUNET_MY_query_param_uint32 (&type),
606 GNUNET_MY_query_param_end
607 };
608
609 ret =
610 GNUNET_MY_exec_prepared (plugin->mc,
611 plugin->count_entry_by_hash_and_type,
612 params_get);
613 GNUNET_break (GNUNET_OK == ret);
614 if (GNUNET_OK == ret)
615 ret =
616 GNUNET_MY_extract_result (plugin->count_entry_by_hash_and_type,
617 results_get);
618 if (GNUNET_OK == ret)
619 GNUNET_break (GNUNET_NO ==
620 GNUNET_MY_extract_result (plugin->count_entry_by_hash_and_type,
621 NULL));
622 }
623 } 610 }
624 else 611 else
625 { 612 rvalue = 0;
626 if (NULL != vhash)
627 {
628 struct GNUNET_MY_QueryParam params_get[] = {
629 GNUNET_MY_query_param_auto_from_type (key),
630 GNUNET_MY_query_param_auto_from_type (vhash),
631 GNUNET_MY_query_param_end
632 };
633
634 ret =
635 GNUNET_MY_exec_prepared (plugin->mc,
636 plugin->count_entry_by_hash_and_vhash,
637 params_get);
638 GNUNET_break (GNUNET_OK == ret);
639 if (GNUNET_OK == ret)
640 ret =
641 GNUNET_MY_extract_result (plugin->count_entry_by_hash_and_vhash,
642 results_get);
643 if (GNUNET_OK == ret)
644 GNUNET_break (GNUNET_NO ==
645 GNUNET_MY_extract_result (plugin->count_entry_by_hash_and_vhash,
646 NULL));
647 }
648 else
649 {
650 struct GNUNET_MY_QueryParam params_get[] = {
651 GNUNET_MY_query_param_auto_from_type (key),
652 GNUNET_MY_query_param_end
653 };
654 613
655 ret = 614 if (NULL == key)
656 GNUNET_MY_exec_prepared (plugin->mc,
657 plugin->count_entry_by_hash,
658 params_get);
659 GNUNET_break (GNUNET_OK == ret);
660 if (GNUNET_OK == ret)
661 ret =
662 GNUNET_MY_extract_result (plugin->count_entry_by_hash,
663 results_get);
664 if (GNUNET_OK == ret)
665 GNUNET_break (GNUNET_NO ==
666 GNUNET_MY_extract_result (plugin->count_entry_by_hash,
667 NULL));
668 }
669 }
670 if ( (GNUNET_OK != ret) ||
671 (0 >= total) )
672 { 615 {
673 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 616 struct GNUNET_MY_QueryParam params_select[] = {
674 return; 617 GNUNET_MY_query_param_uint64 (&next_uid),
618 GNUNET_MY_query_param_uint64 (&rvalue),
619 GNUNET_MY_query_param_uint64 (&rvalue),
620 GNUNET_MY_query_param_end
621 };
622
623 execute_select (plugin,
624 plugin->select_entry,
625 proc,
626 proc_cls,
627 params_select);
675 } 628 }
676 offset = offset % total; 629 else if (type != GNUNET_BLOCK_TYPE_ANY)
677 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
678 "Obtaining %llu/%lld result for GET `%s'\n",
679 (unsigned long long) offset,
680 (unsigned long long) total,
681 GNUNET_h2s (key));
682 if (type != GNUNET_BLOCK_TYPE_ANY)
683 { 630 {
684 if (NULL != vhash) 631 if (NULL != vhash)
685 { 632 {
@@ -687,7 +634,9 @@ mysql_plugin_get_key (void *cls,
687 GNUNET_MY_query_param_auto_from_type (key), 634 GNUNET_MY_query_param_auto_from_type (key),
688 GNUNET_MY_query_param_auto_from_type (vhash), 635 GNUNET_MY_query_param_auto_from_type (vhash),
689 GNUNET_MY_query_param_uint32 (&type), 636 GNUNET_MY_query_param_uint32 (&type),
690 GNUNET_MY_query_param_uint64 (&offset), 637 GNUNET_MY_query_param_uint64 (&next_uid),
638 GNUNET_MY_query_param_uint64 (&rvalue),
639 GNUNET_MY_query_param_uint64 (&rvalue),
691 GNUNET_MY_query_param_end 640 GNUNET_MY_query_param_end
692 }; 641 };
693 642
@@ -702,7 +651,9 @@ mysql_plugin_get_key (void *cls,
702 struct GNUNET_MY_QueryParam params_select[] = { 651 struct GNUNET_MY_QueryParam params_select[] = {
703 GNUNET_MY_query_param_auto_from_type (key), 652 GNUNET_MY_query_param_auto_from_type (key),
704 GNUNET_MY_query_param_uint32 (&type), 653 GNUNET_MY_query_param_uint32 (&type),
705 GNUNET_MY_query_param_uint64 (&offset), 654 GNUNET_MY_query_param_uint64 (&next_uid),
655 GNUNET_MY_query_param_uint64 (&rvalue),
656 GNUNET_MY_query_param_uint64 (&rvalue),
706 GNUNET_MY_query_param_end 657 GNUNET_MY_query_param_end
707 }; 658 };
708 659
@@ -720,7 +671,9 @@ mysql_plugin_get_key (void *cls,
720 struct GNUNET_MY_QueryParam params_select[] = { 671 struct GNUNET_MY_QueryParam params_select[] = {
721 GNUNET_MY_query_param_auto_from_type (key), 672 GNUNET_MY_query_param_auto_from_type (key),
722 GNUNET_MY_query_param_auto_from_type (vhash), 673 GNUNET_MY_query_param_auto_from_type (vhash),
723 GNUNET_MY_query_param_uint64 (&offset), 674 GNUNET_MY_query_param_uint64 (&next_uid),
675 GNUNET_MY_query_param_uint64 (&rvalue),
676 GNUNET_MY_query_param_uint64 (&rvalue),
724 GNUNET_MY_query_param_end 677 GNUNET_MY_query_param_end
725 }; 678 };
726 679
@@ -734,7 +687,9 @@ mysql_plugin_get_key (void *cls,
734 { 687 {
735 struct GNUNET_MY_QueryParam params_select[] = { 688 struct GNUNET_MY_QueryParam params_select[] = {
736 GNUNET_MY_query_param_auto_from_type (key), 689 GNUNET_MY_query_param_auto_from_type (key),
737 GNUNET_MY_query_param_uint64 (&offset), 690 GNUNET_MY_query_param_uint64 (&next_uid),
691 GNUNET_MY_query_param_uint64 (&rvalue),
692 GNUNET_MY_query_param_uint64 (&rvalue),
738 GNUNET_MY_query_param_end 693 GNUNET_MY_query_param_end
739 }; 694 };
740 695
@@ -753,28 +708,26 @@ mysql_plugin_get_key (void *cls,
753 * Get a zero-anonymity datum from the datastore. 708 * Get a zero-anonymity datum from the datastore.
754 * 709 *
755 * @param cls our `struct Plugin *` 710 * @param cls our `struct Plugin *`
756 * @param offset offset of the result 711 * @param next_uid return the result with lowest uid >= next_uid
757 * @param type entries of which type should be considered? 712 * @param type entries of which type should be considered?
758 * Use 0 for any type. 713 * Must not be zero (ANY).
759 * @param proc function to call on a matching value or NULL 714 * @param proc function to call on a matching value;
715 * will be called with NULL if no value matches
760 * @param proc_cls closure for @a proc 716 * @param proc_cls closure for @a proc
761 */ 717 */
762static void 718static void
763mysql_plugin_get_zero_anonymity (void *cls, 719mysql_plugin_get_zero_anonymity (void *cls,
764 uint64_t offset, 720 uint64_t next_uid,
765 enum GNUNET_BLOCK_Type type, 721 enum GNUNET_BLOCK_Type type,
766 PluginDatumProcessor proc, 722 PluginDatumProcessor proc,
767 void *proc_cls) 723 void *proc_cls)
768{ 724{
769 struct Plugin *plugin = cls; 725 struct Plugin *plugin = cls;
770 uint32_t typei = (uint32_t) type; 726 uint32_t typei = (uint32_t) type;
771 uint64_t rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, 727
772 UINT64_MAX);
773 struct GNUNET_MY_QueryParam params_zero_iter[] = { 728 struct GNUNET_MY_QueryParam params_zero_iter[] = {
774 GNUNET_MY_query_param_uint32 (&typei), 729 GNUNET_MY_query_param_uint32 (&typei),
775 GNUNET_MY_query_param_uint64 (&rvalue), 730 GNUNET_MY_query_param_uint64 (&next_uid),
776 GNUNET_MY_query_param_uint32 (&typei),
777 GNUNET_MY_query_param_uint64 (&rvalue),
778 GNUNET_MY_query_param_end 731 GNUNET_MY_query_param_end
779 }; 732 };
780 733
@@ -821,6 +774,7 @@ struct ReplCtx
821 * @param type type of the content 774 * @param type type of the content
822 * @param priority priority of the content 775 * @param priority priority of the content
823 * @param anonymity anonymity-level for the content 776 * @param anonymity anonymity-level for the content
777 * @param replication replication-level for the content
824 * @param expiration expiration time for the content 778 * @param expiration expiration time for the content
825 * @param uid unique identifier for the datum; 779 * @param uid unique identifier for the datum;
826 * maybe 0 if no unique identifier is available 780 * maybe 0 if no unique identifier is available
@@ -836,6 +790,7 @@ repl_proc (void *cls,
836 enum GNUNET_BLOCK_Type type, 790 enum GNUNET_BLOCK_Type type,
837 uint32_t priority, 791 uint32_t priority,
838 uint32_t anonymity, 792 uint32_t anonymity,
793 uint32_t replication,
839 struct GNUNET_TIME_Absolute expiration, 794 struct GNUNET_TIME_Absolute expiration,
840 uint64_t uid) 795 uint64_t uid)
841{ 796{
@@ -851,6 +806,7 @@ repl_proc (void *cls,
851 type, 806 type,
852 priority, 807 priority,
853 anonymity, 808 anonymity,
809 replication,
854 expiration, 810 expiration,
855 uid); 811 uid);
856 if (NULL != key) 812 if (NULL != key)
@@ -918,7 +874,7 @@ mysql_plugin_get_replication (void *cls,
918 plugin->max_repl, 874 plugin->max_repl,
919 params_get)) 875 params_get))
920 { 876 {
921 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 877 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
922 return; 878 return;
923 } 879 }
924 880
@@ -926,7 +882,7 @@ mysql_plugin_get_replication (void *cls,
926 GNUNET_MY_extract_result (plugin->max_repl, 882 GNUNET_MY_extract_result (plugin->max_repl,
927 results_get)) 883 results_get))
928 { 884 {
929 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 885 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
930 return; 886 return;
931 } 887 }
932 GNUNET_break (GNUNET_NO == 888 GNUNET_break (GNUNET_NO ==
@@ -1068,6 +1024,7 @@ struct ExpiCtx
1068 * @param type type of the content 1024 * @param type type of the content
1069 * @param priority priority of the content 1025 * @param priority priority of the content
1070 * @param anonymity anonymity-level for the content 1026 * @param anonymity anonymity-level for the content
1027 * @param replication replication-level for the content
1071 * @param expiration expiration time for the content 1028 * @param expiration expiration time for the content
1072 * @param uid unique identifier for the datum; 1029 * @param uid unique identifier for the datum;
1073 * maybe 0 if no unique identifier is available 1030 * maybe 0 if no unique identifier is available
@@ -1083,6 +1040,7 @@ expi_proc (void *cls,
1083 enum GNUNET_BLOCK_Type type, 1040 enum GNUNET_BLOCK_Type type,
1084 uint32_t priority, 1041 uint32_t priority,
1085 uint32_t anonymity, 1042 uint32_t anonymity,
1043 uint32_t replication,
1086 struct GNUNET_TIME_Absolute expiration, 1044 struct GNUNET_TIME_Absolute expiration,
1087 uint64_t uid) 1045 uint64_t uid)
1088{ 1046{
@@ -1108,6 +1066,7 @@ expi_proc (void *cls,
1108 type, 1066 type,
1109 priority, 1067 priority,
1110 anonymity, 1068 anonymity,
1069 replication,
1111 expiration, 1070 expiration,
1112 uid); 1071 uid);
1113} 1072}
@@ -1209,6 +1168,7 @@ libgnunet_plugin_datastore_mysql_init (void *cls)
1209 ") ENGINE=InnoDB") || MRUNS ("SET AUTOCOMMIT = 1") || 1168 ") ENGINE=InnoDB") || MRUNS ("SET AUTOCOMMIT = 1") ||
1210 PINIT (plugin->insert_entry, INSERT_ENTRY) || 1169 PINIT (plugin->insert_entry, INSERT_ENTRY) ||
1211 PINIT (plugin->delete_entry_by_uid, DELETE_ENTRY_BY_UID) || 1170 PINIT (plugin->delete_entry_by_uid, DELETE_ENTRY_BY_UID) ||
1171 PINIT (plugin->select_entry, SELECT_ENTRY) ||
1212 PINIT (plugin->select_entry_by_hash, SELECT_ENTRY_BY_HASH) || 1172 PINIT (plugin->select_entry_by_hash, SELECT_ENTRY_BY_HASH) ||
1213 PINIT (plugin->select_entry_by_hash_and_vhash, 1173 PINIT (plugin->select_entry_by_hash_and_vhash,
1214 SELECT_ENTRY_BY_HASH_AND_VHASH) || 1174 SELECT_ENTRY_BY_HASH_AND_VHASH) ||
@@ -1216,13 +1176,7 @@ libgnunet_plugin_datastore_mysql_init (void *cls)
1216 SELECT_ENTRY_BY_HASH_AND_TYPE) || 1176 SELECT_ENTRY_BY_HASH_AND_TYPE) ||
1217 PINIT (plugin->select_entry_by_hash_vhash_and_type, 1177 PINIT (plugin->select_entry_by_hash_vhash_and_type,
1218 SELECT_ENTRY_BY_HASH_VHASH_AND_TYPE) || 1178 SELECT_ENTRY_BY_HASH_VHASH_AND_TYPE) ||
1219 PINIT (plugin->count_entry_by_hash, COUNT_ENTRY_BY_HASH) ||
1220 PINIT (plugin->get_size, SELECT_SIZE) || 1179 PINIT (plugin->get_size, SELECT_SIZE) ||
1221 PINIT (plugin->count_entry_by_hash_and_vhash,
1222 COUNT_ENTRY_BY_HASH_AND_VHASH) ||
1223 PINIT (plugin->count_entry_by_hash_and_type, COUNT_ENTRY_BY_HASH_AND_TYPE)
1224 || PINIT (plugin->count_entry_by_hash_vhash_and_type,
1225 COUNT_ENTRY_BY_HASH_VHASH_AND_TYPE) ||
1226 PINIT (plugin->update_entry, UPDATE_ENTRY) || 1180 PINIT (plugin->update_entry, UPDATE_ENTRY) ||
1227 PINIT (plugin->dec_repl, DEC_REPL) || 1181 PINIT (plugin->dec_repl, DEC_REPL) ||
1228 PINIT (plugin->zero_iter, SELECT_IT_NON_ANONYMOUS) || 1182 PINIT (plugin->zero_iter, SELECT_IT_NON_ANONYMOUS) ||
diff --git a/src/datastore/plugin_datastore_postgres.c b/src/datastore/plugin_datastore_postgres.c
index 8b8737935..87a7acbdc 100644
--- a/src/datastore/plugin_datastore_postgres.c
+++ b/src/datastore/plugin_datastore_postgres.c
@@ -80,6 +80,7 @@ init_connection (struct Plugin *plugin)
80 * we only test equality on it and can cast it to/from uint32_t. For repl, prio, and anonLevel 80 * we only test equality on it and can cast it to/from uint32_t. For repl, prio, and anonLevel
81 * we do math or inequality tests, so we can't handle the entire range of uint32_t. 81 * we do math or inequality tests, so we can't handle the entire range of uint32_t.
82 * This will also cause problems for expiration times after 294247-01-10-04:00:54 UTC. 82 * This will also cause problems for expiration times after 294247-01-10-04:00:54 UTC.
83 * PostgreSQL also recommends against using WITH OIDS.
83 */ 84 */
84 ret = 85 ret =
85 PQexec (plugin->dbh, 86 PQexec (plugin->dbh,
@@ -175,64 +176,49 @@ init_connection (struct Plugin *plugin)
175 return GNUNET_SYSERR; 176 return GNUNET_SYSERR;
176 } 177 }
177 PQclear (ret); 178 PQclear (ret);
179#define RESULT_COLUMNS "repl, type, prio, anonLevel, expire, hash, value, oid"
178 if ((GNUNET_OK != 180 if ((GNUNET_OK !=
179 GNUNET_POSTGRES_prepare (plugin->dbh, "getvt",
180 "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 "
181 "WHERE hash=$1 AND vhash=$2 AND type=$3 "
182 "ORDER BY oid ASC LIMIT 1 OFFSET $4", 4)) ||
183 (GNUNET_OK !=
184 GNUNET_POSTGRES_prepare (plugin->dbh, "gett",
185 "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 "
186 "WHERE hash=$1 AND type=$2 "
187 "ORDER BY oid ASC LIMIT 1 OFFSET $3", 3)) ||
188 (GNUNET_OK !=
189 GNUNET_POSTGRES_prepare (plugin->dbh, "getv",
190 "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 "
191 "WHERE hash=$1 AND vhash=$2 "
192 "ORDER BY oid ASC LIMIT 1 OFFSET $3", 3)) ||
193 (GNUNET_OK !=
194 GNUNET_POSTGRES_prepare (plugin->dbh, "get", 181 GNUNET_POSTGRES_prepare (plugin->dbh, "get",
195 "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " 182 "SELECT " RESULT_COLUMNS " FROM gn090 "
196 "WHERE hash=$1 " "ORDER BY oid ASC LIMIT 1 OFFSET $2", 2)) || 183 "WHERE oid >= $1::bigint AND "
197 (GNUNET_OK != 184 "(rvalue >= $2 OR 0 = $3::smallint) AND "
198 GNUNET_POSTGRES_prepare (plugin->dbh, "count_getvt", 185 "(hash = $4 OR 0 = $5::smallint) AND "
199 "SELECT count(*) FROM gn090 WHERE hash=$1 AND vhash=$2 AND type=$3", 3)) || 186 "(vhash = $6 OR 0 = $7::smallint) AND "
200 (GNUNET_OK != 187 "(type = $8 OR 0 = $9::smallint) "
201 GNUNET_POSTGRES_prepare (plugin->dbh, "count_gett", 188 "ORDER BY oid ASC LIMIT 1", 9)) ||
202 "SELECT count(*) FROM gn090 WHERE hash=$1 AND type=$2", 2)) ||
203 (GNUNET_OK !=
204 GNUNET_POSTGRES_prepare (plugin->dbh, "count_getv",
205 "SELECT count(*) FROM gn090 WHERE hash=$1 AND vhash=$2", 2)) ||
206 (GNUNET_OK !=
207 GNUNET_POSTGRES_prepare (plugin->dbh, "count_get",
208 "SELECT count(*) FROM gn090 WHERE hash=$1", 1)) ||
209 (GNUNET_OK != 189 (GNUNET_OK !=
210 GNUNET_POSTGRES_prepare (plugin->dbh, "put", 190 GNUNET_POSTGRES_prepare (plugin->dbh, "put",
211 "INSERT INTO gn090 (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) " 191 "INSERT INTO gn090 (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) "
212 "VALUES ($1, $2, $3, $4, $5, RANDOM(), $6, $7, $8)", 9)) || 192 "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", 9)) ||
213 (GNUNET_OK != 193 (GNUNET_OK !=
214 GNUNET_POSTGRES_prepare (plugin->dbh, "update", 194 GNUNET_POSTGRES_prepare (plugin->dbh, "update",
215 "UPDATE gn090 SET prio = prio + $1, expire = CASE WHEN expire < $2 THEN $2 ELSE expire END " 195 "UPDATE gn090 "
216 "WHERE oid = $3", 3)) || 196 "SET prio = prio + $1, "
197 "repl = repl + $2, "
198 "expire = CASE WHEN expire < $3 THEN $3 ELSE expire END "
199 "WHERE oid = $4", 4)) ||
217 (GNUNET_OK != 200 (GNUNET_OK !=
218 GNUNET_POSTGRES_prepare (plugin->dbh, "decrepl", 201 GNUNET_POSTGRES_prepare (plugin->dbh, "decrepl",
219 "UPDATE gn090 SET repl = GREATEST (repl - 1, 0) " 202 "UPDATE gn090 SET repl = GREATEST (repl - 1, 0) "
220 "WHERE oid = $1", 1)) || 203 "WHERE oid = $1", 1)) ||
221 (GNUNET_OK != 204 (GNUNET_OK !=
222 GNUNET_POSTGRES_prepare (plugin->dbh, "select_non_anonymous", 205 GNUNET_POSTGRES_prepare (plugin->dbh, "select_non_anonymous",
223 "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " 206 "SELECT " RESULT_COLUMNS " FROM gn090 "
224 "WHERE anonLevel = 0 AND type = $1 ORDER BY oid DESC LIMIT 1 OFFSET $2", 207 "WHERE anonLevel = 0 AND type = $1 AND oid >= $2::bigint "
225 1)) || 208 "ORDER BY oid ASC LIMIT 1",
209 2)) ||
226 (GNUNET_OK != 210 (GNUNET_OK !=
227 GNUNET_POSTGRES_prepare (plugin->dbh, "select_expiration_order", 211 GNUNET_POSTGRES_prepare (plugin->dbh, "select_expiration_order",
228 "(SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " 212 "(SELECT " RESULT_COLUMNS " FROM gn090 "
229 "WHERE expire < $1 ORDER BY prio ASC LIMIT 1) " "UNION " 213 "WHERE expire < $1 ORDER BY prio ASC LIMIT 1) "
230 "(SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " 214 "UNION "
231 "ORDER BY prio ASC LIMIT 1) " "ORDER BY expire ASC LIMIT 1", 215 "(SELECT " RESULT_COLUMNS " FROM gn090 "
216 "ORDER BY prio ASC LIMIT 1) "
217 "ORDER BY expire ASC LIMIT 1",
232 1)) || 218 1)) ||
233 (GNUNET_OK != 219 (GNUNET_OK !=
234 GNUNET_POSTGRES_prepare (plugin->dbh, "select_replication_order", 220 GNUNET_POSTGRES_prepare (plugin->dbh, "select_replication_order",
235 "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " 221 "SELECT " RESULT_COLUMNS " FROM gn090 "
236 "ORDER BY repl DESC,RANDOM() LIMIT 1", 0)) || 222 "ORDER BY repl DESC,RANDOM() LIMIT 1", 0)) ||
237 (GNUNET_OK != 223 (GNUNET_OK !=
238 GNUNET_POSTGRES_prepare (plugin->dbh, "delrow", "DELETE FROM gn090 " "WHERE oid=$1", 1)) || 224 GNUNET_POSTGRES_prepare (plugin->dbh, "delrow", "DELETE FROM gn090 " "WHERE oid=$1", 1)) ||
@@ -328,6 +314,8 @@ postgres_plugin_put (void *cls,
328 struct Plugin *plugin = cls; 314 struct Plugin *plugin = cls;
329 uint32_t utype = type; 315 uint32_t utype = type;
330 struct GNUNET_HashCode vhash; 316 struct GNUNET_HashCode vhash;
317 uint64_t rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
318 UINT64_MAX);
331 PGresult *ret; 319 PGresult *ret;
332 struct GNUNET_PQ_QueryParam params[] = { 320 struct GNUNET_PQ_QueryParam params[] = {
333 GNUNET_PQ_query_param_uint32 (&replication), 321 GNUNET_PQ_query_param_uint32 (&replication),
@@ -335,6 +323,7 @@ postgres_plugin_put (void *cls,
335 GNUNET_PQ_query_param_uint32 (&priority), 323 GNUNET_PQ_query_param_uint32 (&priority),
336 GNUNET_PQ_query_param_uint32 (&anonymity), 324 GNUNET_PQ_query_param_uint32 (&anonymity),
337 GNUNET_PQ_query_param_absolute_time (&expiration), 325 GNUNET_PQ_query_param_absolute_time (&expiration),
326 GNUNET_PQ_query_param_uint64 (&rvalue),
338 GNUNET_PQ_query_param_auto_from_type (key), 327 GNUNET_PQ_query_param_auto_from_type (key),
339 GNUNET_PQ_query_param_auto_from_type (&vhash), 328 GNUNET_PQ_query_param_auto_from_type (&vhash),
340 GNUNET_PQ_query_param_fixed_size (data, size), 329 GNUNET_PQ_query_param_fixed_size (data, size),
@@ -388,19 +377,21 @@ process_result (struct Plugin *plugin,
388 uint32_t rowid; 377 uint32_t rowid;
389 uint32_t utype; 378 uint32_t utype;
390 uint32_t anonymity; 379 uint32_t anonymity;
380 uint32_t replication;
391 uint32_t priority; 381 uint32_t priority;
392 size_t size; 382 size_t size;
393 void *data; 383 void *data;
394 struct GNUNET_TIME_Absolute expiration_time; 384 struct GNUNET_TIME_Absolute expiration_time;
395 struct GNUNET_HashCode key; 385 struct GNUNET_HashCode key;
396 struct GNUNET_PQ_ResultSpec rs[] = { 386 struct GNUNET_PQ_ResultSpec rs[] = {
387 GNUNET_PQ_result_spec_uint32 ("repl", &replication),
397 GNUNET_PQ_result_spec_uint32 ("type", &utype), 388 GNUNET_PQ_result_spec_uint32 ("type", &utype),
398 GNUNET_PQ_result_spec_uint32 ("prio", &priority), 389 GNUNET_PQ_result_spec_uint32 ("prio", &priority),
399 GNUNET_PQ_result_spec_uint32 ("anonLevel", &anonymity), 390 GNUNET_PQ_result_spec_uint32 ("anonLevel", &anonymity),
400 GNUNET_PQ_result_spec_uint32 ("oid", &rowid),
401 GNUNET_PQ_result_spec_absolute_time ("expire", &expiration_time), 391 GNUNET_PQ_result_spec_absolute_time ("expire", &expiration_time),
402 GNUNET_PQ_result_spec_auto_from_type ("hash", &key), 392 GNUNET_PQ_result_spec_auto_from_type ("hash", &key),
403 GNUNET_PQ_result_spec_variable_size ("value", &data, &size), 393 GNUNET_PQ_result_spec_variable_size ("value", &data, &size),
394 GNUNET_PQ_result_spec_uint32 ("oid", &rowid),
404 GNUNET_PQ_result_spec_end 395 GNUNET_PQ_result_spec_end
405 }; 396 };
406 397
@@ -415,8 +406,7 @@ process_result (struct Plugin *plugin,
415 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 406 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
416 "datastore-postgres", 407 "datastore-postgres",
417 "Ending iteration (postgres error)\n"); 408 "Ending iteration (postgres error)\n");
418 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 409 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
419 GNUNET_TIME_UNIT_ZERO_ABS, 0);
420 return; 410 return;
421 } 411 }
422 412
@@ -426,16 +416,14 @@ process_result (struct Plugin *plugin,
426 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 416 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
427 "datastore-postgres", 417 "datastore-postgres",
428 "Ending iteration (no more results)\n"); 418 "Ending iteration (no more results)\n");
429 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 419 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
430 GNUNET_TIME_UNIT_ZERO_ABS, 0);
431 PQclear (res); 420 PQclear (res);
432 return; 421 return;
433 } 422 }
434 if (1 != PQntuples (res)) 423 if (1 != PQntuples (res))
435 { 424 {
436 GNUNET_break (0); 425 GNUNET_break (0);
437 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 426 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
438 GNUNET_TIME_UNIT_ZERO_ABS, 0);
439 PQclear (res); 427 PQclear (res);
440 return; 428 return;
441 } 429 }
@@ -449,8 +437,7 @@ process_result (struct Plugin *plugin,
449 GNUNET_POSTGRES_delete_by_rowid (plugin->dbh, 437 GNUNET_POSTGRES_delete_by_rowid (plugin->dbh,
450 "delrow", 438 "delrow",
451 rowid); 439 rowid);
452 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 440 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
453 GNUNET_TIME_UNIT_ZERO_ABS, 0);
454 return; 441 return;
455 } 442 }
456 443
@@ -460,14 +447,15 @@ process_result (struct Plugin *plugin,
460 (unsigned int) size, 447 (unsigned int) size,
461 (unsigned int) utype); 448 (unsigned int) utype);
462 iret = proc (proc_cls, 449 iret = proc (proc_cls,
463 &key, 450 &key,
464 size, 451 size,
465 data, 452 data,
466 (enum GNUNET_BLOCK_Type) utype, 453 (enum GNUNET_BLOCK_Type) utype,
467 priority, 454 priority,
468 anonymity, 455 anonymity,
469 expiration_time, 456 replication,
470 rowid); 457 expiration_time,
458 rowid);
471 PQclear (res); 459 PQclear (res);
472 if (iret == GNUNET_NO) 460 if (iret == GNUNET_NO)
473 { 461 {
@@ -495,12 +483,11 @@ process_result (struct Plugin *plugin,
495 483
496 484
497/** 485/**
498 * Iterate over the results for a particular key 486 * Get one of the results for a particular key in the datastore.
499 * in the datastore.
500 * 487 *
501 * @param cls closure with the 'struct Plugin' 488 * @param cls closure with the 'struct Plugin'
502 * @param offset offset of the result (modulo num-results); 489 * @param next_uid return the result with lowest uid >= next_uid
503 * specific ordering does not matter for the offset 490 * @param random if true, return a random result instead of using next_uid
504 * @param key maybe NULL (to match all entries) 491 * @param key maybe NULL (to match all entries)
505 * @param vhash hash of the value, maybe NULL (to 492 * @param vhash hash of the value, maybe NULL (to
506 * match all values that have the right key). 493 * match all values that have the right key).
@@ -510,160 +497,52 @@ process_result (struct Plugin *plugin,
510 * @param type entries of which type are relevant? 497 * @param type entries of which type are relevant?
511 * Use 0 for any type. 498 * Use 0 for any type.
512 * @param proc function to call on the matching value; 499 * @param proc function to call on the matching value;
513 * will be called once with a NULL if no value matches 500 * will be called with NULL if nothing matches
514 * @param proc_cls closure for iter 501 * @param proc_cls closure for @a proc
515 */ 502 */
516static void 503static void
517postgres_plugin_get_key (void *cls, 504postgres_plugin_get_key (void *cls,
518 uint64_t offset, 505 uint64_t next_uid,
506 bool random,
519 const struct GNUNET_HashCode *key, 507 const struct GNUNET_HashCode *key,
520 const struct GNUNET_HashCode *vhash, 508 const struct GNUNET_HashCode *vhash,
521 enum GNUNET_BLOCK_Type type, 509 enum GNUNET_BLOCK_Type type,
522 PluginDatumProcessor proc, 510 PluginDatumProcessor proc,
523 void *proc_cls) 511 void *proc_cls)
524{ 512{
525 struct Plugin *plugin = cls; 513 struct Plugin *plugin = cls;
526 uint32_t utype = type; 514 uint32_t utype = type;
515 uint16_t use_rvalue = random;
516 uint16_t use_key = NULL != key;
517 uint16_t use_vhash = NULL != vhash;
518 uint16_t use_type = GNUNET_BLOCK_TYPE_ANY != type;
519 uint64_t rvalue;
520 struct GNUNET_PQ_QueryParam params[] = {
521 GNUNET_PQ_query_param_uint64 (&next_uid),
522 GNUNET_PQ_query_param_uint64 (&rvalue),
523 GNUNET_PQ_query_param_uint16 (&use_rvalue),
524 GNUNET_PQ_query_param_auto_from_type (key),
525 GNUNET_PQ_query_param_uint16 (&use_key),
526 GNUNET_PQ_query_param_auto_from_type (vhash),
527 GNUNET_PQ_query_param_uint16 (&use_vhash),
528 GNUNET_PQ_query_param_uint32 (&utype),
529 GNUNET_PQ_query_param_uint16 (&use_type),
530 GNUNET_PQ_query_param_end
531 };
527 PGresult *ret; 532 PGresult *ret;
528 uint64_t total;
529 uint64_t limit_off;
530 533
531 if (0 != type) 534 if (random)
532 { 535 {
533 if (NULL != vhash) 536 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
534 { 537 UINT64_MAX);
535 struct GNUNET_PQ_QueryParam params[] = { 538 next_uid = 0;
536 GNUNET_PQ_query_param_auto_from_type (key),
537 GNUNET_PQ_query_param_auto_from_type (vhash),
538 GNUNET_PQ_query_param_uint32 (&utype),
539 GNUNET_PQ_query_param_end
540 };
541 ret = GNUNET_PQ_exec_prepared (plugin->dbh,
542 "count_getvt",
543 params);
544 }
545 else
546 {
547 struct GNUNET_PQ_QueryParam params[] = {
548 GNUNET_PQ_query_param_auto_from_type (key),
549 GNUNET_PQ_query_param_uint32 (&utype),
550 GNUNET_PQ_query_param_end
551 };
552 ret = GNUNET_PQ_exec_prepared (plugin->dbh,
553 "count_gett",
554 params);
555 }
556 } 539 }
557 else 540 else
558 { 541 rvalue = 0;
559 if (NULL != vhash)
560 {
561 struct GNUNET_PQ_QueryParam params[] = {
562 GNUNET_PQ_query_param_auto_from_type (key),
563 GNUNET_PQ_query_param_auto_from_type (vhash),
564 GNUNET_PQ_query_param_end
565 };
566 ret = GNUNET_PQ_exec_prepared (plugin->dbh,
567 "count_getv",
568 params);
569 }
570 else
571 {
572 struct GNUNET_PQ_QueryParam params[] = {
573 GNUNET_PQ_query_param_auto_from_type (key),
574 GNUNET_PQ_query_param_end
575 };
576 ret = GNUNET_PQ_exec_prepared (plugin->dbh,
577 "count_get",
578 params);
579 }
580 }
581 542
582 if (GNUNET_OK != 543 ret = GNUNET_PQ_exec_prepared (plugin->dbh,
583 GNUNET_POSTGRES_check_result (plugin->dbh, 544 "get",
584 ret, 545 params);
585 PGRES_TUPLES_OK,
586 "PQexecParams",
587 "count"))
588 {
589 proc (proc_cls, NULL, 0, NULL, 0, 0, 0,
590 GNUNET_TIME_UNIT_ZERO_ABS, 0);
591 return;
592 }
593 if ( (PQntuples (ret) != 1) ||
594 (PQnfields (ret) != 1) ||
595 (PQgetlength (ret, 0, 0) != sizeof (uint64_t)))
596 {
597 GNUNET_break (0);
598 PQclear (ret);
599 proc (proc_cls, NULL, 0, NULL, 0, 0, 0,
600 GNUNET_TIME_UNIT_ZERO_ABS, 0);
601 return;
602 }
603 total = GNUNET_ntohll (*(const uint64_t *) PQgetvalue (ret, 0, 0));
604 PQclear (ret);
605 if (0 == total)
606 {
607 proc (proc_cls, NULL, 0, NULL, 0, 0, 0,
608 GNUNET_TIME_UNIT_ZERO_ABS, 0);
609 return;
610 }
611 limit_off = offset % total;
612
613 if (0 != type)
614 {
615 if (NULL != vhash)
616 {
617 struct GNUNET_PQ_QueryParam params[] = {
618 GNUNET_PQ_query_param_auto_from_type (key),
619 GNUNET_PQ_query_param_auto_from_type (vhash),
620 GNUNET_PQ_query_param_uint32 (&utype),
621 GNUNET_PQ_query_param_uint64 (&limit_off),
622 GNUNET_PQ_query_param_end
623 };
624 ret = GNUNET_PQ_exec_prepared (plugin->dbh,
625 "getvt",
626 params);
627 }
628 else
629 {
630 struct GNUNET_PQ_QueryParam params[] = {
631 GNUNET_PQ_query_param_auto_from_type (key),
632 GNUNET_PQ_query_param_uint32 (&utype),
633 GNUNET_PQ_query_param_uint64 (&limit_off),
634 GNUNET_PQ_query_param_end
635 };
636 ret = GNUNET_PQ_exec_prepared (plugin->dbh,
637 "gett",
638 params);
639 }
640 }
641 else
642 {
643 if (NULL != vhash)
644 {
645 struct GNUNET_PQ_QueryParam params[] = {
646 GNUNET_PQ_query_param_auto_from_type (key),
647 GNUNET_PQ_query_param_auto_from_type (vhash),
648 GNUNET_PQ_query_param_uint64 (&limit_off),
649 GNUNET_PQ_query_param_end
650 };
651 ret = GNUNET_PQ_exec_prepared (plugin->dbh,
652 "getv",
653 params);
654 }
655 else
656 {
657 struct GNUNET_PQ_QueryParam params[] = {
658 GNUNET_PQ_query_param_auto_from_type (key),
659 GNUNET_PQ_query_param_uint64 (&limit_off),
660 GNUNET_PQ_query_param_end
661 };
662 ret = GNUNET_PQ_exec_prepared (plugin->dbh,
663 "get",
664 params);
665 }
666 }
667 process_result (plugin, 546 process_result (plugin,
668 proc, 547 proc,
669 proc_cls, 548 proc_cls,
@@ -677,26 +556,25 @@ postgres_plugin_get_key (void *cls,
677 * the given iterator for each of them. 556 * the given iterator for each of them.
678 * 557 *
679 * @param cls our `struct Plugin *` 558 * @param cls our `struct Plugin *`
680 * @param offset offset of the result (modulo num-results); 559 * @param next_uid return the result with lowest uid >= next_uid
681 * specific ordering does not matter for the offset
682 * @param type entries of which type should be considered? 560 * @param type entries of which type should be considered?
683 * Use 0 for any type. 561 * Must not be zero (ANY).
684 * @param proc function to call on the matching value; 562 * @param proc function to call on the matching value;
685 * will be called with a NULL if no value matches 563 * will be called with NULL if no value matches
686 * @param proc_cls closure for @a proc 564 * @param proc_cls closure for @a proc
687 */ 565 */
688static void 566static void
689postgres_plugin_get_zero_anonymity (void *cls, 567postgres_plugin_get_zero_anonymity (void *cls,
690 uint64_t offset, 568 uint64_t next_uid,
691 enum GNUNET_BLOCK_Type type, 569 enum GNUNET_BLOCK_Type type,
692 PluginDatumProcessor proc, 570 PluginDatumProcessor proc,
693 void *proc_cls) 571 void *proc_cls)
694{ 572{
695 struct Plugin *plugin = cls; 573 struct Plugin *plugin = cls;
696 uint32_t utype = type; 574 uint32_t utype = type;
697 struct GNUNET_PQ_QueryParam params[] = { 575 struct GNUNET_PQ_QueryParam params[] = {
698 GNUNET_PQ_query_param_uint32 (&utype), 576 GNUNET_PQ_query_param_uint32 (&utype),
699 GNUNET_PQ_query_param_uint64 (&offset), 577 GNUNET_PQ_query_param_uint64 (&next_uid),
700 GNUNET_PQ_query_param_end 578 GNUNET_PQ_query_param_end
701 }; 579 };
702 PGresult *ret; 580 PGresult *ret;
@@ -747,6 +625,7 @@ struct ReplCtx
747 * @param type type of the content 625 * @param type type of the content
748 * @param priority priority of the content 626 * @param priority priority of the content
749 * @param anonymity anonymity-level for the content 627 * @param anonymity anonymity-level for the content
628 * @param replication replication-level for the content
750 * @param expiration expiration time for the content 629 * @param expiration expiration time for the content
751 * @param uid unique identifier for the datum; 630 * @param uid unique identifier for the datum;
752 * maybe 0 if no unique identifier is available 631 * maybe 0 if no unique identifier is available
@@ -757,13 +636,14 @@ struct ReplCtx
757 */ 636 */
758static int 637static int
759repl_proc (void *cls, 638repl_proc (void *cls,
760 const struct GNUNET_HashCode *key, 639 const struct GNUNET_HashCode *key,
761 uint32_t size, 640 uint32_t size,
762 const void *data, 641 const void *data,
763 enum GNUNET_BLOCK_Type type, 642 enum GNUNET_BLOCK_Type type,
764 uint32_t priority, 643 uint32_t priority,
765 uint32_t anonymity, 644 uint32_t anonymity,
766 struct GNUNET_TIME_Absolute expiration, 645 uint32_t replication,
646 struct GNUNET_TIME_Absolute expiration,
767 uint64_t uid) 647 uint64_t uid)
768{ 648{
769 struct ReplCtx *rc = cls; 649 struct ReplCtx *rc = cls;
@@ -777,12 +657,15 @@ repl_proc (void *cls,
777 PGresult *qret; 657 PGresult *qret;
778 658
779 ret = rc->proc (rc->proc_cls, 659 ret = rc->proc (rc->proc_cls,
780 key, 660 key,
781 size, data, 661 size,
782 type, 662 data,
783 priority, 663 type,
784 anonymity, 664 priority,
785 expiration, uid); 665 anonymity,
666 replication,
667 expiration,
668 uid);
786 if (NULL == key) 669 if (NULL == key)
787 return ret; 670 return ret;
788 qret = GNUNET_PQ_exec_prepared (plugin->dbh, 671 qret = GNUNET_PQ_exec_prepared (plugin->dbh,
@@ -867,19 +750,17 @@ postgres_plugin_get_expiration (void *cls,
867 750
868 751
869/** 752/**
870 * Update the priority for a particular key in the datastore. If 753 * Update the priority, replication and expiration for a particular
871 * the expiration time in value is different than the time found in 754 * unique ID in the datastore. If the expiration time in value is
872 * the datastore, the higher value should be kept. For the 755 * different than the time found in the datastore, the higher value
873 * anonymity level, the lower value is to be used. The specified 756 * should be kept. The specified priority and replication is added
874 * priority should be added to the existing priority, ignoring the 757 * to the existing value.
875 * priority in value.
876 *
877 * Note that it is possible for multiple values to match this put.
878 * In that case, all of the respective values are updated.
879 * 758 *
880 * @param cls our `struct Plugin *` 759 * @param cls our `struct Plugin *`
881 * @param uid unique identifier of the datum 760 * @param uid unique identifier of the datum
882 * @param delta by how much should the priority 761 * @param priority by how much should the priority
762 * change?
763 * @param replication by how much should the replication
883 * change? 764 * change?
884 * @param expire new expiration time should be the 765 * @param expire new expiration time should be the
885 * MAX of any existing expiration time and 766 * MAX of any existing expiration time and
@@ -889,16 +770,18 @@ postgres_plugin_get_expiration (void *cls,
889 */ 770 */
890static void 771static void
891postgres_plugin_update (void *cls, 772postgres_plugin_update (void *cls,
892 uint64_t uid, 773 uint64_t uid,
893 uint32_t delta, 774 uint32_t priority,
775 uint32_t replication,
894 struct GNUNET_TIME_Absolute expire, 776 struct GNUNET_TIME_Absolute expire,
895 PluginUpdateCont cont, 777 PluginUpdateCont cont,
896 void *cont_cls) 778 void *cont_cls)
897{ 779{
898 struct Plugin *plugin = cls; 780 struct Plugin *plugin = cls;
899 uint32_t oid = (uint32_t) uid; 781 uint32_t oid = (uint32_t) uid;
900 struct GNUNET_PQ_QueryParam params[] = { 782 struct GNUNET_PQ_QueryParam params[] = {
901 GNUNET_PQ_query_param_uint32 (&delta), 783 GNUNET_PQ_query_param_uint32 (&priority),
784 GNUNET_PQ_query_param_uint32 (&replication),
902 GNUNET_PQ_query_param_absolute_time (&expire), 785 GNUNET_PQ_query_param_absolute_time (&expire),
903 GNUNET_PQ_query_param_uint32 (&oid), 786 GNUNET_PQ_query_param_uint32 (&oid),
904 GNUNET_PQ_query_param_end 787 GNUNET_PQ_query_param_end
diff --git a/src/datastore/plugin_datastore_sqlite.c b/src/datastore/plugin_datastore_sqlite.c
index 9ca8f056a..1f874e190 100644
--- a/src/datastore/plugin_datastore_sqlite.c
+++ b/src/datastore/plugin_datastore_sqlite.c
@@ -130,42 +130,7 @@ struct Plugin
130 /** 130 /**
131 * Precompiled SQL for selection 131 * Precompiled SQL for selection
132 */ 132 */
133 sqlite3_stmt *count_key; 133 sqlite3_stmt *get;
134
135 /**
136 * Precompiled SQL for selection
137 */
138 sqlite3_stmt *count_key_vhash;
139
140 /**
141 * Precompiled SQL for selection
142 */
143 sqlite3_stmt *count_key_type;
144
145 /**
146 * Precompiled SQL for selection
147 */
148 sqlite3_stmt *count_key_vhash_type;
149
150 /**
151 * Precompiled SQL for selection
152 */
153 sqlite3_stmt *get_key;
154
155 /**
156 * Precompiled SQL for selection
157 */
158 sqlite3_stmt *get_key_vhash;
159
160 /**
161 * Precompiled SQL for selection
162 */
163 sqlite3_stmt *get_key_type;
164
165 /**
166 * Precompiled SQL for selection
167 */
168 sqlite3_stmt *get_key_vhash_type;
169 134
170 /** 135 /**
171 * Should the database be dropped on shutdown? 136 * Should the database be dropped on shutdown?
@@ -384,10 +349,14 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
384 sqlite3_finalize (stmt); 349 sqlite3_finalize (stmt);
385 create_indices (plugin->dbh); 350 create_indices (plugin->dbh);
386 351
352#define RESULT_COLUMNS "repl, type, prio, anonLevel, expire, hash, value, _ROWID_"
387 if ( (SQLITE_OK != 353 if ( (SQLITE_OK !=
388 sq_prepare (plugin->dbh, 354 sq_prepare (plugin->dbh,
389 "UPDATE gn090 " 355 "UPDATE gn090 "
390 "SET prio = prio + ?, expire = MAX(expire,?) WHERE _ROWID_ = ?", 356 "SET prio = prio + ?, "
357 "repl = repl + ?, "
358 "expire = MAX(expire, ?) "
359 "WHERE _ROWID_ = ?",
391 &plugin->updPrio)) || 360 &plugin->updPrio)) ||
392 (SQLITE_OK != 361 (SQLITE_OK !=
393 sq_prepare (plugin->dbh, 362 sq_prepare (plugin->dbh,
@@ -395,7 +364,7 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
395 &plugin->updRepl)) || 364 &plugin->updRepl)) ||
396 (SQLITE_OK != 365 (SQLITE_OK !=
397 sq_prepare (plugin->dbh, 366 sq_prepare (plugin->dbh,
398 "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 " 367 "SELECT " RESULT_COLUMNS " FROM gn090 "
399#if SQLITE_VERSION_NUMBER >= 3007000 368#if SQLITE_VERSION_NUMBER >= 3007000
400 "INDEXED BY idx_repl_rvalue " 369 "INDEXED BY idx_repl_rvalue "
401#endif 370#endif
@@ -417,7 +386,7 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
417 &plugin->maxRepl)) || 386 &plugin->maxRepl)) ||
418 (SQLITE_OK != 387 (SQLITE_OK !=
419 sq_prepare (plugin->dbh, 388 sq_prepare (plugin->dbh,
420 "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 " 389 "SELECT " RESULT_COLUMNS " FROM gn090 "
421#if SQLITE_VERSION_NUMBER >= 3007000 390#if SQLITE_VERSION_NUMBER >= 3007000
422 "INDEXED BY idx_expire " 391 "INDEXED BY idx_expire "
423#endif 392#endif
@@ -426,12 +395,14 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
426 &plugin->selExpi)) || 395 &plugin->selExpi)) ||
427 (SQLITE_OK != 396 (SQLITE_OK !=
428 sq_prepare (plugin->dbh, 397 sq_prepare (plugin->dbh,
429 "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 " 398 "SELECT " RESULT_COLUMNS " FROM gn090 "
430#if SQLITE_VERSION_NUMBER >= 3007000 399#if SQLITE_VERSION_NUMBER >= 3007000
431 "INDEXED BY idx_anon_type_hash " 400 "INDEXED BY idx_anon_type_hash "
432#endif 401#endif
433 "WHERE (anonLevel = 0 AND type=?1) " 402 "WHERE _ROWID_ >= ? AND "
434 "ORDER BY hash DESC LIMIT 1 OFFSET ?2", 403 "anonLevel = 0 AND "
404 "type = ? "
405 "ORDER BY _ROWID_ ASC LIMIT 1",
435 &plugin->selZeroAnon)) || 406 &plugin->selZeroAnon)) ||
436 (SQLITE_OK != 407 (SQLITE_OK !=
437 sq_prepare (plugin->dbh, 408 sq_prepare (plugin->dbh,
@@ -440,44 +411,14 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
440 &plugin->insertContent)) || 411 &plugin->insertContent)) ||
441 (SQLITE_OK != 412 (SQLITE_OK !=
442 sq_prepare (plugin->dbh, 413 sq_prepare (plugin->dbh,
443 "SELECT count(*) FROM gn090 WHERE hash=?", 414 "SELECT " RESULT_COLUMNS " FROM gn090 "
444 &plugin->count_key)) || 415 "WHERE _ROWID_ >= ? AND "
445 (SQLITE_OK != 416 "(rvalue >= ? OR 0 = ?) AND "
446 sq_prepare (plugin->dbh, 417 "(hash = ? OR 0 = ?) AND "
447 "SELECT count(*) FROM gn090 WHERE hash=? AND vhash=?", 418 "(vhash = ? OR 0 = ?) AND "
448 &plugin->count_key_vhash)) || 419 "(type = ? OR 0 = ?) "
449 (SQLITE_OK != 420 "ORDER BY _ROWID_ ASC LIMIT 1",
450 sq_prepare (plugin->dbh, 421 &plugin->get)) ||
451 "SELECT count(*) FROM gn090 WHERE hash=? AND type=?",
452 &plugin->count_key_type)) ||
453 (SQLITE_OK !=
454 sq_prepare (plugin->dbh,
455 "SELECT count(*) FROM gn090 WHERE hash=? AND vhash=? AND type=?",
456 &plugin->count_key_vhash_type)) ||
457 (SQLITE_OK !=
458 sq_prepare (plugin->dbh,
459 "SELECT type, prio, anonLevel, expire, hash, value, _ROWID_ FROM gn090 "
460 "WHERE hash=?"
461 "ORDER BY _ROWID_ ASC LIMIT 1 OFFSET ?",
462 &plugin->get_key)) ||
463 (SQLITE_OK !=
464 sq_prepare (plugin->dbh,
465 "SELECT type, prio, anonLevel, expire, hash, value, _ROWID_ FROM gn090 "
466 "WHERE hash=? AND vhash=?"
467 "ORDER BY _ROWID_ ASC LIMIT 1 OFFSET ?",
468 &plugin->get_key_vhash)) ||
469 (SQLITE_OK !=
470 sq_prepare (plugin->dbh,
471 "SELECT type, prio, anonLevel, expire, hash, value, _ROWID_ FROM gn090 "
472 "WHERE hash=? AND type=?"
473 "ORDER BY _ROWID_ ASC LIMIT 1 OFFSET ?",
474 &plugin->get_key_type)) ||
475 (SQLITE_OK !=
476 sq_prepare (plugin->dbh,
477 "SELECT type, prio, anonLevel, expire, hash, value, _ROWID_ FROM gn090 "
478 "WHERE hash=? AND vhash=? AND type=?"
479 "ORDER BY _ROWID_ ASC LIMIT 1 OFFSET ?",
480 &plugin->get_key_vhash_type)) ||
481 (SQLITE_OK != 422 (SQLITE_OK !=
482 sq_prepare (plugin->dbh, 423 sq_prepare (plugin->dbh,
483 "DELETE FROM gn090 WHERE _ROWID_ = ?", 424 "DELETE FROM gn090 WHERE _ROWID_ = ?",
@@ -523,22 +464,8 @@ database_shutdown (struct Plugin *plugin)
523 sqlite3_finalize (plugin->selZeroAnon); 464 sqlite3_finalize (plugin->selZeroAnon);
524 if (NULL != plugin->insertContent) 465 if (NULL != plugin->insertContent)
525 sqlite3_finalize (plugin->insertContent); 466 sqlite3_finalize (plugin->insertContent);
526 if (NULL != plugin->count_key) 467 if (NULL != plugin->get)
527 sqlite3_finalize (plugin->count_key); 468 sqlite3_finalize (plugin->get);
528 if (NULL != plugin->count_key_vhash)
529 sqlite3_finalize (plugin->count_key_vhash);
530 if (NULL != plugin->count_key_type)
531 sqlite3_finalize (plugin->count_key_type);
532 if (NULL != plugin->count_key_vhash_type)
533 sqlite3_finalize (plugin->count_key_vhash_type);
534 if (NULL != plugin->count_key)
535 sqlite3_finalize (plugin->get_key);
536 if (NULL != plugin->count_key_vhash)
537 sqlite3_finalize (plugin->get_key_vhash);
538 if (NULL != plugin->count_key_type)
539 sqlite3_finalize (plugin->get_key_type);
540 if (NULL != plugin->count_key_vhash_type)
541 sqlite3_finalize (plugin->get_key_vhash_type);
542 result = sqlite3_close (plugin->dbh); 469 result = sqlite3_close (plugin->dbh);
543#if SQLITE_VERSION_NUMBER >= 3007000 470#if SQLITE_VERSION_NUMBER >= 3007000
544 if (result == SQLITE_BUSY) 471 if (result == SQLITE_BUSY)
@@ -719,19 +646,17 @@ sqlite_plugin_put (void *cls,
719 646
720 647
721/** 648/**
722 * Update the priority for a particular key in the datastore. If 649 * Update the priority, replication and expiration for a particular
723 * the expiration time in value is different than the time found in 650 * unique ID in the datastore. If the expiration time in value is
724 * the datastore, the higher value should be kept. For the 651 * different than the time found in the datastore, the higher value
725 * anonymity level, the lower value is to be used. The specified 652 * should be kept. The specified priority and replication is added
726 * priority should be added to the existing priority, ignoring the 653 * to the existing value.
727 * priority in value.
728 *
729 * Note that it is possible for multiple values to match this put.
730 * In that case, all of the respective values are updated.
731 * 654 *
732 * @param cls the plugin context (state for this module) 655 * @param cls the plugin context (state for this module)
733 * @param uid unique identifier of the datum 656 * @param uid unique identifier of the datum
734 * @param delta by how much should the priority 657 * @param priority by how much should the priority
658 * change?
659 * @param replication by how much should the replication
735 * change? 660 * change?
736 * @param expire new expiration time should be the 661 * @param expire new expiration time should be the
737 * MAX of any existing expiration time and 662 * MAX of any existing expiration time and
@@ -742,14 +667,16 @@ sqlite_plugin_put (void *cls,
742static void 667static void
743sqlite_plugin_update (void *cls, 668sqlite_plugin_update (void *cls,
744 uint64_t uid, 669 uint64_t uid,
745 uint32_t delta, 670 uint32_t priority,
671 uint32_t replication,
746 struct GNUNET_TIME_Absolute expire, 672 struct GNUNET_TIME_Absolute expire,
747 PluginUpdateCont cont, 673 PluginUpdateCont cont,
748 void *cont_cls) 674 void *cont_cls)
749{ 675{
750 struct Plugin *plugin = cls; 676 struct Plugin *plugin = cls;
751 struct GNUNET_SQ_QueryParam params[] = { 677 struct GNUNET_SQ_QueryParam params[] = {
752 GNUNET_SQ_query_param_uint32 (&delta), 678 GNUNET_SQ_query_param_uint32 (&priority),
679 GNUNET_SQ_query_param_uint32 (&replication),
753 GNUNET_SQ_query_param_absolute_time (&expire), 680 GNUNET_SQ_query_param_absolute_time (&expire),
754 GNUNET_SQ_query_param_uint64 (&uid), 681 GNUNET_SQ_query_param_uint64 (&uid),
755 GNUNET_SQ_query_param_end 682 GNUNET_SQ_query_param_end
@@ -808,6 +735,7 @@ execute_get (struct Plugin *plugin,
808{ 735{
809 int n; 736 int n;
810 struct GNUNET_TIME_Absolute expiration; 737 struct GNUNET_TIME_Absolute expiration;
738 uint32_t replication;
811 uint32_t type; 739 uint32_t type;
812 uint32_t priority; 740 uint32_t priority;
813 uint32_t anonymity; 741 uint32_t anonymity;
@@ -817,6 +745,7 @@ execute_get (struct Plugin *plugin,
817 struct GNUNET_HashCode key; 745 struct GNUNET_HashCode key;
818 int ret; 746 int ret;
819 struct GNUNET_SQ_ResultSpec rs[] = { 747 struct GNUNET_SQ_ResultSpec rs[] = {
748 GNUNET_SQ_result_spec_uint32 (&replication),
820 GNUNET_SQ_result_spec_uint32 (&type), 749 GNUNET_SQ_result_spec_uint32 (&type),
821 GNUNET_SQ_result_spec_uint32 (&priority), 750 GNUNET_SQ_result_spec_uint32 (&priority),
822 GNUNET_SQ_result_spec_uint32 (&anonymity), 751 GNUNET_SQ_result_spec_uint32 (&anonymity),
@@ -850,6 +779,7 @@ execute_get (struct Plugin *plugin,
850 type, 779 type,
851 priority, 780 priority,
852 anonymity, 781 anonymity,
782 replication,
853 expiration, 783 expiration,
854 rowid); 784 rowid);
855 GNUNET_SQ_cleanup_result (rs); 785 GNUNET_SQ_cleanup_result (rs);
@@ -878,7 +808,7 @@ execute_get (struct Plugin *plugin,
878 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 808 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
879 "sqlite3_reset"); 809 "sqlite3_reset");
880 GNUNET_break (0); 810 GNUNET_break (0);
881 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 811 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
882 database_shutdown (plugin); 812 database_shutdown (plugin);
883 database_setup (plugin->env->cfg, 813 database_setup (plugin->env->cfg,
884 plugin); 814 plugin);
@@ -886,7 +816,7 @@ execute_get (struct Plugin *plugin,
886 } 816 }
887 GNUNET_SQ_reset (plugin->dbh, 817 GNUNET_SQ_reset (plugin->dbh,
888 stmt); 818 stmt);
889 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 819 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
890} 820}
891 821
892 822
@@ -895,38 +825,36 @@ execute_get (struct Plugin *plugin,
895 * the given processor for the item. 825 * the given processor for the item.
896 * 826 *
897 * @param cls our plugin context 827 * @param cls our plugin context
898 * @param offset offset of the result (modulo num-results); 828 * @param next_uid return the result with lowest uid >= next_uid
899 * specific ordering does not matter for the offset
900 * @param type entries of which type should be considered? 829 * @param type entries of which type should be considered?
901 * Use 0 for any type. 830 * Must not be zero (ANY).
902 * @param proc function to call on each matching value; 831 * @param proc function to call on the matching value;
903 * will be called once with a NULL value at the end 832 * will be called with NULL if no value matches
904 * @param proc_cls closure for @a proc 833 * @param proc_cls closure for @a proc
905 */ 834 */
906static void 835static void
907sqlite_plugin_get_zero_anonymity (void *cls, 836sqlite_plugin_get_zero_anonymity (void *cls,
908 uint64_t offset, 837 uint64_t next_uid,
909 enum GNUNET_BLOCK_Type type, 838 enum GNUNET_BLOCK_Type type,
910 PluginDatumProcessor proc, 839 PluginDatumProcessor proc,
911 void *proc_cls) 840 void *proc_cls)
912{ 841{
913 struct Plugin *plugin = cls; 842 struct Plugin *plugin = cls;
914 struct GNUNET_SQ_QueryParam params[] = { 843 struct GNUNET_SQ_QueryParam params[] = {
844 GNUNET_SQ_query_param_uint64 (&next_uid),
915 GNUNET_SQ_query_param_uint32 (&type), 845 GNUNET_SQ_query_param_uint32 (&type),
916 GNUNET_SQ_query_param_uint64 (&offset),
917 GNUNET_SQ_query_param_end 846 GNUNET_SQ_query_param_end
918 }; 847 };
919 sqlite3_stmt *stmt = plugin->selZeroAnon;
920 848
921 GNUNET_assert (type != GNUNET_BLOCK_TYPE_ANY); 849 GNUNET_assert (type != GNUNET_BLOCK_TYPE_ANY);
922 if (GNUNET_OK != 850 if (GNUNET_OK !=
923 GNUNET_SQ_bind (stmt, 851 GNUNET_SQ_bind (plugin->selZeroAnon,
924 params)) 852 params))
925 { 853 {
926 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 854 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
927 return; 855 return;
928 } 856 }
929 execute_get (plugin, stmt, proc, proc_cls); 857 execute_get (plugin, plugin->selZeroAnon, proc, proc_cls);
930} 858}
931 859
932 860
@@ -934,8 +862,9 @@ sqlite_plugin_get_zero_anonymity (void *cls,
934 * Get results for a particular key in the datastore. 862 * Get results for a particular key in the datastore.
935 * 863 *
936 * @param cls closure 864 * @param cls closure
937 * @param offset offset (mod count). 865 * @param next_uid return the result with lowest uid >= next_uid
938 * @param key key to match, never NULL 866 * @param random if true, return a random result instead of using next_uid
867 * @param key maybe NULL (to match all entries)
939 * @param vhash hash of the value, maybe NULL (to 868 * @param vhash hash of the value, maybe NULL (to
940 * match all values that have the right key). 869 * match all values that have the right key).
941 * Note that for DBlocks there is no difference 870 * Note that for DBlocks there is no difference
@@ -949,7 +878,8 @@ sqlite_plugin_get_zero_anonymity (void *cls,
949 */ 878 */
950static void 879static void
951sqlite_plugin_get_key (void *cls, 880sqlite_plugin_get_key (void *cls,
952 uint64_t offset, 881 uint64_t next_uid,
882 bool random,
953 const struct GNUNET_HashCode *key, 883 const struct GNUNET_HashCode *key,
954 const struct GNUNET_HashCode *vhash, 884 const struct GNUNET_HashCode *vhash,
955 enum GNUNET_BLOCK_Type type, 885 enum GNUNET_BLOCK_Type type,
@@ -957,133 +887,45 @@ sqlite_plugin_get_key (void *cls,
957 void *proc_cls) 887 void *proc_cls)
958{ 888{
959 struct Plugin *plugin = cls; 889 struct Plugin *plugin = cls;
890 uint64_t rvalue;
891 uint16_t use_rvalue = random;
960 uint32_t type32 = (uint32_t) type; 892 uint32_t type32 = (uint32_t) type;
961 int ret; 893 uint16_t use_type = GNUNET_BLOCK_TYPE_ANY != type;
962 int total; 894 uint16_t use_key = NULL != key;
963 uint32_t limit_off; 895 uint16_t use_vhash = NULL != vhash;
964 struct GNUNET_SQ_QueryParam count_params_key[] = { 896 struct GNUNET_SQ_QueryParam params[] = {
965 GNUNET_SQ_query_param_auto_from_type (key), 897 GNUNET_SQ_query_param_uint64 (&next_uid),
966 GNUNET_SQ_query_param_end 898 GNUNET_SQ_query_param_uint64 (&rvalue),
967 }; 899 GNUNET_SQ_query_param_uint16 (&use_rvalue),
968 struct GNUNET_SQ_QueryParam count_params_key_vhash[] = {
969 GNUNET_SQ_query_param_auto_from_type (key),
970 GNUNET_SQ_query_param_auto_from_type (vhash),
971 GNUNET_SQ_query_param_end
972 };
973 struct GNUNET_SQ_QueryParam count_params_key_type[] = {
974 GNUNET_SQ_query_param_auto_from_type (key),
975 GNUNET_SQ_query_param_uint32 (&type32),
976 GNUNET_SQ_query_param_end
977 };
978 struct GNUNET_SQ_QueryParam count_params_key_vhash_type[] = {
979 GNUNET_SQ_query_param_auto_from_type (key),
980 GNUNET_SQ_query_param_auto_from_type (vhash),
981 GNUNET_SQ_query_param_uint32 (&type32),
982 GNUNET_SQ_query_param_end
983 };
984 struct GNUNET_SQ_QueryParam get_params_key[] = {
985 GNUNET_SQ_query_param_auto_from_type (key),
986 GNUNET_SQ_query_param_uint32 (&limit_off),
987 GNUNET_SQ_query_param_end
988 };
989 struct GNUNET_SQ_QueryParam get_params_key_vhash[] = {
990 GNUNET_SQ_query_param_auto_from_type (key),
991 GNUNET_SQ_query_param_auto_from_type (vhash),
992 GNUNET_SQ_query_param_uint32 (&limit_off),
993 GNUNET_SQ_query_param_end
994 };
995 struct GNUNET_SQ_QueryParam get_params_key_type[] = {
996 GNUNET_SQ_query_param_auto_from_type (key),
997 GNUNET_SQ_query_param_uint32 (&type32),
998 GNUNET_SQ_query_param_uint32 (&limit_off),
999 GNUNET_SQ_query_param_end
1000 };
1001 struct GNUNET_SQ_QueryParam get_params_key_vhash_type[] = {
1002 GNUNET_SQ_query_param_auto_from_type (key), 900 GNUNET_SQ_query_param_auto_from_type (key),
901 GNUNET_SQ_query_param_uint16 (&use_key),
1003 GNUNET_SQ_query_param_auto_from_type (vhash), 902 GNUNET_SQ_query_param_auto_from_type (vhash),
903 GNUNET_SQ_query_param_uint16 (&use_vhash),
1004 GNUNET_SQ_query_param_uint32 (&type32), 904 GNUNET_SQ_query_param_uint32 (&type32),
1005 GNUNET_SQ_query_param_uint32 (&limit_off), 905 GNUNET_SQ_query_param_uint16 (&use_type),
1006 GNUNET_SQ_query_param_end 906 GNUNET_SQ_query_param_end
1007 }; 907 };
1008 struct GNUNET_SQ_QueryParam *count_params;
1009 sqlite3_stmt *count_stmt;
1010 struct GNUNET_SQ_QueryParam *get_params;
1011 sqlite3_stmt *get_stmt;
1012 908
1013 if (NULL == vhash) 909 if (random)
1014 { 910 {
1015 if (GNUNET_BLOCK_TYPE_ANY == type) 911 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1016 { 912 UINT64_MAX);
1017 count_params = count_params_key; 913 next_uid = 0;
1018 count_stmt = plugin->count_key;
1019 get_params = get_params_key;
1020 get_stmt = plugin->get_key;
1021 }
1022 else
1023 {
1024 count_params = count_params_key_type;
1025 count_stmt = plugin->count_key_type;
1026 get_params = get_params_key_type;
1027 get_stmt = plugin->get_key_type;
1028 }
1029 } 914 }
1030 else 915 else
1031 { 916 rvalue = 0;
1032 if (GNUNET_BLOCK_TYPE_ANY == type) 917
1033 {
1034 count_params = count_params_key_vhash;
1035 count_stmt = plugin->count_key_vhash;
1036 get_params = get_params_key_vhash;
1037 get_stmt = plugin->get_key_vhash;
1038 }
1039 else
1040 {
1041 count_params = count_params_key_vhash_type;
1042 count_stmt = plugin->count_key_vhash_type;
1043 get_params = get_params_key_vhash_type;
1044 get_stmt = plugin->get_key_vhash_type;
1045 }
1046 }
1047 if (GNUNET_OK !=
1048 GNUNET_SQ_bind (count_stmt,
1049 count_params))
1050 {
1051 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1052 return;
1053 }
1054 ret = sqlite3_step (count_stmt);
1055 if (ret != SQLITE_ROW)
1056 {
1057 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1058 "sqlite_step");
1059 GNUNET_SQ_reset (plugin->dbh,
1060 count_stmt);
1061 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1062 return;
1063 }
1064 total = sqlite3_column_int (count_stmt,
1065 0);
1066 GNUNET_SQ_reset (plugin->dbh,
1067 count_stmt);
1068 if (0 == total)
1069 {
1070 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1071 return;
1072 }
1073 limit_off = (uint32_t) (offset % total);
1074 if (GNUNET_OK != 918 if (GNUNET_OK !=
1075 GNUNET_SQ_bind (get_stmt, 919 GNUNET_SQ_bind (plugin->get,
1076 get_params)) 920 params))
1077 { 921 {
1078 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 922 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1079 return; 923 return;
1080 } 924 }
1081 execute_get (plugin, 925 execute_get (plugin,
1082 get_stmt, 926 plugin->get,
1083 proc, 927 proc,
1084 proc_cls); 928 proc_cls);
1085 GNUNET_SQ_reset (plugin->dbh,
1086 get_stmt);
1087} 929}
1088 930
1089 931
@@ -1127,6 +969,7 @@ struct ReplCtx
1127 * @param type type of the content 969 * @param type type of the content
1128 * @param priority priority of the content 970 * @param priority priority of the content
1129 * @param anonymity anonymity-level for the content 971 * @param anonymity anonymity-level for the content
972 * @param replication replication-level for the content
1130 * @param expiration expiration time for the content 973 * @param expiration expiration time for the content
1131 * @param uid unique identifier for the datum; 974 * @param uid unique identifier for the datum;
1132 * maybe 0 if no unique identifier is available 975 * maybe 0 if no unique identifier is available
@@ -1141,6 +984,7 @@ repl_proc (void *cls,
1141 enum GNUNET_BLOCK_Type type, 984 enum GNUNET_BLOCK_Type type,
1142 uint32_t priority, 985 uint32_t priority,
1143 uint32_t anonymity, 986 uint32_t anonymity,
987 uint32_t replication,
1144 struct GNUNET_TIME_Absolute expiration, 988 struct GNUNET_TIME_Absolute expiration,
1145 uint64_t uid) 989 uint64_t uid)
1146{ 990{
@@ -1156,6 +1000,7 @@ repl_proc (void *cls,
1156 type, 1000 type,
1157 priority, 1001 priority,
1158 anonymity, 1002 anonymity,
1003 replication,
1159 expiration, 1004 expiration,
1160 uid); 1005 uid);
1161 if (NULL != key) 1006 if (NULL != key)
@@ -1205,7 +1050,7 @@ sqlite_plugin_get_replication (void *cls,
1205 GNUNET_SQ_reset (plugin->dbh, 1050 GNUNET_SQ_reset (plugin->dbh,
1206 plugin->maxRepl); 1051 plugin->maxRepl);
1207 /* DB empty */ 1052 /* DB empty */
1208 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 1053 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1209 return; 1054 return;
1210 } 1055 }
1211 repl = sqlite3_column_int (plugin->maxRepl, 1056 repl = sqlite3_column_int (plugin->maxRepl,
@@ -1218,7 +1063,7 @@ sqlite_plugin_get_replication (void *cls,
1218 GNUNET_SQ_bind (plugin->selRepl, 1063 GNUNET_SQ_bind (plugin->selRepl,
1219 params_sel_repl)) 1064 params_sel_repl))
1220 { 1065 {
1221 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 1066 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1222 return; 1067 return;
1223 } 1068 }
1224 rc.have_uid = GNUNET_SYSERR; 1069 rc.have_uid = GNUNET_SYSERR;
@@ -1234,7 +1079,7 @@ sqlite_plugin_get_replication (void *cls,
1234 GNUNET_SQ_bind (plugin->updRepl, 1079 GNUNET_SQ_bind (plugin->updRepl,
1235 params_upd_repl)) 1080 params_upd_repl))
1236 { 1081 {
1237 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 1082 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1238 return; 1083 return;
1239 } 1084 }
1240 if (SQLITE_DONE != 1085 if (SQLITE_DONE !=
@@ -1248,7 +1093,7 @@ sqlite_plugin_get_replication (void *cls,
1248 if (GNUNET_SYSERR == rc.have_uid) 1093 if (GNUNET_SYSERR == rc.have_uid)
1249 { 1094 {
1250 /* proc was not called at all so far, do it now. */ 1095 /* proc was not called at all so far, do it now. */
1251 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 1096 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1252 } 1097 }
1253} 1098}
1254 1099
@@ -1282,7 +1127,7 @@ sqlite_plugin_get_expiration (void *cls, PluginDatumProcessor proc,
1282 GNUNET_SQ_bind (stmt, 1127 GNUNET_SQ_bind (stmt,
1283 params)) 1128 params))
1284 { 1129 {
1285 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 1130 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1286 return; 1131 return;
1287 } 1132 }
1288 execute_get (plugin, stmt, proc, proc_cls); 1133 execute_get (plugin, stmt, proc, proc_cls);
diff --git a/src/datastore/plugin_datastore_template.c b/src/datastore/plugin_datastore_template.c
index a1e03e8ee..8e44f020d 100644
--- a/src/datastore/plugin_datastore_template.c
+++ b/src/datastore/plugin_datastore_template.c
@@ -89,8 +89,8 @@ template_plugin_put (void *cls, const struct GNUNET_HashCode * key, uint32_t siz
89 * Get one of the results for a particular key in the datastore. 89 * Get one of the results for a particular key in the datastore.
90 * 90 *
91 * @param cls closure 91 * @param cls closure
92 * @param offset offset of the result (modulo num-results); 92 * @param next_uid return the result with lowest uid >= next_uid
93 * specific ordering does not matter for the offset 93 * @param random if true, return a random result instead of using next_uid
94 * @param key maybe NULL (to match all entries) 94 * @param key maybe NULL (to match all entries)
95 * @param vhash hash of the value, maybe NULL (to 95 * @param vhash hash of the value, maybe NULL (to
96 * match all values that have the right key). 96 * match all values that have the right key).
@@ -104,7 +104,7 @@ template_plugin_put (void *cls, const struct GNUNET_HashCode * key, uint32_t siz
104 * @param proc_cls closure for proc 104 * @param proc_cls closure for proc
105 */ 105 */
106static void 106static void
107template_plugin_get_key (void *cls, uint64_t offset, 107template_plugin_get_key (void *cls, uint64_t next_uid, bool random,
108 const struct GNUNET_HashCode * key, 108 const struct GNUNET_HashCode * key,
109 const struct GNUNET_HashCode * vhash, 109 const struct GNUNET_HashCode * vhash,
110 enum GNUNET_BLOCK_Type type, PluginDatumProcessor proc, 110 enum GNUNET_BLOCK_Type type, PluginDatumProcessor proc,
@@ -151,19 +151,17 @@ template_plugin_get_expiration (void *cls, PluginDatumProcessor proc,
151 151
152 152
153/** 153/**
154 * Update the priority for a particular key in the datastore. If 154 * Update the priority, replication and expiration for a particular
155 * the expiration time in value is different than the time found in 155 * unique ID in the datastore. If the expiration time in value is
156 * the datastore, the higher value should be kept. For the 156 * different than the time found in the datastore, the higher value
157 * anonymity level, the lower value is to be used. The specified 157 * should be kept. The specified priority and replication is added
158 * priority should be added to the existing priority, ignoring the 158 * to the existing value.
159 * priority in value.
160 *
161 * Note that it is possible for multiple values to match this put.
162 * In that case, all of the respective values are updated.
163 * 159 *
164 * @param cls our "struct Plugin*" 160 * @param cls our "struct Plugin*"
165 * @param uid unique identifier of the datum 161 * @param uid unique identifier of the datum
166 * @param delta by how much should the priority 162 * @param priority by how much should the priority
163 * change?
164 * @param replication by how much should the replication
167 * change? 165 * change?
168 * @param expire new expiration time should be the 166 * @param expire new expiration time should be the
169 * MAX of any existing expiration time and 167 * MAX of any existing expiration time and
@@ -172,9 +170,13 @@ template_plugin_get_expiration (void *cls, PluginDatumProcessor proc,
172 * @param cons_cls continuation closure 170 * @param cons_cls continuation closure
173 */ 171 */
174static void 172static void
175template_plugin_update (void *cls, uint64_t uid, uint32_t delta, 173template_plugin_update (void *cls,
174 uint64_t uid,
175 uint32_t priority,
176 uint32_t replication,
176 struct GNUNET_TIME_Absolute expire, 177 struct GNUNET_TIME_Absolute expire,
177 PluginUpdateCont cont, void *cont_cls) 178 PluginUpdateCont cont,
179 void *cont_cls)
178{ 180{
179 GNUNET_break (0); 181 GNUNET_break (0);
180 cont (cont_cls, GNUNET_SYSERR, "not implemented"); 182 cont (cont_cls, GNUNET_SYSERR, "not implemented");
@@ -185,16 +187,15 @@ template_plugin_update (void *cls, uint64_t uid, uint32_t delta,
185 * Call the given processor on an item with zero anonymity. 187 * Call the given processor on an item with zero anonymity.
186 * 188 *
187 * @param cls our "struct Plugin*" 189 * @param cls our "struct Plugin*"
188 * @param offset offset of the result (modulo num-results); 190 * @param next_uid return the result with lowest uid >= next_uid
189 * specific ordering does not matter for the offset
190 * @param type entries of which type should be considered? 191 * @param type entries of which type should be considered?
191 * Use 0 for any type. 192 * Must not be zero (ANY).
192 * @param proc function to call on each matching value; 193 * @param proc function to call on the matching value;
193 * will be called with NULL if no value matches 194 * will be called with NULL if no value matches
194 * @param proc_cls closure for proc 195 * @param proc_cls closure for proc
195 */ 196 */
196static void 197static void
197template_plugin_get_zero_anonymity (void *cls, uint64_t offset, 198template_plugin_get_zero_anonymity (void *cls, uint64_t next_uid,
198 enum GNUNET_BLOCK_Type type, 199 enum GNUNET_BLOCK_Type type,
199 PluginDatumProcessor proc, void *proc_cls) 200 PluginDatumProcessor proc, void *proc_cls)
200{ 201{
diff --git a/src/datastore/test_datastore_api.c b/src/datastore/test_datastore_api.c
index a99668240..63927a364 100644
--- a/src/datastore/test_datastore_api.c
+++ b/src/datastore/test_datastore_api.c
@@ -156,8 +156,6 @@ struct CpsRunContext
156 void *data; 156 void *data;
157 size_t size; 157 size_t size;
158 158
159 uint64_t uid;
160 uint64_t offset;
161 uint64_t first_uid; 159 uint64_t first_uid;
162}; 160};
163 161
@@ -233,6 +231,7 @@ check_value (void *cls,
233 enum GNUNET_BLOCK_Type type, 231 enum GNUNET_BLOCK_Type type,
234 uint32_t priority, 232 uint32_t priority,
235 uint32_t anonymity, 233 uint32_t anonymity,
234 uint32_t replication,
236 struct GNUNET_TIME_Absolute expiration, 235 struct GNUNET_TIME_Absolute expiration,
237 uint64_t uid) 236 uint64_t uid)
238{ 237{
@@ -267,7 +266,6 @@ check_value (void *cls,
267 GNUNET_assert (priority == get_priority (i)); 266 GNUNET_assert (priority == get_priority (i));
268 GNUNET_assert (anonymity == get_anonymity (i)); 267 GNUNET_assert (anonymity == get_anonymity (i));
269 GNUNET_assert (expiration.abs_value_us == get_expiration (i).abs_value_us); 268 GNUNET_assert (expiration.abs_value_us == get_expiration (i).abs_value_us);
270 crc->offset++;
271 if (crc->i == 0) 269 if (crc->i == 0)
272 { 270 {
273 crc->phase = RP_DEL; 271 crc->phase = RP_DEL;
@@ -286,6 +284,7 @@ delete_value (void *cls,
286 enum GNUNET_BLOCK_Type type, 284 enum GNUNET_BLOCK_Type type,
287 uint32_t priority, 285 uint32_t priority,
288 uint32_t anonymity, 286 uint32_t anonymity,
287 uint32_t replication,
289 struct GNUNET_TIME_Absolute expiration, 288 struct GNUNET_TIME_Absolute expiration,
290 uint64_t uid) 289 uint64_t uid)
291{ 290{
@@ -311,6 +310,7 @@ check_nothing (void *cls,
311 enum GNUNET_BLOCK_Type type, 310 enum GNUNET_BLOCK_Type type,
312 uint32_t priority, 311 uint32_t priority,
313 uint32_t anonymity, 312 uint32_t anonymity,
313 uint32_t replication,
314 struct GNUNET_TIME_Absolute expiration, 314 struct GNUNET_TIME_Absolute expiration,
315 uint64_t uid) 315 uint64_t uid)
316{ 316{
@@ -332,6 +332,7 @@ check_multiple (void *cls,
332 enum GNUNET_BLOCK_Type type, 332 enum GNUNET_BLOCK_Type type,
333 uint32_t priority, 333 uint32_t priority,
334 uint32_t anonymity, 334 uint32_t anonymity,
335 uint32_t replication,
335 struct GNUNET_TIME_Absolute expiration, 336 struct GNUNET_TIME_Absolute expiration,
336 uint64_t uid) 337 uint64_t uid)
337{ 338{
@@ -343,7 +344,6 @@ check_multiple (void *cls,
343 case RP_GET_MULTIPLE: 344 case RP_GET_MULTIPLE:
344 crc->phase = RP_GET_MULTIPLE_NEXT; 345 crc->phase = RP_GET_MULTIPLE_NEXT;
345 crc->first_uid = uid; 346 crc->first_uid = uid;
346 crc->offset++;
347 break; 347 break;
348 case RP_GET_MULTIPLE_NEXT: 348 case RP_GET_MULTIPLE_NEXT:
349 GNUNET_assert (uid != crc->first_uid); 349 GNUNET_assert (uid != crc->first_uid);
@@ -354,8 +354,6 @@ check_multiple (void *cls,
354 crc->phase = RP_ERROR; 354 crc->phase = RP_ERROR;
355 break; 355 break;
356 } 356 }
357 if (priority == get_priority (42))
358 crc->uid = uid;
359 GNUNET_SCHEDULER_add_now (&run_continuation, crc); 357 GNUNET_SCHEDULER_add_now (&run_continuation, crc);
360} 358}
361 359
@@ -400,7 +398,8 @@ run_continuation (void *cls)
400 sizeof (int), 398 sizeof (int),
401 &crc->key); 399 &crc->key);
402 GNUNET_DATASTORE_get_key (datastore, 400 GNUNET_DATASTORE_get_key (datastore,
403 crc->offset, 401 0,
402 false,
404 &crc->key, 403 &crc->key,
405 get_type (crc->i), 404 get_type (crc->i),
406 1, 405 1,
@@ -417,7 +416,8 @@ run_continuation (void *cls)
417 GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key); 416 GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
418 GNUNET_assert (NULL != 417 GNUNET_assert (NULL !=
419 GNUNET_DATASTORE_get_key (datastore, 418 GNUNET_DATASTORE_get_key (datastore,
420 crc->offset, 419 0,
420 false,
421 &crc->key, 421 &crc->key,
422 get_type (crc->i), 422 get_type (crc->i),
423 1, 423 1,
@@ -450,9 +450,15 @@ run_continuation (void *cls)
450 crc->i); 450 crc->i);
451 GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key); 451 GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
452 GNUNET_assert (NULL != 452 GNUNET_assert (NULL !=
453 GNUNET_DATASTORE_get_key (datastore, crc->offset, &crc->key, 453 GNUNET_DATASTORE_get_key (datastore,
454 get_type (crc->i), 1, 1, 454 0,
455 &check_nothing, crc)); 455 false,
456 &crc->key,
457 get_type (crc->i),
458 1,
459 1,
460 &check_nothing,
461 crc));
456 break; 462 break;
457 case RP_RESERVE: 463 case RP_RESERVE:
458 crc->phase = RP_PUT_MULTIPLE; 464 crc->phase = RP_PUT_MULTIPLE;
@@ -483,19 +489,26 @@ run_continuation (void *cls)
483 case RP_GET_MULTIPLE: 489 case RP_GET_MULTIPLE:
484 GNUNET_assert (NULL != 490 GNUNET_assert (NULL !=
485 GNUNET_DATASTORE_get_key (datastore, 491 GNUNET_DATASTORE_get_key (datastore,
486 crc->offset, 492 0,
493 false,
487 &crc->key, 494 &crc->key,
488 get_type (42), 1, 1, 495 get_type (42),
489 &check_multiple, crc)); 496 1,
497 1,
498 &check_multiple,
499 crc));
490 break; 500 break;
491 case RP_GET_MULTIPLE_NEXT: 501 case RP_GET_MULTIPLE_NEXT:
492 GNUNET_assert (NULL != 502 GNUNET_assert (NULL !=
493 GNUNET_DATASTORE_get_key (datastore, 503 GNUNET_DATASTORE_get_key (datastore,
494 crc->offset, 504 crc->first_uid + 1,
505 false,
495 &crc->key, 506 &crc->key,
496 get_type (42), 507 get_type (42),
497 1, 1, 508 1,
498 &check_multiple, crc)); 509 1,
510 &check_multiple,
511 crc));
499 break; 512 break;
500 case RP_DONE: 513 case RP_DONE:
501 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
diff --git a/src/datastore/test_datastore_api_management.c b/src/datastore/test_datastore_api_management.c
index 9a3e5446b..e50b98909 100644
--- a/src/datastore/test_datastore_api_management.c
+++ b/src/datastore/test_datastore_api_management.c
@@ -58,7 +58,6 @@ struct CpsRunContext
58 const struct GNUNET_CONFIGURATION_Handle *cfg; 58 const struct GNUNET_CONFIGURATION_Handle *cfg;
59 void *data; 59 void *data;
60 enum RunPhase phase; 60 enum RunPhase phase;
61 uint64_t offset;
62}; 61};
63 62
64 63
@@ -138,9 +137,15 @@ check_success (void *cls, int success, struct GNUNET_TIME_Absolute min_expiratio
138 137
139 138
140static void 139static void
141check_value (void *cls, const struct GNUNET_HashCode * key, size_t size, 140check_value (void *cls,
142 const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, 141 const struct GNUNET_HashCode *key,
143 uint32_t anonymity, struct GNUNET_TIME_Absolute expiration, 142 size_t size,
143 const void *data,
144 enum GNUNET_BLOCK_Type type,
145 uint32_t priority,
146 uint32_t anonymity,
147 uint32_t replication,
148 struct GNUNET_TIME_Absolute expiration,
144 uint64_t uid) 149 uint64_t uid)
145{ 150{
146 struct CpsRunContext *crc = cls; 151 struct CpsRunContext *crc = cls;
@@ -159,7 +164,6 @@ check_value (void *cls, const struct GNUNET_HashCode * key, size_t size,
159 GNUNET_assert (priority == get_priority (i)); 164 GNUNET_assert (priority == get_priority (i));
160 GNUNET_assert (anonymity == get_anonymity (i)); 165 GNUNET_assert (anonymity == get_anonymity (i));
161 GNUNET_assert (expiration.abs_value_us == get_expiration (i).abs_value_us); 166 GNUNET_assert (expiration.abs_value_us == get_expiration (i).abs_value_us);
162 crc->offset++;
163 crc->i--; 167 crc->i--;
164 if (crc->i == 0) 168 if (crc->i == 0)
165 crc->phase = RP_DONE; 169 crc->phase = RP_DONE;
@@ -168,9 +172,15 @@ check_value (void *cls, const struct GNUNET_HashCode * key, size_t size,
168 172
169 173
170static void 174static void
171check_nothing (void *cls, const struct GNUNET_HashCode * key, size_t size, 175check_nothing (void *cls,
172 const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, 176 const struct GNUNET_HashCode *key,
173 uint32_t anonymity, struct GNUNET_TIME_Absolute expiration, 177 size_t size,
178 const void *data,
179 enum GNUNET_BLOCK_Type type,
180 uint32_t priority,
181 uint32_t anonymity,
182 uint32_t replication,
183 struct GNUNET_TIME_Absolute expiration,
174 uint64_t uid) 184 uint64_t uid)
175{ 185{
176 struct CpsRunContext *crc = cls; 186 struct CpsRunContext *crc = cls;
@@ -221,8 +231,13 @@ run_continuation (void *cls)
221 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "GET", 231 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "GET",
222 crc->i); 232 crc->i);
223 GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key); 233 GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
224 GNUNET_DATASTORE_get_key (datastore, crc->offset++, &crc->key, 234 GNUNET_DATASTORE_get_key (datastore,
225 get_type (crc->i), 1, 1, 235 0,
236 false,
237 &crc->key,
238 get_type (crc->i),
239 1,
240 1,
226 &check_value, 241 &check_value,
227 crc); 242 crc);
228 break; 243 break;
@@ -230,8 +245,13 @@ run_continuation (void *cls)
230 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "GET(f)", 245 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "GET(f)",
231 crc->i); 246 crc->i);
232 GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key); 247 GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key);
233 GNUNET_DATASTORE_get_key (datastore, crc->offset++, &crc->key, 248 GNUNET_DATASTORE_get_key (datastore,
234 get_type (crc->i), 1, 1, 249 0,
250 false,
251 &crc->key,
252 get_type (crc->i),
253 1,
254 1,
235 &check_nothing, 255 &check_nothing,
236 crc); 256 crc);
237 break; 257 break;
diff --git a/src/datastore/test_plugin_datastore.c b/src/datastore/test_plugin_datastore.c
index 9b85d57da..1867d6755 100644
--- a/src/datastore/test_plugin_datastore.c
+++ b/src/datastore/test_plugin_datastore.c
@@ -64,7 +64,6 @@ struct CpsRunContext
64 enum RunPhase phase; 64 enum RunPhase phase;
65 unsigned int cnt; 65 unsigned int cnt;
66 unsigned int i; 66 unsigned int i;
67 uint64_t offset;
68}; 67};
69 68
70 69
@@ -194,6 +193,7 @@ iterate_one_shot (void *cls,
194 enum GNUNET_BLOCK_Type type, 193 enum GNUNET_BLOCK_Type type,
195 uint32_t priority, 194 uint32_t priority,
196 uint32_t anonymity, 195 uint32_t anonymity,
196 uint32_t replication,
197 struct GNUNET_TIME_Absolute expiration, 197 struct GNUNET_TIME_Absolute expiration,
198 uint64_t uid) 198 uint64_t uid)
199{ 199{
@@ -308,7 +308,8 @@ test (void *cls)
308 "Looking for %s\n", 308 "Looking for %s\n",
309 GNUNET_h2s (&key)); 309 GNUNET_h2s (&key));
310 crc->api->get_key (crc->api->cls, 310 crc->api->get_key (crc->api->cls,
311 crc->offset++, 311 0,
312 false,
312 &key, 313 &key,
313 NULL, 314 NULL,
314 GNUNET_BLOCK_TYPE_ANY, 315 GNUNET_BLOCK_TYPE_ANY,
@@ -317,11 +318,12 @@ test (void *cls)
317 break; 318 break;
318 case RP_UPDATE: 319 case RP_UPDATE:
319 crc->api->update (crc->api->cls, 320 crc->api->update (crc->api->cls,
320 guid, 321 guid,
321 1, 322 1,
322 GNUNET_TIME_UNIT_ZERO_ABS, 323 1,
324 GNUNET_TIME_UNIT_ZERO_ABS,
323 &update_continuation, 325 &update_continuation,
324 crc); 326 crc);
325 break; 327 break;
326 328
327 case RP_ITER_ZERO: 329 case RP_ITER_ZERO:
diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c
index ee208b50e..42ddc7b60 100644
--- a/src/dht/dht_api.c
+++ b/src/dht/dht_api.c
@@ -319,7 +319,7 @@ send_get_known_results (struct GNUNET_DHT_GetHandle *gh,
319 unsigned int max; 319 unsigned int max;
320 unsigned int transmission_offset; 320 unsigned int transmission_offset;
321 321
322 max = (GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*msg)) 322 max = (GNUNET_MAX_MESSAGE_SIZE - sizeof (*msg))
323 / sizeof (struct GNUNET_HashCode); 323 / sizeof (struct GNUNET_HashCode);
324 transmission_offset = transmission_offset_start; 324 transmission_offset = transmission_offset_start;
325 while (transmission_offset < gh->seen_results_end) 325 while (transmission_offset < gh->seen_results_end)
@@ -704,9 +704,9 @@ check_client_result (void *cls,
704 sizeof (struct GNUNET_PeerIdentity) * (get_path_length + put_path_length); 704 sizeof (struct GNUNET_PeerIdentity) * (get_path_length + put_path_length);
705 if ( (msize < meta_length) || 705 if ( (msize < meta_length) ||
706 (get_path_length > 706 (get_path_length >
707 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)) || 707 GNUNET_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)) ||
708 (put_path_length > 708 (put_path_length >
709 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)) ) 709 GNUNET_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)) )
710 { 710 {
711 GNUNET_break (0); 711 GNUNET_break (0);
712 return GNUNET_SYSERR; 712 return GNUNET_SYSERR;
@@ -998,8 +998,8 @@ GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle,
998 struct GNUNET_DHT_PutHandle *ph; 998 struct GNUNET_DHT_PutHandle *ph;
999 999
1000 msize = sizeof (struct GNUNET_DHT_ClientPutMessage) + size; 1000 msize = sizeof (struct GNUNET_DHT_ClientPutMessage) + size;
1001 if ((msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || 1001 if ((msize >= GNUNET_MAX_MESSAGE_SIZE) ||
1002 (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)) 1002 (size >= GNUNET_MAX_MESSAGE_SIZE))
1003 { 1003 {
1004 GNUNET_break (0); 1004 GNUNET_break (0);
1005 return NULL; 1005 return NULL;
@@ -1090,8 +1090,8 @@ GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle,
1090 size_t msize; 1090 size_t msize;
1091 1091
1092 msize = sizeof (struct GNUNET_DHT_ClientGetMessage) + xquery_size; 1092 msize = sizeof (struct GNUNET_DHT_ClientGetMessage) + xquery_size;
1093 if ((msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || 1093 if ((msize >= GNUNET_MAX_MESSAGE_SIZE) ||
1094 (xquery_size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)) 1094 (xquery_size >= GNUNET_MAX_MESSAGE_SIZE))
1095 { 1095 {
1096 GNUNET_break (0); 1096 GNUNET_break (0);
1097 return NULL; 1097 return NULL;
diff --git a/src/dht/gnunet-dht-get.c b/src/dht/gnunet-dht-get.c
index ce479dc3e..67f0ce76d 100644
--- a/src/dht/gnunet-dht-get.c
+++ b/src/dht/gnunet-dht-get.c
@@ -50,7 +50,7 @@ static struct GNUNET_TIME_Relative timeout_request = { 60000 };
50/** 50/**
51 * Be verbose 51 * Be verbose
52 */ 52 */
53static int verbose; 53static unsigned int verbose;
54 54
55/** 55/**
56 * Use DHT demultixplex_everywhere 56 * Use DHT demultixplex_everywhere
@@ -226,33 +226,6 @@ run (void *cls, char *const *args, const char *cfgfile,
226 226
227} 227}
228 228
229
230/**
231 * gnunet-dht-get command line options
232 */
233static struct GNUNET_GETOPT_CommandLineOption options[] = {
234 {'k', "key", "KEY",
235 gettext_noop ("the query key"),
236 1, &GNUNET_GETOPT_set_string, &query_key},
237 {'r', "replication", "LEVEL",
238 gettext_noop ("how many parallel requests (replicas) to create"),
239 1, &GNUNET_GETOPT_set_uint, &replication},
240 {'t', "type", "TYPE",
241 gettext_noop ("the type of data to look for"),
242 1, &GNUNET_GETOPT_set_uint, &query_type},
243 {'T', "timeout", "TIMEOUT",
244 gettext_noop ("how long to execute this query before giving up?"),
245 1, &GNUNET_GETOPT_set_relative_time, &timeout_request},
246 {'x', "demultiplex", NULL,
247 gettext_noop ("use DHT's demultiplex everywhere option"),
248 0, &GNUNET_GETOPT_set_one, &demultixplex_everywhere},
249 {'V', "verbose", NULL,
250 gettext_noop ("be verbose (print progress information)"),
251 0, &GNUNET_GETOPT_set_one, &verbose},
252 GNUNET_GETOPT_OPTION_END
253};
254
255
256/** 229/**
257 * Entry point for gnunet-dht-get 230 * Entry point for gnunet-dht-get
258 * 231 *
@@ -263,6 +236,45 @@ static struct GNUNET_GETOPT_CommandLineOption options[] = {
263int 236int
264main (int argc, char *const *argv) 237main (int argc, char *const *argv)
265{ 238{
239
240 struct GNUNET_GETOPT_CommandLineOption options[] = {
241
242 GNUNET_GETOPT_OPTION_STRING ('k',
243 "key",
244 "KEY",
245 gettext_noop ("the query key"),
246 &query_key),
247
248 GNUNET_GETOPT_OPTION_SET_UINT ('r',
249 "replication",
250 "LEVEL",
251 gettext_noop ("how many parallel requests (replicas) to create"),
252 &replication),
253
254
255 GNUNET_GETOPT_OPTION_SET_UINT ('t',
256 "type",
257 "TYPE",
258 gettext_noop ("the type of data to look for"),
259 &query_type),
260
261 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('T',
262 "timeout",
263 "TIMEOUT",
264 gettext_noop ("how long to execute this query before giving up?"),
265 &timeout_request),
266
267 GNUNET_GETOPT_OPTION_SET_ONE ('x',
268 "demultiplex",
269 gettext_noop ("use DHT's demultiplex everywhere option"),
270 &demultixplex_everywhere),
271
272 GNUNET_GETOPT_OPTION_VERBOSE (&verbose),
273 GNUNET_GETOPT_OPTION_END
274 };
275
276
277
266 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 278 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
267 return 2; 279 return 2;
268 return (GNUNET_OK == 280 return (GNUNET_OK ==
diff --git a/src/dht/gnunet-dht-monitor.c b/src/dht/gnunet-dht-monitor.c
index 7f14255d3..e4e8c46a1 100644
--- a/src/dht/gnunet-dht-monitor.c
+++ b/src/dht/gnunet-dht-monitor.c
@@ -280,27 +280,6 @@ run (void *cls, char *const *args, const char *cfgfile,
280 NULL); 280 NULL);
281} 281}
282 282
283
284/**
285 * gnunet-dht-monitor command line options
286 */
287static struct GNUNET_GETOPT_CommandLineOption options[] = {
288 {'k', "key", "KEY",
289 gettext_noop ("the query key"),
290 1, &GNUNET_GETOPT_set_string, &query_key},
291 {'t', "type", "TYPE",
292 gettext_noop ("the type of data to look for"),
293 1, &GNUNET_GETOPT_set_uint, &block_type},
294 {'T', "timeout", "TIMEOUT",
295 gettext_noop ("how long should the monitor command run"),
296 1, &GNUNET_GETOPT_set_relative_time, &timeout_request},
297 {'V', "verbose", NULL,
298 gettext_noop ("be verbose (print progress information)"),
299 0, &GNUNET_GETOPT_set_one, &verbose},
300 GNUNET_GETOPT_OPTION_END
301};
302
303
304/** 283/**
305 * Entry point for gnunet-dht-monitor 284 * Entry point for gnunet-dht-monitor
306 * 285 *
@@ -311,6 +290,35 @@ static struct GNUNET_GETOPT_CommandLineOption options[] = {
311int 290int
312main (int argc, char *const *argv) 291main (int argc, char *const *argv)
313{ 292{
293 struct GNUNET_GETOPT_CommandLineOption options[] = {
294
295 GNUNET_GETOPT_OPTION_STRING ('k',
296 "key",
297 "KEY",
298 gettext_noop ("the query key"),
299 &query_key),
300
301 GNUNET_GETOPT_OPTION_SET_UINT ('t',
302 "type",
303 "TYPE",
304 gettext_noop ("the type of data to look for"),
305 &block_type),
306
307 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('T',
308 "timeout",
309 "TIMEOUT",
310 gettext_noop ("how long should the monitor command run"),
311 &timeout_request),
312
313 GNUNET_GETOPT_OPTION_SET_ONE ('V',
314 "verbose",
315 gettext_noop ("be verbose (print progress information)"),
316 &verbose),
317
318 GNUNET_GETOPT_OPTION_END
319 };
320
321
314 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 322 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
315 return 2; 323 return 2;
316 324
diff --git a/src/dht/gnunet-dht-put.c b/src/dht/gnunet-dht-put.c
index a44e49d70..bf88e5ded 100644
--- a/src/dht/gnunet-dht-put.c
+++ b/src/dht/gnunet-dht-put.c
@@ -54,7 +54,7 @@ static unsigned int replication = 5;
54/** 54/**
55 * Be verbose 55 * Be verbose
56 */ 56 */
57static int verbose; 57static unsigned int verbose;
58 58
59/** 59/**
60 * Use #GNUNET_DHT_DEMULTIPLEX_EVERYWHERE. 60 * Use #GNUNET_DHT_DEMULTIPLEX_EVERYWHERE.
@@ -191,39 +191,6 @@ run (void *cls,
191 NULL); 191 NULL);
192} 192}
193 193
194
195/**
196 * gnunet-dht-put command line options
197 */
198static struct GNUNET_GETOPT_CommandLineOption options[] = {
199 {'d', "data", "DATA",
200 gettext_noop ("the data to insert under the key"),
201 1, &GNUNET_GETOPT_set_string, &data},
202 {'e', "expiration", "EXPIRATION",
203 gettext_noop ("how long to store this entry in the dht (in seconds)"),
204 1, &GNUNET_GETOPT_set_relative_time, &expiration},
205 {'k', "key", "KEY",
206 gettext_noop ("the query key"),
207 1, &GNUNET_GETOPT_set_string, &query_key},
208 {'x', "demultiplex", NULL,
209 gettext_noop ("use DHT's demultiplex everywhere option"),
210 0, &GNUNET_GETOPT_set_one, &demultixplex_everywhere},
211 {'r', "replication", "LEVEL",
212 gettext_noop ("how many replicas to create"),
213 1, &GNUNET_GETOPT_set_uint, &replication},
214 {'R', "record", NULL,
215 gettext_noop ("use DHT's record route option"),
216 0, &GNUNET_GETOPT_set_one, &record_route},
217 {'t', "type", "TYPE",
218 gettext_noop ("the type to insert data as"),
219 1, &GNUNET_GETOPT_set_uint, &query_type},
220 {'V', "verbose", NULL,
221 gettext_noop ("be verbose (print progress information)"),
222 0, &GNUNET_GETOPT_set_one, &verbose},
223 GNUNET_GETOPT_OPTION_END
224};
225
226
227/** 194/**
228 * Entry point for gnunet-dht-put 195 * Entry point for gnunet-dht-put
229 * 196 *
@@ -234,6 +201,55 @@ static struct GNUNET_GETOPT_CommandLineOption options[] = {
234int 201int
235main (int argc, char *const *argv) 202main (int argc, char *const *argv)
236{ 203{
204
205 struct GNUNET_GETOPT_CommandLineOption options[] = {
206
207 GNUNET_GETOPT_OPTION_STRING ('d',
208 "data",
209 "DATA",
210 gettext_noop ("the data to insert under the key"),
211 &data),
212
213 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('e',
214 "expiration",
215 "EXPIRATION",
216 gettext_noop ("how long to store this entry in the dht (in seconds)"),
217 &expiration),
218
219 GNUNET_GETOPT_OPTION_STRING ('k',
220 "key",
221 "KEY",
222 gettext_noop ("the query key"),
223 &query_key),
224
225 GNUNET_GETOPT_OPTION_SET_ONE ('x',
226 "demultiplex",
227 gettext_noop ("use DHT's demultiplex everywhere option"),
228 &demultixplex_everywhere),
229
230 GNUNET_GETOPT_OPTION_SET_UINT ('r',
231 "replication",
232 "LEVEL",
233 gettext_noop ("how many replicas to create"),
234 &replication),
235
236 GNUNET_GETOPT_OPTION_SET_ONE ('R',
237 "record",
238 gettext_noop ("use DHT's record route option"),
239 &record_route),
240
241 GNUNET_GETOPT_OPTION_SET_UINT ('t',
242 "type",
243 "TYPE",
244 gettext_noop ("the type to insert data as"),
245 &query_type),
246
247 GNUNET_GETOPT_OPTION_VERBOSE (&verbose),
248
249 GNUNET_GETOPT_OPTION_END
250 };
251
252
237 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, 253 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv,
238 &argc, &argv)) 254 &argc, &argv))
239 return 2; 255 return 2;
diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c
index 0f521a401..cb155c484 100644
--- a/src/dht/gnunet-service-dht_clients.c
+++ b/src/dht/gnunet-service-dht_clients.c
@@ -1166,7 +1166,7 @@ GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration,
1166 1166
1167 msize = sizeof (struct GNUNET_DHT_ClientResultMessage) + data_size + 1167 msize = sizeof (struct GNUNET_DHT_ClientResultMessage) + data_size +
1168 (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity); 1168 (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity);
1169 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 1169 if (msize >= GNUNET_MAX_MESSAGE_SIZE)
1170 { 1170 {
1171 GNUNET_break (0); 1171 GNUNET_break (0);
1172 return; 1172 return;
diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c
index fef637cad..36047d561 100644
--- a/src/dht/gnunet-service-dht_datacache.c
+++ b/src/dht/gnunet-service-dht_datacache.c
@@ -72,7 +72,7 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
72 _("%s request received, but have no datacache!\n"), "PUT"); 72 _("%s request received, but have no datacache!\n"), "PUT");
73 return; 73 return;
74 } 74 }
75 if (data_size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 75 if (data_size >= GNUNET_MAX_MESSAGE_SIZE)
76 { 76 {
77 GNUNET_break (0); 77 GNUNET_break (0);
78 return; 78 return;
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c
index 15071edca..0309bea88 100644
--- a/src/dht/gnunet-service-dht_neighbours.c
+++ b/src/dht/gnunet-service-dht_neighbours.c
@@ -1423,7 +1423,7 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
1423 UINT32_MAX); 1423 UINT32_MAX);
1424 } 1424 }
1425 msize = xquery_size + reply_bf_size; 1425 msize = xquery_size + reply_bf_size;
1426 if (msize + sizeof (struct PeerGetMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 1426 if (msize + sizeof (struct PeerGetMessage) >= GNUNET_MAX_MESSAGE_SIZE)
1427 { 1427 {
1428 GNUNET_break (0); 1428 GNUNET_break (0);
1429 GNUNET_free_non_null (reply_bf); 1429 GNUNET_free_non_null (reply_bf);
@@ -1522,12 +1522,12 @@ GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target,
1522 1522
1523 msize = data_size + (get_path_length + put_path_length) * 1523 msize = data_size + (get_path_length + put_path_length) *
1524 sizeof (struct GNUNET_PeerIdentity); 1524 sizeof (struct GNUNET_PeerIdentity);
1525 if ((msize + sizeof (struct PeerResultMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || 1525 if ((msize + sizeof (struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) ||
1526 (get_path_length > 1526 (get_path_length >
1527 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)) || 1527 GNUNET_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)) ||
1528 (put_path_length > 1528 (put_path_length >
1529 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)) || 1529 GNUNET_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)) ||
1530 (data_size > GNUNET_SERVER_MAX_MESSAGE_SIZE)) 1530 (data_size > GNUNET_MAX_MESSAGE_SIZE))
1531 { 1531 {
1532 GNUNET_break (0); 1532 GNUNET_break (0);
1533 return; 1533 return;
@@ -1627,7 +1627,7 @@ check_dht_p2p_put (void *cls,
1627 sizeof (struct PeerPutMessage) + 1627 sizeof (struct PeerPutMessage) +
1628 putlen * sizeof (struct GNUNET_PeerIdentity)) || 1628 putlen * sizeof (struct GNUNET_PeerIdentity)) ||
1629 (putlen > 1629 (putlen >
1630 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))) 1630 GNUNET_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
1631 { 1631 {
1632 GNUNET_break_op (0); 1632 GNUNET_break_op (0);
1633 return GNUNET_SYSERR; 1633 return GNUNET_SYSERR;
@@ -2213,9 +2213,9 @@ check_dht_p2p_result (void *cls,
2213 put_path_length) * 2213 put_path_length) *
2214 sizeof (struct GNUNET_PeerIdentity)) || 2214 sizeof (struct GNUNET_PeerIdentity)) ||
2215 (get_path_length > 2215 (get_path_length >
2216 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)) || 2216 GNUNET_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)) ||
2217 (put_path_length > 2217 (put_path_length >
2218 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))) 2218 GNUNET_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2219 { 2219 {
2220 GNUNET_break_op (0); 2220 GNUNET_break_op (0);
2221 return GNUNET_SYSERR; 2221 return GNUNET_SYSERR;
diff --git a/src/dht/gnunet_dht_profiler.c b/src/dht/gnunet_dht_profiler.c
index 460eaa572..f65141640 100644
--- a/src/dht/gnunet_dht_profiler.c
+++ b/src/dht/gnunet_dht_profiler.c
@@ -1181,31 +1181,54 @@ main (int argc, char *const *argv)
1181{ 1181{
1182 int rc; 1182 int rc;
1183 1183
1184 static struct GNUNET_GETOPT_CommandLineOption options[] = { 1184 struct GNUNET_GETOPT_CommandLineOption options[] = {
1185 {'n', "peers", "COUNT", 1185 GNUNET_GETOPT_OPTION_SET_UINT ('n',
1186 gettext_noop ("number of peers to start"), 1186 "peers",
1187 1, &GNUNET_GETOPT_set_uint, &num_peers}, 1187 "COUNT",
1188 {'s', "searches", "COUNT", 1188 gettext_noop ("number of peers to start"),
1189 gettext_noop ("maximum number of times we try to search for successor circle formation (0 for R5N)"), 1189 &num_peers),
1190 1, &GNUNET_GETOPT_set_uint, &max_searches}, 1190
1191 {'H', "hosts", "FILENAME", 1191 GNUNET_GETOPT_OPTION_SET_UINT ('s',
1192 gettext_noop ("name of the file with the login information for the testbed"), 1192 "searches",
1193 1, &GNUNET_GETOPT_set_string, &hosts_file}, 1193 "COUNT",
1194 {'D', "delay", "DELAY", 1194 gettext_noop ("maximum number of times we try to search for successor circle formation (0 for R5N)"),
1195 gettext_noop ("delay between rounds for collecting statistics (default: 30 sec)"), 1195 &max_searches),
1196 1, &GNUNET_GETOPT_set_relative_time, &delay_stats}, 1196
1197 {'P', "PUT-delay", "DELAY", 1197 GNUNET_GETOPT_OPTION_STRING ('H',
1198 gettext_noop ("delay to start doing PUTs (default: 1 sec)"), 1198 "hosts",
1199 1, &GNUNET_GETOPT_set_relative_time, &delay_put}, 1199 "FILENAME",
1200 {'G', "GET-delay", "DELAY", 1200 gettext_noop ("name of the file with the login information for the testbed"),
1201 gettext_noop ("delay to start doing GETs (default: 5 min)"), 1201 &hosts_file),
1202 1, &GNUNET_GETOPT_set_relative_time, &delay_get}, 1202
1203 {'r', "replication", "DEGREE", 1203 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('D',
1204 gettext_noop ("replication degree for DHT PUTs"), 1204 "delay",
1205 1, &GNUNET_GETOPT_set_uint, &replication}, 1205 "DELAY",
1206 {'t', "timeout", "TIMEOUT", 1206 gettext_noop ("delay between rounds for collecting statistics (default: 30 sec)"),
1207 gettext_noop ("timeout for DHT PUT and GET requests (default: 1 min)"), 1207 &delay_stats),
1208 1, &GNUNET_GETOPT_set_relative_time, &timeout}, 1208
1209 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('P',
1210 "PUT-delay",
1211 "DELAY",
1212 gettext_noop ("delay to start doing PUTs (default: 1 sec)"),
1213 &delay_put),
1214
1215 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('G',
1216 "GET-delay",
1217 "DELAY",
1218 gettext_noop ("delay to start doing GETs (default: 5 min)"),
1219 &delay_get),
1220 GNUNET_GETOPT_OPTION_SET_UINT ('r',
1221 "replication",
1222 "DEGREE",
1223 gettext_noop ("replication degree for DHT PUTs"),
1224 &replication),
1225
1226
1227 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('t',
1228 "timeout",
1229 "TIMEOUT",
1230 gettext_noop ("timeout for DHT PUT and GET requests (default: 1 min)"),
1231 &timeout),
1209 GNUNET_GETOPT_OPTION_END 1232 GNUNET_GETOPT_OPTION_END
1210 }; 1233 };
1211 1234
diff --git a/src/dns/dns_api.c b/src/dns/dns_api.c
index e7450a1d4..9f0dee9a9 100644
--- a/src/dns/dns_api.c
+++ b/src/dns/dns_api.c
@@ -317,7 +317,7 @@ GNUNET_DNS_request_answer (struct GNUNET_DNS_RequestHandle *rh,
317 return; 317 return;
318 } 318 }
319 if (reply_length + sizeof (struct GNUNET_DNS_Response) 319 if (reply_length + sizeof (struct GNUNET_DNS_Response)
320 >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 320 >= GNUNET_MAX_MESSAGE_SIZE)
321 { 321 {
322 GNUNET_break (0); 322 GNUNET_break (0);
323 GNUNET_free (rh); 323 GNUNET_free (rh);
diff --git a/src/dns/gnunet-dns-monitor.c b/src/dns/gnunet-dns-monitor.c
index 5e6f90555..2436931fb 100644
--- a/src/dns/gnunet-dns-monitor.c
+++ b/src/dns/gnunet-dns-monitor.c
@@ -52,7 +52,7 @@ static int ret;
52/** 52/**
53 * Selected level of verbosity. 53 * Selected level of verbosity.
54 */ 54 */
55static int verbosity; 55static unsigned int verbosity;
56 56
57 57
58/** 58/**
@@ -346,13 +346,18 @@ run (void *cls, char *const *args, const char *cfgfile,
346int 346int
347main (int argc, char *const *argv) 347main (int argc, char *const *argv)
348{ 348{
349 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 349 struct GNUNET_GETOPT_CommandLineOption options[] = {
350 {'i', "inbound-only", NULL, 350
351 gettext_noop ("only monitor DNS queries"), 351 GNUNET_GETOPT_OPTION_SET_ONE ('i',
352 0, &GNUNET_GETOPT_set_one, &inbound_only}, 352 "inbound-only",
353 {'o', "outbound-only", NULL, 353 gettext_noop ("only monitor DNS queries"),
354 gettext_noop ("only monitor DNS replies"), 354 &inbound_only),
355 0, &GNUNET_GETOPT_set_one, &outbound_only}, 355
356 GNUNET_GETOPT_OPTION_SET_ONE ('o',
357 "outbound-only",
358 gettext_noop ("only monitor DNS queries"),
359 &outbound_only),
360
356 GNUNET_GETOPT_OPTION_VERBOSE (&verbosity), 361 GNUNET_GETOPT_OPTION_VERBOSE (&verbosity),
357 GNUNET_GETOPT_OPTION_END 362 GNUNET_GETOPT_OPTION_END
358 }; 363 };
diff --git a/src/dns/gnunet-dns-redirector.c b/src/dns/gnunet-dns-redirector.c
index 89929815a..0469af732 100644
--- a/src/dns/gnunet-dns-redirector.c
+++ b/src/dns/gnunet-dns-redirector.c
@@ -52,7 +52,7 @@ static int ret;
52/** 52/**
53 * Selected level of verbosity. 53 * Selected level of verbosity.
54 */ 54 */
55static int verbosity; 55static unsigned int verbosity;
56 56
57 57
58/** 58/**
@@ -230,13 +230,19 @@ run (void *cls, char *const *args, const char *cfgfile,
230int 230int
231main (int argc, char *const *argv) 231main (int argc, char *const *argv)
232{ 232{
233 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 233 struct GNUNET_GETOPT_CommandLineOption options[] = {
234 {'4', "ipv4", "IPV4", 234 GNUNET_GETOPT_OPTION_STRING ('4',
235 gettext_noop ("set A records"), 235 "ipv4",
236 1, &GNUNET_GETOPT_set_string, &n4}, 236 "IPV4",
237 {'6', "ipv4", "IPV6", 237 gettext_noop ("set A records"),
238 gettext_noop ("set AAAA records"), 238 &n4),
239 1, &GNUNET_GETOPT_set_string, &n6}, 239
240 GNUNET_GETOPT_OPTION_STRING ('6',
241 "ipv4",
242 "IPV6",
243 gettext_noop ("set AAAA records"),
244 &n6),
245
240 GNUNET_GETOPT_OPTION_VERBOSE (&verbosity), 246 GNUNET_GETOPT_OPTION_VERBOSE (&verbosity),
241 GNUNET_GETOPT_OPTION_END 247 GNUNET_GETOPT_OPTION_END
242 }; 248 };
diff --git a/src/dns/gnunet-helper-dns.c b/src/dns/gnunet-helper-dns.c
index d083a9df2..5cf1967f5 100644
--- a/src/dns/gnunet-helper-dns.c
+++ b/src/dns/gnunet-helper-dns.c
@@ -79,7 +79,7 @@
79#include "gnunet_protocols.h" 79#include "gnunet_protocols.h"
80 80
81/** 81/**
82 * Maximum size of a GNUnet message (GNUNET_SERVER_MAX_MESSAGE_SIZE) 82 * Maximum size of a GNUnet message (GNUNET_MAX_MESSAGE_SIZE)
83 */ 83 */
84#define MAX_SIZE 65536 84#define MAX_SIZE 65536
85 85
diff --git a/src/dns/gnunet-service-dns.c b/src/dns/gnunet-service-dns.c
index 74f595c5e..ffc94afb7 100644
--- a/src/dns/gnunet-service-dns.c
+++ b/src/dns/gnunet-service-dns.c
@@ -347,7 +347,7 @@ request_done (struct RequestRecord *rr)
347 } 347 }
348 reply_len += sizeof (struct GNUNET_TUN_UdpHeader); 348 reply_len += sizeof (struct GNUNET_TUN_UdpHeader);
349 reply_len += rr->payload_length; 349 reply_len += rr->payload_length;
350 if (reply_len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 350 if (reply_len >= GNUNET_MAX_MESSAGE_SIZE)
351 { 351 {
352 /* response too big, drop */ 352 /* response too big, drop */
353 GNUNET_break (0); /* how can this be? */ 353 GNUNET_break (0); /* how can this be? */
@@ -481,7 +481,7 @@ send_request_to_client (struct RequestRecord *rr,
481 struct GNUNET_MQ_Envelope *env; 481 struct GNUNET_MQ_Envelope *env;
482 struct GNUNET_DNS_Request *req; 482 struct GNUNET_DNS_Request *req;
483 483
484 if (sizeof (struct GNUNET_DNS_Request) + rr->payload_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 484 if (sizeof (struct GNUNET_DNS_Request) + rr->payload_length >= GNUNET_MAX_MESSAGE_SIZE)
485 { 485 {
486 GNUNET_break (0); 486 GNUNET_break (0);
487 cleanup_rr (rr); 487 cleanup_rr (rr);
@@ -882,11 +882,10 @@ handle_client_response (void *cls,
882 * message is received by the tokenizer from the DNS hijack process. 882 * message is received by the tokenizer from the DNS hijack process.
883 * 883 *
884 * @param cls closure 884 * @param cls closure
885 * @param client identification of the client
886 * @param message the actual message, a DNS request we should handle 885 * @param message the actual message, a DNS request we should handle
887 */ 886 */
888static int 887static int
889process_helper_messages (void *cls GNUNET_UNUSED, void *client, 888process_helper_messages (void *cls,
890 const struct GNUNET_MessageHeader *message) 889 const struct GNUNET_MessageHeader *message)
891{ 890{
892 uint16_t msize; 891 uint16_t msize;
diff --git a/src/dv/dv_api.c b/src/dv/dv_api.c
index 062f9a95f..ab521ec1f 100644
--- a/src/dv/dv_api.c
+++ b/src/dv/dv_api.c
@@ -437,7 +437,7 @@ GNUNET_DV_send (struct GNUNET_DV_ServiceHandle *sh,
437 struct ConnectedPeer *peer; 437 struct ConnectedPeer *peer;
438 struct GNUNET_MQ_Envelope *env; 438 struct GNUNET_MQ_Envelope *env;
439 439
440 if (ntohs (msg->size) + sizeof (*sm) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 440 if (ntohs (msg->size) + sizeof (*sm) >= GNUNET_MAX_MESSAGE_SIZE)
441 { 441 {
442 GNUNET_break (0); 442 GNUNET_break (0);
443 return; 443 return;
diff --git a/src/dv/gnunet-dv.c b/src/dv/gnunet-dv.c
index d0917d363..cb40bb6d2 100644
--- a/src/dv/gnunet-dv.c
+++ b/src/dv/gnunet-dv.c
@@ -34,7 +34,7 @@ static struct GNUNET_DV_ServiceHandle *sh;
34/** 34/**
35 * Was verbose specified? 35 * Was verbose specified?
36 */ 36 */
37static int verbose; 37static unsigned int verbose;
38 38
39 39
40/** 40/**
@@ -161,10 +161,10 @@ main (int argc, char *const *argv)
161{ 161{
162 int res; 162 int res;
163 163
164 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 164 struct GNUNET_GETOPT_CommandLineOption options[] = {
165 {'V', "verbose", NULL, 165
166 gettext_noop ("verbose output"), 166 GNUNET_GETOPT_OPTION_VERBOSE (&verbose),
167 0, &GNUNET_GETOPT_set_one, &verbose}, 167
168 GNUNET_GETOPT_OPTION_END 168 GNUNET_GETOPT_OPTION_END
169 }; 169 };
170 170
diff --git a/src/dv/gnunet-service-dv.c b/src/dv/gnunet-service-dv.c
index 3fbd0cc03..fa1c16be8 100644
--- a/src/dv/gnunet-service-dv.c
+++ b/src/dv/gnunet-service-dv.c
@@ -399,7 +399,7 @@ send_data_to_plugin (const struct GNUNET_MessageHeader *message,
399 (unsigned int) distance); 399 (unsigned int) distance);
400 size = sizeof (struct GNUNET_DV_ReceivedMessage) + 400 size = sizeof (struct GNUNET_DV_ReceivedMessage) +
401 ntohs (message->size); 401 ntohs (message->size);
402 if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 402 if (size >= GNUNET_MAX_MESSAGE_SIZE)
403 { 403 {
404 GNUNET_break (0); /* too big */ 404 GNUNET_break (0); /* too big */
405 return; 405 return;
@@ -537,7 +537,7 @@ forward_payload (struct DirectNeighbor *target,
537 return; 537 return;
538 } 538 }
539 if (sizeof (struct RouteMessage) + ntohs (payload->size) 539 if (sizeof (struct RouteMessage) + ntohs (payload->size)
540 >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 540 >= GNUNET_MAX_MESSAGE_SIZE)
541 { 541 {
542 GNUNET_break (0); 542 GNUNET_break (0);
543 return; 543 return;
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c
index a32cb3086..2cd3441a1 100644
--- a/src/exit/gnunet-daemon-exit.c
+++ b/src/exit/gnunet-daemon-exit.c
@@ -979,7 +979,7 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
979 } 979 }
980 len += sizeof (struct GNUNET_TUN_TcpHeader); 980 len += sizeof (struct GNUNET_TUN_TcpHeader);
981 len += payload_length; 981 len += payload_length;
982 if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 982 if (len >= GNUNET_MAX_MESSAGE_SIZE)
983 { 983 {
984 GNUNET_break (0); 984 GNUNET_break (0);
985 return; 985 return;
@@ -1079,7 +1079,7 @@ send_icmp_packet_via_tun (const struct SocketAddress *destination_address,
1079 } 1079 }
1080 len += sizeof (struct GNUNET_TUN_IcmpHeader); 1080 len += sizeof (struct GNUNET_TUN_IcmpHeader);
1081 len += payload_length; 1081 len += payload_length;
1082 if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 1082 if (len >= GNUNET_MAX_MESSAGE_SIZE)
1083 { 1083 {
1084 GNUNET_break (0); 1084 GNUNET_break (0);
1085 return; 1085 return;
@@ -1358,7 +1358,7 @@ send_udp_packet_via_tun (const struct SocketAddress *destination_address,
1358 } 1358 }
1359 len += sizeof (struct GNUNET_TUN_UdpHeader); 1359 len += sizeof (struct GNUNET_TUN_UdpHeader);
1360 len += payload_length; 1360 len += payload_length;
1361 if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 1361 if (len >= GNUNET_MAX_MESSAGE_SIZE)
1362 { 1362 {
1363 GNUNET_break (0); 1363 GNUNET_break (0);
1364 return; 1364 return;
@@ -2884,7 +2884,7 @@ tcp_from_helper (const struct GNUNET_TUN_TcpHeader *tcp,
2884 mtcp->crc = 0; 2884 mtcp->crc = 0;
2885 2885
2886 mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof (struct GNUNET_TUN_TcpHeader)); 2886 mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof (struct GNUNET_TUN_TcpHeader));
2887 if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 2887 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2888 { 2888 {
2889 GNUNET_break (0); 2889 GNUNET_break (0);
2890 return; 2890 return;
@@ -2905,12 +2905,10 @@ tcp_from_helper (const struct GNUNET_TUN_TcpHeader *tcp,
2905 * Receive packets from the helper-process 2905 * Receive packets from the helper-process
2906 * 2906 *
2907 * @param cls unused 2907 * @param cls unused
2908 * @param client unsued
2909 * @param message message received from helper 2908 * @param message message received from helper
2910 */ 2909 */
2911static int 2910static int
2912message_token (void *cls GNUNET_UNUSED, 2911message_token (void *cls GNUNET_UNUSED,
2913 void *client GNUNET_UNUSED,
2914 const struct GNUNET_MessageHeader *message) 2912 const struct GNUNET_MessageHeader *message)
2915{ 2913{
2916 const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun; 2914 const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun;
diff --git a/src/exit/gnunet-helper-exit-windows.c b/src/exit/gnunet-helper-exit-windows.c
index 6be65ccd5..aa7a7a4a3 100644
--- a/src/exit/gnunet-helper-exit-windows.c
+++ b/src/exit/gnunet-helper-exit-windows.c
@@ -77,7 +77,7 @@
77static boolean privilege_testing = FALSE; 77static boolean privilege_testing = FALSE;
78 78
79/** 79/**
80 * Maximum size of a GNUnet message (GNUNET_SERVER_MAX_MESSAGE_SIZE) 80 * Maximum size of a GNUnet message (GNUNET_MAX_MESSAGE_SIZE)
81 */ 81 */
82#define MAX_SIZE 65536 82#define MAX_SIZE 65536
83 83
diff --git a/src/exit/gnunet-helper-exit.c b/src/exit/gnunet-helper-exit.c
index e14c6ca43..3c6f97557 100644
--- a/src/exit/gnunet-helper-exit.c
+++ b/src/exit/gnunet-helper-exit.c
@@ -62,7 +62,7 @@
62#define DEBUG GNUNET_NO 62#define DEBUG GNUNET_NO
63 63
64/** 64/**
65 * Maximum size of a GNUnet message (GNUNET_SERVER_MAX_MESSAGE_SIZE) 65 * Maximum size of a GNUnet message (GNUNET_MAX_MESSAGE_SIZE)
66 */ 66 */
67#define MAX_SIZE 65536 67#define MAX_SIZE 65536
68 68
diff --git a/src/fs/fs_api.h b/src/fs/fs_api.h
index e85de94a7..be22ea73e 100644
--- a/src/fs/fs_api.h
+++ b/src/fs/fs_api.h
@@ -1464,21 +1464,11 @@ struct GNUNET_FS_UnindexContext
1464 struct GNUNET_CRYPTO_FileHashContext *fhc; 1464 struct GNUNET_CRYPTO_FileHashContext *fhc;
1465 1465
1466 /** 1466 /**
1467 * Which values have we seen already?
1468 */
1469 struct GNUNET_CONTAINER_MultiHashMap *seen_dh;
1470
1471 /**
1472 * Overall size of the file. 1467 * Overall size of the file.
1473 */ 1468 */
1474 uint64_t file_size; 1469 uint64_t file_size;
1475 1470
1476 /** 1471 /**
1477 * Random offset given to #GNUNET_DATASTORE_get_key.
1478 */
1479 uint64_t roff;
1480
1481 /**
1482 * When did we start? 1472 * When did we start?
1483 */ 1473 */
1484 struct GNUNET_TIME_Absolute start_time; 1474 struct GNUNET_TIME_Absolute start_time;
diff --git a/src/fs/fs_dirmetascan.c b/src/fs/fs_dirmetascan.c
index 2f79c7c05..7b9f178fd 100644
--- a/src/fs/fs_dirmetascan.c
+++ b/src/fs/fs_dirmetascan.c
@@ -245,12 +245,10 @@ finish_scan (void *cls)
245 * Calls the scanner progress handler. 245 * Calls the scanner progress handler.
246 * 246 *
247 * @param cls the closure (directory scanner object) 247 * @param cls the closure (directory scanner object)
248 * @param client always NULL
249 * @param msg message from the helper process 248 * @param msg message from the helper process
250 */ 249 */
251static int 250static int
252process_helper_msgs (void *cls, 251process_helper_msgs (void *cls,
253 void *client,
254 const struct GNUNET_MessageHeader *msg) 252 const struct GNUNET_MessageHeader *msg)
255{ 253{
256 struct GNUNET_FS_DirScanner *ds = cls; 254 struct GNUNET_FS_DirScanner *ds = cls;
diff --git a/src/fs/fs_getopt.c b/src/fs/fs_getopt.c
index f78e311d3..bfe45957e 100644
--- a/src/fs/fs_getopt.c
+++ b/src/fs/fs_getopt.c
@@ -25,6 +25,7 @@
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_fs_service.h" 27#include "gnunet_fs_service.h"
28#include "gnunet_getopt_lib.h"
28#include "fs_api.h" 29#include "fs_api.h"
29 30
30/* ******************** command-line option parsing API ******************** */ 31/* ******************** command-line option parsing API ******************** */
@@ -41,10 +42,10 @@
41 * @param value command line argument given 42 * @param value command line argument given
42 * @return GNUNET_OK on success 43 * @return GNUNET_OK on success
43 */ 44 */
44int 45static int
45GNUNET_FS_getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext 46getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext
46 *ctx, void *scls, const char *option, 47 *ctx, void *scls, const char *option,
47 const char *value) 48 const char *value)
48{ 49{
49 struct GNUNET_FS_Uri **uri = scls; 50 struct GNUNET_FS_Uri **uri = scls;
50 struct GNUNET_FS_Uri *u = *uri; 51 struct GNUNET_FS_Uri *u = *uri;
@@ -107,6 +108,34 @@ GNUNET_FS_getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext
107 return GNUNET_OK; 108 return GNUNET_OK;
108} 109}
109 110
111/**
112 * Allow user to specify keywords.
113 *
114 * @param shortName short name of the option
115 * @param name long name of the option
116 * @param argumentHelp help text for the option argument
117 * @param description long help text for the option
118 * @param[out] topKeywords set to the desired value
119 */
120struct GNUNET_GETOPT_CommandLineOption
121GNUNET_FS_GETOPT_KEYWORDS (char shortName,
122 const char *name,
123 const char *argumentHelp,
124 const char *description,
125 struct GNUNET_FS_Uri **topKeywords)
126{
127 struct GNUNET_GETOPT_CommandLineOption clo = {
128 .shortName = shortName,
129 .name = name,
130 .argumentHelp = argumentHelp,
131 .description = description,
132 .require_argument = 1,
133 .processor = &getopt_set_keywords,
134 .scls = (void *) topKeywords
135 };
136
137 return clo;
138}
110 139
111/** 140/**
112 * Command-line option parser function that allows the user to specify 141 * Command-line option parser function that allows the user to specify
@@ -120,11 +149,11 @@ GNUNET_FS_getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext
120 * @param value command line argument given 149 * @param value command line argument given
121 * @return #GNUNET_OK on success 150 * @return #GNUNET_OK on success
122 */ 151 */
123int 152static int
124GNUNET_FS_getopt_set_metadata (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 153getopt_set_metadata (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
125 void *scls, 154 void *scls,
126 const char *option, 155 const char *option,
127 const char *value) 156 const char *value)
128{ 157{
129 struct GNUNET_CONTAINER_MetaData **mm = scls; 158 struct GNUNET_CONTAINER_MetaData **mm = scls;
130#if HAVE_EXTRACTOR_H && HAVE_LIBEXTRACTOR 159#if HAVE_EXTRACTOR_H && HAVE_LIBEXTRACTOR
@@ -200,4 +229,36 @@ GNUNET_FS_getopt_set_metadata (struct GNUNET_GETOPT_CommandLineProcessorContext
200 return GNUNET_OK; 229 return GNUNET_OK;
201} 230}
202 231
232/**
233 * Allow user to specify metadata.
234 *
235 * @param shortName short name of the option
236 * @param name long name of the option
237 * @param argumentHelp help text for the option argument
238 * @param description long help text for the option
239 * @param[out] metadata set to the desired value
240 */
241struct GNUNET_GETOPT_CommandLineOption
242GNUNET_FS_GETOPT_METADATA (char shortName,
243 const char *name,
244 const char *argumentHelp,
245 const char *description,
246 struct GNUNET_CONTAINER_MetaData **meta)
247{
248 struct GNUNET_GETOPT_CommandLineOption clo = {
249 .shortName = shortName,
250 .name = name,
251 .argumentHelp = argumentHelp,
252 .description = description,
253 .require_argument = 1,
254 .processor = &getopt_set_metadata,
255 .scls = (void *) meta
256 };
257
258 return clo;
259}
260
261
262
263
203/* end of fs_getopt.c */ 264/* end of fs_getopt.c */
diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c
index 86a58a58b..759467ba4 100644
--- a/src/fs/fs_publish.c
+++ b/src/fs/fs_publish.c
@@ -837,7 +837,7 @@ hash_for_index_cb (void *cls,
837 GNUNET_assert (fn != NULL); 837 GNUNET_assert (fn != NULL);
838 slen = strlen (fn) + 1; 838 slen = strlen (fn) + 1;
839 if (slen >= 839 if (slen >=
840 GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct IndexStartMessage)) 840 GNUNET_MAX_MESSAGE_SIZE - sizeof (struct IndexStartMessage))
841 { 841 {
842 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 842 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
843 _ 843 _
@@ -1226,7 +1226,7 @@ fip_signal_start (void *cls,
1226 { 1226 {
1227 kc = GNUNET_FS_uri_ksk_get_keyword_count (*uri); 1227 kc = GNUNET_FS_uri_ksk_get_keyword_count (*uri);
1228 pc->reserve_entries += kc; 1228 pc->reserve_entries += kc;
1229 pc->reserve_space += GNUNET_SERVER_MAX_MESSAGE_SIZE * kc; 1229 pc->reserve_space += GNUNET_MAX_MESSAGE_SIZE * kc;
1230 } 1230 }
1231 pi.status = GNUNET_FS_STATUS_PUBLISH_START; 1231 pi.status = GNUNET_FS_STATUS_PUBLISH_START;
1232 *client_info = GNUNET_FS_publish_make_status_ (&pi, pc, fi, 0); 1232 *client_info = GNUNET_FS_publish_make_status_ (&pi, pc, fi, 0);
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c
index 01e65ed57..8c6f5edcf 100644
--- a/src/fs/fs_search.c
+++ b/src/fs/fs_search.c
@@ -1121,7 +1121,7 @@ schedule_transmit_search_request (struct GNUNET_FS_SearchContext *sc)
1121 if (0 != (sc->options & GNUNET_FS_SEARCH_OPTION_LOOPBACK_ONLY)) 1121 if (0 != (sc->options & GNUNET_FS_SEARCH_OPTION_LOOPBACK_ONLY))
1122 options |= SEARCH_MESSAGE_OPTION_LOOPBACK_ONLY; 1122 options |= SEARCH_MESSAGE_OPTION_LOOPBACK_ONLY;
1123 1123
1124 fit = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (*sm)) / sizeof (struct GNUNET_HashCode); 1124 fit = (GNUNET_MAX_MESSAGE_SIZE - 1 - sizeof (*sm)) / sizeof (struct GNUNET_HashCode);
1125 todo = GNUNET_MIN (fit, 1125 todo = GNUNET_MIN (fit,
1126 left); 1126 left);
1127 env = GNUNET_MQ_msg_extra (sm, 1127 env = GNUNET_MQ_msg_extra (sm,
diff --git a/src/fs/fs_unindex.c b/src/fs/fs_unindex.c
index ad1499f00..e1c7ea535 100644
--- a/src/fs/fs_unindex.c
+++ b/src/fs/fs_unindex.c
@@ -312,8 +312,6 @@ unindex_finish (struct GNUNET_FS_UnindexContext *uc)
312 uc->fh = NULL; 312 uc->fh = NULL;
313 GNUNET_DATASTORE_disconnect (uc->dsh, GNUNET_NO); 313 GNUNET_DATASTORE_disconnect (uc->dsh, GNUNET_NO);
314 uc->dsh = NULL; 314 uc->dsh = NULL;
315 GNUNET_CONTAINER_multihashmap_destroy (uc->seen_dh);
316 uc->seen_dh = NULL;
317 uc->state = UNINDEX_STATE_FS_NOTIFY; 315 uc->state = UNINDEX_STATE_FS_NOTIFY;
318 GNUNET_FS_unindex_sync_ (uc); 316 GNUNET_FS_unindex_sync_ (uc);
319 uc->mq = GNUNET_CLIENT_connect (uc->h->cfg, 317 uc->mq = GNUNET_CLIENT_connect (uc->h->cfg,
@@ -444,7 +442,6 @@ continue_after_remove (void *cls,
444 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 442 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
445 _("Failed to remove UBlock: %s\n"), 443 _("Failed to remove UBlock: %s\n"),
446 msg); 444 msg);
447 GNUNET_CONTAINER_multihashmap_clear (uc->seen_dh);
448 uc->ksk_offset++; 445 uc->ksk_offset++;
449 GNUNET_FS_unindex_do_remove_kblocks_ (uc); 446 GNUNET_FS_unindex_do_remove_kblocks_ (uc);
450} 447}
@@ -486,34 +483,15 @@ process_kblock_for_unindex (void *cls,
486 const struct UBlock *ub; 483 const struct UBlock *ub;
487 struct GNUNET_FS_Uri *chk_uri; 484 struct GNUNET_FS_Uri *chk_uri;
488 struct GNUNET_HashCode query; 485 struct GNUNET_HashCode query;
489 struct GNUNET_HashCode dh;
490 486
491 uc->dqe = NULL; 487 uc->dqe = NULL;
492 if (NULL == data) 488 if (NULL == data)
493 { 489 {
494 /* no result */ 490 /* no result */
495 GNUNET_CONTAINER_multihashmap_clear (uc->seen_dh);
496 uc->ksk_offset++; 491 uc->ksk_offset++;
497 GNUNET_FS_unindex_do_remove_kblocks_ (uc); 492 GNUNET_FS_unindex_do_remove_kblocks_ (uc);
498 return; 493 return;
499 } 494 }
500 GNUNET_CRYPTO_hash (data,
501 size,
502 &dh);
503 if (GNUNET_YES ==
504 GNUNET_CONTAINER_multihashmap_contains (uc->seen_dh,
505 &dh))
506 {
507 GNUNET_CONTAINER_multihashmap_clear (uc->seen_dh);
508 uc->ksk_offset++;
509 GNUNET_FS_unindex_do_remove_kblocks_ (uc);
510 return;
511 }
512 GNUNET_assert (GNUNET_OK ==
513 GNUNET_CONTAINER_multihashmap_put (uc->seen_dh,
514 &dh,
515 uc,
516 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
517 GNUNET_assert (GNUNET_BLOCK_TYPE_FS_UBLOCK == type); 495 GNUNET_assert (GNUNET_BLOCK_TYPE_FS_UBLOCK == type);
518 if (size < sizeof (struct UBlock)) 496 if (size < sizeof (struct UBlock))
519 { 497 {
@@ -566,23 +544,24 @@ process_kblock_for_unindex (void *cls,
566 GNUNET_FS_uri_destroy (chk_uri); 544 GNUNET_FS_uri_destroy (chk_uri);
567 /* matches! */ 545 /* matches! */
568 uc->dqe = GNUNET_DATASTORE_remove (uc->dsh, 546 uc->dqe = GNUNET_DATASTORE_remove (uc->dsh,
569 key, 547 key,
570 size, 548 size,
571 data, 549 data,
572 0 /* priority */, 550 0 /* priority */,
573 1 /* queue size */, 551 1 /* queue size */,
574 &continue_after_remove, 552 &continue_after_remove,
575 uc); 553 uc);
576 return; 554 return;
577 get_next: 555 get_next:
578 uc->dqe = GNUNET_DATASTORE_get_key (uc->dsh, 556 uc->dqe = GNUNET_DATASTORE_get_key (uc->dsh,
579 uc->roff++, 557 uid + 1 /* next_uid */,
580 &uc->uquery, 558 false /* random */,
581 GNUNET_BLOCK_TYPE_FS_UBLOCK, 559 &uc->uquery,
582 0 /* priority */, 560 GNUNET_BLOCK_TYPE_FS_UBLOCK,
561 0 /* priority */,
583 1 /* queue size */, 562 1 /* queue size */,
584 &process_kblock_for_unindex, 563 &process_kblock_for_unindex,
585 uc); 564 uc);
586} 565}
587 566
588 567
@@ -627,13 +606,14 @@ GNUNET_FS_unindex_do_remove_kblocks_ (struct GNUNET_FS_UnindexContext *uc)
627 sizeof (dpub), 606 sizeof (dpub),
628 &uc->uquery); 607 &uc->uquery);
629 uc->dqe = GNUNET_DATASTORE_get_key (uc->dsh, 608 uc->dqe = GNUNET_DATASTORE_get_key (uc->dsh,
630 uc->roff++, 609 0 /* next_uid */,
631 &uc->uquery, 610 false /* random */,
632 GNUNET_BLOCK_TYPE_FS_UBLOCK, 611 &uc->uquery,
633 0 /* priority */, 612 GNUNET_BLOCK_TYPE_FS_UBLOCK,
613 0 /* priority */,
634 1 /* queue size */, 614 1 /* queue size */,
635 &process_kblock_for_unindex, 615 &process_kblock_for_unindex,
636 uc); 616 uc);
637} 617}
638 618
639 619
@@ -826,8 +806,6 @@ GNUNET_FS_unindex_start (struct GNUNET_FS_Handle *h,
826 uc->start_time = GNUNET_TIME_absolute_get (); 806 uc->start_time = GNUNET_TIME_absolute_get ();
827 uc->file_size = size; 807 uc->file_size = size;
828 uc->client_info = cctx; 808 uc->client_info = cctx;
829 uc->seen_dh = GNUNET_CONTAINER_multihashmap_create (4,
830 GNUNET_NO);
831 GNUNET_FS_unindex_sync_ (uc); 809 GNUNET_FS_unindex_sync_ (uc);
832 pi.status = GNUNET_FS_STATUS_UNINDEX_START; 810 pi.status = GNUNET_FS_STATUS_UNINDEX_START;
833 pi.value.unindex.eta = GNUNET_TIME_UNIT_FOREVER_REL; 811 pi.value.unindex.eta = GNUNET_TIME_UNIT_FOREVER_REL;
diff --git a/src/fs/gnunet-auto-share.c b/src/fs/gnunet-auto-share.c
index cc0111111..2f980520a 100644
--- a/src/fs/gnunet-auto-share.c
+++ b/src/fs/gnunet-auto-share.c
@@ -72,7 +72,7 @@ static int ret;
72/** 72/**
73 * Are we running 'verbosely'? 73 * Are we running 'verbosely'?
74 */ 74 */
75static int verbose; 75static unsigned int verbose;
76 76
77/** 77/**
78 * Configuration to use. 78 * Configuration to use.
@@ -759,26 +759,38 @@ free_item (void *cls,
759int 759int
760main (int argc, char *const *argv) 760main (int argc, char *const *argv)
761{ 761{
762 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 762 struct GNUNET_GETOPT_CommandLineOption options[] = {
763 {'a', "anonymity", "LEVEL", 763
764 gettext_noop ("set the desired LEVEL of sender-anonymity"), 764 GNUNET_GETOPT_OPTION_SET_UINT ('a',
765 1, &GNUNET_GETOPT_set_uint, &anonymity_level}, 765 "anonymity",
766 {'d', "disable-creation-time", NULL, 766 "LEVEL",
767 gettext_noop 767 gettext_noop ("set the desired LEVEL of sender-anonymity"),
768 ("disable adding the creation time to the metadata of the uploaded file"), 768 &anonymity_level),
769 0, &GNUNET_GETOPT_set_one, &do_disable_creation_time}, 769
770 {'D', "disable-extractor", NULL, 770 GNUNET_GETOPT_OPTION_SET_ONE ('d',
771 gettext_noop ("do not use libextractor to add keywords or metadata"), 771 "disable-creation-time",
772 0, &GNUNET_GETOPT_set_one, &disable_extractor}, 772 gettext_noop ("disable adding the creation time to the metadata of the uploaded file"),
773 {'p', "priority", "PRIORITY", 773 &do_disable_creation_time),
774 gettext_noop ("specify the priority of the content"), 774
775 1, &GNUNET_GETOPT_set_uint, &content_priority}, 775 GNUNET_GETOPT_OPTION_SET_ONE ('D',
776 {'r', "replication", "LEVEL", 776 "disable-extractor",
777 gettext_noop ("set the desired replication LEVEL"), 777 gettext_noop ("do not use libextractor to add keywords or metadata"),
778 1, &GNUNET_GETOPT_set_uint, &replication_level}, 778 &disable_extractor),
779 {'V', "verbose", NULL, 779
780 gettext_noop ("be verbose (print progress information)"), 780 GNUNET_GETOPT_OPTION_SET_UINT ('p',
781 0, &GNUNET_GETOPT_set_one, &verbose}, 781 "priority",
782 "PRIORITY",
783 gettext_noop ("specify the priority of the content"),
784 &content_priority),
785
786 GNUNET_GETOPT_OPTION_SET_UINT ('r',
787 "replication",
788 "LEVEL",
789 gettext_noop ("set the desired replication LEVEL"),
790 &replication_level),
791
792 GNUNET_GETOPT_OPTION_VERBOSE (&verbose),
793
782 GNUNET_GETOPT_OPTION_END 794 GNUNET_GETOPT_OPTION_END
783 }; 795 };
784 struct WorkItem *wi; 796 struct WorkItem *wi;
diff --git a/src/fs/gnunet-download.c b/src/fs/gnunet-download.c
index 6d9adb8ab..4d6f30587 100644
--- a/src/fs/gnunet-download.c
+++ b/src/fs/gnunet-download.c
@@ -30,7 +30,7 @@
30 30
31static int ret; 31static int ret;
32 32
33static int verbose; 33static unsigned int verbose;
34 34
35static int delete_incomplete; 35static int delete_incomplete;
36 36
@@ -299,33 +299,51 @@ run (void *cls, char *const *args, const char *cfgfile,
299int 299int
300main (int argc, char *const *argv) 300main (int argc, char *const *argv)
301{ 301{
302 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 302 struct GNUNET_GETOPT_CommandLineOption options[] = {
303 {'a', "anonymity", "LEVEL", 303 GNUNET_GETOPT_OPTION_SET_UINT ('a',
304 gettext_noop ("set the desired LEVEL of receiver-anonymity"), 304 "anonymity",
305 1, &GNUNET_GETOPT_set_uint, &anonymity}, 305 "LEVEL",
306 {'D', "delete-incomplete", NULL, 306 gettext_noop ("set the desired LEVEL of receiver-anonymity"),
307 gettext_noop ("delete incomplete downloads (when aborted with CTRL-C)"), 307 &anonymity),
308 0, &GNUNET_GETOPT_set_one, &delete_incomplete}, 308
309 {'n', "no-network", NULL, 309 GNUNET_GETOPT_OPTION_SET_ONE ('D',
310 gettext_noop ("only search the local peer (no P2P network search)"), 310 "delete-incomplete",
311 0, &GNUNET_GETOPT_set_one, &local_only}, 311 gettext_noop ("delete incomplete downloads (when aborted with CTRL-C)"),
312 {'o', "output", "FILENAME", 312 &delete_incomplete),
313 gettext_noop ("write the file to FILENAME"), 313
314 1, &GNUNET_GETOPT_set_string, &filename}, 314 GNUNET_GETOPT_OPTION_SET_ONE ('n',
315 {'p', "parallelism", "DOWNLOADS", 315 "no-network",
316 gettext_noop 316 gettext_noop ("only search the local peer (no P2P network search)"),
317 ("set the maximum number of parallel downloads that is allowed"), 317 &local_only),
318 1, &GNUNET_GETOPT_set_uint, &parallelism}, 318
319 {'r', "request-parallelism", "REQUESTS", 319 GNUNET_GETOPT_OPTION_STRING ('o',
320 gettext_noop 320 "output",
321 ("set the maximum number of parallel requests for blocks that is allowed"), 321 "FILENAME",
322 1, &GNUNET_GETOPT_set_uint, &request_parallelism}, 322 gettext_noop ("write the file to FILENAME"),
323 {'R', "recursive", NULL, 323 &filename),
324 gettext_noop ("download a GNUnet directory recursively"), 324
325 0, &GNUNET_GETOPT_set_one, &do_recursive}, 325 GNUNET_GETOPT_OPTION_SET_UINT ('p',
326 {'V', "verbose", NULL, 326 "parallelism",
327 gettext_noop ("be verbose (print progress information)"), 327 "DOWNLOADS",
328 0, &GNUNET_GETOPT_increment_value, &verbose}, 328 gettext_noop ("set the maximum number of parallel downloads that is allowed"),
329 &parallelism),
330
331 GNUNET_GETOPT_OPTION_SET_UINT ('r',
332 "request-parallelism",
333 "REQUESTS",
334 gettext_noop ("set the maximum number of parallel requests for blocks that is allowed"),
335 &request_parallelism),
336
337 GNUNET_GETOPT_OPTION_SET_ONE ('R',
338 "recursive",
339 gettext_noop ("download a GNUnet directory recursively"),
340 &do_recursive),
341
342 GNUNET_GETOPT_OPTION_INCREMENT_VALUE ('V',
343 "verbose",
344 gettext_noop ("be verbose (print progress information)"),
345 &verbose),
346
329 GNUNET_GETOPT_OPTION_END 347 GNUNET_GETOPT_OPTION_END
330 }; 348 };
331 349
diff --git a/src/fs/gnunet-fs-profiler.c b/src/fs/gnunet-fs-profiler.c
index cfbe57bbd..fb99d8f90 100644
--- a/src/fs/gnunet-fs-profiler.c
+++ b/src/fs/gnunet-fs-profiler.c
@@ -203,16 +203,26 @@ run (void *cls, char *const *args, const char *cfgfile,
203int 203int
204main (int argc, char *const *argv) 204main (int argc, char *const *argv)
205{ 205{
206 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 206 struct GNUNET_GETOPT_CommandLineOption options[] = {
207 {'n', "num-peers", "COUNT", 207
208 gettext_noop ("run the experiment with COUNT peers"), 208 GNUNET_GETOPT_OPTION_SET_UINT ('n',
209 1, &GNUNET_GETOPT_set_uint, &num_peers}, 209 "num-peers",
210 {'H', "hosts", "HOSTFILE", 210 "COUNT",
211 gettext_noop ("specifies name of a file with the HOSTS the testbed should use"), 211 gettext_noop ("run the experiment with COUNT peers"),
212 1, &GNUNET_GETOPT_set_string, &host_filename}, 212 &num_peers),
213 {'t', "timeout", "DELAY", 213
214 gettext_noop ("automatically terminate experiment after DELAY"), 214 GNUNET_GETOPT_OPTION_STRING ('H',
215 1, &GNUNET_GETOPT_set_relative_time, &timeout}, 215 "hosts",
216 "HOSTFILE",
217 gettext_noop ("specifies name of a file with the HOSTS the testbed should use"),
218 &host_filename),
219
220 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('t',
221 "timeout",
222 "DELAY",
223 gettext_noop ("automatically terminate experiment after DELAY"),
224 &timeout),
225
216 GNUNET_GETOPT_OPTION_END 226 GNUNET_GETOPT_OPTION_END
217 }; 227 };
218 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 228 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
diff --git a/src/fs/gnunet-fs.c b/src/fs/gnunet-fs.c
index 7c20e025f..2b24b7124 100644
--- a/src/fs/gnunet-fs.c
+++ b/src/fs/gnunet-fs.c
@@ -43,7 +43,7 @@ static int list_indexed_files;
43/** 43/**
44 * Option -v given? 44 * Option -v given?
45 */ 45 */
46static int verbose; 46static unsigned int verbose;
47 47
48 48
49/** 49/**
@@ -112,10 +112,13 @@ run (void *cls, char *const *args, const char *cfgfile,
112int 112int
113main (int argc, char *const *argv) 113main (int argc, char *const *argv)
114{ 114{
115 static struct GNUNET_GETOPT_CommandLineOption options[] = { 115 struct GNUNET_GETOPT_CommandLineOption options[] = {
116 {'i', "list-indexed", NULL, 116
117 gettext_noop ("print a list of all indexed files"), 0, 117 GNUNET_GETOPT_OPTION_SET_ONE ('i',
118 &GNUNET_GETOPT_set_one, &list_indexed_files}, 118 "list-indexed",
119 gettext_noop ("print a list of all indexed files"),
120 &list_indexed_files),
121
119 GNUNET_GETOPT_OPTION_VERBOSE (&verbose), 122 GNUNET_GETOPT_OPTION_VERBOSE (&verbose),
120 GNUNET_GETOPT_OPTION_END 123 GNUNET_GETOPT_OPTION_END
121 }; 124 };
diff --git a/src/fs/gnunet-publish.c b/src/fs/gnunet-publish.c
index a563d7b7a..2229e45e7 100644
--- a/src/fs/gnunet-publish.c
+++ b/src/fs/gnunet-publish.c
@@ -37,7 +37,7 @@ static int ret;
37/** 37/**
38 * Command line option 'verbose' set 38 * Command line option 'verbose' set
39 */ 39 */
40static int verbose; 40static unsigned int verbose;
41 41
42/** 42/**
43 * Handle to our configuration. 43 * Handle to our configuration.
@@ -893,63 +893,98 @@ run (void *cls,
893int 893int
894main (int argc, char *const *argv) 894main (int argc, char *const *argv)
895{ 895{
896 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 896 struct GNUNET_GETOPT_CommandLineOption options[] = {
897 {'a', "anonymity", "LEVEL", 897 GNUNET_GETOPT_OPTION_SET_UINT ('a',
898 gettext_noop ("set the desired LEVEL of sender-anonymity"), 898 "anonymity",
899 1, &GNUNET_GETOPT_set_uint, &bo.anonymity_level}, 899 "LEVEL",
900 {'d', "disable-creation-time", NULL, 900 gettext_noop ("set the desired LEVEL of sender-anonymity"),
901 gettext_noop 901 &bo.anonymity_level),
902 ("disable adding the creation time to the metadata of the uploaded file"), 902
903 0, &GNUNET_GETOPT_set_one, &do_disable_creation_time}, 903 GNUNET_GETOPT_OPTION_SET_ONE ('d',
904 {'D', "disable-extractor", NULL, 904 "disable-creation-time",
905 gettext_noop ("do not use libextractor to add keywords or metadata"), 905 gettext_noop ("disable adding the creation time to the "
906 0, &GNUNET_GETOPT_set_one, &disable_extractor}, 906 "metadata of the uploaded file"),
907 {'e', "extract", NULL, 907 &do_disable_creation_time),
908 gettext_noop 908
909 ("print list of extracted keywords that would be used, but do not perform upload"), 909 GNUNET_GETOPT_OPTION_SET_ONE ('D',
910 0, &GNUNET_GETOPT_set_one, &extract_only}, 910 "disable-extractor",
911 {'k', "key", "KEYWORD", 911 gettext_noop ("do not use libextractor to add keywords or metadata"),
912 gettext_noop 912 &disable_extractor),
913 ("add an additional keyword for the top-level file or directory" 913
914 " (this option can be specified multiple times)"), 914 GNUNET_GETOPT_OPTION_SET_ONE ('e',
915 1, &GNUNET_FS_getopt_set_keywords, &topKeywords}, 915 "extract",
916 {'m', "meta", "TYPE:VALUE", 916 gettext_noop ("print list of extracted keywords that would "
917 gettext_noop ("set the meta-data for the given TYPE to the given VALUE"), 917 "be used, but do not perform upload"),
918 1, &GNUNET_FS_getopt_set_metadata, &meta}, 918 &extract_only),
919 {'n', "noindex", NULL, 919
920 gettext_noop ("do not index, perform full insertion (stores entire " 920 GNUNET_FS_GETOPT_KEYWORDS ('k',
921 "file in encrypted form in GNUnet database)"), 921 "key",
922 0, &GNUNET_GETOPT_set_one, &do_insert}, 922 "KEYWORD",
923 {'N', "next", "ID", 923 gettext_noop ("add an additional keyword for the top-level "
924 gettext_noop 924 "file or directory (this option can be specified multiple times)"),
925 ("specify ID of an updated version to be published in the future" 925 &topKeywords),
926 " (for namespace insertions only)"), 926
927 1, &GNUNET_GETOPT_set_string, &next_id}, 927 GNUNET_FS_GETOPT_METADATA ('m',
928 {'p', "priority", "PRIORITY", 928 "meta",
929 gettext_noop ("specify the priority of the content"), 929 "TYPE:VALUE",
930 1, &GNUNET_GETOPT_set_uint, &bo.content_priority}, 930 gettext_noop ("set the meta-data for the given TYPE to the given VALUE"),
931 {'P', "pseudonym", "NAME", 931 &meta),
932 gettext_noop 932
933 ("publish the files under the pseudonym NAME (place file into namespace)"), 933 GNUNET_GETOPT_OPTION_SET_ONE ('n',
934 1, &GNUNET_GETOPT_set_string, &pseudonym}, 934 "noindex",
935 {'r', "replication", "LEVEL", 935 gettext_noop ("do not index, perform full insertion (stores "
936 gettext_noop ("set the desired replication LEVEL"), 936 "entire file in encrypted form in GNUnet database)"),
937 1, &GNUNET_GETOPT_set_uint, &bo.replication_level}, 937 &do_insert),
938 {'s', "simulate-only", NULL, 938
939 gettext_noop ("only simulate the process but do not do any " 939 GNUNET_GETOPT_OPTION_STRING ('N',
940 "actual publishing (useful to compute URIs)"), 940 "next",
941 0, &GNUNET_GETOPT_set_one, &do_simulate}, 941 "ID",
942 {'t', "this", "ID", 942 gettext_noop ("specify ID of an updated version to be "
943 gettext_noop ("set the ID of this version of the publication" 943 "published in the future (for namespace insertions only)"),
944 " (for namespace insertions only)"), 944 &next_id),
945 1, &GNUNET_GETOPT_set_string, &this_id}, 945
946 {'u', "uri", "URI", 946 GNUNET_GETOPT_OPTION_SET_UINT ('p',
947 gettext_noop ("URI to be published (can be used instead of passing a " 947 "priority",
948 "file to add keywords to the file with the respective URI)"), 948 "PRIORITY",
949 1, &GNUNET_GETOPT_set_string, &uri_string}, 949 gettext_noop ("specify the priority of the content"),
950 {'V', "verbose", NULL, 950 &bo.content_priority),
951 gettext_noop ("be verbose (print progress information)"), 951
952 0, &GNUNET_GETOPT_set_one, &verbose}, 952 GNUNET_GETOPT_OPTION_STRING ('P',
953 "pseudonym",
954 "NAME",
955 gettext_noop ("publish the files under the pseudonym "
956 "NAME (place file into namespace)"),
957 &pseudonym),
958
959 GNUNET_GETOPT_OPTION_SET_UINT ('r',
960 "replication",
961 "LEVEL",
962 gettext_noop ("set the desired replication LEVEL"),
963 &bo.replication_level),
964
965
966 GNUNET_GETOPT_OPTION_SET_ONE ('s',
967 "simulate-only",
968 gettext_noop ("only simulate the process but do not do "
969 "any actual publishing (useful to compute URIs)"),
970 &do_simulate),
971
972 GNUNET_GETOPT_OPTION_STRING ('t',
973 "this",
974 "ID",
975 gettext_noop ("set the ID of this version of the publication "
976 "(for namespace insertions only)"),
977 &this_id),
978
979 GNUNET_GETOPT_OPTION_STRING ('u',
980 "uri",
981 "URI",
982 gettext_noop ("URI to be published (can be used instead of passing a "
983 "file to add keywords to the file with the respective URI)"),
984 &uri_string),
985
986 GNUNET_GETOPT_OPTION_VERBOSE (&verbose),
987
953 GNUNET_GETOPT_OPTION_END 988 GNUNET_GETOPT_OPTION_END
954 }; 989 };
955 bo.expiration_time = 990 bo.expiration_time =
diff --git a/src/fs/gnunet-search.c b/src/fs/gnunet-search.c
index dfe6d0e75..22e790cf3 100644
--- a/src/fs/gnunet-search.c
+++ b/src/fs/gnunet-search.c
@@ -51,7 +51,7 @@ static unsigned int results_limit;
51 51
52static unsigned int results; 52static unsigned int results;
53 53
54static int verbose; 54static unsigned int verbose;
55 55
56static int local_only; 56static int local_only;
57 57
@@ -305,26 +305,42 @@ run (void *cls, char *const *args, const char *cfgfile,
305int 305int
306main (int argc, char *const *argv) 306main (int argc, char *const *argv)
307{ 307{
308 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 308 struct GNUNET_GETOPT_CommandLineOption options[] = {
309 {'a', "anonymity", "LEVEL", 309
310 gettext_noop ("set the desired LEVEL of receiver-anonymity"), 310 GNUNET_GETOPT_OPTION_SET_UINT ('a',
311 1, &GNUNET_GETOPT_set_uint, &anonymity}, 311 "anonymity",
312 {'n', "no-network", NULL, 312 "LEVEL",
313 gettext_noop ("only search the local peer (no P2P network search)"), 313 gettext_noop ("set the desired LEVEL of receiver-anonymity"),
314 0, &GNUNET_GETOPT_set_one, &local_only}, 314 &anonymity),
315 {'o', "output", "PREFIX", 315
316 gettext_noop ("write search results to file starting with PREFIX"), 316
317 1, &GNUNET_GETOPT_set_string, &output_filename}, 317 GNUNET_GETOPT_OPTION_SET_ONE ('n',
318 {'t', "timeout", "DELAY", 318 "no-network",
319 gettext_noop ("automatically terminate search after DELAY"), 319 gettext_noop ("only search the local peer (no P2P network search)"),
320 1, &GNUNET_GETOPT_set_relative_time, &timeout}, 320 &local_only),
321 {'V', "verbose", NULL, 321
322 gettext_noop ("be verbose (print progress information)"), 322 GNUNET_GETOPT_OPTION_STRING ('o',
323 0, &GNUNET_GETOPT_set_one, &verbose}, 323 "output",
324 {'N', "results", "VALUE", 324 "PREFIX",
325 gettext_noop 325 gettext_noop ("write search results to file starting with PREFIX"),
326 ("automatically terminate search after VALUE results are found"), 326 &output_filename),
327 1, &GNUNET_GETOPT_set_uint, &results_limit}, 327
328 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('t',
329 "timeout",
330 "DELAY",
331 gettext_noop ("automatically terminate search after DELAY"),
332 &timeout),
333
334
335 GNUNET_GETOPT_OPTION_VERBOSE (&verbose),
336
337 GNUNET_GETOPT_OPTION_SET_UINT ('N',
338 "results",
339 "VALUE",
340 gettext_noop ("automatically terminate search "
341 "after VALUE results are found"),
342 &results_limit),
343
328 GNUNET_GETOPT_OPTION_END 344 GNUNET_GETOPT_OPTION_END
329 }; 345 };
330 346
diff --git a/src/fs/gnunet-service-fs_cadet_server.c b/src/fs/gnunet-service-fs_cadet_server.c
index 8567e63a2..02ebb2ffe 100644
--- a/src/fs/gnunet-service-fs_cadet_server.c
+++ b/src/fs/gnunet-service-fs_cadet_server.c
@@ -219,19 +219,21 @@ continue_writing (void *cls)
219 * @param type type of the content 219 * @param type type of the content
220 * @param priority priority of the content 220 * @param priority priority of the content
221 * @param anonymity anonymity-level for the content 221 * @param anonymity anonymity-level for the content
222 * @param replication replication-level for the content
222 * @param expiration expiration time for the content 223 * @param expiration expiration time for the content
223 * @param uid unique identifier for the datum; 224 * @param uid unique identifier for the datum;
224 * maybe 0 if no unique identifier is available 225 * maybe 0 if no unique identifier is available
225 */ 226 */
226static void 227static void
227handle_datastore_reply (void *cls, 228handle_datastore_reply (void *cls,
228 const struct GNUNET_HashCode *key, 229 const struct GNUNET_HashCode *key,
229 size_t size, 230 size_t size,
230 const void *data, 231 const void *data,
231 enum GNUNET_BLOCK_Type type, 232 enum GNUNET_BLOCK_Type type,
232 uint32_t priority, 233 uint32_t priority,
233 uint32_t anonymity, 234 uint32_t anonymity,
234 struct GNUNET_TIME_Absolute expiration, 235 uint32_t replication,
236 struct GNUNET_TIME_Absolute expiration,
235 uint64_t uid) 237 uint64_t uid)
236{ 238{
237 struct CadetClient *sc = cls; 239 struct CadetClient *sc = cls;
@@ -273,15 +275,16 @@ handle_datastore_reply (void *cls,
273 GNUNET_h2s (key)); 275 GNUNET_h2s (key));
274 if (GNUNET_OK != 276 if (GNUNET_OK !=
275 GNUNET_FS_handle_on_demand_block (key, 277 GNUNET_FS_handle_on_demand_block (key,
276 size, 278 size,
277 data, 279 data,
278 type, 280 type,
279 priority, 281 priority,
280 anonymity, 282 anonymity,
281 expiration, 283 replication,
282 uid, 284 expiration,
283 &handle_datastore_reply, 285 uid,
284 sc)) 286 &handle_datastore_reply,
287 sc))
285 { 288 {
286 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 289 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
287 "On-demand encoding request failed\n"); 290 "On-demand encoding request failed\n");
@@ -289,7 +292,7 @@ handle_datastore_reply (void *cls,
289 } 292 }
290 return; 293 return;
291 } 294 }
292 if (msize > GNUNET_SERVER_MAX_MESSAGE_SIZE) 295 if (msize > GNUNET_MAX_MESSAGE_SIZE)
293 { 296 {
294 GNUNET_break (0); 297 GNUNET_break (0);
295 continue_writing (sc); 298 continue_writing (sc);
@@ -345,12 +348,13 @@ handle_request (void *cls,
345 GNUNET_NO); 348 GNUNET_NO);
346 refresh_timeout_task (sc); 349 refresh_timeout_task (sc);
347 sc->qe = GNUNET_DATASTORE_get_key (GSF_dsh, 350 sc->qe = GNUNET_DATASTORE_get_key (GSF_dsh,
348 0, 351 0 /* next_uid */,
349 &sqm->query, 352 false /* random */,
350 ntohl (sqm->type), 353 &sqm->query,
351 0 /* priority */, 354 ntohl (sqm->type),
352 GSF_datastore_queue_size, 355 0 /* priority */,
353 &handle_datastore_reply, 356 GSF_datastore_queue_size,
357 &handle_datastore_reply,
354 sc); 358 sc);
355 if (NULL == sc->qe) 359 if (NULL == sc->qe)
356 { 360 {
diff --git a/src/fs/gnunet-service-fs_cp.c b/src/fs/gnunet-service-fs_cp.c
index 3f7783ded..817aed257 100644
--- a/src/fs/gnunet-service-fs_cp.c
+++ b/src/fs/gnunet-service-fs_cp.c
@@ -859,7 +859,7 @@ handle_p2p_reply (void *cls,
859 size_t msize; 859 size_t msize;
860 860
861 GNUNET_assert (data_len + sizeof (struct PutMessage) < 861 GNUNET_assert (data_len + sizeof (struct PutMessage) <
862 GNUNET_SERVER_MAX_MESSAGE_SIZE); 862 GNUNET_MAX_MESSAGE_SIZE);
863 GNUNET_assert (peerreq->pr == pr); 863 GNUNET_assert (peerreq->pr == pr);
864 prd = GSF_pending_request_get_data_ (pr); 864 prd = GSF_pending_request_get_data_ (pr);
865 if (NULL == data) 865 if (NULL == data)
@@ -883,7 +883,7 @@ handle_p2p_reply (void *cls,
883 gettext_noop ("# replies received for other peers"), 883 gettext_noop ("# replies received for other peers"),
884 1, GNUNET_NO); 884 1, GNUNET_NO);
885 msize = sizeof (struct PutMessage) + data_len; 885 msize = sizeof (struct PutMessage) + data_len;
886 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 886 if (msize >= GNUNET_MAX_MESSAGE_SIZE)
887 { 887 {
888 GNUNET_break (0); 888 GNUNET_break (0);
889 return; 889 return;
diff --git a/src/fs/gnunet-service-fs_indexing.c b/src/fs/gnunet-service-fs_indexing.c
index 3ce68f487..b5e8af95f 100644
--- a/src/fs/gnunet-service-fs_indexing.c
+++ b/src/fs/gnunet-service-fs_indexing.c
@@ -266,6 +266,7 @@ remove_cont (void *cls, int success,
266 * @param type type of the content 266 * @param type type of the content
267 * @param priority priority of the content 267 * @param priority priority of the content
268 * @param anonymity anonymity-level for the content 268 * @param anonymity anonymity-level for the content
269 * @param replication replication-level for the content
269 * @param expiration expiration time for the content 270 * @param expiration expiration time for the content
270 * @param uid unique identifier for the datum; 271 * @param uid unique identifier for the datum;
271 * maybe 0 if no unique identifier is available 272 * maybe 0 if no unique identifier is available
@@ -280,6 +281,7 @@ GNUNET_FS_handle_on_demand_block (const struct GNUNET_HashCode * key,
280 enum GNUNET_BLOCK_Type type, 281 enum GNUNET_BLOCK_Type type,
281 uint32_t priority, 282 uint32_t priority,
282 uint32_t anonymity, 283 uint32_t anonymity,
284 uint32_t replication,
283 struct GNUNET_TIME_Absolute expiration, 285 struct GNUNET_TIME_Absolute expiration,
284 uint64_t uid, 286 uint64_t uid,
285 GNUNET_DATASTORE_DatumProcessor cont, 287 GNUNET_DATASTORE_DatumProcessor cont,
@@ -412,6 +414,7 @@ GNUNET_FS_handle_on_demand_block (const struct GNUNET_HashCode * key,
412 GNUNET_BLOCK_TYPE_FS_DBLOCK, 414 GNUNET_BLOCK_TYPE_FS_DBLOCK,
413 priority, 415 priority,
414 anonymity, 416 anonymity,
417 replication,
415 expiration, 418 expiration,
416 uid); 419 uid);
417 return GNUNET_OK; 420 return GNUNET_OK;
@@ -438,7 +441,7 @@ GNUNET_FS_indexing_send_list (struct GNUNET_MQ_Handle *mq)
438 fn = pos->filename; 441 fn = pos->filename;
439 slen = strlen (fn) + 1; 442 slen = strlen (fn) + 1;
440 if (slen + sizeof (struct IndexInfoMessage) >= 443 if (slen + sizeof (struct IndexInfoMessage) >=
441 GNUNET_SERVER_MAX_MESSAGE_SIZE) 444 GNUNET_MAX_MESSAGE_SIZE)
442 { 445 {
443 GNUNET_break (0); 446 GNUNET_break (0);
444 break; 447 break;
diff --git a/src/fs/gnunet-service-fs_indexing.h b/src/fs/gnunet-service-fs_indexing.h
index 8b861e3f7..331c51105 100644
--- a/src/fs/gnunet-service-fs_indexing.h
+++ b/src/fs/gnunet-service-fs_indexing.h
@@ -47,6 +47,7 @@
47 * @param type type of the content 47 * @param type type of the content
48 * @param priority priority of the content 48 * @param priority priority of the content
49 * @param anonymity anonymity-level for the content 49 * @param anonymity anonymity-level for the content
50 * @param replication replication-level for the content
50 * @param expiration expiration time for the content 51 * @param expiration expiration time for the content
51 * @param uid unique identifier for the datum; 52 * @param uid unique identifier for the datum;
52 * maybe 0 if no unique identifier is available 53 * maybe 0 if no unique identifier is available
@@ -55,9 +56,13 @@
55 * @return #GNUNET_OK on success 56 * @return #GNUNET_OK on success
56 */ 57 */
57int 58int
58GNUNET_FS_handle_on_demand_block (const struct GNUNET_HashCode * key, uint32_t size, 59GNUNET_FS_handle_on_demand_block (const struct GNUNET_HashCode *key,
59 const void *data, enum GNUNET_BLOCK_Type type, 60 uint32_t size,
60 uint32_t priority, uint32_t anonymity, 61 const void *data,
62 enum GNUNET_BLOCK_Type type,
63 uint32_t priority,
64 uint32_t anonymity,
65 uint32_t replication,
61 struct GNUNET_TIME_Absolute expiration, 66 struct GNUNET_TIME_Absolute expiration,
62 uint64_t uid, 67 uint64_t uid,
63 GNUNET_DATASTORE_DatumProcessor cont, 68 GNUNET_DATASTORE_DatumProcessor cont,
diff --git a/src/fs/gnunet-service-fs_pr.c b/src/fs/gnunet-service-fs_pr.c
index b0fda24b5..7c64ab98b 100644
--- a/src/fs/gnunet-service-fs_pr.c
+++ b/src/fs/gnunet-service-fs_pr.c
@@ -160,20 +160,27 @@ struct GSF_PendingRequest
160 struct GNUNET_SCHEDULER_Task * warn_task; 160 struct GNUNET_SCHEDULER_Task * warn_task;
161 161
162 /** 162 /**
163 * Current offset for querying our local datastore for results. 163 * Do we have a first UID yet?
164 * Starts at a random value, incremented until we get the same 164 */
165 * UID again (detected using 'first_uid'), which is then used 165 bool have_first_uid;
166 * to termiante the iteration. 166
167 /**
168 * Have we seen a NULL result yet?
167 */ 169 */
168 uint64_t local_result_offset; 170 bool seen_null;
169 171
170 /** 172 /**
171 * Unique ID of the first result from the local datastore; 173 * Unique ID of the first result from the local datastore;
172 * used to detect wrap-around of the offset. 174 * used to terminate the loop.
173 */ 175 */
174 uint64_t first_uid; 176 uint64_t first_uid;
175 177
176 /** 178 /**
179 * Result count.
180 */
181 size_t result_count;
182
183 /**
177 * How often have we retried this request via 'cadet'? 184 * How often have we retried this request via 'cadet'?
178 * (used to bound overall retries). 185 * (used to bound overall retries).
179 */ 186 */
@@ -189,11 +196,6 @@ struct GSF_PendingRequest
189 */ 196 */
190 unsigned int replies_seen_size; 197 unsigned int replies_seen_size;
191 198
192 /**
193 * Do we have a first UID yet?
194 */
195 unsigned int have_first_uid;
196
197}; 199};
198 200
199 201
@@ -332,8 +334,6 @@ GSF_pending_request_create_ (enum GSF_PendingRequestOptions options,
332 if (NULL != target) 334 if (NULL != target)
333 extra += sizeof (struct GNUNET_PeerIdentity); 335 extra += sizeof (struct GNUNET_PeerIdentity);
334 pr = GNUNET_malloc (sizeof (struct GSF_PendingRequest) + extra); 336 pr = GNUNET_malloc (sizeof (struct GSF_PendingRequest) + extra);
335 pr->local_result_offset =
336 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
337 pr->public_data.query = *query; 337 pr->public_data.query = *query;
338 eptr = (struct GNUNET_HashCode *) &pr[1]; 338 eptr = (struct GNUNET_HashCode *) &pr[1];
339 if (NULL != target) 339 if (NULL != target)
@@ -1340,6 +1340,124 @@ odc_warn_delay_task (void *cls)
1340} 1340}
1341 1341
1342 1342
1343/* Call our continuation (if we have any) */
1344static void
1345call_continuation (struct GSF_PendingRequest *pr)
1346{
1347 GSF_LocalLookupContinuation cont = pr->llc_cont;
1348
1349 GNUNET_assert (NULL == pr->qe);
1350 if (NULL != pr->warn_task)
1351 {
1352 GNUNET_SCHEDULER_cancel (pr->warn_task);
1353 pr->warn_task = NULL;
1354 }
1355 if (NULL == cont)
1356 return; /* no continuation */
1357 pr->llc_cont = NULL;
1358 if (0 != (GSF_PRO_LOCAL_ONLY & pr->public_data.options))
1359 {
1360 if (GNUNET_BLOCK_EVALUATION_OK_LAST != pr->local_result)
1361 {
1362 /* Signal that we are done and that there won't be any
1363 additional results to allow client to clean up state. */
1364 pr->rh (pr->rh_cls,
1365 GNUNET_BLOCK_EVALUATION_OK_LAST,
1366 pr,
1367 UINT32_MAX,
1368 GNUNET_TIME_UNIT_ZERO_ABS,
1369 GNUNET_TIME_UNIT_FOREVER_ABS,
1370 GNUNET_BLOCK_TYPE_ANY,
1371 NULL,
1372 0);
1373 }
1374 /* Finally, call our continuation to signal that we are
1375 done with local processing of this request; i.e. to
1376 start reading again from the client. */
1377 cont (pr->llc_cont_cls, NULL, GNUNET_BLOCK_EVALUATION_OK_LAST);
1378 return;
1379 }
1380
1381 cont (pr->llc_cont_cls, pr, pr->local_result);
1382}
1383
1384
1385/* Update stats and call continuation */
1386static void
1387no_more_local_results (struct GSF_PendingRequest *pr)
1388{
1389 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
1390 "No further local responses available.\n");
1391#if INSANE_STATISTICS
1392 if ( (GNUNET_BLOCK_TYPE_FS_DBLOCK == pr->public_data.type) ||
1393 (GNUNET_BLOCK_TYPE_FS_IBLOCK == pr->public_data.type) )
1394 GNUNET_STATISTICS_update (GSF_stats,
1395 gettext_noop ("# requested DBLOCK or IBLOCK not found"),
1396 1,
1397 GNUNET_NO);
1398#endif
1399 call_continuation (pr);
1400}
1401
1402
1403/* forward declaration */
1404static void
1405process_local_reply (void *cls,
1406 const struct GNUNET_HashCode *key,
1407 size_t size,
1408 const void *data,
1409 enum GNUNET_BLOCK_Type type,
1410 uint32_t priority,
1411 uint32_t anonymity,
1412 uint32_t replication,
1413 struct GNUNET_TIME_Absolute expiration,
1414 uint64_t uid);
1415
1416
1417/* Start a local query */
1418static void
1419start_local_query (struct GSF_PendingRequest *pr,
1420 uint64_t next_uid,
1421 bool random)
1422{
1423 pr->qe_start = GNUNET_TIME_absolute_get ();
1424 pr->warn_task =
1425 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
1426 &warn_delay_task,
1427 pr);
1428 pr->qe =
1429 GNUNET_DATASTORE_get_key (GSF_dsh,
1430 next_uid,
1431 random,
1432 &pr->public_data.query,
1433 pr->public_data.type ==
1434 GNUNET_BLOCK_TYPE_FS_DBLOCK ?
1435 GNUNET_BLOCK_TYPE_ANY : pr->public_data.type,
1436 (0 !=
1437 (GSF_PRO_PRIORITY_UNLIMITED & pr->
1438 public_data.options)) ? UINT_MAX : 1
1439 /* queue priority */ ,
1440 (0 !=
1441 (GSF_PRO_PRIORITY_UNLIMITED & pr->
1442 public_data.options)) ? UINT_MAX :
1443 GSF_datastore_queue_size
1444 /* max queue size */ ,
1445 &process_local_reply, pr);
1446 if (NULL != pr->qe)
1447 return;
1448 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1449 "ERROR Requesting `%s' of type %d with next_uid %llu from datastore.\n",
1450 GNUNET_h2s (&pr->public_data.query),
1451 pr->public_data.type,
1452 (unsigned long long) next_uid);
1453 GNUNET_STATISTICS_update (GSF_stats,
1454 gettext_noop ("# Datastore lookups concluded (error queueing)"),
1455 1,
1456 GNUNET_NO);
1457 call_continuation (pr);
1458}
1459
1460
1343/** 1461/**
1344 * We're processing (local) results for a search request 1462 * We're processing (local) results for a search request
1345 * from another peer. Pass applicable results to the 1463 * from another peer. Pass applicable results to the
@@ -1353,6 +1471,7 @@ odc_warn_delay_task (void *cls)
1353 * @param type type of the content 1471 * @param type type of the content
1354 * @param priority priority of the content 1472 * @param priority priority of the content
1355 * @param anonymity anonymity-level for the content 1473 * @param anonymity anonymity-level for the content
1474 * @param replication replication-level for the content
1356 * @param expiration expiration time for the content 1475 * @param expiration expiration time for the content
1357 * @param uid unique identifier for the datum; 1476 * @param uid unique identifier for the datum;
1358 * maybe 0 if no unique identifier is available 1477 * maybe 0 if no unique identifier is available
@@ -1365,73 +1484,76 @@ process_local_reply (void *cls,
1365 enum GNUNET_BLOCK_Type type, 1484 enum GNUNET_BLOCK_Type type,
1366 uint32_t priority, 1485 uint32_t priority,
1367 uint32_t anonymity, 1486 uint32_t anonymity,
1487 uint32_t replication,
1368 struct GNUNET_TIME_Absolute expiration, 1488 struct GNUNET_TIME_Absolute expiration,
1369 uint64_t uid) 1489 uint64_t uid)
1370{ 1490{
1371 struct GSF_PendingRequest *pr = cls; 1491 struct GSF_PendingRequest *pr = cls;
1372 GSF_LocalLookupContinuation cont;
1373 struct ProcessReplyClosure prq; 1492 struct ProcessReplyClosure prq;
1374 struct GNUNET_HashCode query; 1493 struct GNUNET_HashCode query;
1375 unsigned int old_rf; 1494 unsigned int old_rf;
1376 1495
1377 GNUNET_SCHEDULER_cancel (pr->warn_task); 1496 GNUNET_SCHEDULER_cancel (pr->warn_task);
1378 pr->warn_task = NULL; 1497 pr->warn_task = NULL;
1379 if (NULL != pr->qe) 1498 if (NULL == pr->qe)
1499 goto called_from_on_demand;
1500 pr->qe = NULL;
1501 if ( (NULL == key) &&
1502 pr->seen_null &&
1503 !pr->have_first_uid) /* We have hit the end for the 2nd time with no results */
1380 { 1504 {
1381 pr->qe = NULL; 1505 /* No results */
1382 if (NULL == key)
1383 {
1384#if INSANE_STATISTICS 1506#if INSANE_STATISTICS
1385 GNUNET_STATISTICS_update (GSF_stats, 1507 GNUNET_STATISTICS_update (GSF_stats,
1386 gettext_noop 1508 gettext_noop
1387 ("# Datastore lookups concluded (no results)"), 1509 ("# Datastore lookups concluded (no results)"),
1388 1, GNUNET_NO); 1510 1, GNUNET_NO);
1389#endif 1511#endif
1390 } 1512 no_more_local_results (pr);
1391 if (GNUNET_NO == pr->have_first_uid) 1513 return;
1392 { 1514 }
1393 pr->first_uid = uid; 1515 if ( ( (NULL == key) &&
1394 pr->have_first_uid = 1; 1516 pr->seen_null ) || /* We have hit the end for the 2nd time OR */
1395 } 1517 ( pr->seen_null &&
1396 else 1518 pr->have_first_uid &&
1397 { 1519 (uid >= pr->first_uid) ) ) /* We have hit the end and past first UID */
1398 if ((uid == pr->first_uid) && (key != NULL)) 1520 {
1399 { 1521 /* Seen all results */
1400 GNUNET_STATISTICS_update (GSF_stats, 1522 GNUNET_STATISTICS_update (GSF_stats,
1401 gettext_noop 1523 gettext_noop
1402 ("# Datastore lookups concluded (seen all)"), 1524 ("# Datastore lookups concluded (seen all)"),
1403 1, GNUNET_NO); 1525 1, GNUNET_NO);
1404 key = NULL; /* all replies seen! */ 1526 no_more_local_results (pr);
1405 } 1527 return;
1406 pr->have_first_uid++;
1407 if ((pr->have_first_uid > MAX_RESULTS) && (key != NULL))
1408 {
1409 GNUNET_STATISTICS_update (GSF_stats,
1410 gettext_noop
1411 ("# Datastore lookups aborted (more than MAX_RESULTS)"),
1412 1, GNUNET_NO);
1413 key = NULL; /* all replies seen! */
1414 }
1415 }
1416 } 1528 }
1417 if (NULL == key) 1529 if (NULL == key)
1418 { 1530 {
1419 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 1531 GNUNET_assert (!pr->seen_null);
1420 "No further local responses available.\n"); 1532 pr->seen_null = true;
1421#if INSANE_STATISTICS 1533 start_local_query (pr,
1422 if ((pr->public_data.type == GNUNET_BLOCK_TYPE_FS_DBLOCK) || 1534 0 /* next_uid */,
1423 (pr->public_data.type == GNUNET_BLOCK_TYPE_FS_IBLOCK)) 1535 false /* random */);
1424 GNUNET_STATISTICS_update (GSF_stats, 1536 return;
1425 gettext_noop 1537 }
1426 ("# requested DBLOCK or IBLOCK not found"), 1, 1538 if (!pr->have_first_uid)
1427 GNUNET_NO); 1539 {
1428#endif 1540 pr->first_uid = uid;
1429 goto check_error_and_continue; 1541 pr->have_first_uid = true;
1542 }
1543 pr->result_count++;
1544 if (pr->result_count > MAX_RESULTS)
1545 {
1546 GNUNET_STATISTICS_update (GSF_stats,
1547 gettext_noop
1548 ("# Datastore lookups aborted (more than MAX_RESULTS)"),
1549 1, GNUNET_NO);
1550 no_more_local_results (pr);
1551 return;
1430 } 1552 }
1431 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1553 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1432 "Received reply for `%s' of type %d with UID %llu from datastore.\n", 1554 "Received reply for `%s' of type %d with UID %llu from datastore.\n",
1433 GNUNET_h2s (key), type, (unsigned long long) uid); 1555 GNUNET_h2s (key), type, (unsigned long long) uid);
1434 if (type == GNUNET_BLOCK_TYPE_FS_ONDEMAND) 1556 if (GNUNET_BLOCK_TYPE_FS_ONDEMAND == type)
1435 { 1557 {
1436 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1558 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1437 "Found ONDEMAND block, performing on-demand encoding\n"); 1559 "Found ONDEMAND block, performing on-demand encoding\n");
@@ -1444,9 +1566,17 @@ process_local_reply (void *cls,
1444 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, 1566 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
1445 &odc_warn_delay_task, pr); 1567 &odc_warn_delay_task, pr);
1446 if (GNUNET_OK == 1568 if (GNUNET_OK ==
1447 GNUNET_FS_handle_on_demand_block (key, size, data, type, priority, 1569 GNUNET_FS_handle_on_demand_block (key,
1448 anonymity, expiration, uid, 1570 size,
1449 &process_local_reply, pr)) 1571 data,
1572 type,
1573 priority,
1574 anonymity,
1575 replication,
1576 expiration,
1577 uid,
1578 &process_local_reply,
1579 pr))
1450 { 1580 {
1451 GNUNET_STATISTICS_update (GSF_stats, 1581 GNUNET_STATISTICS_update (GSF_stats,
1452 gettext_noop 1582 gettext_noop
@@ -1458,33 +1588,12 @@ process_local_reply (void *cls,
1458 gettext_noop ("# on-demand lookups failed"), 1, 1588 gettext_noop ("# on-demand lookups failed"), 1,
1459 GNUNET_NO); 1589 GNUNET_NO);
1460 GNUNET_SCHEDULER_cancel (pr->warn_task); 1590 GNUNET_SCHEDULER_cancel (pr->warn_task);
1461 pr->warn_task = 1591 start_local_query (pr,
1462 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, 1592 uid + 1 /* next_uid */,
1463 &warn_delay_task, pr); 1593 false /* random */);
1464 pr->qe = 1594 return;
1465 GNUNET_DATASTORE_get_key (GSF_dsh, pr->local_result_offset - 1,
1466 &pr->public_data.query,
1467 pr->public_data.type ==
1468 GNUNET_BLOCK_TYPE_FS_DBLOCK ?
1469 GNUNET_BLOCK_TYPE_ANY : pr->public_data.type,
1470 (0 !=
1471 (GSF_PRO_PRIORITY_UNLIMITED &
1472 pr->public_data.options)) ? UINT_MAX : 1
1473 /* queue priority */ ,
1474 (0 !=
1475 (GSF_PRO_PRIORITY_UNLIMITED &
1476 pr->public_data.options)) ? UINT_MAX :
1477 GSF_datastore_queue_size
1478 /* max queue size */ ,
1479 &process_local_reply, pr);
1480 if (NULL != pr->qe)
1481 return; /* we're done */
1482 GNUNET_STATISTICS_update (GSF_stats,
1483 gettext_noop
1484 ("# Datastore lookups concluded (error queueing)"),
1485 1, GNUNET_NO);
1486 goto check_error_and_continue;
1487 } 1595 }
1596called_from_on_demand:
1488 old_rf = pr->public_data.results_found; 1597 old_rf = pr->public_data.results_found;
1489 memset (&prq, 0, sizeof (prq)); 1598 memset (&prq, 0, sizeof (prq));
1490 prq.data = data; 1599 prq.data = data;
@@ -1496,34 +1605,9 @@ process_local_reply (void *cls,
1496 GNUNET_break (0); 1605 GNUNET_break (0);
1497 GNUNET_DATASTORE_remove (GSF_dsh, key, size, data, -1, -1, 1606 GNUNET_DATASTORE_remove (GSF_dsh, key, size, data, -1, -1,
1498 NULL, NULL); 1607 NULL, NULL);
1499 pr->qe_start = GNUNET_TIME_absolute_get (); 1608 start_local_query (pr,
1500 pr->warn_task = 1609 uid + 1 /* next_uid */,
1501 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, 1610 false /* random */);
1502 &warn_delay_task, pr);
1503 pr->qe =
1504 GNUNET_DATASTORE_get_key (GSF_dsh, pr->local_result_offset - 1,
1505 &pr->public_data.query,
1506 pr->public_data.type ==
1507 GNUNET_BLOCK_TYPE_FS_DBLOCK ?
1508 GNUNET_BLOCK_TYPE_ANY : pr->public_data.type,
1509 (0 !=
1510 (GSF_PRO_PRIORITY_UNLIMITED &
1511 pr->public_data.options)) ? UINT_MAX : 1
1512 /* queue priority */ ,
1513 (0 !=
1514 (GSF_PRO_PRIORITY_UNLIMITED &
1515 pr->public_data.options)) ? UINT_MAX :
1516 GSF_datastore_queue_size
1517 /* max queue size */ ,
1518 &process_local_reply, pr);
1519 if (NULL == pr->qe)
1520 {
1521 GNUNET_STATISTICS_update (GSF_stats,
1522 gettext_noop
1523 ("# Datastore lookups concluded (error queueing)"),
1524 1, GNUNET_NO);
1525 goto check_error_and_continue;
1526 }
1527 return; 1611 return;
1528 } 1612 }
1529 prq.type = type; 1613 prq.type = type;
@@ -1535,14 +1619,15 @@ process_local_reply (void *cls,
1535 prq.eo = GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO; 1619 prq.eo = GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO;
1536 process_reply (&prq, key, pr); 1620 process_reply (&prq, key, pr);
1537 pr->local_result = prq.eval; 1621 pr->local_result = prq.eval;
1538 if (prq.eval == GNUNET_BLOCK_EVALUATION_OK_LAST) 1622 if (GNUNET_BLOCK_EVALUATION_OK_LAST == prq.eval)
1539 { 1623 {
1540 GNUNET_STATISTICS_update (GSF_stats, 1624 GNUNET_STATISTICS_update (GSF_stats,
1541 gettext_noop 1625 gettext_noop
1542 ("# Datastore lookups concluded (found last result)"), 1626 ("# Datastore lookups concluded (found last result)"),
1543 1, 1627 1,
1544 GNUNET_NO); 1628 GNUNET_NO);
1545 goto check_error_and_continue; 1629 call_continuation (pr);
1630 return;
1546 } 1631 }
1547 if ((0 == (GSF_PRO_PRIORITY_UNLIMITED & pr->public_data.options)) && 1632 if ((0 == (GSF_PRO_PRIORITY_UNLIMITED & pr->public_data.options)) &&
1548 ((GNUNET_YES == GSF_test_get_load_too_high_ (0)) || 1633 ((GNUNET_YES == GSF_test_get_load_too_high_ (0)) ||
@@ -1554,66 +1639,12 @@ process_local_reply (void *cls,
1554 gettext_noop ("# Datastore lookups concluded (load too high)"), 1639 gettext_noop ("# Datastore lookups concluded (load too high)"),
1555 1, 1640 1,
1556 GNUNET_NO); 1641 GNUNET_NO);
1557 goto check_error_and_continue; 1642 call_continuation (pr);
1558 }
1559 pr->qe_start = GNUNET_TIME_absolute_get ();
1560 pr->warn_task =
1561 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
1562 &warn_delay_task,
1563 pr);
1564 pr->qe =
1565 GNUNET_DATASTORE_get_key (GSF_dsh, pr->local_result_offset++,
1566 &pr->public_data.query,
1567 pr->public_data.type ==
1568 GNUNET_BLOCK_TYPE_FS_DBLOCK ?
1569 GNUNET_BLOCK_TYPE_ANY : pr->public_data.type,
1570 (0 !=
1571 (GSF_PRO_PRIORITY_UNLIMITED & pr->
1572 public_data.options)) ? UINT_MAX : 1
1573 /* queue priority */ ,
1574 (0 !=
1575 (GSF_PRO_PRIORITY_UNLIMITED & pr->
1576 public_data.options)) ? UINT_MAX :
1577 GSF_datastore_queue_size
1578 /* max queue size */ ,
1579 &process_local_reply, pr);
1580 /* check if we successfully queued another datastore request;
1581 * if so, return, otherwise call our continuation (if we have
1582 * any) */
1583check_error_and_continue:
1584 if (NULL != pr->qe)
1585 return; 1643 return;
1586 if (NULL != pr->warn_task)
1587 {
1588 GNUNET_SCHEDULER_cancel (pr->warn_task);
1589 pr->warn_task = NULL;
1590 } 1644 }
1591 if (NULL == (cont = pr->llc_cont)) 1645 start_local_query (pr,
1592 return; /* no continuation */ 1646 uid + 1 /* next_uid */,
1593 pr->llc_cont = NULL; 1647 false /* random */);
1594 if (0 != (GSF_PRO_LOCAL_ONLY & pr->public_data.options))
1595 {
1596 if (GNUNET_BLOCK_EVALUATION_OK_LAST != pr->local_result)
1597 {
1598 /* Signal that we are done and that there won't be any
1599 additional results to allow client to clean up state. */
1600 pr->rh (pr->rh_cls,
1601 GNUNET_BLOCK_EVALUATION_OK_LAST,
1602 pr,
1603 UINT32_MAX,
1604 GNUNET_TIME_UNIT_ZERO_ABS,
1605 GNUNET_TIME_UNIT_FOREVER_ABS,
1606 GNUNET_BLOCK_TYPE_ANY,
1607 NULL, 0);
1608 }
1609 /* Finally, call our continuation to signal that we are
1610 done with local processing of this request; i.e. to
1611 start reading again from the client. */
1612 cont (pr->llc_cont_cls, NULL, GNUNET_BLOCK_EVALUATION_OK_LAST);
1613 return;
1614 }
1615
1616 cont (pr->llc_cont_cls, pr, pr->local_result);
1617} 1648}
1618 1649
1619 1650
@@ -1657,43 +1688,14 @@ GSF_local_lookup_ (struct GSF_PendingRequest *pr,
1657 GNUNET_assert (NULL == pr->llc_cont); 1688 GNUNET_assert (NULL == pr->llc_cont);
1658 pr->llc_cont = cont; 1689 pr->llc_cont = cont;
1659 pr->llc_cont_cls = cont_cls; 1690 pr->llc_cont_cls = cont_cls;
1660 pr->qe_start = GNUNET_TIME_absolute_get ();
1661 pr->warn_task =
1662 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
1663 &warn_delay_task,
1664 pr);
1665#if INSANE_STATISTICS 1691#if INSANE_STATISTICS
1666 GNUNET_STATISTICS_update (GSF_stats, 1692 GNUNET_STATISTICS_update (GSF_stats,
1667 gettext_noop ("# Datastore lookups initiated"), 1, 1693 gettext_noop ("# Datastore lookups initiated"), 1,
1668 GNUNET_NO); 1694 GNUNET_NO);
1669#endif 1695#endif
1670 pr->qe = 1696 start_local_query(pr,
1671 GNUNET_DATASTORE_get_key (GSF_dsh, pr->local_result_offset++, 1697 0 /* next_uid */,
1672 &pr->public_data.query, 1698 true /* random */);
1673 pr->public_data.type ==
1674 GNUNET_BLOCK_TYPE_FS_DBLOCK ?
1675 GNUNET_BLOCK_TYPE_ANY : pr->public_data.type,
1676 (0 !=
1677 (GSF_PRO_PRIORITY_UNLIMITED & pr->
1678 public_data.options)) ? UINT_MAX : 1
1679 /* queue priority */ ,
1680 (0 !=
1681 (GSF_PRO_PRIORITY_UNLIMITED & pr->
1682 public_data.options)) ? UINT_MAX :
1683 GSF_datastore_queue_size
1684 /* max queue size */ ,
1685 &process_local_reply, pr);
1686 if (NULL != pr->qe)
1687 return;
1688 GNUNET_STATISTICS_update (GSF_stats,
1689 gettext_noop
1690 ("# Datastore lookups concluded (error queueing)"),
1691 1, GNUNET_NO);
1692 GNUNET_SCHEDULER_cancel (pr->warn_task);
1693 pr->warn_task = NULL;
1694 pr->llc_cont = NULL;
1695 if (NULL != cont)
1696 cont (cont_cls, pr, pr->local_result);
1697} 1699}
1698 1700
1699 1701
diff --git a/src/fs/gnunet-service-fs_push.c b/src/fs/gnunet-service-fs_push.c
index 361d30755..21c598a72 100644
--- a/src/fs/gnunet-service-fs_push.c
+++ b/src/fs/gnunet-service-fs_push.c
@@ -448,6 +448,7 @@ consider_gathering ()
448 * @param type type of the content 448 * @param type type of the content
449 * @param priority priority of the content 449 * @param priority priority of the content
450 * @param anonymity anonymity-level for the content 450 * @param anonymity anonymity-level for the content
451 * @param replication replication-level for the content
451 * @param expiration expiration time for the content 452 * @param expiration expiration time for the content
452 * @param uid unique identifier for the datum; 453 * @param uid unique identifier for the datum;
453 * maybe 0 if no unique identifier is available 454 * maybe 0 if no unique identifier is available
@@ -460,6 +461,7 @@ process_migration_content (void *cls,
460 enum GNUNET_BLOCK_Type type, 461 enum GNUNET_BLOCK_Type type,
461 uint32_t priority, 462 uint32_t priority,
462 uint32_t anonymity, 463 uint32_t anonymity,
464 uint32_t replication,
463 struct GNUNET_TIME_Absolute expiration, 465 struct GNUNET_TIME_Absolute expiration,
464 uint64_t uid) 466 uint64_t uid)
465{ 467{
@@ -491,9 +493,11 @@ process_migration_content (void *cls,
491 type, 493 type,
492 priority, 494 priority,
493 anonymity, 495 anonymity,
496 replication,
494 expiration, 497 expiration,
495 uid, 498 uid,
496 &process_migration_content, NULL)) 499 &process_migration_content,
500 NULL))
497 consider_gathering (); 501 consider_gathering ();
498 return; 502 return;
499 } 503 }
diff --git a/src/fs/gnunet-service-fs_put.c b/src/fs/gnunet-service-fs_put.c
index bb4cb4ecb..e8c7f586d 100644
--- a/src/fs/gnunet-service-fs_put.c
+++ b/src/fs/gnunet-service-fs_put.c
@@ -72,9 +72,14 @@ struct PutOperator
72 uint64_t zero_anonymity_count_estimate; 72 uint64_t zero_anonymity_count_estimate;
73 73
74 /** 74 /**
75 * Current offset when iterating the database. 75 * Count of results received from the database.
76 */ 76 */
77 uint64_t current_offset; 77 uint64_t result_count;
78
79 /**
80 * Next UID to request when iterating the database.
81 */
82 uint64_t next_uid;
78}; 83};
79 84
80 85
@@ -171,43 +176,51 @@ delay_dht_put_task (void *cls)
171 * @param type type of the content 176 * @param type type of the content
172 * @param priority priority of the content 177 * @param priority priority of the content
173 * @param anonymity anonymity-level for the content 178 * @param anonymity anonymity-level for the content
179 * @param replication replication-level for the content
174 * @param expiration expiration time for the content 180 * @param expiration expiration time for the content
175 * @param uid unique identifier for the datum; 181 * @param uid unique identifier for the datum;
176 * maybe 0 if no unique identifier is available 182 * maybe 0 if no unique identifier is available
177 */ 183 */
178static void 184static void
179process_dht_put_content (void *cls, 185process_dht_put_content (void *cls,
180 const struct GNUNET_HashCode * key, 186 const struct GNUNET_HashCode * key,
181 size_t size, 187 size_t size,
182 const void *data, 188 const void *data,
183 enum GNUNET_BLOCK_Type type, 189 enum GNUNET_BLOCK_Type type,
184 uint32_t priority, uint32_t anonymity, 190 uint32_t priority,
185 struct GNUNET_TIME_Absolute expiration, uint64_t uid) 191 uint32_t anonymity,
192 uint32_t replication,
193 struct GNUNET_TIME_Absolute expiration,
194 uint64_t uid)
186{ 195{
187 struct PutOperator *po = cls; 196 struct PutOperator *po = cls;
188 197
189 po->dht_qe = NULL; 198 po->dht_qe = NULL;
190 if (key == NULL) 199 if (key == NULL)
191 { 200 {
192 po->zero_anonymity_count_estimate = po->current_offset - 1; 201 po->zero_anonymity_count_estimate = po->result_count;
193 po->current_offset = 0; 202 po->result_count = 0;
203 po->next_uid = 0;
194 po->dht_task = GNUNET_SCHEDULER_add_now (&delay_dht_put_task, po); 204 po->dht_task = GNUNET_SCHEDULER_add_now (&delay_dht_put_task, po);
195 return; 205 return;
196 } 206 }
207 po->result_count++;
208 po->next_uid = uid + 1;
197 po->zero_anonymity_count_estimate = 209 po->zero_anonymity_count_estimate =
198 GNUNET_MAX (po->current_offset, po->zero_anonymity_count_estimate); 210 GNUNET_MAX (po->result_count, po->zero_anonymity_count_estimate);
199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 211 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
200 "Retrieved block `%s' of type %u for DHT PUT\n", GNUNET_h2s (key), 212 "Retrieved block `%s' of type %u for DHT PUT\n", GNUNET_h2s (key),
201 type); 213 type);
202 po->dht_put = GNUNET_DHT_put (GSF_dht, 214 po->dht_put = GNUNET_DHT_put (GSF_dht,
203 key, 215 key,
204 DEFAULT_PUT_REPLICATION, 216 DEFAULT_PUT_REPLICATION,
205 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, 217 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
206 type, 218 type,
207 size, 219 size,
208 data, 220 data,
209 expiration, 221 expiration,
210 &delay_dht_put_blocks, po); 222 &delay_dht_put_blocks,
223 po);
211} 224}
212 225
213 226
@@ -223,10 +236,13 @@ gather_dht_put_blocks (void *cls)
223 236
224 po->dht_task = NULL; 237 po->dht_task = NULL;
225 po->dht_qe = 238 po->dht_qe =
226 GNUNET_DATASTORE_get_zero_anonymity (GSF_dsh, po->current_offset++, 0, 239 GNUNET_DATASTORE_get_zero_anonymity (GSF_dsh,
240 po->next_uid,
241 0,
227 UINT_MAX, 242 UINT_MAX,
228 po->dht_put_type, 243 po->dht_put_type,
229 &process_dht_put_content, po); 244 &process_dht_put_content,
245 po);
230 if (NULL == po->dht_qe) 246 if (NULL == po->dht_qe)
231 po->dht_task = GNUNET_SCHEDULER_add_now (&delay_dht_put_task, po); 247 po->dht_task = GNUNET_SCHEDULER_add_now (&delay_dht_put_task, po);
232} 248}
diff --git a/src/fs/gnunet-unindex.c b/src/fs/gnunet-unindex.c
index 40fa13b62..c53a85fb4 100644
--- a/src/fs/gnunet-unindex.c
+++ b/src/fs/gnunet-unindex.c
@@ -30,7 +30,7 @@
30 30
31static int ret; 31static int ret;
32 32
33static int verbose; 33static unsigned int verbose;
34 34
35static const struct GNUNET_CONFIGURATION_Handle *cfg; 35static const struct GNUNET_CONFIGURATION_Handle *cfg;
36 36
@@ -162,10 +162,10 @@ run (void *cls, char *const *args, const char *cfgfile,
162int 162int
163main (int argc, char *const *argv) 163main (int argc, char *const *argv)
164{ 164{
165 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 165 struct GNUNET_GETOPT_CommandLineOption options[] = {
166 {'V', "verbose", NULL, 166
167 gettext_noop ("be verbose (print progress information)"), 167 GNUNET_GETOPT_OPTION_VERBOSE (&verbose),
168 0, &GNUNET_GETOPT_set_one, &verbose}, 168
169 GNUNET_GETOPT_OPTION_END 169 GNUNET_GETOPT_OPTION_END
170 }; 170 };
171 171
diff --git a/src/gns/gns_api.c b/src/gns/gns_api.c
index 15a59a4bc..26293f4df 100644
--- a/src/gns/gns_api.c
+++ b/src/gns/gns_api.c
@@ -391,7 +391,7 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle,
391 "Trying to lookup `%s' in GNS\n", 391 "Trying to lookup `%s' in GNS\n",
392 name); 392 name);
393 nlen = strlen (name) + 1; 393 nlen = strlen (name) + 1;
394 if (nlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*lr)) 394 if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (*lr))
395 { 395 {
396 GNUNET_break (0); 396 GNUNET_break (0);
397 return NULL; 397 return NULL;
diff --git a/src/gns/gnunet-bcd.c b/src/gns/gnunet-bcd.c
index 21471350d..fb7ac10c1 100644
--- a/src/gns/gnunet-bcd.c
+++ b/src/gns/gnunet-bcd.c
@@ -514,10 +514,14 @@ run (void *cls,
514int 514int
515main (int argc, char *const *argv) 515main (int argc, char *const *argv)
516{ 516{
517 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 517 struct GNUNET_GETOPT_CommandLineOption options[] = {
518 {'p', "port", "PORT", 518
519 gettext_noop ("Run HTTP serve on port PORT (default is 8888)"), 1, 519 GNUNET_GETOPT_OPTION_SET_UINT ('p',
520 &GNUNET_GETOPT_set_uint, &port}, 520 "port",
521 "PORT",
522 gettext_noop ("Run HTTP serve on port PORT (default is 8888)"),
523 &port),
524
521 GNUNET_GETOPT_OPTION_END 525 GNUNET_GETOPT_OPTION_END
522 }; 526 };
523 int ret; 527 int ret;
diff --git a/src/gns/gnunet-dns2gns.c b/src/gns/gnunet-dns2gns.c
index 813ecdf8e..c9b4bde9c 100644
--- a/src/gns/gnunet-dns2gns.c
+++ b/src/gns/gnunet-dns2gns.c
@@ -776,22 +776,38 @@ int
776main (int argc, 776main (int argc,
777 char *const *argv) 777 char *const *argv)
778{ 778{
779 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 779 struct GNUNET_GETOPT_CommandLineOption options[] = {
780 {'d', "dns", "IP", 780
781 gettext_noop ("IP of recursive DNS resolver to use (required)"), 1, 781 GNUNET_GETOPT_OPTION_STRING ('d',
782 &GNUNET_GETOPT_set_string, &dns_ip}, 782 "dns",
783 {'f', "fcfs", "NAME", 783 "IP",
784 gettext_noop ("Authoritative FCFS suffix to use (optional); default: fcfs.zkey.eu"), 1, 784 gettext_noop ("IP of recursive DNS resolver to use (required)"),
785 &GNUNET_GETOPT_set_string, &fcfs_suffix}, 785 &dns_ip),
786 {'s', "suffix", "SUFFIX", 786
787 gettext_noop ("Authoritative DNS suffix to use (optional); default: zkey.eu"), 1, 787 GNUNET_GETOPT_OPTION_STRING ('f',
788 &GNUNET_GETOPT_set_string, &dns_suffix}, 788 "fcfs",
789 {'p', "port", "UDPPORT", 789 "NAME",
790 gettext_noop ("UDP port to listen on for inbound DNS requests; default: 2853"), 1, 790 gettext_noop ("Authoritative FCFS suffix to use (optional); default: fcfs.zkey.eu"),
791 &GNUNET_GETOPT_set_uint, &listen_port}, 791 &fcfs_suffix),
792 {'z', "zone", "PUBLICKEY", 792
793 gettext_noop ("Public key of the GNS zone to use (overrides default)"), 1, 793 GNUNET_GETOPT_OPTION_STRING ('s',
794 &GNUNET_GETOPT_set_string, &gns_zone_str}, 794 "suffix",
795 "SUFFIX",
796 gettext_noop ("Authoritative DNS suffix to use (optional); default: zkey.eu"),
797 &dns_suffix),
798
799 GNUNET_GETOPT_OPTION_SET_UINT ('p',
800 "port",
801 "UDPPORT",
802 gettext_noop ("UDP port to listen on for inbound DNS requests; default: 2853"),
803 &listen_port),
804
805 GNUNET_GETOPT_OPTION_STRING ('z',
806 "zone",
807 "PUBLICKEY",
808 gettext_noop ("Public key of the GNS zone to use (overrides default)"),
809 &gns_zone_str),
810
795 GNUNET_GETOPT_OPTION_END 811 GNUNET_GETOPT_OPTION_END
796 }; 812 };
797 int ret; 813 int ret;
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c
index c336848ce..35f42cdec 100644
--- a/src/gns/gnunet-gns-proxy.c
+++ b/src/gns/gnunet-gns-proxy.c
@@ -621,7 +621,7 @@ struct Socks5Request
621/** 621/**
622 * The port the proxy is running on (default 7777) 622 * The port the proxy is running on (default 7777)
623 */ 623 */
624static unsigned long port = GNUNET_GNS_PROXY_PORT; 624static unsigned long long port = GNUNET_GNS_PROXY_PORT;
625 625
626/** 626/**
627 * The CA file (pem) to use for the proxy CA 627 * The CA file (pem) to use for the proxy CA
@@ -3108,7 +3108,7 @@ run_cont ()
3108 return; 3108 return;
3109 } 3109 }
3110 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3110 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3111 "Proxy listens on port %lu\n", 3111 "Proxy listens on port %llu\n",
3112 port); 3112 port);
3113 3113
3114 /* start MHD daemon for HTTP */ 3114 /* start MHD daemon for HTTP */
@@ -3261,13 +3261,20 @@ run (void *cls,
3261int 3261int
3262main (int argc, char *const *argv) 3262main (int argc, char *const *argv)
3263{ 3263{
3264 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 3264 struct GNUNET_GETOPT_CommandLineOption options[] = {
3265 {'p', "port", NULL, 3265
3266 gettext_noop ("listen on specified port (default: 7777)"), 1, 3266 GNUNET_GETOPT_OPTION_SET_ULONG ('p',
3267 &GNUNET_GETOPT_set_ulong, &port}, 3267 "port",
3268 {'a', "authority", NULL, 3268 NULL,
3269 gettext_noop ("pem file to use as CA"), 1, 3269 gettext_noop ("listen on specified port (default: 7777)"),
3270 &GNUNET_GETOPT_set_string, &cafile_opt}, 3270 &port),
3271
3272 GNUNET_GETOPT_OPTION_STRING ('a',
3273 "authority",
3274 NULL,
3275 gettext_noop ("pem file to use as CA"),
3276 &cafile_opt),
3277
3271 GNUNET_GETOPT_OPTION_END 3278 GNUNET_GETOPT_OPTION_END
3272 }; 3279 };
3273 static const char* page = 3280 static const char* page =
diff --git a/src/gns/gnunet-gns.c b/src/gns/gnunet-gns.c
index a261e008b..c85ddfe81 100644
--- a/src/gns/gnunet-gns.c
+++ b/src/gns/gnunet-gns.c
@@ -420,25 +420,43 @@ int
420main (int argc, 420main (int argc,
421 char *const *argv) 421 char *const *argv)
422{ 422{
423 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 423 struct GNUNET_GETOPT_CommandLineOption options[] = {
424 {'u', "lookup", "NAME", 424
425 gettext_noop ("Lookup a record for the given name"), 1, 425 GNUNET_GETOPT_OPTION_STRING ('u',
426 &GNUNET_GETOPT_set_string, &lookup_name}, 426 "lookup",
427 {'t', "type", "TYPE", 427 "NAME",
428 gettext_noop ("Specify the type of the record to lookup"), 1, 428 gettext_noop ("Lookup a record for the given name"),
429 &GNUNET_GETOPT_set_string, &lookup_type}, 429 &lookup_name),
430 { 'T', "timeout", "DELAY", 430
431 gettext_noop ("Specify timeout for the lookup"), 1, 431 GNUNET_GETOPT_OPTION_STRING ('t',
432 &GNUNET_GETOPT_set_relative_time, &timeout }, 432 "type",
433 {'r', "raw", NULL, 433 "TYPE",
434 gettext_noop ("No unneeded output"), 0, 434 gettext_noop ("Specify the type of the record to lookup"),
435 &GNUNET_GETOPT_set_one, &raw}, 435 &lookup_type),
436 {'p', "public-key", "PKEY", 436
437 gettext_noop ("Specify the public key of the zone to lookup the record in"), 1, 437 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('T',
438 &GNUNET_GETOPT_set_string, &public_key}, 438 "timeout",
439 {'z', "zone", "NAME", 439 "DELAY",
440 gettext_noop ("Specify the name of the ego of the zone to lookup the record in"), 1, 440 gettext_noop ("Specify timeout for the lookup"),
441 &GNUNET_GETOPT_set_string, &zone_ego_name}, 441 &timeout),
442
443 GNUNET_GETOPT_OPTION_SET_ONE ('r',
444 "raw",
445 gettext_noop ("No unneeded output"),
446 &raw),
447
448 GNUNET_GETOPT_OPTION_STRING ('p',
449 "public-key",
450 "PKEY",
451 gettext_noop ("Specify the public key of the zone to lookup the record in"),
452 &public_key),
453
454 GNUNET_GETOPT_OPTION_STRING ('z',
455 "zone",
456 "NAME",
457 gettext_noop ("Specify the name of the ego of the zone to lookup the record in"),
458 &zone_ego_name),
459
442 GNUNET_GETOPT_OPTION_END 460 GNUNET_GETOPT_OPTION_END
443 }; 461 };
444 int ret; 462 int ret;
diff --git a/src/hello/hello.c b/src/hello/hello.c
index f9b21aa4f..27580275f 100644
--- a/src/hello/hello.c
+++ b/src/hello/hello.c
@@ -206,7 +206,7 @@ GNUNET_HELLO_create (const struct GNUNET_CRYPTO_EddsaPublicKey *public_key,
206 void *addrgen_cls, 206 void *addrgen_cls,
207 int friend_only) 207 int friend_only)
208{ 208{
209 char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - 256 - 209 char buffer[GNUNET_MAX_MESSAGE_SIZE - 1 - 256 -
210 sizeof (struct GNUNET_HELLO_Message)]; 210 sizeof (struct GNUNET_HELLO_Message)];
211 size_t max; 211 size_t max;
212 size_t used; 212 size_t used;
diff --git a/src/hostlist/gnunet-daemon-hostlist.c b/src/hostlist/gnunet-daemon-hostlist.c
index a83d46e07..9b4790c32 100644
--- a/src/hostlist/gnunet-daemon-hostlist.c
+++ b/src/hostlist/gnunet-daemon-hostlist.c
@@ -369,23 +369,26 @@ run (void *cls,
369int 369int
370main (int argc, char *const *argv) 370main (int argc, char *const *argv)
371{ 371{
372 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 372 struct GNUNET_GETOPT_CommandLineOption options[] = {
373#if HAVE_MHD 373#if HAVE_MHD
374 {'a', "advertise", NULL, 374 GNUNET_GETOPT_OPTION_SET_ONE ('a',
375 gettext_noop ("advertise our hostlist to other peers"), 375 "advertise",
376 GNUNET_NO, &GNUNET_GETOPT_set_one, &advertising}, 376 gettext_noop ("advertise our hostlist to other peers"),
377 &advertising),
377#endif 378#endif
378 {'b', "bootstrap", NULL, 379 GNUNET_GETOPT_OPTION_SET_ONE ('b',
379 gettext_noop 380 "bootstrap",
380 ("bootstrap using hostlists (it is highly recommended that you always use this option)"), 381 gettext_noop ("bootstrap using hostlists (it is highly recommended that you always use this option)"),
381 GNUNET_NO, &GNUNET_GETOPT_set_one, &bootstrapping}, 382 &bootstrapping),
382 {'e', "enable-learning", NULL, 383 GNUNET_GETOPT_OPTION_SET_ONE ('e',
383 gettext_noop ("enable learning about hostlist servers from other peers"), 384 "enable-learning",
384 GNUNET_NO, &GNUNET_GETOPT_set_one, &learning}, 385 gettext_noop ("enable learning about hostlist servers from other peers"),
386 &learning),
385#if HAVE_MHD 387#if HAVE_MHD
386 {'p', "provide-hostlist", NULL, 388 GNUNET_GETOPT_OPTION_SET_ONE ('p',
387 gettext_noop ("provide a hostlist server"), 389 "provide-hostlist",
388 GNUNET_NO, &GNUNET_GETOPT_set_one, &provide_hostlist}, 390 gettext_noop ("provide a hostlist server"),
391 &provide_hostlist),
389#endif 392#endif
390 GNUNET_GETOPT_OPTION_END 393 GNUNET_GETOPT_OPTION_END
391 }; 394 };
diff --git a/src/hostlist/gnunet-daemon-hostlist_client.c b/src/hostlist/gnunet-daemon-hostlist_client.c
index a973fcc28..207cc4a81 100644
--- a/src/hostlist/gnunet-daemon-hostlist_client.c
+++ b/src/hostlist/gnunet-daemon-hostlist_client.c
@@ -350,7 +350,7 @@ callback_download (void *ptr,
350 size_t nmemb, 350 size_t nmemb,
351 void *ctx) 351 void *ctx)
352{ 352{
353 static char download_buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; 353 static char download_buffer[GNUNET_MAX_MESSAGE_SIZE - 1];
354 const char *cbuf = ptr; 354 const char *cbuf = ptr;
355 const struct GNUNET_MessageHeader *msg; 355 const struct GNUNET_MessageHeader *msg;
356 struct HelloOffer *ho; 356 struct HelloOffer *ho;
@@ -373,7 +373,7 @@ callback_download (void *ptr,
373 left = total; 373 left = total;
374 while ((left > 0) || (download_pos > 0)) 374 while ((left > 0) || (download_pos > 0))
375 { 375 {
376 cpy = GNUNET_MIN (left, GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - download_pos); 376 cpy = GNUNET_MIN (left, GNUNET_MAX_MESSAGE_SIZE - 1 - download_pos);
377 GNUNET_memcpy (&download_buffer[download_pos], cbuf, cpy); 377 GNUNET_memcpy (&download_buffer[download_pos], cbuf, cpy);
378 cbuf += cpy; 378 cbuf += cpy;
379 download_pos += cpy; 379 download_pos += cpy;
@@ -1042,7 +1042,7 @@ download_hostlist ()
1042#if 0 1042#if 0
1043 CURL_EASY_SETOPT (curl, CURLOPT_VERBOSE, 1); 1043 CURL_EASY_SETOPT (curl, CURLOPT_VERBOSE, 1);
1044#endif 1044#endif
1045 CURL_EASY_SETOPT (curl, CURLOPT_BUFFERSIZE, GNUNET_SERVER_MAX_MESSAGE_SIZE); 1045 CURL_EASY_SETOPT (curl, CURLOPT_BUFFERSIZE, GNUNET_MAX_MESSAGE_SIZE);
1046 if (0 == strncmp (current_url, "http", 4)) 1046 if (0 == strncmp (current_url, "http", 4))
1047 CURL_EASY_SETOPT (curl, CURLOPT_USERAGENT, "GNUnet"); 1047 CURL_EASY_SETOPT (curl, CURLOPT_USERAGENT, "GNUnet");
1048 CURL_EASY_SETOPT (curl, CURLOPT_CONNECTTIMEOUT, 60L); 1048 CURL_EASY_SETOPT (curl, CURLOPT_CONNECTTIMEOUT, 60L);
diff --git a/src/hostlist/gnunet-daemon-hostlist_server.c b/src/hostlist/gnunet-daemon-hostlist_server.c
index 48c1a5622..3df6f1ef8 100644
--- a/src/hostlist/gnunet-daemon-hostlist_server.c
+++ b/src/hostlist/gnunet-daemon-hostlist_server.c
@@ -489,7 +489,7 @@ connect_handler (void *cls,
489 return NULL; 489 return NULL;
490 size = strlen (hostlist_uri) + 1; 490 size = strlen (hostlist_uri) + 1;
491 if (size + sizeof (struct GNUNET_MessageHeader) >= 491 if (size + sizeof (struct GNUNET_MessageHeader) >=
492 GNUNET_SERVER_MAX_MESSAGE_SIZE) 492 GNUNET_MAX_MESSAGE_SIZE)
493 { 493 {
494 GNUNET_break (0); 494 GNUNET_break (0);
495 return NULL; 495 return NULL;
diff --git a/src/identity-provider/gnunet-identity-token.c b/src/identity-provider/gnunet-identity-token.c
index 4bb3292be..906899ea7 100644
--- a/src/identity-provider/gnunet-identity-token.c
+++ b/src/identity-provider/gnunet-identity-token.c
@@ -158,13 +158,18 @@ run (void *cls,
158int 158int
159main(int argc, char *const argv[]) 159main(int argc, char *const argv[])
160{ 160{
161 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 161 struct GNUNET_GETOPT_CommandLineOption options[] = {
162 {'t', "token", NULL, 162
163 gettext_noop ("GNUid token"), 1, 163 GNUNET_GETOPT_OPTION_STRING ('t',
164 &GNUNET_GETOPT_set_string, &token}, 164 "token",
165 {'p', "print", NULL, 165 NULL,
166 gettext_noop ("Print token contents"), 0, 166 gettext_noop ("GNUid token"),
167 &GNUNET_GETOPT_set_one, &print_token}, 167 &token),
168
169 GNUNET_GETOPT_OPTION_SET_ONE ('p',
170 "print",
171 gettext_noop ("Print token contents"),
172 &print_token),
168 173
169 GNUNET_GETOPT_OPTION_END 174 GNUNET_GETOPT_OPTION_END
170 }; 175 };
diff --git a/src/identity-provider/identity_provider_api.c b/src/identity-provider/identity_provider_api.c
index 32c3cb703..845d1f753 100644
--- a/src/identity-provider/identity_provider_api.c
+++ b/src/identity-provider/identity_provider_api.c
@@ -440,7 +440,7 @@ GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id
440 size_t slen; 440 size_t slen;
441 441
442 slen = strlen (scopes) + 1; 442 slen = strlen (scopes) + 1;
443 if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct IssueMessage)) 443 if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct IssueMessage))
444 { 444 {
445 GNUNET_break (0); 445 GNUNET_break (0);
446 return NULL; 446 return NULL;
@@ -493,7 +493,7 @@ GNUNET_IDENTITY_PROVIDER_exchange_ticket (struct GNUNET_IDENTITY_PROVIDER_Handle
493 ticket_str = GNUNET_IDENTITY_PROVIDER_ticket_to_string (ticket); 493 ticket_str = GNUNET_IDENTITY_PROVIDER_ticket_to_string (ticket);
494 494
495 slen = strlen (ticket_str) + 1; 495 slen = strlen (ticket_str) + 1;
496 if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct ExchangeMessage)) 496 if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct ExchangeMessage))
497 { 497 {
498 GNUNET_free (ticket_str); 498 GNUNET_free (ticket_str);
499 GNUNET_break (0); 499 GNUNET_break (0);
diff --git a/src/identity/gnunet-identity.c b/src/identity/gnunet-identity.c
index 8c8485249..5c457ef5d 100644
--- a/src/identity/gnunet-identity.c
+++ b/src/identity/gnunet-identity.c
@@ -349,25 +349,41 @@ run (void *cls,
349int 349int
350main (int argc, char *const *argv) 350main (int argc, char *const *argv)
351{ 351{
352 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 352 struct GNUNET_GETOPT_CommandLineOption options[] = {
353 {'C', "create", "NAME", 353 GNUNET_GETOPT_OPTION_STRING ('C',
354 gettext_noop ("create ego NAME"), 354 "create",
355 1, &GNUNET_GETOPT_set_string, &create_ego}, 355 "NAME",
356 {'D', "delete", "NAME", 356 gettext_noop ("create ego NAME"),
357 gettext_noop ("delete ego NAME "), 357 &create_ego),
358 1, &GNUNET_GETOPT_set_string, &delete_ego}, 358
359 {'d', "display", NULL, 359 GNUNET_GETOPT_OPTION_STRING ('D',
360 gettext_noop ("display all egos"), 360 "delete",
361 0, &GNUNET_GETOPT_set_one, &list}, 361 "NAME",
362 {'e', "ego", "NAME", 362 gettext_noop ("delete ego NAME "),
363 gettext_noop ("set default identity to EGO for a subsystem SUBSYSTEM (use together with -s)"), 363 &delete_ego),
364 1, &GNUNET_GETOPT_set_string, &set_ego}, 364
365 {'m', "monitor", NULL, 365 GNUNET_GETOPT_OPTION_SET_ONE ('d',
366 gettext_noop ("run in monitor mode egos"), 366 "display",
367 0, &GNUNET_GETOPT_set_one, &monitor}, 367 gettext_noop ("display all egos"),
368 {'s', "set", "SUBSYSTEM", 368 &list),
369 gettext_noop ("set default identity to EGO for a subsystem SUBSYSTEM (use together with -e)"), 369
370 1, &GNUNET_GETOPT_set_string, &set_subsystem}, 370 GNUNET_GETOPT_OPTION_STRING ('e',
371 "ego",
372 "NAME",
373 gettext_noop ("set default identity to EGO for a subsystem SUBSYSTEM (use together with -s)"),
374 &set_ego),
375
376 GNUNET_GETOPT_OPTION_SET_ONE ('m',
377 "monitor",
378 gettext_noop ("run in monitor mode egos"),
379 &monitor),
380
381 GNUNET_GETOPT_OPTION_STRING ('s',
382 "set",
383 "SUBSYSTEM",
384 gettext_noop ("set default identity to EGO for a subsystem SUBSYSTEM (use together with -e)"),
385 &set_subsystem),
386
371 GNUNET_GETOPT_OPTION_END 387 GNUNET_GETOPT_OPTION_END
372 }; 388 };
373 int res; 389 int res;
diff --git a/src/identity/identity_api.c b/src/identity/identity_api.c
index 905b3fd8b..1601ae2fd 100644
--- a/src/identity/identity_api.c
+++ b/src/identity/identity_api.c
@@ -671,7 +671,7 @@ GNUNET_IDENTITY_get (struct GNUNET_IDENTITY_Handle *h,
671 if (NULL == h->mq) 671 if (NULL == h->mq)
672 return NULL; 672 return NULL;
673 slen = strlen (service_name) + 1; 673 slen = strlen (service_name) + 1;
674 if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GetDefaultMessage)) 674 if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct GetDefaultMessage))
675 { 675 {
676 GNUNET_break (0); 676 GNUNET_break (0);
677 return NULL; 677 return NULL;
@@ -722,7 +722,7 @@ GNUNET_IDENTITY_set (struct GNUNET_IDENTITY_Handle *h,
722 if (NULL == h->mq) 722 if (NULL == h->mq)
723 return NULL; 723 return NULL;
724 slen = strlen (service_name) + 1; 724 slen = strlen (service_name) + 1;
725 if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct SetDefaultMessage)) 725 if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct SetDefaultMessage))
726 { 726 {
727 GNUNET_break (0); 727 GNUNET_break (0);
728 return NULL; 728 return NULL;
@@ -773,7 +773,7 @@ GNUNET_IDENTITY_create (struct GNUNET_IDENTITY_Handle *h,
773 if (NULL == h->mq) 773 if (NULL == h->mq)
774 return NULL; 774 return NULL;
775 slen = strlen (name) + 1; 775 slen = strlen (name) + 1;
776 if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct CreateRequestMessage)) 776 if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct CreateRequestMessage))
777 { 777 {
778 GNUNET_break (0); 778 GNUNET_break (0);
779 return NULL; 779 return NULL;
@@ -830,9 +830,9 @@ GNUNET_IDENTITY_rename (struct GNUNET_IDENTITY_Handle *h,
830 return NULL; 830 return NULL;
831 slen_old = strlen (old_name) + 1; 831 slen_old = strlen (old_name) + 1;
832 slen_new = strlen (new_name) + 1; 832 slen_new = strlen (new_name) + 1;
833 if ( (slen_old >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || 833 if ( (slen_old >= GNUNET_MAX_MESSAGE_SIZE) ||
834 (slen_new >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || 834 (slen_new >= GNUNET_MAX_MESSAGE_SIZE) ||
835 (slen_old + slen_new >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct RenameMessage)) ) 835 (slen_old + slen_new >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct RenameMessage)) )
836 { 836 {
837 GNUNET_break (0); 837 GNUNET_break (0);
838 return NULL; 838 return NULL;
@@ -885,7 +885,7 @@ GNUNET_IDENTITY_delete (struct GNUNET_IDENTITY_Handle *h,
885 if (NULL == h->mq) 885 if (NULL == h->mq)
886 return NULL; 886 return NULL;
887 slen = strlen (name) + 1; 887 slen = strlen (name) + 1;
888 if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct DeleteMessage)) 888 if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct DeleteMessage))
889 { 889 {
890 GNUNET_break (0); 890 GNUNET_break (0);
891 return NULL; 891 return NULL;
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index 4fb2577fd..b745da125 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -38,7 +38,6 @@ gnunetinclude_HEADERS = \
38 gnunet_common.h \ 38 gnunet_common.h \
39 gnunet_constants.h \ 39 gnunet_constants.h \
40 gnunet_configuration_lib.h \ 40 gnunet_configuration_lib.h \
41 gnunet_connection_lib.h \
42 gnunet_consensus_service.h \ 41 gnunet_consensus_service.h \
43 gnunet_container_lib.h \ 42 gnunet_container_lib.h \
44 gnunet_conversation_service.h \ 43 gnunet_conversation_service.h \
@@ -107,7 +106,6 @@ gnunetinclude_HEADERS = \
107 gnunet_scalarproduct_service.h \ 106 gnunet_scalarproduct_service.h \
108 gnunet_scheduler_lib.h \ 107 gnunet_scheduler_lib.h \
109 gnunet_secretsharing_service.h \ 108 gnunet_secretsharing_service.h \
110 gnunet_server_lib.h \
111 gnunet_service_lib.h \ 109 gnunet_service_lib.h \
112 gnunet_set_service.h \ 110 gnunet_set_service.h \
113 gnunet_signal_lib.h \ 111 gnunet_signal_lib.h \
diff --git a/src/include/gnunet_bandwidth_lib.h b/src/include/gnunet_bandwidth_lib.h
index 178ddaaac..967d50dea 100644
--- a/src/include/gnunet_bandwidth_lib.h
+++ b/src/include/gnunet_bandwidth_lib.h
@@ -133,7 +133,7 @@ struct GNUNET_BANDWIDTH_Tracker
133 /** 133 /**
134 * Maximum number of seconds over which bandwidth may "accumulate". 134 * Maximum number of seconds over which bandwidth may "accumulate".
135 * Note that additionally, we also always allow at least 135 * Note that additionally, we also always allow at least
136 * #GNUNET_SERVER_MAX_MESSAGE_SIZE to accumulate. 136 * #GNUNET_MAX_MESSAGE_SIZE to accumulate.
137 */ 137 */
138 uint32_t max_carry_s__; 138 uint32_t max_carry_s__;
139}; 139};
@@ -214,10 +214,10 @@ GNUNET_BANDWIDTH_value_max (struct GNUNET_BANDWIDTH_Value32NBO b1,
214/** 214/**
215 * Initialize bandwidth tracker. Note that in addition to the 215 * Initialize bandwidth tracker. Note that in addition to the
216 * 'max_carry_s' limit, we also always allow at least 216 * 'max_carry_s' limit, we also always allow at least
217 * #GNUNET_SERVER_MAX_MESSAGE_SIZE to accumulate. So if the 217 * #GNUNET_MAX_MESSAGE_SIZE to accumulate. So if the
218 * bytes-per-second limit is so small that within 'max_carry_s' not 218 * bytes-per-second limit is so small that within 'max_carry_s' not
219 * even #GNUNET_SERVER_MAX_MESSAGE_SIZE is allowed to accumulate, it is 219 * even #GNUNET_MAX_MESSAGE_SIZE is allowed to accumulate, it is
220 * ignored and replaced by #GNUNET_SERVER_MAX_MESSAGE_SIZE (which is in 220 * ignored and replaced by #GNUNET_MAX_MESSAGE_SIZE (which is in
221 * bytes). 221 * bytes).
222 * 222 *
223 * @param av tracker to initialize 223 * @param av tracker to initialize
@@ -238,10 +238,10 @@ GNUNET_BANDWIDTH_tracker_init (struct GNUNET_BANDWIDTH_Tracker *av,
238/** 238/**
239 * Initialize bandwidth tracker. Note that in addition to the 239 * Initialize bandwidth tracker. Note that in addition to the
240 * 'max_carry_s' limit, we also always allow at least 240 * 'max_carry_s' limit, we also always allow at least
241 * GNUNET_SERVER_MAX_MESSAGE_SIZE to accumulate. So if the 241 * GNUNET_MAX_MESSAGE_SIZE to accumulate. So if the
242 * bytes-per-second limit is so small that within 'max_carry_s' not 242 * bytes-per-second limit is so small that within 'max_carry_s' not
243 * even GNUNET_SERVER_MAX_MESSAGE_SIZE is allowed to accumulate, it is 243 * even GNUNET_MAX_MESSAGE_SIZE is allowed to accumulate, it is
244 * ignored and replaced by GNUNET_SERVER_MAX_MESSAGE_SIZE (which is in 244 * ignored and replaced by GNUNET_MAX_MESSAGE_SIZE (which is in
245 * bytes). 245 * bytes).
246 * 246 *
247 * @param av tracker to initialize 247 * @param av tracker to initialize
diff --git a/src/include/gnunet_connection_lib.h b/src/include/gnunet_connection_lib.h
deleted file mode 100644
index e9dd95d1b..000000000
--- a/src/include/gnunet_connection_lib.h
+++ /dev/null
@@ -1,400 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @author Christian Grothoff
23 *
24 * @file include/gnunet_connection_lib.h
25 * Basic, low-level TCP networking interface
26 *
27 * @defgroup connection Connection library
28 * Basic, low-level TCP networking interface
29 * @{
30 */
31#ifndef GNUNET_CONNECTION_LIB_H
32#define GNUNET_CONNECTION_LIB_H
33
34#ifdef __cplusplus
35extern "C"
36{
37#if 0 /* keep Emacsens' auto-indent happy */
38}
39#endif
40#endif
41
42#include "gnunet_network_lib.h"
43#include "gnunet_scheduler_lib.h"
44#include "gnunet_time_lib.h"
45
46/**
47 * Timeout we use on TCP connect before trying another
48 * result from the DNS resolver. Actual value used
49 * is this value divided by the number of address families.
50 * Default is 5s.
51 */
52#define GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
53
54/**
55 * @brief handle for a network connection
56 */
57struct GNUNET_CONNECTION_Handle;
58
59
60/**
61 * Credentials for UNIX domain sockets.
62 */
63struct GNUNET_CONNECTION_Credentials
64{
65 /**
66 * UID of the other end of the connection.
67 */
68 uid_t uid;
69
70 /**
71 * GID of the other end of the connection.
72 */
73 gid_t gid;
74};
75
76
77/**
78 * Function to call for access control checks.
79 *
80 * @param cls closure
81 * @param ucred credentials, if available, otherwise NULL
82 * @param addr address
83 * @param addrlen length of address
84 * @return GNUNET_YES to allow, GNUNET_NO to deny, GNUNET_SYSERR
85 * for unknown address family (will be denied).
86 */
87typedef int (*GNUNET_CONNECTION_AccessCheck) (void *cls,
88 const struct
89 GNUNET_CONNECTION_Credentials *
90 ucred,
91 const struct sockaddr * addr,
92 socklen_t addrlen);
93
94
95/**
96 * Callback function for data received from the network. Note that
97 * both "available" and "err" would be 0 if the read simply timed out.
98 *
99 * @param cls closure
100 * @param buf pointer to received data
101 * @param available number of bytes availabe in "buf",
102 * possibly 0 (on errors)
103 * @param addr address of the sender
104 * @param addrlen size of addr
105 * @param errCode value of errno (on errors receiving)
106 */
107typedef void (*GNUNET_CONNECTION_Receiver) (void *cls, const void *buf,
108 size_t available,
109 const struct sockaddr * addr,
110 socklen_t addrlen, int errCode);
111
112/**
113 * Set the persist option on this connection handle. Indicates
114 * that the underlying socket or fd should never really be closed.
115 * Used for indicating process death.
116 *
117 * @param connection the connection to set persistent
118 */
119void
120GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *connection);
121
122/**
123 * Disable the "CORK" feature for communication with the given socket,
124 * forcing the OS to immediately flush the buffer on transmission
125 * instead of potentially buffering multiple messages. Essentially
126 * reduces the OS send buffers to zero.
127 * Used to make sure that the last messages sent through the connection
128 * reach the other side before the process is terminated.
129 *
130 * @param connection the connection to make flushing and blocking
131 * @return #GNUNET_OK on success
132 */
133int
134GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *connection);
135
136
137/**
138 * Create a connection handle by (asynchronously) connecting to a host.
139 * This function returns immediately, even if the connection has not
140 * yet been established. This function only creates TCP connections.
141 *
142 * @param s socket to connect
143 * @param serv_addr server address
144 * @param addrlen length of server address
145 * @return the connection handle
146 */
147struct GNUNET_CONNECTION_Handle *
148GNUNET_CONNECTION_connect_socket (struct GNUNET_NETWORK_Handle *s,
149 const struct sockaddr *serv_addr,
150 socklen_t addrlen);
151
152
153/**
154 * Create a connection handle by boxing an existing OS socket. The OS
155 * socket should henceforth be no longer used directly.
156 * #GNUNET_CONNECTION_destroy() will close it.
157 *
158 * @param osSocket existing socket to box
159 * @return the boxed socket handle
160 */
161struct GNUNET_CONNECTION_Handle *
162GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle *osSocket);
163
164
165/**
166 * Create a connection handle by accepting on a listen socket. This
167 * function may block if the listen socket has no connection ready.
168 *
169 * @param access_cb function to use to check if access is allowed
170 * @param access_cb_cls closure for @a access_cb
171 * @param lsock listen socket
172 * @return the connection handle, NULL on error (for example, access refused)
173 */
174struct GNUNET_CONNECTION_Handle *
175GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access_cb,
176 void *access_cb_cls,
177 struct GNUNET_NETWORK_Handle *lsock);
178
179
180/**
181 * Create a connection handle by (asynchronously) connecting to a host.
182 * This function returns immediately, even if the connection has not
183 * yet been established. This function only creates TCP connections.
184 *
185 * @param cfg configuration to use
186 * @param hostname name of the host to connect to
187 * @param port port to connect to
188 * @return the connection handle
189 */
190struct GNUNET_CONNECTION_Handle *
191GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle
192 *cfg, const char *hostname,
193 uint16_t port);
194
195
196/**
197 * Create a connection handle by connecting to a UNIX domain service.
198 * This function returns immediately, even if the connection has not
199 * yet been established. This function only creates UNIX connections.
200 *
201 * @param cfg configuration to use
202 * @param unixpath path to connect to)
203 * @return the connection handle, NULL on systems without UNIX support
204 */
205struct GNUNET_CONNECTION_Handle *
206GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct
207 GNUNET_CONFIGURATION_Handle
208 *cfg, const char *unixpath);
209
210
211
212
213/**
214 * Create a connection handle by (asynchronously) connecting to a host.
215 * This function returns immediately, even if the connection has not
216 * yet been established. This function only creates TCP connections.
217 *
218 * @param af_family address family to use
219 * @param serv_addr server address
220 * @param addrlen length of server address
221 * @return the connection handle
222 */
223struct GNUNET_CONNECTION_Handle *
224GNUNET_CONNECTION_create_from_sockaddr (int af_family,
225 const struct sockaddr *serv_addr,
226 socklen_t addrlen);
227
228/**
229 * Check if connection is valid (no fatal errors have happened so far).
230 * Note that a connection that is still trying to connect is considered
231 * valid.
232 *
233 * @param connection handle to check
234 * @return GNUNET_YES if valid, GNUNET_NO otherwise
235 */
236int
237GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *connection);
238
239
240/**
241 * Obtain the network address of the other party.
242 *
243 * @param connection the client to get the address for
244 * @param addr where to store the address
245 * @param addrlen where to store the length of the address
246 * @return GNUNET_OK on success
247 */
248int
249GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *connection,
250 void **addr, size_t * addrlen);
251
252
253/**
254 * Close the connection and free associated resources. There must
255 * not be any pending requests for reading or writing to the
256 * connection at this time.
257 *
258 * @param connection connection to destroy
259 */
260void
261GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection);
262
263
264/**
265 * Receive data from the given connection. Note that this function will
266 * call "receiver" asynchronously using the scheduler. It will
267 * "immediately" return. Note that there MUST only be one active
268 * receive call per connection at any given point in time (so do not
269 * call receive again until the receiver callback has been invoked).
270 *
271 * @param connection connection handle
272 * @param max maximum number of bytes to read
273 * @param timeout maximum amount of time to wait
274 * @param receiver function to call with received data
275 * @param receiver_cls closure for receiver
276 */
277void
278GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *connection, size_t max,
279 struct GNUNET_TIME_Relative timeout,
280 GNUNET_CONNECTION_Receiver receiver,
281 void *receiver_cls);
282
283
284/**
285 * Cancel receive job on the given connection. Note that the
286 * receiver callback must not have been called yet in order
287 * for the cancellation to be valid.
288 *
289 * @param connection connection handle
290 * @return closure of the original receiver callback closure
291 */
292void *
293GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *connection);
294
295
296/**
297 * Function called to notify a client about the connection begin ready
298 * to queue more data. @a buf will be NULL and @a size zero if the
299 * connection was closed for writing in the meantime.
300 *
301 * @param cls closure
302 * @param size number of bytes available in @a buf
303 * @param buf where the callee should write the message
304 * @return number of bytes written to @a buf
305 */
306typedef size_t
307(*GNUNET_CONNECTION_TransmitReadyNotify) (void *cls,
308 size_t size,
309 void *buf);
310
311
312/**
313 * Opaque handle that can be used to cancel
314 * a transmit-ready notification.
315 */
316struct GNUNET_CONNECTION_TransmitHandle;
317
318/**
319 * Ask the connection to call us once the specified number of bytes
320 * are free in the transmission buffer. Will never call the @a notify
321 * callback in this task, but always first go into the scheduler. Note that
322 * this function will abort if "size" is greater than
323 * #GNUNET_SERVER_MAX_MESSAGE_SIZE.
324 *
325 * Note that "notify" will be called either when enough
326 * buffer space is available OR when the connection is destroyed.
327 * The size parameter given to notify is guaranteed to be
328 * larger or equal to size if the buffer is ready, or zero
329 * if the connection was destroyed (or at least closed for
330 * writing). Finally, any time before 'notify' is called, a
331 * client may call "notify_transmit_ready_cancel" to cancel
332 * the transmission request.
333 *
334 * Only one transmission request can be scheduled at the same
335 * time. Notify will be run with the same scheduler priority
336 * as that of the caller.
337 *
338 * @param connection connection
339 * @param size number of bytes to send
340 * @param timeout after how long should we give up (and call
341 * notify with buf NULL and size 0)?
342 * @param notify function to call when buffer space is available
343 * @param notify_cls closure for notify
344 * @return non-NULL if the notify callback was queued,
345 * NULL if we are already going to notify someone else (busy)
346 */
347struct GNUNET_CONNECTION_TransmitHandle *
348GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connection,
349 size_t size,
350 struct GNUNET_TIME_Relative timeout,
351 GNUNET_CONNECTION_TransmitReadyNotify
352 notify, void *notify_cls);
353
354
355/**
356 * Cancel the specified transmission-ready
357 * notification.
358 *
359 * @param th handle for notification to cancel
360 */
361void
362GNUNET_CONNECTION_notify_transmit_ready_cancel (struct
363 GNUNET_CONNECTION_TransmitHandle
364 *th);
365
366
367/**
368 * Create a connection to be proxied using a given connection.
369 *
370 * @param cph connection to proxy server
371 * @return connection to be proxied
372 */
373struct GNUNET_CONNECTION_Handle *
374GNUNET_CONNECTION_create_proxied_from_handshake (struct GNUNET_CONNECTION_Handle *cph);
375
376
377/**
378 * Activate proxied connection and destroy initial proxy handshake connection.
379 * There must not be any pending requests for reading or writing to the
380 * proxy hadshake connection at this time.
381 *
382 * @param proxied connection connection to proxy server
383 */
384void
385GNUNET_CONNECTION_acivate_proxied (struct GNUNET_CONNECTION_Handle *proxied);
386
387
388#if 0 /* keep Emacsens' auto-indent happy */
389{
390#endif
391#ifdef __cplusplus
392}
393#endif
394
395/* ifndef GNUNET_CONNECTION_LIB_H */
396#endif
397
398/** @} */ /* end of group */
399
400/* end of gnunet_connection_lib.h */
diff --git a/src/include/gnunet_constants.h b/src/include/gnunet_constants.h
index 1d0232cea..1c48298a0 100644
--- a/src/include/gnunet_constants.h
+++ b/src/include/gnunet_constants.h
@@ -40,6 +40,8 @@ extern "C"
40#endif 40#endif
41#endif 41#endif
42 42
43
44
43/** 45/**
44 * Bandwidth (in/out) to assume initially (before either peer has 46 * Bandwidth (in/out) to assume initially (before either peer has
45 * communicated any particular preference). Should be rather low; set 47 * communicated any particular preference). Should be rather low; set
diff --git a/src/include/gnunet_datastore_plugin.h b/src/include/gnunet_datastore_plugin.h
index 2295d4e72..516ba525c 100644
--- a/src/include/gnunet_datastore_plugin.h
+++ b/src/include/gnunet_datastore_plugin.h
@@ -93,6 +93,7 @@ struct GNUNET_DATASTORE_PluginEnvironment
93 * @param type type of the content 93 * @param type type of the content
94 * @param priority priority of the content 94 * @param priority priority of the content
95 * @param anonymity anonymity-level for the content 95 * @param anonymity anonymity-level for the content
96 * @param replication replication-level for the content
96 * @param expiration expiration time for the content 97 * @param expiration expiration time for the content
97 * @param uid unique identifier for the datum 98 * @param uid unique identifier for the datum
98 * @return #GNUNET_OK to keep the item 99 * @return #GNUNET_OK to keep the item
@@ -100,14 +101,15 @@ struct GNUNET_DATASTORE_PluginEnvironment
100 */ 101 */
101typedef int 102typedef int
102(*PluginDatumProcessor) (void *cls, 103(*PluginDatumProcessor) (void *cls,
103 const struct GNUNET_HashCode *key, 104 const struct GNUNET_HashCode *key,
104 uint32_t size, 105 uint32_t size,
105 const void *data, 106 const void *data,
106 enum GNUNET_BLOCK_Type type, 107 enum GNUNET_BLOCK_Type type,
107 uint32_t priority, 108 uint32_t priority,
108 uint32_t anonymity, 109 uint32_t anonymity,
109 struct GNUNET_TIME_Absolute expiration, 110 uint32_t replication,
110 uint64_t uid); 111 struct GNUNET_TIME_Absolute expiration,
112 uint64_t uid);
111 113
112 114
113/** 115/**
@@ -204,9 +206,9 @@ typedef void
204 * Get one of the results for a particular key in the datastore. 206 * Get one of the results for a particular key in the datastore.
205 * 207 *
206 * @param cls closure 208 * @param cls closure
207 * @param offset offset of the result (modulo num-results); 209 * @param next_uid return the result with lowest uid >= next_uid
208 * specific ordering does not matter for the offset 210 * @param random if true, return a random result instead of using next_uid
209 * @param key key to match, never NULL 211 * @param key maybe NULL (to match all entries)
210 * @param vhash hash of the value, maybe NULL (to 212 * @param vhash hash of the value, maybe NULL (to
211 * match all values that have the right key). 213 * match all values that have the right key).
212 * Note that for DBlocks there is no difference 214 * Note that for DBlocks there is no difference
@@ -215,17 +217,18 @@ typedef void
215 * @param type entries of which type are relevant? 217 * @param type entries of which type are relevant?
216 * Use 0 for any type. 218 * Use 0 for any type.
217 * @param proc function to call on the matching value; 219 * @param proc function to call on the matching value;
218 * proc should be called with NULL if there is no result 220 * will be called with NULL if nothing matches
219 * @param proc_cls closure for @a proc 221 * @param proc_cls closure for @a proc
220 */ 222 */
221typedef void 223typedef void
222(*PluginGetKey) (void *cls, 224(*PluginGetKey) (void *cls,
223 uint64_t offset, 225 uint64_t next_uid,
224 const struct GNUNET_HashCode *key, 226 bool random,
225 const struct GNUNET_HashCode *vhash, 227 const struct GNUNET_HashCode *key,
226 enum GNUNET_BLOCK_Type type, 228 const struct GNUNET_HashCode *vhash,
227 PluginDatumProcessor proc, 229 enum GNUNET_BLOCK_Type type,
228 void *proc_cls); 230 PluginDatumProcessor proc,
231 void *proc_cls);
229 232
230 233
231/** 234/**
@@ -258,16 +261,17 @@ typedef void
258 261
259 262
260/** 263/**
261 * Update the priority for a particular key in the datastore. If 264 * Update the priority, replication and expiration for a particular
262 * the expiration time in value is different than the time found in 265 * unique ID in the datastore. If the expiration time in value is
263 * the datastore, the higher value should be kept. For the 266 * different than the time found in the datastore, the higher value
264 * anonymity level, the lower value is to be used. The specified 267 * should be kept. The specified priority and replication is added
265 * priority should be added to the existing priority, ignoring the 268 * to the existing value.
266 * priority in value.
267 * 269 *
268 * @param cls closure 270 * @param cls closure
269 * @param uid unique identifier of the datum 271 * @param uid unique identifier of the datum
270 * @param delta by how much should the priority 272 * @param priority by how much should the priority
273 * change?
274 * @param replication by how much should the replication
271 * change? 275 * change?
272 * @param expire new expiration time should be the 276 * @param expire new expiration time should be the
273 * MAX of any existing expiration time and 277 * MAX of any existing expiration time and
@@ -277,31 +281,31 @@ typedef void
277 */ 281 */
278typedef void 282typedef void
279(*PluginUpdate) (void *cls, 283(*PluginUpdate) (void *cls,
280 uint64_t uid, 284 uint64_t uid,
281 uint32_t delta, 285 uint32_t priority,
282 struct GNUNET_TIME_Absolute expire, 286 uint32_t replication,
283 PluginUpdateCont cont, 287 struct GNUNET_TIME_Absolute expire,
284 void *cont_cls); 288 PluginUpdateCont cont,
289 void *cont_cls);
285 290
286 291
287/** 292/**
288 * Select a single item from the datastore at the specified offset 293 * Select a single item from the datastore (among those applicable).
289 * (among those applicable).
290 * 294 *
291 * @param cls closure 295 * @param cls closure
292 * @param offset offset of the result (modulo num-results); 296 * @param next_uid return the result with lowest uid >= next_uid
293 * specific ordering does not matter for the offset
294 * @param type entries of which type should be considered? 297 * @param type entries of which type should be considered?
295 * Must not be zero (ANY). 298 * Must not be zero (ANY).
296 * @param proc function to call on the matching value 299 * @param proc function to call on the matching value;
300 * will be called with NULL if no value matches
297 * @param proc_cls closure for @a proc 301 * @param proc_cls closure for @a proc
298 */ 302 */
299typedef void 303typedef void
300(*PluginGetType) (void *cls, 304(*PluginGetType) (void *cls,
301 uint64_t offset, 305 uint64_t next_uid,
302 enum GNUNET_BLOCK_Type type, 306 enum GNUNET_BLOCK_Type type,
303 PluginDatumProcessor proc, 307 PluginDatumProcessor proc,
304 void *proc_cls); 308 void *proc_cls);
305 309
306 310
307/** 311/**
@@ -354,9 +358,6 @@ struct GNUNET_DATASTORE_PluginFunctions
354 358
355 /** 359 /**
356 * Get datum (of the specified type) with anonymity level zero. 360 * Get datum (of the specified type) with anonymity level zero.
357 * This function is allowed to ignore the 'offset' argument
358 * and instead return a random result (with zero anonymity of
359 * the correct type) if implementing an offset is expensive.
360 */ 361 */
361 PluginGetType get_zero_anonymity; 362 PluginGetType get_zero_anonymity;
362 363
diff --git a/src/include/gnunet_datastore_service.h b/src/include/gnunet_datastore_service.h
index 233598667..f851385c5 100644
--- a/src/include/gnunet_datastore_service.h
+++ b/src/include/gnunet_datastore_service.h
@@ -240,6 +240,7 @@ GNUNET_DATASTORE_remove (struct GNUNET_DATASTORE_Handle *h,
240 * @param type type of the content 240 * @param type type of the content
241 * @param priority priority of the content 241 * @param priority priority of the content
242 * @param anonymity anonymity-level for the content 242 * @param anonymity anonymity-level for the content
243 * @param replication how often should the content be replicated to other peers?
243 * @param expiration expiration time for the content 244 * @param expiration expiration time for the content
244 * @param uid unique identifier for the datum; 245 * @param uid unique identifier for the datum;
245 * maybe 0 if no unique identifier is available 246 * maybe 0 if no unique identifier is available
@@ -252,6 +253,7 @@ typedef void
252 enum GNUNET_BLOCK_Type type, 253 enum GNUNET_BLOCK_Type type,
253 uint32_t priority, 254 uint32_t priority,
254 uint32_t anonymity, 255 uint32_t anonymity,
256 uint32_t replication,
255 struct GNUNET_TIME_Absolute expiration, 257 struct GNUNET_TIME_Absolute expiration,
256 uint64_t uid); 258 uint64_t uid);
257 259
@@ -261,10 +263,8 @@ typedef void
261 * will only be called once. 263 * will only be called once.
262 * 264 *
263 * @param h handle to the datastore 265 * @param h handle to the datastore
264 * @param offset offset of the result (modulo num-results); set to 266 * @param next_uid return the result with lowest uid >= next_uid
265 * a random 64-bit value initially; then increment by 267 * @param random if true, return a random result instead of using next_uid
266 * one each time; detect that all results have been found by uid
267 * being again the first uid ever returned.
268 * @param key maybe NULL (to match all entries) 268 * @param key maybe NULL (to match all entries)
269 * @param type desired type, 0 for any 269 * @param type desired type, 0 for any
270 * @param queue_priority ranking of this request in the priority queue 270 * @param queue_priority ranking of this request in the priority queue
@@ -278,7 +278,8 @@ typedef void
278 */ 278 */
279struct GNUNET_DATASTORE_QueueEntry * 279struct GNUNET_DATASTORE_QueueEntry *
280GNUNET_DATASTORE_get_key (struct GNUNET_DATASTORE_Handle *h, 280GNUNET_DATASTORE_get_key (struct GNUNET_DATASTORE_Handle *h,
281 uint64_t offset, 281 uint64_t next_uid,
282 bool random,
282 const struct GNUNET_HashCode *key, 283 const struct GNUNET_HashCode *key,
283 enum GNUNET_BLOCK_Type type, 284 enum GNUNET_BLOCK_Type type,
284 unsigned int queue_priority, 285 unsigned int queue_priority,
@@ -289,16 +290,9 @@ GNUNET_DATASTORE_get_key (struct GNUNET_DATASTORE_Handle *h,
289 290
290/** 291/**
291 * Get a single zero-anonymity value from the datastore. 292 * Get a single zero-anonymity value from the datastore.
292 * Note that some implementations can ignore the 'offset' and
293 * instead return a random zero-anonymity value. In that case,
294 * detecting the wrap-around based on a repeating UID is at best
295 * probabilistic.
296 * 293 *
297 * @param h handle to the datastore 294 * @param h handle to the datastore
298 * @param offset offset of the result (modulo num-results); set to 295 * @param next_uid return the result with lowest uid >= next_uid
299 * a random 64-bit value initially; then increment by
300 * one each time; detect that all results have been found by uid
301 * being again the first uid ever returned.
302 * @param queue_priority ranking of this request in the priority queue 296 * @param queue_priority ranking of this request in the priority queue
303 * @param max_queue_size at what queue size should this request be dropped 297 * @param max_queue_size at what queue size should this request be dropped
304 * (if other requests of higher priority are in the queue) 298 * (if other requests of higher priority are in the queue)
@@ -312,7 +306,7 @@ GNUNET_DATASTORE_get_key (struct GNUNET_DATASTORE_Handle *h,
312 */ 306 */
313struct GNUNET_DATASTORE_QueueEntry * 307struct GNUNET_DATASTORE_QueueEntry *
314GNUNET_DATASTORE_get_zero_anonymity (struct GNUNET_DATASTORE_Handle *h, 308GNUNET_DATASTORE_get_zero_anonymity (struct GNUNET_DATASTORE_Handle *h,
315 uint64_t offset, 309 uint64_t next_uid,
316 unsigned int queue_priority, 310 unsigned int queue_priority,
317 unsigned int max_queue_size, 311 unsigned int max_queue_size,
318 enum GNUNET_BLOCK_Type type, 312 enum GNUNET_BLOCK_Type type,
diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h
index a9c7e8944..ac418072e 100644
--- a/src/include/gnunet_fs_service.h
+++ b/src/include/gnunet_fs_service.h
@@ -438,23 +438,36 @@ GNUNET_FS_uri_ksk_create_from_meta_data (const struct GNUNET_CONTAINER_MetaData
438/* ******************** command-line option parsing API *********************** */ 438/* ******************** command-line option parsing API *********************** */
439 439
440/** 440/**
441 * Command-line option parser function that allows the user 441 * Allow user to specify keywords.
442 * to specify one or more '-k' options with keywords. Each 442 *
443 * specified keyword will be added to the URI. A pointer to 443 * @param shortName short name of the option
444 * the URI must be passed as the "scls" argument. 444 * @param name long name of the option
445 * 445 * @param argumentHelp help text for the option argument
446 * @param ctx command line processor context 446 * @param description long help text for the option
447 * @param scls must be of type "struct GNUNET_FS_Uri **" 447 * @param[out] topKeywords set to the desired value
448 * @param option name of the option (typically 'k') 448 */
449 * @param value command line argument given 449struct GNUNET_GETOPT_CommandLineOption
450 * @return #GNUNET_OK on success 450GNUNET_FS_GETOPT_KEYWORDS (char shortName,
451 */ 451 const char *name,
452int 452 const char *argumentHelp,
453GNUNET_FS_getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 453 const char *description,
454 void *scls, 454 struct GNUNET_FS_Uri **topKeywords);
455 const char *option, 455
456 const char *value); 456/**
457 457 * Allow user to specify metadata.
458 *
459 * @param shortName short name of the option
460 * @param name long name of the option
461 * @param argumentHelp help text for the option argument
462 * @param description long help text for the option
463 * @param[out] metadata set to the desired value
464 */
465struct GNUNET_GETOPT_CommandLineOption
466GNUNET_FS_GETOPT_METADATA (char shortName,
467 const char *name,
468 const char *argumentHelp,
469 const char *description,
470 struct GNUNET_CONTAINER_MetaData **meta);
458 471
459/** 472/**
460 * Command-line option parser function that allows the user to specify 473 * Command-line option parser function that allows the user to specify
diff --git a/src/include/gnunet_getopt_lib.h b/src/include/gnunet_getopt_lib.h
index b04020a70..c2bd72340 100644
--- a/src/include/gnunet_getopt_lib.h
+++ b/src/include/gnunet_getopt_lib.h
@@ -97,6 +97,7 @@ typedef int
97 const char *option, 97 const char *option,
98 const char *value); 98 const char *value);
99 99
100
100/** 101/**
101 * @brief Definition of a command line option. 102 * @brief Definition of a command line option.
102 */ 103 */
@@ -130,255 +131,301 @@ struct GNUNET_GETOPT_CommandLineOption
130 int require_argument; 131 int require_argument;
131 132
132 /** 133 /**
134 * Is the presence of this option mandatory?
135 */
136 int option_mandatory;
137
138 /**
133 * Handler for the option. 139 * Handler for the option.
134 */ 140 */
135 GNUNET_GETOPT_CommandLineOptionProcessor processor; 141 GNUNET_GETOPT_CommandLineOptionProcessor processor;
136 142
137 /** 143 /**
144 * Function to call on @e scls to clean up after processing all
145 * the arguments. Can be NULL.
146 */
147 void (*cleaner)(void *cls);
148
149 /**
138 * Specific closure to pass to the processor. 150 * Specific closure to pass to the processor.
139 */ 151 */
140 void *scls; 152 void *scls;
141 153
142}; 154};
143 155
156
144/** 157/**
145 * Macro defining the option to print the command line 158 * Defining the option to print the command line
146 * help text (-h option). 159 * help text (-h option).
147 * 160 *
148 * @param about string with brief description of the application 161 * @param about string with brief description of the application
149 */ 162 */
150#define GNUNET_GETOPT_OPTION_HELP(about) \ 163struct GNUNET_GETOPT_CommandLineOption
151 { 'h', "help", (const char *) NULL, gettext_noop("print this help"), 0, &GNUNET_GETOPT_format_help_, (void *) about } 164GNUNET_GETOPT_OPTION_HELP (const char *about);
152 165
153 166
154/** 167/**
155 * Macro defining the option to print the version of 168 * Define the option to print the version of
156 * the application (-v option) 169 * the application (-v option)
157 * 170 *
158 * @param version string with the version number 171 * @param version string with the version number
159 */ 172 */
160#define GNUNET_GETOPT_OPTION_VERSION(version) \ 173struct GNUNET_GETOPT_CommandLineOption
161 { 'v', "version", (const char *) NULL, gettext_noop("print the version number"), 0, &GNUNET_GETOPT_print_version_, (void *) version } 174GNUNET_GETOPT_OPTION_VERSION (const char *version);
175
162 176
163 177
164/** 178/**
165 * Allow user to specify log file name (-l option) 179 * Allow user to specify log file name (-l option)
166 * 180 *
167 * @param logfn set to the name of the logfile 181 * @param[out] logfn set to the name of the logfile
168 */ 182 */
169#define GNUNET_GETOPT_OPTION_LOGFILE(logfn) \ 183struct GNUNET_GETOPT_CommandLineOption
170 { 'l', "logfile", "LOGFILE", gettext_noop("configure logging to write logs to LOGFILE"), 1, &GNUNET_GETOPT_set_string, (void *) logfn } 184GNUNET_GETOPT_OPTION_LOGFILE (char **logfn);
171 185
172 186
173/** 187/**
174 * Allow user to specify log level (-L option) 188 * Allow user to specify a string.
175 * 189 *
176 * @param loglev set to the log level 190 * @param shortName short name of the option
191 * @param name long name of the option
192 * @param argumentHelp help text for the option argument
193 * @param description long help text for the option
194 * @param[out] str set to the string
177 */ 195 */
178#define GNUNET_GETOPT_OPTION_LOGLEVEL(loglev) \ 196struct GNUNET_GETOPT_CommandLineOption
179 { 'L', "log", "LOGLEVEL", gettext_noop("configure logging to use LOGLEVEL"), 1, &GNUNET_GETOPT_set_string, (void *) loglev } 197GNUNET_GETOPT_OPTION_STRING (char shortName,
198 const char *name,
199 const char *argumentHelp,
200 const char *description,
201 char **str);
202
203/**
204 * Allow user to specify a filename (automatically path expanded).
205 *
206 * @param shortName short name of the option
207 * @param name long name of the option
208 * @param argumentHelp help text for the option argument
209 * @param description long help text for the option
210 * @param[out] str set to the string
211 */
212struct GNUNET_GETOPT_CommandLineOption
213GNUNET_GETOPT_OPTION_FILENAME (char shortName,
214 const char *name,
215 const char *argumentHelp,
216 const char *description,
217 char **str);
180 218
181 219
182/** 220/**
183 * Get number of verbose (-V) flags 221 * Allow user to specify a binary value using Crockford
222 * Base32 encoding.
184 * 223 *
185 * @param level where to store the verbosity level (should be an 'int') 224 * @param shortName short name of the option
225 * @param name long name of the option
226 * @param argumentHelp help text for the option argument
227 * @param description long help text for the option
228 * @param[out] val binary value decoded from Crockford Base32-encoded argument
229 * @param val_size size of @a val in bytes
186 */ 230 */
187#define GNUNET_GETOPT_OPTION_VERBOSE(level) \ 231struct GNUNET_GETOPT_CommandLineOption
188 { 'V', "verbose", (const char *) NULL, gettext_noop("be verbose"), 0, &GNUNET_GETOPT_increment_value, (void *) level } 232GNUNET_GETOPT_OPTION_SET_BASE32_FIXED_SIZE (char shortName,
233 const char *name,
234 const char *argumentHelp,
235 const char *description,
236 void *val,
237 size_t val_size);
189 238
190 239
191/** 240/**
192 * Get configuration file name (-c option) 241 * Allow user to specify a binary value using Crockford
242 * Base32 encoding where the size of the binary value is
243 * automatically determined from its type.
193 * 244 *
194 * @param fn set to the configuration file name 245 * @param shortName short name of the option
246 * @param name long name of the option
247 * @param argumentHelp help text for the option argument
248 * @param description long help text for the option
249 * @param[out] val binary value decoded from Crockford Base32-encoded argument;
250 * size is determined by type (sizeof (*val)).
195 */ 251 */
196#define GNUNET_GETOPT_OPTION_CFG_FILE(fn) \ 252#define GNUNET_GETOPT_OPTION_SET_BASE32_AUTO(shortName,name,argumentHelp,description,val) \
197 { 'c', "config", "FILENAME", gettext_noop("use configuration file FILENAME"), 1, &GNUNET_GETOPT_set_string, (void *) fn } 253 GNUNET_GETOPT_OPTION_SET_BASE32_FIXED_SIZE(shortName,name,argumentHelp,description,val,sizeof(*val))
198 254
199 255
200/** 256/**
201 * Marker for the end of the list of options. 257 * Allow user to specify a flag (which internally means setting
258 * an integer to 1/#GNUNET_YES/#GNUNET_OK.
259 *
260 * @param shortName short name of the option
261 * @param name long name of the option
262 * @param description long help text for the option
263 * @param[out] val set to 1 if the option is present
202 */ 264 */
203#define GNUNET_GETOPT_OPTION_END \ 265struct GNUNET_GETOPT_CommandLineOption
204 { '\0', NULL, NULL, NULL, 0, NULL, NULL } 266GNUNET_GETOPT_OPTION_SET_ONE (char shortName,
267 const char *name,
268 const char *description,
269 int *val);
205 270
206 271
207/** 272/**
208 * Parse the command line. 273 * Allow user to specify an `unsigned int`.
209 * 274 *
210 * @param binaryOptions Name of application with option summary 275 * @param shortName short name of the option
211 * @param allOptions defined options and handlers 276 * @param name long name of the option
212 * @param argc number of arguments in @a argv 277 * @param argumentHelp help text for the option argument
213 * @param argv actual arguments 278 * @param description long help text for the option
214 * @return index into argv with first non-option 279 * @param[out] val set to the value specified at the command line
215 * argument, or #GNUNET_SYSERR on error
216 */ 280 */
217int 281struct GNUNET_GETOPT_CommandLineOption
218GNUNET_GETOPT_run (const char *binaryOptions, 282GNUNET_GETOPT_OPTION_SET_UINT (char shortName,
219 const struct GNUNET_GETOPT_CommandLineOption *allOptions, 283 const char *name,
220 unsigned int argc, char *const *argv); 284 const char *argumentHelp,
285 const char *description,
286 unsigned int *val);
221 287
222 288
223/** 289/**
224 * Set an option of type 'unsigned long long' from the command line. 290 * Allow user to specify an `unsigned long long`.
225 * A pointer to this function should be passed as part of the
226 * `struct GNUNET_GETOPT_CommandLineOption` array to initialize options
227 * of this type. It should be followed by a pointer to a value of
228 * type `unsigned long long`.
229 * 291 *
230 * @param ctx command line processing context 292 * @param shortName short name of the option
231 * @param scls additional closure (will point to the 'unsigned long long') 293 * @param name long name of the option
232 * @param option name of the option 294 * @param argumentHelp help text for the option argument
233 * @param value actual value of the option as a string. 295 * @param description long help text for the option
234 * @return #GNUNET_OK if parsing the value worked 296 * @param[out] val set to the value specified at the command line
235 */ 297 */
236int 298struct GNUNET_GETOPT_CommandLineOption
237GNUNET_GETOPT_set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 299GNUNET_GETOPT_OPTION_SET_ULONG (char shortName,
238 void *scls, const char *option, const char *value); 300 const char *name,
301 const char *argumentHelp,
302 const char *description,
303 unsigned long long *val);
239 304
240 305
241/** 306/**
242 * Set an option of type 'struct GNUNET_TIME_Relative' from the command line. 307 * Allow user to specify a `struct GNUNET_TIME_Relative`
243 * A pointer to this function should be passed as part of the 308 * (using human-readable "fancy" time).
244 * `struct GNUNET_GETOPT_CommandLineOption` array to initialize options
245 * of this type. It should be followed by a pointer to a value of
246 * type `struct GNUNET_TIME_Relative`.
247 * 309 *
248 * @param ctx command line processing context 310 * @param shortName short name of the option
249 * @param scls additional closure (will point to the 'struct GNUNET_TIME_Relative') 311 * @param name long name of the option
250 * @param option name of the option 312 * @param argumentHelp help text for the option argument
251 * @param value actual value of the option as a string. 313 * @param description long help text for the option
252 * @return #GNUNET_OK if parsing the value worked 314 * @param[out] val set to the time specified at the command line
253 */ 315 */
254int 316struct GNUNET_GETOPT_CommandLineOption
255GNUNET_GETOPT_set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 317GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME (char shortName,
256 void *scls, const char *option, const char *value); 318 const char *name,
319 const char *argumentHelp,
320 const char *description,
321 struct GNUNET_TIME_Relative *val);
257 322
258 323
259/** 324/**
260 * Set an option of type 'unsigned int' from the command line. 325 * Allow user to specify a `struct GNUNET_TIME_Absolute`
261 * A pointer to this function should be passed as part of the 326 * (using human-readable "fancy" time).
262 * `struct GNUNET_GETOPT_CommandLineOption` array to initialize options
263 * of this type. It should be followed by a pointer to a value of
264 * type `unsigned int`.
265 * 327 *
266 * @param ctx command line processing context 328 * @param shortName short name of the option
267 * @param scls additional closure (will point to the 'unsigned int') 329 * @param name long name of the option
268 * @param option name of the option 330 * @param argumentHelp help text for the option argument
269 * @param value actual value of the option as a string. 331 * @param description long help text for the option
270 * @return #GNUNET_OK if parsing the value worked 332 * @param[out] val set to the time specified at the command line
271 */ 333 */
272int 334struct GNUNET_GETOPT_CommandLineOption
273GNUNET_GETOPT_set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 335GNUNET_GETOPT_OPTION_SET_ABSOLUTE_TIME (char shortName,
274 void *scls, const char *option, const char *value); 336 const char *name,
337 const char *argumentHelp,
338 const char *description,
339 struct GNUNET_TIME_Absolute *val);
275 340
276 341
277/** 342/**
278 * Set an option of type 'int' from the command line to 1 if the 343 * Increment @a val each time the option flag is given by one.
279 * given option is present.
280 * A pointer to this function should be passed as part of the
281 * `struct GNUNET_GETOPT_CommandLineOption` array to initialize options
282 * of this type. It should be followed by a pointer to a value of
283 * type `int`.
284 * 344 *
285 * @param ctx command line processing context 345 * @param shortName short name of the option
286 * @param scls additional closure (will point to the `int`) 346 * @param name long name of the option
287 * @param option name of the option 347 * @param argumentHelp help text for the option argument
288 * @param value not used (NULL) 348 * @param description long help text for the option
289 * @return #GNUNET_OK (always) 349 * @param[out] val set to 1 if the option is present
290 */ 350 */
291int 351struct GNUNET_GETOPT_CommandLineOption
292GNUNET_GETOPT_set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 352GNUNET_GETOPT_OPTION_INCREMENT_VALUE (char shortName,
293 void *scls, const char *option, const char *value); 353 const char *name,
354 const char *description,
355 unsigned int *val);
294 356
295 357
296/** 358/**
297 * Set an option of type 'char *' from the command line. 359 * Define the '-L' log level option. Note that we do not check
298 * A pointer to this function should be passed as part of the 360 * that the log level is valid here.
299 * `struct GNUNET_GETOPT_CommandLineOption` array to initialize options
300 * of this type. It should be followed by a pointer to a value of
301 * type `char *`, which will be allocated with the requested string.
302 * 361 *
303 * @param ctx command line processing context 362 * @param[out] level set to the log level
304 * @param scls additional closure (will point to the `char *`,
305 * which will be allocated)
306 * @param option name of the option
307 * @param value actual value of the option (a string)
308 * @return #GNUNET_OK (always)
309 */ 363 */
310int 364struct GNUNET_GETOPT_CommandLineOption
311GNUNET_GETOPT_set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 365GNUNET_GETOPT_OPTION_LOGLEVEL (char **level);
312 void *scls, const char *option, const char *value);
313 366
314 367
315/** 368/**
316 * Set an option of type 'char *' from the command line doing fs expansion. 369 * Define the '-V' verbosity option. Using the option more
317 * A pointer to this function should be passed as part of the 370 * than once increments @a level each time.
318 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
319 * of this type. It should be followed by a pointer to a value of
320 * type 'char *', which will be allocated with the requested string.
321 * 371 *
322 * @param ctx command line processing context 372 * @param[out] level set to the verbosity level
323 * @param scls additional closure (will point to the 'char *',
324 * which will be allocated)
325 * @param option name of the option
326 * @param value actual value of the option (a string)
327 * @return #GNUNET_OK (always)
328 */ 373 */
329int 374struct GNUNET_GETOPT_CommandLineOption
330GNUNET_GETOPT_set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 375GNUNET_GETOPT_OPTION_VERBOSE (unsigned int *level);
331 void *scls, const char *option, const char *value); 376
332 377
333/** 378/**
334 * Set an option of type 'unsigned int' from the command line. Each 379 * Allow user to specify log file name (-l option)
335 * time the option flag is given, the value is incremented by one.
336 * A pointer to this function should be passed as part of the
337 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
338 * of this type. It should be followed by a pointer to a value of
339 * type 'int'.
340 * 380 *
341 * @param ctx command line processing context 381 * @param[out] logfn set to the name of the logfile
342 * @param scls additional closure (will point to the 'int')
343 * @param option name of the option
344 * @param value not used (NULL)
345 * @return #GNUNET_OK (always)
346 */ 382 */
347int 383struct GNUNET_GETOPT_CommandLineOption
348GNUNET_GETOPT_increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext 384GNUNET_GETOPT_OPTION_LOGFILE (char **logfn);
349 *ctx, void *scls, const char *option,
350 const char *value);
351 385
352 386
353/* *************** internal prototypes - use macros above! ************* */ 387/**
388 * Allow user to specify configuration file name (-c option)
389 *
390 * @param[out] fn set to the name of the configuration file
391 */
392struct GNUNET_GETOPT_CommandLineOption
393GNUNET_GETOPT_OPTION_CFG_FILE (char **fn);
394
354 395
355/** 396/**
356 * Print out details on command line options (implements --help). 397 * Make the given option mandatory.
357 * 398 *
358 * @param ctx command line processing context 399 * @param opt option to modify
359 * @param scls additional closure (points to about text) 400 * @return @a opt with the mandatory flag set.
360 * @param option name of the option
361 * @param value not used (NULL)
362 * @return #GNUNET_NO (do not continue, not an error)
363 */ 401 */
364int 402struct GNUNET_GETOPT_CommandLineOption
365GNUNET_GETOPT_format_help_ (struct GNUNET_GETOPT_CommandLineProcessorContext 403GNUNET_GETOPT_OPTION_MANDATORY (struct GNUNET_GETOPT_CommandLineOption opt);
366 *ctx, void *scls, const char *option, 404
367 const char *value);
368 405
369/** 406/**
370 * Print out program version (implements --version). 407 * Marker for the end of the list of options.
408 */
409#define GNUNET_GETOPT_OPTION_END \
410 { '\0', NULL, NULL, NULL, 0, 0, NULL, NULL, NULL }
411
412
413/**
414 * Parse the command line.
371 * 415 *
372 * @param ctx command line processing context 416 * @param binaryOptions Name of application with option summary
373 * @param scls additional closure (points to version string) 417 * @param allOptions defined options and handlers
374 * @param option name of the option 418 * @param argc number of arguments in @a argv
375 * @param value not used (NULL) 419 * @param argv actual arguments
376 * @return #GNUNET_NO (do not continue, not an error) 420 * @return index into argv with first non-option
421 * argument, or #GNUNET_SYSERR on error
377 */ 422 */
378int 423int
379GNUNET_GETOPT_print_version_ (struct GNUNET_GETOPT_CommandLineProcessorContext 424GNUNET_GETOPT_run (const char *binaryOptions,
380 *ctx, void *scls, const char *option, 425 const struct GNUNET_GETOPT_CommandLineOption *allOptions,
381 const char *value); 426 unsigned int argc,
427 char *const *argv);
428
382 429
383#if 0 /* keep Emacsens' auto-indent happy */ 430#if 0 /* keep Emacsens' auto-indent happy */
384{ 431{
diff --git a/src/include/gnunet_helper_lib.h b/src/include/gnunet_helper_lib.h
index db0ca98aa..60b3ff681 100644
--- a/src/include/gnunet_helper_lib.h
+++ b/src/include/gnunet_helper_lib.h
@@ -38,7 +38,8 @@
38#define GNUNET_HELPER_LIB_H 38#define GNUNET_HELPER_LIB_H
39 39
40#include "gnunet_scheduler_lib.h" 40#include "gnunet_scheduler_lib.h"
41#include "gnunet_server_lib.h" 41#include "gnunet_mst_lib.h"
42
42 43
43/** 44/**
44 * The handle to a helper process. 45 * The handle to a helper process.
@@ -52,7 +53,8 @@ struct GNUNET_HELPER_Handle;
52 * 53 *
53 * @param cls the closure from GNUNET_HELPER_start() 54 * @param cls the closure from GNUNET_HELPER_start()
54 */ 55 */
55typedef void (*GNUNET_HELPER_ExceptionCallback) (void *cls); 56typedef void
57(*GNUNET_HELPER_ExceptionCallback) (void *cls);
56 58
57 59
58/** 60/**
@@ -75,7 +77,7 @@ struct GNUNET_HELPER_Handle *
75GNUNET_HELPER_start (int with_control_pipe, 77GNUNET_HELPER_start (int with_control_pipe,
76 const char *binary_name, 78 const char *binary_name,
77 char *const binary_argv[], 79 char *const binary_argv[],
78 GNUNET_SERVER_MessageTokenizerCallback cb, 80 GNUNET_MessageTokenizerCallback cb,
79 GNUNET_HELPER_ExceptionCallback exp_cb, 81 GNUNET_HELPER_ExceptionCallback exp_cb,
80 void *cb_cls); 82 void *cb_cls);
81 83
diff --git a/src/include/gnunet_json_lib.h b/src/include/gnunet_json_lib.h
index 9e5f9e284..ce721d8d8 100644
--- a/src/include/gnunet_json_lib.h
+++ b/src/include/gnunet_json_lib.h
@@ -427,6 +427,26 @@ void
427GNUNET_JSON_post_parser_cleanup (void *con_cls); 427GNUNET_JSON_post_parser_cleanup (void *con_cls);
428 428
429 429
430/* ****************** GETOPT JSON helper ******************* */
431
432
433/**
434 * Allow user to specify a JSON input value.
435 *
436 * @param shortName short name of the option
437 * @param name long name of the option
438 * @param argumentHelp help text for the option argument
439 * @param description long help text for the option
440 * @param[out] val set to the JSON specified at the command line
441 */
442struct GNUNET_GETOPT_CommandLineOption
443GNUNET_JSON_getopt (char shortName,
444 const char *name,
445 const char *argumentHelp,
446 const char *description,
447 json_t **json);
448
449
430#endif 450#endif
431 451
432/* end of gnunet_json_lib.h */ 452/* end of gnunet_json_lib.h */
diff --git a/src/include/gnunet_mq_lib.h b/src/include/gnunet_mq_lib.h
index b05128ccc..ecee1b223 100644
--- a/src/include/gnunet_mq_lib.h
+++ b/src/include/gnunet_mq_lib.h
@@ -35,6 +35,7 @@
35#ifndef GNUNET_MQ_LIB_H 35#ifndef GNUNET_MQ_LIB_H
36#define GNUNET_MQ_LIB_H 36#define GNUNET_MQ_LIB_H
37 37
38#include "gnunet_scheduler_lib.h"
38 39
39/** 40/**
40 * Allocate an envelope, with extra space allocated after the space needed 41 * Allocate an envelope, with extra space allocated after the space needed
diff --git a/src/include/gnunet_server_lib.h b/src/include/gnunet_server_lib.h
deleted file mode 100644
index 5da31bcd7..000000000
--- a/src/include/gnunet_server_lib.h
+++ /dev/null
@@ -1,887 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @author Christian Grothoff
23 *
24 * @file
25 * Library for building GNUnet network servers
26
27 * @defgroup server Server library
28 * Library for building GNUnet network servers
29 *
30 * Provides functions for a server that communicates with clients.
31 *
32 * @see [Documentation](https://gnunet.org/ipc)
33 *
34 * @{
35 */
36
37#ifndef GNUNET_SERVER_LIB_H
38#define GNUNET_SERVER_LIB_H
39
40#ifdef __cplusplus
41extern "C"
42{
43#if 0 /* keep Emacsens' auto-indent happy */
44}
45#endif
46#endif
47
48#include "gnunet_common.h"
49#include "gnunet_connection_lib.h"
50
51
52/**
53 * Largest supported message (to be precise, one byte more
54 * than the largest possible message, so tests involving
55 * this value should check for messages being smaller than
56 * this value).
57 */
58#define GNUNET_SERVER_MAX_MESSAGE_SIZE 65536
59
60/**
61 * Smallest supported message.
62 */
63#define GNUNET_SERVER_MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
64
65/**
66 * @brief handle for a server
67 */
68struct GNUNET_SERVER_Handle;
69
70/**
71 * @brief opaque handle for a client of the server
72 */
73struct GNUNET_SERVER_Client;
74
75/**
76 * @brief opaque handle server returns for aborting transmission to a client.
77 */
78struct GNUNET_SERVER_TransmitHandle;
79
80
81/**
82 * Functions with this signature are called whenever a message is
83 * received.
84 *
85 * @param cls closure
86 * @param client identification of the client
87 * @param message the actual message
88 */
89typedef void
90(*GNUNET_SERVER_MessageCallback) (void *cls,
91 struct GNUNET_SERVER_Client *client,
92 const struct GNUNET_MessageHeader *message);
93
94
95/**
96 * Message handler. Each struct specifies how to handle on particular
97 * type of message received.
98 */
99struct GNUNET_SERVER_MessageHandler
100{
101 /**
102 * Function to call for messages of "type".
103 */
104 GNUNET_SERVER_MessageCallback callback;
105
106 /**
107 * Closure argument for @e callback.
108 */
109 void *callback_cls;
110
111 /**
112 * Type of the message this handler covers.
113 */
114 uint16_t type;
115
116 /**
117 * Expected size of messages of this type. Use 0 for
118 * variable-size. If non-zero, messages of the given
119 * type will be discarded (and the connection closed)
120 * if they do not have the right size.
121 */
122 uint16_t expected_size;
123
124};
125
126
127/**
128 * Create a new server.
129 *
130 * @param access_cb function for access control
131 * @param access_cb_cls closure for @a access_cb
132 * @param lsocks NULL-terminated array of listen sockets
133 * @param idle_timeout after how long should we timeout idle connections?
134 * @param require_found if #GNUNET_YES, connections sending messages of unknown type
135 * will be closed
136 * @return handle for the new server, NULL on error
137 * (typically, "port" already in use)
138 */
139struct GNUNET_SERVER_Handle *
140GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access_cb,
141 void *access_cb_cls,
142 struct GNUNET_NETWORK_Handle **lsocks,
143 struct GNUNET_TIME_Relative idle_timeout,
144 int require_found);
145
146/**
147 * Create a new server.
148 *
149 * @param access_cb function for access control
150 * @param access_cb_cls closure for @a access_cb
151 * @param server_addr address toes listen on (including port), NULL terminated array
152 * @param socklen lengths of respective @a server_addr
153 * @param idle_timeout after how long should we timeout idle connections?
154 * @param require_found if #GNUNET_YES, connections sending messages of unknown type
155 * will be closed
156 * @return handle for the new server, NULL on error
157 * (typically, "port" already in use)
158 */
159struct GNUNET_SERVER_Handle *
160GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access_cb,
161 void *access_cb_cls,
162 struct sockaddr *const *server_addr,
163 const socklen_t *socklen,
164 struct GNUNET_TIME_Relative idle_timeout,
165 int require_found);
166
167
168/**
169 * Suspend accepting connections from the listen socket temporarily.
170 * Resume activity using #GNUNET_SERVER_resume.
171 *
172 * @param server server to stop accepting connections.
173 */
174void
175GNUNET_SERVER_suspend (struct GNUNET_SERVER_Handle *server);
176
177
178/**
179 * Resume accepting connections from the listen socket.
180 *
181 * @param server server to resume accepting connections.
182 */
183void
184GNUNET_SERVER_resume (struct GNUNET_SERVER_Handle *server);
185
186
187/**
188 * Stop the listen socket and get ready to shutdown the server once
189 * only clients marked using #GNUNET_SERVER_client_mark_monitor are
190 * left.
191 *
192 * @param server server to stop listening on
193 */
194void
195GNUNET_SERVER_stop_listening (struct GNUNET_SERVER_Handle *server);
196
197
198/**
199 * Free resources held by this server.
200 *
201 * @param server server to destroy
202 */
203void
204GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *server);
205
206
207/**
208 * Add additional handlers to an existing server.
209 *
210 * @param server the server to add handlers to
211 * @param handlers array of message handlers for
212 * incoming messages; the last entry must
213 * have "NULL" for the "callback"; multiple
214 * entries for the same type are allowed,
215 * they will be called in order of occurence.
216 * These handlers can be removed later;
217 * the handlers array must exist until removed
218 * (or server is destroyed).
219 */
220void
221GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
222 const struct GNUNET_SERVER_MessageHandler *handlers);
223
224
225/**
226 * Notify us when the server has enough space to transmit
227 * a message of the given size to the given client.
228 *
229 * @param client client to transmit message to
230 * @param size requested amount of buffer space
231 * @param timeout after how long should we give up (and call
232 * notify with buf NULL and size 0)?
233 * @param callback function to call when space is available
234 * @param callback_cls closure for @a callback
235 * @return non-NULL if the notify callback was queued; can be used
236 * to cancel the request using
237 * #GNUNET_SERVER_notify_transmit_ready_cancel.
238 * NULL if we are already going to notify someone else (busy)
239 */
240struct GNUNET_SERVER_TransmitHandle *
241GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
242 size_t size,
243 struct GNUNET_TIME_Relative timeout,
244 GNUNET_CONNECTION_TransmitReadyNotify callback,
245 void *callback_cls);
246
247
248/**
249 * Abort transmission request.
250 *
251 * @param th request to abort
252 */
253void
254GNUNET_SERVER_notify_transmit_ready_cancel (struct GNUNET_SERVER_TransmitHandle *th);
255
256
257/**
258 * Set the 'monitor' flag on this client. Clients which have been
259 * marked as 'monitors' won't prevent the server from shutting down
260 * once #GNUNET_SERVER_stop_listening has been invoked. The idea is
261 * that for "normal" clients we likely want to allow them to process
262 * their requests; however, monitor-clients are likely to 'never'
263 * disconnect during shutdown and thus will not be considered when
264 * determining if the server should continue to exist after
265 * #GNUNET_SERVER_destroy has been called.
266 *
267 * @param client the client to set the 'monitor' flag on
268 */
269void
270GNUNET_SERVER_client_mark_monitor (struct GNUNET_SERVER_Client *client);
271
272
273/**
274 * Set the persistent flag on this client, used to setup client
275 * connection to only be killed when the process of the service it's
276 * connected to is actually dead. This API is used during shutdown
277 * signalling within ARM, and it is not expected that typical users
278 * of the API would need this function.
279 *
280 * @param client the client to set the persistent flag on
281 */
282void
283GNUNET_SERVER_client_persist_ (struct GNUNET_SERVER_Client *client);
284
285
286/**
287 * Resume receiving from this client, we are done processing the
288 * current request. This function must be called from within each
289 * #GNUNET_SERVER_MessageCallback (or its respective continuations).
290 *
291 * @param client client we were processing a message of
292 * @param success #GNUNET_OK to keep the connection open and
293 * continue to receive
294 * #GNUNET_NO to close the connection (normal behavior)
295 * #GNUNET_SYSERR to close the connection (signal
296 * serious error)
297 */
298void
299GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client,
300 int success);
301
302
303/**
304 * Change the timeout for a particular client. Decreasing the timeout
305 * may not go into effect immediately (only after the previous timeout
306 * times out or activity happens on the socket).
307 *
308 * @param client the client to update
309 * @param timeout new timeout for activities on the socket
310 */
311void
312GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client,
313 struct GNUNET_TIME_Relative timeout);
314
315
316/**
317 * Return user context associated with the given client.
318 * Note: you should probably use the macro (call without the underscore).
319 *
320 * @param client client to query
321 * @param size number of bytes in user context struct (for verification only)
322 * @return pointer to user context
323 */
324void *
325GNUNET_SERVER_client_get_user_context_ (struct GNUNET_SERVER_Client *client,
326 size_t size);
327
328
329/**
330 * Set user context to be associated with the given client.
331 * Note: you should probably use the macro (call without the underscore).
332 *
333 * @param client client to query
334 * @param ptr pointer to user context
335 * @param size number of bytes in user context struct (for verification only)
336 */
337void
338GNUNET_SERVER_client_set_user_context_ (struct GNUNET_SERVER_Client *client,
339 void *ptr,
340 size_t size);
341
342
343/**
344 * Return user context associated with the given client.
345 *
346 * @param client client to query
347 * @param type expected return type (i.e. 'struct Foo')
348 * @return pointer to user context of type 'type *'.
349 */
350#define GNUNET_SERVER_client_get_user_context(client,type) \
351 (type *) GNUNET_SERVER_client_get_user_context_ (client, sizeof (type))
352
353/**
354 * Set user context to be associated with the given client.
355 *
356 * @param client client to query
357 * @param value pointer to user context
358 */
359#define GNUNET_SERVER_client_set_user_context(client,value) \
360 GNUNET_SERVER_client_set_user_context_ (client, value, sizeof (*value))
361
362
363/**
364 * Disable the warning the server issues if a message is not acknowledged
365 * in a timely fashion. Use this call if a client is intentionally delayed
366 * for a while. Only applies to the current message.
367 *
368 * @param client client for which to disable the warning
369 */
370void
371GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client
372 *client);
373
374
375/**
376 * Inject a message into the server, pretend it came
377 * from the specified client. Delivery of the message
378 * will happen instantly (if a handler is installed;
379 * otherwise the call does nothing).
380 *
381 * @param server the server receiving the message
382 * @param sender the "pretended" sender of the message
383 * can be NULL!
384 * @param message message to transmit
385 * @return #GNUNET_OK if the message was OK and the
386 * connection can stay open
387 * #GNUNET_SYSERR if the connection to the
388 * client should be shut down
389 */
390int
391GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
392 struct GNUNET_SERVER_Client *sender,
393 const struct GNUNET_MessageHeader *message);
394
395
396/**
397 * Add a TCP socket-based connection to the set of handles managed by
398 * this server. Use this function for outgoing (P2P) connections that
399 * we initiated (and where this server should process incoming
400 * messages).
401 *
402 * @param server the server to use
403 * @param connection the connection to manage (client must
404 * stop using this connection from now on)
405 * @return the client handle
406 */
407struct GNUNET_SERVER_Client *
408GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server,
409 struct GNUNET_CONNECTION_Handle *connection);
410
411
412/**
413 * Notify the server that the given client handle should
414 * be kept (keeps the connection up if possible, increments
415 * the internal reference counter).
416 *
417 * @param client the client to keep
418 */
419void
420GNUNET_SERVER_client_keep (struct GNUNET_SERVER_Client *client);
421
422
423/**
424 * Notify the server that the given client handle is no
425 * longer required. Decrements the reference counter. If
426 * that counter reaches zero an inactive connection maybe
427 * closed.
428 *
429 * @param client the client to drop
430 */
431void
432GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client);
433
434
435/**
436 * Obtain the network address of the other party.
437 *
438 * @param client the client to get the address for
439 * @param addr where to store the address
440 * @param addrlen where to store the length of @a addr
441 * @return #GNUNET_OK on success
442 */
443int
444GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client,
445 void **addr, size_t *addrlen);
446
447
448/**
449 * Functions with this signature are called whenever a client
450 * is disconnected on the network level.
451 *
452 * @param cls closure
453 * @param client identification of the client; NULL
454 * for the last call when the server is destroyed
455 */
456typedef void
457(*GNUNET_SERVER_DisconnectCallback) (void *cls,
458 struct GNUNET_SERVER_Client *client);
459
460
461/**
462 * Functions with this signature are called whenever a client
463 * is connected on the network level.
464 *
465 * @param cls closure
466 * @param client identification of the client
467 */
468typedef void
469(*GNUNET_SERVER_ConnectCallback) (void *cls,
470 struct GNUNET_SERVER_Client *client);
471
472
473/**
474 * Ask the server to notify us whenever a client disconnects.
475 * This function is called whenever the actual network connection
476 * is closed; the reference count may be zero or larger than zero
477 * at this point. If the server is destroyed before this
478 * notification is explicitly cancelled, the 'callback' will
479 * once be called with a 'client' argument of NULL to indicate
480 * that the server itself is now gone (and that the callback
481 * won't be called anymore and also can no longer be cancelled).
482 *
483 * @param server the server manageing the clients
484 * @param callback function to call on disconnect
485 * @param callback_cls closure for @a callback
486 */
487void
488GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server,
489 GNUNET_SERVER_DisconnectCallback callback,
490 void *callback_cls);
491
492
493/**
494 * Ask the server to notify us whenever a client connects.
495 * This function is called whenever the actual network connection
496 * is opened. If the server is destroyed before this
497 * notification is explicitly cancelled, the @a callback will
498 * once be called with a 'client' argument of NULL to indicate
499 * that the server itself is now gone (and that the callback
500 * won't be called anymore and also can no longer be cancelled).
501 *
502 * @param server the server manageing the clients
503 * @param callback function to call on sconnect
504 * @param callback_cls closure for @a callback
505 */
506void
507GNUNET_SERVER_connect_notify (struct GNUNET_SERVER_Handle *server,
508 GNUNET_SERVER_ConnectCallback callback,
509 void *callback_cls);
510
511
512/**
513 * Ask the server to stop notifying us whenever a client disconnects.
514 * Arguments must match exactly those given to
515 * #GNUNET_SERVER_disconnect_notify. It is not necessary to call this
516 * function during shutdown of the server; in fact, most applications
517 * will never use this function.
518 *
519 * @param server the server manageing the clients
520 * @param callback function to call on disconnect
521 * @param callback_cls closure for @a callback
522 */
523void
524GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server,
525 GNUNET_SERVER_DisconnectCallback callback,
526 void *callback_cls);
527
528
529/**
530 * Ask the server to stop notifying us whenever a client connects.
531 * Arguments must match exactly those given to
532 * #GNUNET_SERVER_connect_notify. It is not necessary to call this
533 * function during shutdown of the server; in fact, most applications
534 * will never use this function.
535 *
536 * @param server the server manageing the clients
537 * @param callback function to call on connect
538 * @param callback_cls closure for @a callback
539 */
540void
541GNUNET_SERVER_connect_notify_cancel (struct GNUNET_SERVER_Handle *server,
542 GNUNET_SERVER_ConnectCallback callback,
543 void *callback_cls);
544
545
546/**
547 * Ask the server to disconnect from the given client. This is the
548 * same as passing #GNUNET_SYSERR to #GNUNET_SERVER_receive_done,
549 * except that it allows dropping of a client even when not handling a
550 * message from that client.
551 *
552 * @param client the client to disconnect from
553 */
554void
555GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client);
556
557
558/**
559 * Disable the "CORK" feature for communication with the given client,
560 * forcing the OS to immediately flush the buffer on transmission
561 * instead of potentially buffering multiple messages.
562 *
563 * @param client handle to the client
564 * @return #GNUNET_OK on success
565 */
566int
567GNUNET_SERVER_client_disable_corking (struct GNUNET_SERVER_Client *client);
568
569
570/**
571 * The tansmit context is the key datastructure for a conveniance API
572 * used for transmission of complex results to the client followed
573 * ONLY by signaling receive_done with success or error
574 */
575struct GNUNET_SERVER_TransmitContext;
576
577
578/**
579 * Create a new transmission context for the given client.
580 *
581 * @param client client to create the context for.
582 * @return NULL on error
583 */
584struct GNUNET_SERVER_TransmitContext *
585GNUNET_SERVER_transmit_context_create (struct GNUNET_SERVER_Client *client);
586
587
588/**
589 * Append a message to the transmission context.
590 * All messages in the context will be sent by
591 * the #GNUNET_SERVER_transmit_context_run method.
592 *
593 * @param tc context to use
594 * @param data what to append to the result message
595 * @param length length of @a data
596 * @param type type of the message
597 */
598void
599GNUNET_SERVER_transmit_context_append_data (struct GNUNET_SERVER_TransmitContext *tc,
600 const void *data,
601 size_t length, uint16_t type);
602
603
604/**
605 * Append a message to the transmission context.
606 * All messages in the context will be sent by
607 * the transmit_context_run method.
608 *
609 * @param tc context to use
610 * @param msg message to append
611 */
612void
613GNUNET_SERVER_transmit_context_append_message (struct GNUNET_SERVER_TransmitContext *tc,
614 const struct GNUNET_MessageHeader *msg);
615
616
617/**
618 * Execute a transmission context. If there is an error in the
619 * transmission, the receive_done method will be called with an error
620 * code (#GNUNET_SYSERR), otherwise with #GNUNET_OK.
621 *
622 * @param tc transmission context to use
623 * @param timeout when to time out and abort the transmission
624 */
625void
626GNUNET_SERVER_transmit_context_run (struct GNUNET_SERVER_TransmitContext *tc,
627 struct GNUNET_TIME_Relative timeout);
628
629
630/**
631 * Destroy a transmission context. This function must not be called
632 * after #GNUNET_SERVER_transmit_context_run.
633 *
634 * @param tc transmission context to destroy
635 * @param success code to give to #GNUNET_SERVER_receive_done for
636 * the client: #GNUNET_OK to keep the connection open and
637 * continue to receive
638 * #GNUNET_NO to close the connection (normal behavior)
639 * #GNUNET_SYSERR to close the connection (signal
640 * serious error)
641 */
642void
643GNUNET_SERVER_transmit_context_destroy (struct GNUNET_SERVER_TransmitContext *tc,
644 int success);
645
646
647/**
648 * The notification context is the key datastructure for a conveniance
649 * API used for transmission of notifications to the client until the
650 * client disconnects or is disconnected (or the notification context
651 * is destroyed, in which case we disconnect these clients).
652 * Essentially, all (notification) messages are queued up until the
653 * client is able to read them.
654 */
655struct GNUNET_SERVER_NotificationContext;
656
657
658/**
659 * Create a new notification context.
660 *
661 * @param server server for which this function creates the context
662 * @param queue_length maximum number of messages to keep in
663 * the notification queue; optional messages are dropped
664 * if the queue gets longer than this number of messages
665 * @return handle to the notification context
666 */
667struct GNUNET_SERVER_NotificationContext *
668GNUNET_SERVER_notification_context_create (struct GNUNET_SERVER_Handle *server,
669 unsigned int queue_length);
670
671
672/**
673 * Destroy the context, force disconnect for all clients.
674 *
675 * @param nc context to destroy.
676 */
677void
678GNUNET_SERVER_notification_context_destroy (struct GNUNET_SERVER_NotificationContext *nc);
679
680
681/**
682 * Add a client to the notification context.
683 *
684 * @param nc context to modify
685 * @param client client to add
686 */
687void
688GNUNET_SERVER_notification_context_add (struct GNUNET_SERVER_NotificationContext *nc,
689 struct GNUNET_SERVER_Client *client);
690
691
692/**
693 * Send a message to a particular client; must have
694 * already been added to the notification context.
695 *
696 * @param nc context to modify
697 * @param client client to transmit to
698 * @param msg message to send
699 * @param can_drop can this message be dropped due to queue length limitations
700 */
701void
702GNUNET_SERVER_notification_context_unicast (struct GNUNET_SERVER_NotificationContext *nc,
703 struct GNUNET_SERVER_Client *client,
704 const struct GNUNET_MessageHeader *msg,
705 int can_drop);
706
707
708/**
709 * Send a message to all clients of this context.
710 *
711 * @param nc context to modify
712 * @param msg message to send
713 * @param can_drop can this message be dropped due to queue length limitations
714 */
715void
716GNUNET_SERVER_notification_context_broadcast (struct GNUNET_SERVER_NotificationContext *nc,
717 const struct GNUNET_MessageHeader *msg,
718 int can_drop);
719
720
721/**
722 * Return active number of subscribers in this context.
723 *
724 * @param nc context to query
725 * @return number of current subscribers
726 */
727unsigned int
728GNUNET_SERVER_notification_context_get_size (struct GNUNET_SERVER_NotificationContext *nc);
729
730
731/**
732 * Create a message queue for a server's client.
733 *
734 * @param client the client
735 * @return the message queue
736 */
737struct GNUNET_MQ_Handle *
738GNUNET_MQ_queue_for_server_client (struct GNUNET_SERVER_Client *client);
739
740
741/**
742 * Handle to a message stream tokenizer.
743 */
744struct GNUNET_SERVER_MessageStreamTokenizer;
745
746
747/**
748 * Functions with this signature are called whenever a
749 * complete message is received by the tokenizer.
750 *
751 * Do not call #GNUNET_SERVER_mst_destroy from within
752 * the scope of this callback.
753 *
754 * @param cls closure
755 * @param client identification of the client
756 * @param message the actual message
757 * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
758 */
759typedef int
760(*GNUNET_SERVER_MessageTokenizerCallback) (void *cls,
761 void *client,
762 const struct GNUNET_MessageHeader *message);
763
764
765/**
766 * Create a message stream tokenizer.
767 *
768 * @param cb function to call on completed messages
769 * @param cb_cls closure for @a cb
770 * @return handle to tokenizer
771 */
772struct GNUNET_SERVER_MessageStreamTokenizer *
773GNUNET_SERVER_mst_create (GNUNET_SERVER_MessageTokenizerCallback cb,
774 void *cb_cls);
775
776
777/**
778 * Add incoming data to the receive buffer and call the
779 * callback for all complete messages.
780 *
781 * @param mst tokenizer to use
782 * @param client_identity ID of client for which this is a buffer,
783 * can be NULL (will be passed back to 'cb')
784 * @param buf input data to add
785 * @param size number of bytes in @a buf
786 * @param purge should any excess bytes in the buffer be discarded
787 * (i.e. for packet-based services like UDP)
788 * @param one_shot only call callback once, keep rest of message in buffer
789 * @return #GNUNET_OK if we are done processing (need more data)
790 * #GNUNET_NO if one_shot was set and we have another message ready
791 * #GNUNET_SYSERR if the data stream is corrupt
792 */
793int
794GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
795 void *client_identity,
796 const char *buf, size_t size,
797 int purge, int one_shot);
798
799
800/**
801 * Destroys a tokenizer.
802 *
803 * @param mst tokenizer to destroy
804 */
805void
806GNUNET_SERVER_mst_destroy (struct GNUNET_SERVER_MessageStreamTokenizer *mst);
807
808
809/**
810 * Signature of a function to create a custom tokenizer.
811 *
812 * @param cls closure from #GNUNET_SERVER_set_callbacks
813 * @param client handle to client the tokenzier will be used for
814 * @return handle to custom tokenizer ('mst')
815 */
816typedef void*
817(*GNUNET_SERVER_MstCreateCallback) (void *cls,
818 struct GNUNET_SERVER_Client *client);
819
820
821/**
822 * Signature of a function to destroy a custom tokenizer.
823 *
824 * @param cls closure from #GNUNET_SERVER_set_callbacks
825 * @param mst custom tokenizer handle
826 */
827typedef void
828(*GNUNET_SERVER_MstDestroyCallback) (void *cls,
829 void *mst);
830
831
832/**
833 * Signature of a function to receive data for a custom tokenizer.
834 *
835 * @param cls closure from #GNUNET_SERVER_set_callbacks
836 * @param mst custom tokenizer handle
837 * @param client_identity ID of client for which this is a buffer,
838 * can be NULL (will be passed back to 'cb')
839 * @param buf input data to add
840 * @param size number of bytes in @a buf
841 * @param purge should any excess bytes in the buffer be discarded
842 * (i.e. for packet-based services like UDP)
843 * @param one_shot only call callback once, keep rest of message in buffer
844 * @return #GNUNET_OK if we are done processing (need more data)
845 * #GNUNET_NO if one_shot was set and we have another message ready
846 * #GNUNET_SYSERR if the data stream is corrupt
847 */
848typedef int
849(*GNUNET_SERVER_MstReceiveCallback) (void *cls, void *mst,
850 struct GNUNET_SERVER_Client *client,
851 const char *buf,
852 size_t size,
853 int purge,
854 int one_shot);
855
856
857/**
858 * Change functions used by the server to tokenize the message stream.
859 * (very rarely used).
860 *
861 * @param server server to modify
862 * @param create new tokenizer initialization function
863 * @param destroy new tokenizer destruction function
864 * @param receive new tokenizer receive function
865 * @param cls closure for @a create, @a receive and @a destroy
866 */
867void
868GNUNET_SERVER_set_callbacks (struct GNUNET_SERVER_Handle *server,
869 GNUNET_SERVER_MstCreateCallback create,
870 GNUNET_SERVER_MstDestroyCallback destroy,
871 GNUNET_SERVER_MstReceiveCallback receive,
872 void *cls);
873
874
875#if 0 /* keep Emacsens' auto-indent happy */
876{
877#endif
878#ifdef __cplusplus
879}
880#endif
881
882/* ifndef GNUNET_SERVER_LIB_H */
883#endif
884
885/** @} */ /* end of group server */
886
887/* end of gnunet_server_lib.h */
diff --git a/src/include/gnunet_service_lib.h b/src/include/gnunet_service_lib.h
index 75b880530..aacafe956 100644
--- a/src/include/gnunet_service_lib.h
+++ b/src/include/gnunet_service_lib.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2009-2013, 2016 GNUnet e.V. 3 Copyright (C) 2009-2013, 2016, 2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -44,25 +44,10 @@ extern "C"
44#endif 44#endif
45 45
46#include "gnunet_configuration_lib.h" 46#include "gnunet_configuration_lib.h"
47#include "gnunet_server_lib.h"
48#include "gnunet_mq_lib.h" 47#include "gnunet_mq_lib.h"
49 48
50 49
51/** 50/**
52 * Function called by the service's run
53 * method to run service-specific setup code.
54 *
55 * @param cls closure
56 * @param server the initialized server
57 * @param cfg configuration to use
58 */
59typedef void
60(*GNUNET_SERVICE_Main) (void *cls,
61 struct GNUNET_SERVER_Handle *server,
62 const struct GNUNET_CONFIGURATION_Handle *cfg);
63
64
65/**
66 * Options for the service (bitmask). 51 * Options for the service (bitmask).
67 */ 52 */
68enum GNUNET_SERVICE_Options 53enum GNUNET_SERVICE_Options
@@ -88,84 +73,6 @@ enum GNUNET_SERVICE_Options
88}; 73};
89 74
90 75
91/**
92 * Run a standard GNUnet service startup sequence (initialize loggers
93 * and configuration, parse options).
94 *
95 * @param argc number of command line arguments in @a argv
96 * @param argv command line arguments
97 * @param service_name our service name
98 * @param options service options
99 * @param task main task of the service
100 * @param task_cls closure for @a task
101 * @return #GNUNET_SYSERR on error, #GNUNET_OK
102 * if we shutdown nicely
103 * @deprecated
104 */
105int
106GNUNET_SERVICE_run (int argc,
107 char *const *argv,
108 const char *service_name,
109 enum GNUNET_SERVICE_Options options,
110 GNUNET_SERVICE_Main task,
111 void *task_cls);
112
113
114/**
115 * Opaque handle for a service.
116 */
117struct GNUNET_SERVICE_Context;
118
119
120/**
121 * Run a service startup sequence within an existing
122 * initialized system.
123 *
124 * @param service_name our service name
125 * @param cfg configuration to use
126 * @param options service options
127 * @return NULL on error, service handle
128 * @deprecated
129 */
130struct GNUNET_SERVICE_Context *
131GNUNET_SERVICE_start (const char *service_name,
132 const struct GNUNET_CONFIGURATION_Handle *cfg,
133 enum GNUNET_SERVICE_Options options);
134
135
136/**
137 * Obtain the server used by a service. Note that the server must NOT
138 * be destroyed by the caller.
139 *
140 * @param ctx the service context returned from the start function
141 * @return handle to the server for this service, NULL if there is none
142 * @deprecated
143 */
144struct GNUNET_SERVER_Handle *
145GNUNET_SERVICE_get_server (struct GNUNET_SERVICE_Context *ctx);
146
147
148/**
149 * Get the NULL-terminated array of listen sockets for this service.
150 *
151 * @param ctx service context to query
152 * @return NULL if there are no listen sockets, otherwise NULL-terminated
153 * array of listen sockets.
154 * @deprecated
155 */
156struct GNUNET_NETWORK_Handle *const *
157GNUNET_SERVICE_get_listen_sockets (struct GNUNET_SERVICE_Context *ctx);
158
159
160/**
161 * Stop a service that was started with #GNUNET_SERVICE_start.
162 *
163 * @param sctx the service context returned from the start function
164 * @deprecated
165 */
166void
167GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Context *sctx);
168
169 76
170/* **************** NEW SERVICE API ********************** */ 77/* **************** NEW SERVICE API ********************** */
171 78
@@ -245,7 +152,7 @@ typedef void
245 * dropped. Additionally, clients can be dropped at any time using 152 * dropped. Additionally, clients can be dropped at any time using
246 * #GNUNET_SERVICE_client_drop(). 153 * #GNUNET_SERVICE_client_drop().
247 * 154 *
248 * The service must be stopped using #GNUNET_SERVICE_stoP(). 155 * The service must be stopped using #GNUNET_SERVICE_stop().
249 * 156 *
250 * @param service_name name of the service to run 157 * @param service_name name of the service to run
251 * @param cfg configuration to use 158 * @param cfg configuration to use
@@ -258,7 +165,7 @@ typedef void
258 * @return NULL on error 165 * @return NULL on error
259 */ 166 */
260struct GNUNET_SERVICE_Handle * 167struct GNUNET_SERVICE_Handle *
261GNUNET_SERVICE_starT (const char *service_name, 168GNUNET_SERVICE_start (const char *service_name,
262 const struct GNUNET_CONFIGURATION_Handle *cfg, 169 const struct GNUNET_CONFIGURATION_Handle *cfg,
263 GNUNET_SERVICE_ConnectHandler connect_cb, 170 GNUNET_SERVICE_ConnectHandler connect_cb,
264 GNUNET_SERVICE_DisconnectHandler disconnect_cb, 171 GNUNET_SERVICE_DisconnectHandler disconnect_cb,
@@ -267,12 +174,12 @@ GNUNET_SERVICE_starT (const char *service_name,
267 174
268 175
269/** 176/**
270 * Stops a service that was started with #GNUNET_SERVICE_starT(). 177 * Stops a service that was started with #GNUNET_SERVICE_start().
271 * 178 *
272 * @param srv service to stop 179 * @param srv service to stop
273 */ 180 */
274void 181void
275GNUNET_SERVICE_stoP (struct GNUNET_SERVICE_Handle *srv); 182GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Handle *srv);
276 183
277 184
278/** 185/**
@@ -317,7 +224,7 @@ GNUNET_SERVICE_stoP (struct GNUNET_SERVICE_Handle *srv);
317 * @return 0 on success, non-zero on error 224 * @return 0 on success, non-zero on error
318 */ 225 */
319int 226int
320GNUNET_SERVICE_ruN_ (int argc, 227GNUNET_SERVICE_run_ (int argc,
321 char *const *argv, 228 char *const *argv,
322 const char *service_name, 229 const char *service_name,
323 enum GNUNET_SERVICE_Options options, 230 enum GNUNET_SERVICE_Options options,
@@ -393,7 +300,7 @@ GNUNET_SERVICE_ruN_ (int argc,
393 struct GNUNET_MQ_MessageHandler mh[] = { \ 300 struct GNUNET_MQ_MessageHandler mh[] = { \
394 __VA_ARGS__ \ 301 __VA_ARGS__ \
395 }; \ 302 }; \
396 return GNUNET_SERVICE_ruN_ (argc, \ 303 return GNUNET_SERVICE_run_ (argc, \
397 argv, \ 304 argv, \
398 service_name, \ 305 service_name, \
399 service_options, \ 306 service_options, \
diff --git a/src/include/gnunet_util_lib.h b/src/include/gnunet_util_lib.h
index 52f5d8ab2..a9bd6c33f 100644
--- a/src/include/gnunet_util_lib.h
+++ b/src/include/gnunet_util_lib.h
@@ -38,10 +38,24 @@ extern "C"
38#endif 38#endif
39#endif 39#endif
40 40
41
42/**
43 * Largest supported message (to be precise, one byte more
44 * than the largest possible message, so tests involving
45 * this value should check for messages being smaller than
46 * this value).
47 */
48#define GNUNET_MAX_MESSAGE_SIZE 65536
49
50/**
51 * Smallest supported message.
52 */
53#define GNUNET_MIN_MESSAGE_SIZE sizeof (struct GNUNET_MessageHeader)
54
55
41#include "gnunet_crypto_lib.h" 56#include "gnunet_crypto_lib.h"
42#include "gnunet_bandwidth_lib.h" 57#include "gnunet_bandwidth_lib.h"
43#include "gnunet_bio_lib.h" 58#include "gnunet_bio_lib.h"
44#include "gnunet_connection_lib.h"
45#include "gnunet_client_lib.h" 59#include "gnunet_client_lib.h"
46#include "gnunet_container_lib.h" 60#include "gnunet_container_lib.h"
47#include "gnunet_getopt_lib.h" 61#include "gnunet_getopt_lib.h"
@@ -55,7 +69,6 @@ extern "C"
55#include "gnunet_plugin_lib.h" 69#include "gnunet_plugin_lib.h"
56#include "gnunet_program_lib.h" 70#include "gnunet_program_lib.h"
57#include "gnunet_protocols.h" 71#include "gnunet_protocols.h"
58#include "gnunet_server_lib.h"
59#include "gnunet_service_lib.h" 72#include "gnunet_service_lib.h"
60#include "gnunet_signal_lib.h" 73#include "gnunet_signal_lib.h"
61#include "gnunet_strings_lib.h" 74#include "gnunet_strings_lib.h"
diff --git a/src/include/platform.h b/src/include/platform.h
index add58821f..6095d0258 100644
--- a/src/include/platform.h
+++ b/src/include/platform.h
@@ -110,6 +110,7 @@
110#include <stdlib.h> 110#include <stdlib.h>
111#include <stdint.h> 111#include <stdint.h>
112#include <stdarg.h> 112#include <stdarg.h>
113#include <stdbool.h>
113#include <errno.h> 114#include <errno.h>
114#include <signal.h> 115#include <signal.h>
115#include <libgen.h> 116#include <libgen.h>
diff --git a/src/json/json.c b/src/json/json.c
index a2d1a9608..c182a02f4 100644
--- a/src/json/json.c
+++ b/src/json/json.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2014, 2015, 2016 GNUnet e.V. 3 Copyright (C) 2014-2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify it under the 5 GNUnet is free software; you can redistribute it and/or modify it under the
6 terms of the GNU General Public License as published by the Free Software 6 terms of the GNU General Public License as published by the Free Software
@@ -82,13 +82,78 @@ GNUNET_JSON_parse (const json_t *root,
82void 82void
83GNUNET_JSON_parse_free (struct GNUNET_JSON_Specification *spec) 83GNUNET_JSON_parse_free (struct GNUNET_JSON_Specification *spec)
84{ 84{
85 unsigned int i; 85 for (unsigned int i=0;NULL != spec[i].parser;i++)
86
87 for (i=0;NULL != spec[i].parser;i++)
88 if (NULL != spec[i].cleaner) 86 if (NULL != spec[i].cleaner)
89 spec[i].cleaner (spec[i].cls, 87 spec[i].cleaner (spec[i].cls,
90 &spec[i]); 88 &spec[i]);
91} 89}
92 90
93 91
92/**
93 * Set an option with a JSON value from the command line.
94 * A pointer to this function should be passed as part of the
95 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
96 * of this type.
97 *
98 * @param ctx command line processing context
99 * @param scls additional closure (will point to the 'json_t *')
100 * @param option name of the option
101 * @param value actual value of the option as a string.
102 * @return #GNUNET_OK if parsing the value worked
103 */
104static int
105set_json (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
106 void *scls,
107 const char *option,
108 const char *value)
109{
110 json_t **json = scls;
111 json_error_t error;
112
113 *json = json_loads (value,
114 JSON_REJECT_DUPLICATES,
115 &error);
116 if (NULL == *json)
117 {
118 FPRINTF (stderr,
119 _("Failed to parse JSON in option `%s': %s (%s)\n"),
120 option,
121 error.text,
122 error.source);
123 return GNUNET_SYSERR;
124 }
125 return GNUNET_OK;
126}
127
128
129/**
130 * Allow user to specify a JSON input value.
131 *
132 * @param shortName short name of the option
133 * @param name long name of the option
134 * @param argumentHelp help text for the option argument
135 * @param description long help text for the option
136 * @param[out] val set to the JSON specified at the command line
137 */
138struct GNUNET_GETOPT_CommandLineOption
139GNUNET_JSON_getopt (char shortName,
140 const char *name,
141 const char *argumentHelp,
142 const char *description,
143 json_t **json)
144{
145 struct GNUNET_GETOPT_CommandLineOption clo = {
146 .shortName = shortName,
147 .name = name,
148 .argumentHelp = argumentHelp,
149 .description = description,
150 .require_argument = 1,
151 .processor = &set_json,
152 .scls = (void *) json
153 };
154
155 return clo;
156}
157
158
94/* end of json.c */ 159/* end of json.c */
diff --git a/src/multicast/.gitignore b/src/multicast/.gitignore
index d38ca9c02..43752ec4b 100644
--- a/src/multicast/.gitignore
+++ b/src/multicast/.gitignore
@@ -2,3 +2,4 @@ gnunet-service-multicast
2gnunet-multicast 2gnunet-multicast
3test_multicast 3test_multicast
4test_multicast_multipeer 4test_multicast_multipeer
5test_multicast_2peers
diff --git a/src/multicast/gnunet-service-multicast.c b/src/multicast/gnunet-service-multicast.c
index cf39d3b22..9683efcff 100644
--- a/src/multicast/gnunet-service-multicast.c
+++ b/src/multicast/gnunet-service-multicast.c
@@ -464,6 +464,9 @@ replay_key_hash (uint64_t fragment_id, uint64_t message_id,
464static int 464static int
465replay_req_remove_cadet (struct Channel *chn) 465replay_req_remove_cadet (struct Channel *chn)
466{ 466{
467 if (NULL == chn || NULL == chn->group)
468 return GNUNET_SYSERR;
469
467 struct GNUNET_CONTAINER_MultiHashMap * 470 struct GNUNET_CONTAINER_MultiHashMap *
468 grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet, 471 grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet,
469 &chn->group->pub_key_hash); 472 &chn->group->pub_key_hash);
diff --git a/src/namecache/gnunet-namecache.c b/src/namecache/gnunet-namecache.c
index 490197b1e..2410c9b3c 100644
--- a/src/namecache/gnunet-namecache.c
+++ b/src/namecache/gnunet-namecache.c
@@ -225,13 +225,19 @@ run (void *cls, char *const *args, const char *cfgfile,
225int 225int
226main (int argc, char *const *argv) 226main (int argc, char *const *argv)
227{ 227{
228 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 228 struct GNUNET_GETOPT_CommandLineOption options[] = {
229 {'n', "name", "NAME", 229 GNUNET_GETOPT_OPTION_STRING ('n',
230 gettext_noop ("name of the record to add/delete/display"), 1, 230 "name",
231 &GNUNET_GETOPT_set_string, &name}, 231 "NAME",
232 {'z', "zone", "PKEY", 232 gettext_noop ("name of the record to add/delete/display"),
233 gettext_noop ("spezifies the public key of the zone to look in"), 1, 233 &name),
234 &GNUNET_GETOPT_set_string, &pkey}, 234
235 GNUNET_GETOPT_OPTION_STRING ('z',
236 "zone",
237 "PKEY",
238 gettext_noop ("spezifies the public key of the zone to look in"),
239 &pkey),
240
235 GNUNET_GETOPT_OPTION_END 241 GNUNET_GETOPT_OPTION_END
236 }; 242 };
237 243
diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c
index 457e77022..2ce3741f8 100644
--- a/src/namestore/gnunet-namestore.c
+++ b/src/namestore/gnunet-namestore.c
@@ -1130,49 +1130,88 @@ main (int argc,
1130 is_public = -1; 1130 is_public = -1;
1131 is_shadow = -1; 1131 is_shadow = -1;
1132 1132
1133 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 1133 struct GNUNET_GETOPT_CommandLineOption options[] = {
1134 {'a', "add", NULL, 1134
1135 gettext_noop ("add record"), 0, 1135 GNUNET_GETOPT_OPTION_SET_ONE ('a',
1136 &GNUNET_GETOPT_set_one, &add}, 1136 "add",
1137 {'d', "delete", NULL, 1137 gettext_noop ("add record"),
1138 gettext_noop ("delete record"), 0, 1138 &add),
1139 &GNUNET_GETOPT_set_one, &del}, 1139
1140 {'D', "display", NULL, 1140 GNUNET_GETOPT_OPTION_SET_ONE ('d',
1141 gettext_noop ("display records"), 0, 1141 "delete",
1142 &GNUNET_GETOPT_set_one, &list}, 1142 gettext_noop ("delete record"),
1143 {'e', "expiration", "TIME", 1143 &del),
1144 gettext_noop ("expiration time for record to use (for adding only), \"never\" is possible"), 1, 1144
1145 &GNUNET_GETOPT_set_string, &expirationstring}, 1145 GNUNET_GETOPT_OPTION_SET_ONE ('D',
1146 {'i', "nick", "NICKNAME", 1146 "display",
1147 gettext_noop ("set the desired nick name for the zone"), 1, 1147 gettext_noop ("display records"),
1148 &GNUNET_GETOPT_set_string, &nickstring}, 1148 &list),
1149 {'m', "monitor", NULL, 1149
1150 gettext_noop ("monitor changes in the namestore"), 0, 1150 GNUNET_GETOPT_OPTION_STRING ('e',
1151 &GNUNET_GETOPT_set_one, &monitor}, 1151 "expiration",
1152 {'n', "name", "NAME", 1152 "TIME",
1153 gettext_noop ("name of the record to add/delete/display"), 1, 1153 gettext_noop ("expiration time for record to use (for adding only), \"never\" is possible"),
1154 &GNUNET_GETOPT_set_string, &name}, 1154 &expirationstring),
1155 {'r', "reverse", "PKEY", 1155
1156 gettext_noop ("determine our name for the given PKEY"), 1, 1156 GNUNET_GETOPT_OPTION_STRING ('i',
1157 &GNUNET_GETOPT_set_string, &reverse_pkey}, 1157 "nick",
1158 {'t', "type", "TYPE", 1158 "NICKNAME",
1159 gettext_noop ("type of the record to add/delete/display"), 1, 1159 gettext_noop ("set the desired nick name for the zone"),
1160 &GNUNET_GETOPT_set_string, &typestring}, 1160 &nickstring),
1161 {'u', "uri", "URI", 1161
1162 gettext_noop ("URI to import into our zone"), 1, 1162 GNUNET_GETOPT_OPTION_SET_ONE ('m',
1163 &GNUNET_GETOPT_set_string, &uri}, 1163 "monitor",
1164 {'V', "value", "VALUE", 1164 gettext_noop ("monitor changes in the namestore"),
1165 gettext_noop ("value of the record to add/delete"), 1, 1165 &monitor),
1166 &GNUNET_GETOPT_set_string, &value}, 1166
1167 {'p', "public", NULL, 1167 GNUNET_GETOPT_OPTION_STRING ('n',
1168 gettext_noop ("create or list public record"), 0, 1168 "name",
1169 &GNUNET_GETOPT_set_one, &is_public}, 1169 "NAME",
1170 {'s', "shadow", NULL, 1170 gettext_noop ("name of the record to add/delete/display"),
1171 gettext_noop ("create shadow record (only valid if all other records of the same type have expired"), 0, 1171 &name),
1172 &GNUNET_GETOPT_set_one, &is_shadow}, 1172
1173 {'z', "zone", "EGO", 1173 GNUNET_GETOPT_OPTION_STRING ('r',
1174 gettext_noop ("name of the ego controlling the zone"), 1, 1174 "reverse",
1175 &GNUNET_GETOPT_set_string, &ego_name}, 1175 "PKEY",
1176 gettext_noop ("determine our name for the given PKEY"),
1177 &reverse_pkey),
1178
1179
1180
1181 GNUNET_GETOPT_OPTION_STRING ('t',
1182 "type",
1183 "TYPE",
1184 gettext_noop ("type of the record to add/delete/display"),
1185 &typestring),
1186
1187 GNUNET_GETOPT_OPTION_STRING ('u',
1188 "uri",
1189 "URI",
1190 gettext_noop ("URI to import into our zone"),
1191 &uri),
1192
1193 GNUNET_GETOPT_OPTION_STRING ('V',
1194 "value",
1195 "VALUE",
1196 gettext_noop ("value of the record to add/delete"),
1197 &value),
1198
1199 GNUNET_GETOPT_OPTION_SET_ONE ('p',
1200 "public",
1201 gettext_noop ("create or list public record"),
1202 &is_public),
1203
1204 GNUNET_GETOPT_OPTION_SET_ONE ('s',
1205 "shadow",
1206 gettext_noop ("create shadow record (only valid if all other records of the same type have expired"),
1207 &is_shadow),
1208
1209 GNUNET_GETOPT_OPTION_STRING ('z',
1210 "zone",
1211 "EGO",
1212 gettext_noop ("name of the ego controlling the zone"),
1213 &ego_name),
1214
1176 GNUNET_GETOPT_OPTION_END 1215 GNUNET_GETOPT_OPTION_END
1177 }; 1216 };
1178 1217
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c
index ae65802b0..6cb4290a0 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -1136,7 +1136,7 @@ handle_zone_to_name_it (void *cls,
1136 name_len = (NULL == name) ? 0 : strlen (name) + 1; 1136 name_len = (NULL == name) ? 0 : strlen (name) + 1;
1137 rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd); 1137 rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1138 msg_size = sizeof (struct ZoneToNameResponseMessage) + name_len + rd_ser_len; 1138 msg_size = sizeof (struct ZoneToNameResponseMessage) + name_len + rd_ser_len;
1139 if (msg_size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 1139 if (msg_size >= GNUNET_MAX_MESSAGE_SIZE)
1140 { 1140 {
1141 GNUNET_break (0); 1141 GNUNET_break (0);
1142 ztn_ctx->success = GNUNET_SYSERR; 1142 ztn_ctx->success = GNUNET_SYSERR;
diff --git a/src/nat-auto/Makefile.am b/src/nat-auto/Makefile.am
index 19695fabd..14f3f2330 100644
--- a/src/nat-auto/Makefile.am
+++ b/src/nat-auto/Makefile.am
@@ -37,11 +37,11 @@ lib_LTLIBRARIES = \
37 37
38libgnunetnatauto_la_SOURCES = \ 38libgnunetnatauto_la_SOURCES = \
39 nat_auto_api.c \ 39 nat_auto_api.c \
40 nat_auto_api_test.c 40 nat_auto_api_test.c
41libgnunetnatauto_la_LIBADD = \ 41libgnunetnatauto_la_LIBADD = \
42 $(top_builddir)/src/nat/libgnunetnatnew.la \ 42 $(top_builddir)/src/nat/libgnunetnatnew.la \
43 $(top_builddir)/src/util/libgnunetutil.la \ 43 $(top_builddir)/src/util/libgnunetutil.la \
44 $(GN_LIBINTL) @EXT_LIBS@ 44 $(GN_LIBINTL) @EXT_LIBS@
45libgnunetnatauto_la_LDFLAGS = \ 45libgnunetnatauto_la_LDFLAGS = \
46 $(GN_LIB_LDFLAGS) $(WINFLAGS) \ 46 $(GN_LIB_LDFLAGS) $(WINFLAGS) \
47 -version-info 0:0:0 47 -version-info 0:0:0
@@ -55,4 +55,3 @@ gnunet_service_nat_auto_LDADD = \
55 $(LIBGCRYPT_LIBS) \ 55 $(LIBGCRYPT_LIBS) \
56 -lgcrypt \ 56 -lgcrypt \
57 $(GN_LIBINTL) 57 $(GN_LIBINTL)
58
diff --git a/src/nat-auto/gnunet-nat-auto.c b/src/nat-auto/gnunet-nat-auto.c
index 5eb0a4be3..8b281d1ab 100644
--- a/src/nat-auto/gnunet-nat-auto.c
+++ b/src/nat-auto/gnunet-nat-auto.c
@@ -63,7 +63,7 @@ static char *section_name;
63/** 63/**
64 * Should we run autoconfiguration? 64 * Should we run autoconfiguration?
65 */ 65 */
66static unsigned int do_auto; 66static int do_auto;
67 67
68/** 68/**
69 * Handle to a NAT test operation. 69 * Handle to a NAT test operation.
@@ -339,22 +339,32 @@ int
339main (int argc, 339main (int argc,
340 char *const argv[]) 340 char *const argv[])
341{ 341{
342 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 342 struct GNUNET_GETOPT_CommandLineOption options[] = {
343 {'a', "auto", NULL, 343 GNUNET_GETOPT_OPTION_SET_ONE ('a',
344 gettext_noop ("run autoconfiguration"), 344 "auto",
345 GNUNET_NO, &GNUNET_GETOPT_set_one, &do_auto }, 345 gettext_noop ("run autoconfiguration"),
346 {'S', "section", "NAME", 346 &do_auto),
347 gettext_noop ("section name providing the configuration for the adapter"), 347
348 GNUNET_YES, &GNUNET_GETOPT_set_string, &section_name }, 348 GNUNET_GETOPT_OPTION_STRING ('S',
349 {'t', "tcp", NULL, 349 "section",
350 gettext_noop ("use TCP"), 350 "NAME",
351 GNUNET_NO, &GNUNET_GETOPT_set_one, &use_tcp }, 351 gettext_noop ("section name providing the configuration for the adapter"),
352 {'u', "udp", NULL, 352 &section_name),
353 gettext_noop ("use UDP"), 353
354 GNUNET_NO, &GNUNET_GETOPT_set_one, &use_udp }, 354 GNUNET_GETOPT_OPTION_SET_ONE ('t',
355 {'w', "write", NULL, 355 "tcp",
356 gettext_noop ("write configuration file (for autoconfiguration)"), 356 gettext_noop ("use TCP"),
357 GNUNET_NO, &GNUNET_GETOPT_set_one, &write_cfg }, 357 &use_tcp),
358
359 GNUNET_GETOPT_OPTION_SET_ONE ('u',
360 "udp",
361 gettext_noop ("use UDP"),
362 &use_udp),
363
364 GNUNET_GETOPT_OPTION_SET_ONE ('w',
365 "write",
366 gettext_noop ("write configuration file (for autoconfiguration)"),
367 &write_cfg),
358 GNUNET_GETOPT_OPTION_END 368 GNUNET_GETOPT_OPTION_END
359 }; 369 };
360 370
diff --git a/src/nat-auto/gnunet-nat-server.c b/src/nat-auto/gnunet-nat-server.c
index 371e4b27e..590fad4d6 100644
--- a/src/nat-auto/gnunet-nat-server.c
+++ b/src/nat-auto/gnunet-nat-server.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2011 GNUnet e.V. 3 Copyright (C) 2011, 2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -31,9 +31,21 @@
31 31
32 32
33/** 33/**
34 * Our server. 34 * Information we track per client.
35 */ 35 */
36static struct GNUNET_SERVER_Handle *server; 36struct ClientData
37{
38 /**
39 * Timeout task.
40 */
41 struct GNUNET_SCHEDULER_Task *tt;
42
43 /**
44 * Client handle.
45 */
46 struct GNUNET_SERVICE_Client *client;
47};
48
37 49
38/** 50/**
39 * Our configuration. 51 * Our configuration.
@@ -248,21 +260,18 @@ try_send_udp (uint32_t dst_ipv4,
248 * We've received a request to probe a NAT 260 * We've received a request to probe a NAT
249 * traversal. Do it. 261 * traversal. Do it.
250 * 262 *
251 * @param cls unused 263 * @param cls handle to client (we always close)
252 * @param client handle to client (we always close)
253 * @param msg message with details about what to test 264 * @param msg message with details about what to test
254 */ 265 */
255static void 266static void
256test (void *cls, 267handle_test (void *cls,
257 struct GNUNET_SERVER_Client *client, 268 const struct GNUNET_NAT_AUTO_TestMessage *tm)
258 const struct GNUNET_MessageHeader *msg)
259{ 269{
260 const struct GNUNET_NAT_AUTO_TestMessage *tm; 270 struct ClientData *cd = cls;
261 uint16_t dport; 271 uint16_t dport;
262 272
263 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 273 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
264 "Received test request\n"); 274 "Received test request\n");
265 tm = (const struct GNUNET_NAT_AUTO_TestMessage *) msg;
266 dport = ntohs (tm->dport); 275 dport = ntohs (tm->dport);
267 if (0 == dport) 276 if (0 == dport)
268 try_anat (tm->dst_ipv4, 277 try_anat (tm->dst_ipv4,
@@ -276,126 +285,119 @@ test (void *cls,
276 try_send_udp (tm->dst_ipv4, 285 try_send_udp (tm->dst_ipv4,
277 dport, 286 dport,
278 tm->data); 287 tm->data);
279 GNUNET_SERVER_receive_done (client, 288 GNUNET_SERVICE_client_drop (cd->client);
280 GNUNET_NO);
281} 289}
282 290
283 291
284/** 292/**
285 * Task run during shutdown. 293 * Main function that will be run.
286 * 294 *
287 * @param cls unused 295 * @param cls closure
296 * @param c configuration
297 * @param srv service handle
288 */ 298 */
289static void 299static void
290shutdown_task (void *cls) 300run (void *cls,
301 const struct GNUNET_CONFIGURATION_Handle *c,
302 struct GNUNET_SERVICE_Handle *srv)
291{ 303{
292 GNUNET_SERVER_destroy (server); 304 cfg = c;
293 server = NULL;
294} 305}
295 306
296 307
297/** 308/**
298 * Main function that will be run. 309 * Forcefully drops client after 1s.
299 * 310 *
300 * @param cls closure 311 * @param cls our `struct ClientData` of a client to drop
301 * @param args remaining command-line arguments
302 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
303 * @param c configuration
304 */ 312 */
305static void 313static void
306run (void *cls, 314force_timeout (void *cls)
307 char *const *args,
308 const char *cfgfile,
309 const struct GNUNET_CONFIGURATION_Handle *c)
310{ 315{
311 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 316 struct ClientData *cd = cls;
312 {&test, NULL, GNUNET_MESSAGE_TYPE_NAT_TEST,
313 sizeof (struct GNUNET_NAT_AUTO_TestMessage)},
314 {NULL, NULL, 0, 0}
315 };
316 unsigned int port;
317 struct sockaddr_in in4;
318 struct sockaddr_in6 in6;
319
320 socklen_t slen[] = {
321 sizeof (in4),
322 sizeof (in6),
323 0
324 };
325 struct sockaddr *sa[] = {
326 (struct sockaddr *) &in4,
327 (struct sockaddr *) &in6,
328 NULL
329 };
330 317
331 cfg = c; 318 cd->tt = NULL;
332 if ( (NULL == args[0]) || 319 GNUNET_SERVICE_client_drop (cd->client);
333 (1 != SSCANF (args[0], "%u", &port)) ||
334 (0 == port) ||
335 (65536 <= port) )
336 {
337 FPRINTF (stderr,
338 _("Please pass valid port number as the first argument! (got `%s')\n"),
339 args[0]);
340 return;
341 }
342 memset (&in4, 0, sizeof (in4));
343 memset (&in6, 0, sizeof (in6));
344 in4.sin_family = AF_INET;
345 in4.sin_port = htons ((uint16_t) port);
346 in6.sin6_family = AF_INET6;
347 in6.sin6_port = htons ((uint16_t) port);
348#if HAVE_SOCKADDR_IN_SIN_LEN
349 in4.sin_len = sizeof (in4);
350 in6.sin6_len = sizeof (in6);
351#endif
352 server = GNUNET_SERVER_create (NULL,
353 NULL,
354 (struct sockaddr * const *) sa,
355 slen,
356 GNUNET_TIME_UNIT_SECONDS,
357 GNUNET_YES);
358 GNUNET_SERVER_add_handlers (server,
359 handlers);
360 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
361 NULL);
362} 320}
363 321
364 322
323
365/** 324/**
366 * Main function of gnunet-nat-server. 325 * Callback called when a client connects to the service.
367 * 326 *
368 * @param argc number of command-line arguments 327 * @param cls closure for the service
369 * @param argv command line 328 * @param c the new client that connected to the service
370 * @return 0 on success, -1 on error 329 * @param mq the message queue used to send messages to the client
330 * @return our `struct ClientData`
371 */ 331 */
372int 332static void *
373main (int argc, char *const argv[]) 333client_connect_cb (void *cls,
334 struct GNUNET_SERVICE_Client *c,
335 struct GNUNET_MQ_Handle *mq)
374{ 336{
375 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 337 struct ClientData *cd;
376 GNUNET_GETOPT_OPTION_END 338
377 }; 339 cd = GNUNET_new (struct ClientData);
378 340 cd->client = c;
379 if (GNUNET_OK != 341 cd->tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
380 GNUNET_STRINGS_get_utf8_args (argc, argv, 342 &force_timeout,
381 &argc, &argv)) 343 cd);
382 return 2; 344 return cd;
383 345}
384 if (GNUNET_OK != 346
385 GNUNET_PROGRAM_run (argc, 347
386 argv, 348/**
387 "gnunet-nat-server [options] PORT", 349 * Callback called when a client disconnected from the service
388 _("GNUnet NAT traversal test helper daemon"), 350 *
389 options, 351 * @param cls closure for the service
390 &run, 352 * @param c the client that disconnected
391 NULL)) 353 * @param internal_cls our `struct ClientData`
392 { 354 */
393 GNUNET_free ((void*) argv); 355static void
394 return 1; 356client_disconnect_cb (void *cls,
395 } 357 struct GNUNET_SERVICE_Client *c,
396 GNUNET_free ((void*) argv); 358 void *internal_cls)
397 return 0; 359{
360 struct ClientData *cd = internal_cls;
361
362 if (NULL != cd->tt)
363 GNUNET_SCHEDULER_cancel (cd->tt);
364 GNUNET_free (cd);
398} 365}
399 366
400 367
368/**
369 * Define "main" method using service macro.
370 */
371GNUNET_SERVICE_MAIN
372("nat-server",
373 GNUNET_SERVICE_OPTION_NONE,
374 &run,
375 &client_connect_cb,
376 &client_disconnect_cb,
377 NULL,
378 GNUNET_MQ_hd_fixed_size (test,
379 GNUNET_MESSAGE_TYPE_NAT_TEST,
380 struct GNUNET_NAT_AUTO_TestMessage,
381 NULL),
382 GNUNET_MQ_handler_end ());
383
384
385#if defined(LINUX) && defined(__GLIBC__)
386#include <malloc.h>
387
388/**
389 * MINIMIZE heap size (way below 128k) since this process doesn't need much.
390 */
391void __attribute__ ((constructor))
392GNUNET_ARM_memory_init ()
393{
394 mallopt (M_TRIM_THRESHOLD, 4 * 1024);
395 mallopt (M_TOP_PAD, 1 * 1024);
396 malloc_trim (0);
397}
398#endif
399
400
401
402
401/* end of gnunet-nat-server.c */ 403/* end of gnunet-nat-server.c */
diff --git a/src/nat-auto/nat_auto_api.c b/src/nat-auto/nat_auto_api.c
index 6660239c3..8a7eaf264 100644
--- a/src/nat-auto/nat_auto_api.c
+++ b/src/nat-auto/nat_auto_api.c
@@ -224,7 +224,7 @@ GNUNET_NAT_AUTO_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
224 224
225 buf = GNUNET_CONFIGURATION_serialize (cfg, 225 buf = GNUNET_CONFIGURATION_serialize (cfg,
226 &size); 226 &size);
227 if (size > GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*req)) 227 if (size > GNUNET_MAX_MESSAGE_SIZE - sizeof (*req))
228 { 228 {
229 GNUNET_break (0); 229 GNUNET_break (0);
230 GNUNET_free (buf); 230 GNUNET_free (buf);
diff --git a/src/nat/gnunet-nat.c b/src/nat/gnunet-nat.c
index 04bde5111..50e0dff0f 100644
--- a/src/nat/gnunet-nat.c
+++ b/src/nat/gnunet-nat.c
@@ -72,7 +72,7 @@ static char *remote_addr;
72/** 72/**
73 * Should we actually bind to #bind_addr and receive and process STUN requests? 73 * Should we actually bind to #bind_addr and receive and process STUN requests?
74 */ 74 */
75static unsigned int do_stun; 75static int do_stun;
76 76
77/** 77/**
78 * Handle to NAT operation. 78 * Handle to NAT operation.
@@ -417,29 +417,46 @@ int
417main (int argc, 417main (int argc,
418 char *const argv[]) 418 char *const argv[])
419{ 419{
420 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 420 struct GNUNET_GETOPT_CommandLineOption options[] = {
421 {'i', "in", "ADDRESS", 421
422 gettext_noop ("which IP and port are we locally using to bind/listen to"), 422 GNUNET_GETOPT_OPTION_STRING ('i',
423 GNUNET_YES, &GNUNET_GETOPT_set_string, &local_addr }, 423 "in",
424 {'r', "remote", "ADDRESS", 424 "ADDRESS",
425 gettext_noop ("which remote IP and port should be asked for connection reversal"), 425 gettext_noop ("which IP and port are we locally using to bind/listen to"),
426 GNUNET_YES, &GNUNET_GETOPT_set_string, &remote_addr }, 426 &local_addr),
427 {'S', "section", NULL, 427
428 gettext_noop ("name of configuration section to find additional options, such as manual host punching data"), 428 GNUNET_GETOPT_OPTION_STRING ('r',
429 GNUNET_YES, &GNUNET_GETOPT_set_string, &section_name }, 429 "remote",
430 {'s', "stun", NULL, 430 "ADDRESS",
431 gettext_noop ("enable STUN processing"), 431 gettext_noop ("which remote IP and port should be asked for connection reversal"),
432 GNUNET_NO, &GNUNET_GETOPT_set_one, &do_stun }, 432 &remote_addr),
433 {'t', "tcp", NULL, 433
434 gettext_noop ("use TCP"), 434 GNUNET_GETOPT_OPTION_STRING ('S',
435 GNUNET_NO, &GNUNET_GETOPT_set_one, &use_tcp }, 435 "section",
436 {'u', "udp", NULL, 436 NULL,
437 gettext_noop ("use UDP"), 437 gettext_noop ("name of configuration section to find additional options, such as manual host punching data"),
438 GNUNET_NO, &GNUNET_GETOPT_set_one, &use_udp }, 438 &section_name),
439 {'W', "watch", NULL, 439
440 gettext_noop ("watch for connection reversal requests"), 440 GNUNET_GETOPT_OPTION_SET_ONE ('s',
441 GNUNET_NO, &GNUNET_GETOPT_set_one, &listen_reversal }, 441 "stun",
442 GNUNET_GETOPT_OPTION_END 442 gettext_noop ("enable STUN processing"),
443 &do_stun),
444
445 GNUNET_GETOPT_OPTION_SET_ONE ('t',
446 "tcp",
447 gettext_noop ("use TCP"),
448 &use_tcp),
449
450 GNUNET_GETOPT_OPTION_SET_ONE ('u',
451 "udp",
452 gettext_noop ("use UDP"),
453 &use_udp),
454
455 GNUNET_GETOPT_OPTION_SET_ONE ('W',
456 "watch",
457 gettext_noop ("watch for connection reversal requests"),
458 &listen_reversal),
459 GNUNET_GETOPT_OPTION_END
443 }; 460 };
444 461
445 if (GNUNET_OK != 462 if (GNUNET_OK !=
diff --git a/src/nat/nat_api.c b/src/nat/nat_api.c
index a0e9f4793..69612584e 100644
--- a/src/nat/nat_api.c
+++ b/src/nat/nat_api.c
@@ -403,7 +403,7 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
403 len += addrlens[i]; 403 len += addrlens[i];
404 str_len = strlen (config_section) + 1; 404 str_len = strlen (config_section) + 1;
405 len += str_len; 405 len += str_len;
406 if ( (len > GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*rm)) || 406 if ( (len > GNUNET_MAX_MESSAGE_SIZE - sizeof (*rm)) ||
407 (num_addrs > UINT16_MAX) ) 407 (num_addrs > UINT16_MAX) )
408 { 408 {
409 GNUNET_break (0); 409 GNUNET_break (0);
diff --git a/src/nse/gnunet-nse-profiler.c b/src/nse/gnunet-nse-profiler.c
index 48afd9298..ea28bf610 100644
--- a/src/nse/gnunet-nse-profiler.c
+++ b/src/nse/gnunet-nse-profiler.c
@@ -129,7 +129,7 @@ static int ok;
129/** 129/**
130 * Be verbose (configuration option) 130 * Be verbose (configuration option)
131 */ 131 */
132static int verbose; 132static unsigned int verbose;
133 133
134/** 134/**
135 * Name of the file with the hosts to run the test over (configuration option) 135 * Name of the file with the hosts to run the test over (configuration option)
@@ -835,28 +835,47 @@ run (void *cls, char *const *args, const char *cfgfile,
835int 835int
836main (int argc, char *const *argv) 836main (int argc, char *const *argv)
837{ 837{
838 static struct GNUNET_GETOPT_CommandLineOption options[] = { 838 struct GNUNET_GETOPT_CommandLineOption options[] = {
839 {'C', "connections", "COUNT", 839 GNUNET_GETOPT_OPTION_SET_UINT ('C',
840 gettext_noop ("limit to the number of connections to NSE services, 0 for none"), 840 "connections",
841 1, &GNUNET_GETOPT_set_uint, &connection_limit}, 841 "COUNT",
842 {'d', "details", "FILENAME", 842 gettext_noop ("limit to the number of connections to NSE services, 0 for none"),
843 gettext_noop ("name of the file for writing connection information and statistics"), 843 &connection_limit),
844 1, &GNUNET_GETOPT_set_string, &data_filename}, 844 GNUNET_GETOPT_OPTION_STRING ('d',
845 {'H', "hosts", "FILENAME", 845 "details",
846 gettext_noop ("name of the file with the login information for the testbed"), 846 "FILENAME",
847 1, &GNUNET_GETOPT_set_string, &hosts_file}, 847 gettext_noop ("name of the file for writing connection information and statistics"),
848 {'o', "output", "FILENAME", 848 &data_filename),
849 gettext_noop ("name of the file for writing the main results"), 849
850 1, &GNUNET_GETOPT_set_string, &output_filename}, 850 GNUNET_GETOPT_OPTION_STRING ('H',
851 {'p', "peers", "NETWORKSIZESPEC", 851 "hosts",
852 gettext_noop ("Number of peers to run in each round, separated by commas"), 852 "FILENAME",
853 1, &GNUNET_GETOPT_set_string, &num_peer_spec}, 853 gettext_noop ("name of the file with the login information for the testbed"),
854 {'V', "verbose", NULL, 854 &hosts_file),
855 gettext_noop ("be verbose (print progress information)"), 855
856 0, &GNUNET_GETOPT_increment_value, &verbose}, 856 GNUNET_GETOPT_OPTION_STRING ('o',
857 {'w', "wait", "DELAY", 857 "output",
858 gettext_noop ("delay between rounds"), 858 "FILENAME",
859 1, &GNUNET_GETOPT_set_relative_time, &wait_time}, 859 gettext_noop ("name of the file for writing the main results"),
860 &output_filename),
861
862
863 GNUNET_GETOPT_OPTION_STRING ('p',
864 "peers",
865 "NETWORKSIZESPEC",
866 gettext_noop ("Number of peers to run in each round, separated by commas"),
867 &num_peer_spec),
868
869 GNUNET_GETOPT_OPTION_INCREMENT_VALUE ('V',
870 "verbose",
871 gettext_noop ("be verbose (print progress information)"),
872 &verbose),
873
874 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('w',
875 "wait",
876 "DELAY",
877 gettext_noop ("delay between rounds"),
878 &wait_time),
860 GNUNET_GETOPT_OPTION_END 879 GNUNET_GETOPT_OPTION_END
861 }; 880 };
862 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 881 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
diff --git a/src/peerinfo-tool/gnunet-peerinfo.c b/src/peerinfo-tool/gnunet-peerinfo.c
index a5907c63f..59ffe2efd 100644
--- a/src/peerinfo-tool/gnunet-peerinfo.c
+++ b/src/peerinfo-tool/gnunet-peerinfo.c
@@ -837,31 +837,48 @@ state_machine (void *cls)
837int 837int
838main (int argc, char *const *argv) 838main (int argc, char *const *argv)
839{ 839{
840 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 840 struct GNUNET_GETOPT_CommandLineOption options[] = {
841 {'n', "numeric", NULL, 841 GNUNET_GETOPT_OPTION_SET_ONE ('n',
842 gettext_noop ("don't resolve host names"), 842 "numeric",
843 0, &GNUNET_GETOPT_set_one, &no_resolve}, 843 gettext_noop ("don't resolve host names"),
844 {'q', "quiet", NULL, 844 &no_resolve),
845 gettext_noop ("output only the identity strings"), 845
846 0, &GNUNET_GETOPT_set_one, &be_quiet}, 846 GNUNET_GETOPT_OPTION_SET_ONE ('q',
847 {'f', "friends", NULL, 847 "quiet",
848 gettext_noop ("include friend-only information"), 848 gettext_noop ("output only the identity strings"),
849 0, &GNUNET_GETOPT_set_one, &include_friend_only}, 849 &be_quiet),
850 {'s', "self", NULL, 850 GNUNET_GETOPT_OPTION_SET_ONE ('f',
851 gettext_noop ("output our own identity only"), 851 "friends",
852 0, &GNUNET_GETOPT_set_one, &get_self}, 852 gettext_noop ("include friend-only information"),
853 {'i', "info", NULL, 853 &include_friend_only),
854 gettext_noop ("list all known peers"), 854
855 0, &GNUNET_GETOPT_set_one, &get_info}, 855 GNUNET_GETOPT_OPTION_SET_ONE ('s',
856 {'d', "dump-hello", NULL, 856 "self",
857 gettext_noop ("dump hello to file"), 857 gettext_noop ("output our own identity only"),
858 1, &GNUNET_GETOPT_set_string, &dump_hello}, 858 &get_self),
859 {'g', "get-hello", NULL, 859
860 gettext_noop ("also output HELLO uri(s)"), 860 GNUNET_GETOPT_OPTION_SET_ONE ('i',
861 0, &GNUNET_GETOPT_set_one, &get_uri}, 861 "info",
862 {'p', "put-hello", "HELLO", 862 gettext_noop ("list all known peers"),
863 gettext_noop ("add given HELLO uri to the database"), 863 &get_info),
864 1, &GNUNET_GETOPT_set_string, &put_uri}, 864
865 GNUNET_GETOPT_OPTION_STRING ('d',
866 "dump-hello",
867 NULL,
868 gettext_noop ("dump hello to file"),
869 &dump_hello),
870
871 GNUNET_GETOPT_OPTION_SET_ONE ('g',
872 "get-hello",
873 gettext_noop ("also output HELLO uri(s)"),
874 &get_uri),
875
876 GNUNET_GETOPT_OPTION_STRING ('p',
877 "put-hello",
878 "HELLO",
879 gettext_noop ("add given HELLO uri to the database"),
880 &put_uri),
881
865 GNUNET_GETOPT_OPTION_END 882 GNUNET_GETOPT_OPTION_END
866 }; 883 };
867 int ret; 884 int ret;
diff --git a/src/peerinfo/gnunet-service-peerinfo.c b/src/peerinfo/gnunet-service-peerinfo.c
index bc4a2a10d..731c24bf1 100644
--- a/src/peerinfo/gnunet-service-peerinfo.c
+++ b/src/peerinfo/gnunet-service-peerinfo.c
@@ -283,7 +283,7 @@ read_host_file (const char *fn,
283 int unlink_garbage, 283 int unlink_garbage,
284 struct ReadHostFileContext *r) 284 struct ReadHostFileContext *r)
285{ 285{
286 char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN; 286 char buffer[GNUNET_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
287 ssize_t size_total; 287 ssize_t size_total;
288 struct GNUNET_TIME_Absolute now; 288 struct GNUNET_TIME_Absolute now;
289 unsigned int left; 289 unsigned int left;
@@ -919,7 +919,7 @@ add_to_tc (void *cls,
919 { 919 {
920 /* Copy public HELLO */ 920 /* Copy public HELLO */
921 hs = GNUNET_HELLO_size (pos->hello); 921 hs = GNUNET_HELLO_size (pos->hello);
922 GNUNET_assert (hs < GNUNET_SERVER_MAX_MESSAGE_SIZE - 922 GNUNET_assert (hs < GNUNET_MAX_MESSAGE_SIZE -
923 sizeof (struct InfoMessage)); 923 sizeof (struct InfoMessage));
924 env = GNUNET_MQ_msg_extra (im, 924 env = GNUNET_MQ_msg_extra (im,
925 hs, 925 hs,
@@ -937,7 +937,7 @@ add_to_tc (void *cls,
937 { 937 {
938 /* Copy friend only HELLO */ 938 /* Copy friend only HELLO */
939 hs = GNUNET_HELLO_size (pos->friend_only_hello); 939 hs = GNUNET_HELLO_size (pos->friend_only_hello);
940 GNUNET_assert (hs < GNUNET_SERVER_MAX_MESSAGE_SIZE - 940 GNUNET_assert (hs < GNUNET_MAX_MESSAGE_SIZE -
941 sizeof (struct InfoMessage)); 941 sizeof (struct InfoMessage));
942 env = GNUNET_MQ_msg_extra (im, 942 env = GNUNET_MQ_msg_extra (im,
943 hs, 943 hs,
@@ -977,7 +977,7 @@ discard_hosts_helper (void *cls,
977 const char *fn) 977 const char *fn)
978{ 978{
979 struct GNUNET_TIME_Absolute *now = cls; 979 struct GNUNET_TIME_Absolute *now = cls;
980 char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN; 980 char buffer[GNUNET_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
981 const struct GNUNET_HELLO_Message *hello; 981 const struct GNUNET_HELLO_Message *hello;
982 struct GNUNET_HELLO_Message *new_hello; 982 struct GNUNET_HELLO_Message *new_hello;
983 int read_size; 983 int read_size;
diff --git a/src/pq/pq.c b/src/pq/pq.c
index f4bab4e00..4e24e1ef8 100644
--- a/src/pq/pq.c
+++ b/src/pq/pq.c
@@ -85,9 +85,10 @@ GNUNET_PQ_exec_prepared (PGconn *db_conn,
85 off += x->num_params; 85 off += x->num_params;
86 } 86 }
87 GNUNET_assert (off == len); 87 GNUNET_assert (off == len);
88 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 88 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
89 "Executing prepared SQL statement `%s'\n", 89 "pq",
90 name); 90 "Executing prepared SQL statement `%s'\n",
91 name);
91 res = PQexecPrepared (db_conn, 92 res = PQexecPrepared (db_conn,
92 name, 93 name,
93 len, 94 len,
diff --git a/src/psyc/.gitignore b/src/psyc/.gitignore
index e12b3210c..14a175367 100644
--- a/src/psyc/.gitignore
+++ b/src/psyc/.gitignore
@@ -1 +1,2 @@
1gnunet-service-psyc 1gnunet-service-psyc
2test_psyc
diff --git a/src/psyc/psyc_api.c b/src/psyc/psyc_api.c
index c6544df3a..c93d8b383 100644
--- a/src/psyc/psyc_api.c
+++ b/src/psyc/psyc_api.c
@@ -1309,7 +1309,7 @@ channel_history_replay (struct GNUNET_PSYC_Channel *chn,
1309 1309
1310 GNUNET_assert (NULL != method_prefix); 1310 GNUNET_assert (NULL != method_prefix);
1311 uint16_t method_size = strnlen (method_prefix, 1311 uint16_t method_size = strnlen (method_prefix,
1312 GNUNET_SERVER_MAX_MESSAGE_SIZE 1312 GNUNET_MAX_MESSAGE_SIZE
1313 - sizeof (*req)) + 1; 1313 - sizeof (*req)) + 1;
1314 GNUNET_assert ('\0' == method_prefix[method_size - 1]); 1314 GNUNET_assert ('\0' == method_prefix[method_size - 1]);
1315 1315
@@ -1454,7 +1454,7 @@ channel_state_get (struct GNUNET_PSYC_Channel *chn,
1454 sr->op_id = GNUNET_OP_add (chn->op, op_recv_state_result, sr, NULL); 1454 sr->op_id = GNUNET_OP_add (chn->op, op_recv_state_result, sr, NULL);
1455 1455
1456 GNUNET_assert (NULL != name); 1456 GNUNET_assert (NULL != name);
1457 size_t name_size = strnlen (name, GNUNET_SERVER_MAX_MESSAGE_SIZE 1457 size_t name_size = strnlen (name, GNUNET_MAX_MESSAGE_SIZE
1458 - sizeof (*req)) + 1; 1458 - sizeof (*req)) + 1;
1459 struct GNUNET_MQ_Envelope * 1459 struct GNUNET_MQ_Envelope *
1460 env = GNUNET_MQ_msg_extra (req, name_size, type); 1460 env = GNUNET_MQ_msg_extra (req, name_size, type);
diff --git a/src/psycstore/.gitignore b/src/psycstore/.gitignore
index fc2e4cf8e..5ec783202 100644
--- a/src/psycstore/.gitignore
+++ b/src/psycstore/.gitignore
@@ -1 +1,5 @@
1gnunet-service-psycstore 1gnunet-service-psycstore
2test_plugin_psycstore_mysql
3test_plugin_psycstore_sqlite
4test_plugin_psycstore_postgres
5test_psycstore
diff --git a/src/psycstore/gnunet-service-psycstore.c b/src/psycstore/gnunet-service-psycstore.c
index 10c92a878..1bee8da65 100644
--- a/src/psycstore/gnunet-service-psycstore.c
+++ b/src/psycstore/gnunet-service-psycstore.c
@@ -106,7 +106,7 @@ send_result_code (struct GNUNET_SERVICE_Client *client,
106 106
107 if (NULL != err_msg) 107 if (NULL != err_msg)
108 err_size = strnlen (err_msg, 108 err_size = strnlen (err_msg,
109 GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*res) - 1) + 1; 109 GNUNET_MAX_MESSAGE_SIZE - sizeof (*res) - 1) + 1;
110 struct GNUNET_MQ_Envelope * 110 struct GNUNET_MQ_Envelope *
111 env = GNUNET_MQ_msg_extra (res, err_size, 111 env = GNUNET_MQ_msg_extra (res, err_size,
112 GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE); 112 GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE);
diff --git a/src/psycstore/psycstore_api.c b/src/psycstore/psycstore_api.c
index 40322662e..d79daa357 100644
--- a/src/psycstore/psycstore_api.c
+++ b/src/psycstore/psycstore_api.c
@@ -809,7 +809,7 @@ GNUNET_PSYCSTORE_message_get (struct GNUNET_PSYCSTORE_Handle *h,
809 if (NULL == method_prefix) 809 if (NULL == method_prefix)
810 method_prefix = ""; 810 method_prefix = "";
811 uint16_t method_size = strnlen (method_prefix, 811 uint16_t method_size = strnlen (method_prefix,
812 GNUNET_SERVER_MAX_MESSAGE_SIZE 812 GNUNET_MAX_MESSAGE_SIZE
813 - sizeof (*req)) + 1; 813 - sizeof (*req)) + 1;
814 814
815 struct GNUNET_MQ_Envelope * 815 struct GNUNET_MQ_Envelope *
@@ -875,7 +875,7 @@ GNUNET_PSYCSTORE_message_get_latest (struct GNUNET_PSYCSTORE_Handle *h,
875 if (NULL == method_prefix) 875 if (NULL == method_prefix)
876 method_prefix = ""; 876 method_prefix = "";
877 uint16_t method_size = strnlen (method_prefix, 877 uint16_t method_size = strnlen (method_prefix,
878 GNUNET_SERVER_MAX_MESSAGE_SIZE 878 GNUNET_MAX_MESSAGE_SIZE
879 - sizeof (*req)) + 1; 879 - sizeof (*req)) + 1;
880 GNUNET_assert ('\0' == method_prefix[method_size - 1]); 880 GNUNET_assert ('\0' == method_prefix[method_size - 1]);
881 881
diff --git a/src/psycutil/.gitignore b/src/psycutil/.gitignore
new file mode 100644
index 000000000..03d8197fb
--- /dev/null
+++ b/src/psycutil/.gitignore
@@ -0,0 +1 @@
test_psyc_env
diff --git a/src/regex/gnunet-regex-profiler.c b/src/regex/gnunet-regex-profiler.c
index dfbcd388a..71f3580f8 100644
--- a/src/regex/gnunet-regex-profiler.c
+++ b/src/regex/gnunet-regex-profiler.c
@@ -1477,22 +1477,39 @@ run (void *cls,
1477int 1477int
1478main (int argc, char *const *argv) 1478main (int argc, char *const *argv)
1479{ 1479{
1480 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 1480 struct GNUNET_GETOPT_CommandLineOption options[] = {
1481 {'o', "output-file", "FILENAME", 1481
1482 gettext_noop ("name of the file for writing statistics"), 1482 GNUNET_GETOPT_OPTION_FILENAME ('o',
1483 GNUNET_YES, &GNUNET_GETOPT_set_string, &data_filename}, 1483 "output-file",
1484 {'t', "matching-timeout", "TIMEOUT", 1484 "FILENAME",
1485 gettext_noop ("wait TIMEOUT before ending the experiment"), 1485 gettext_noop ("name of the file for writing statistics"),
1486 GNUNET_YES, &GNUNET_GETOPT_set_relative_time, &search_timeout_time}, 1486 &data_filename),
1487 {'p', "policy-dir", "DIRECTORY", 1487
1488 gettext_noop ("directory with policy files"), 1488 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('t',
1489 GNUNET_YES, &GNUNET_GETOPT_set_filename, &policy_dir}, 1489 "matching-timeout",
1490 {'s', "strings-file", "FILENAME", 1490 "TIMEOUT",
1491 gettext_noop ("name of file with input strings"), 1491 gettext_noop ("wait TIMEOUT before ending the experiment"),
1492 GNUNET_YES, &GNUNET_GETOPT_set_filename, &strings_file}, 1492 &search_timeout_time),
1493 {'H', "hosts-file", "FILENAME", 1493
1494 gettext_noop ("name of file with hosts' names"), 1494 GNUNET_GETOPT_OPTION_FILENAME ('p',
1495 GNUNET_YES, &GNUNET_GETOPT_set_filename, &hosts_file}, 1495 "policy-dir",
1496 "DIRECTORY",
1497 gettext_noop ("directory with policy files"),
1498 &policy_dir),
1499
1500
1501 GNUNET_GETOPT_OPTION_FILENAME ('s',
1502 "strings-file",
1503 "FILENAME",
1504 gettext_noop ("name of file with input strings"),
1505 &strings_file),
1506
1507 GNUNET_GETOPT_OPTION_FILENAME ('H',
1508 "hosts-file",
1509 "FILENAME",
1510 gettext_noop ("name of file with hosts' names"),
1511 &hosts_file),
1512
1496 GNUNET_GETOPT_OPTION_END 1513 GNUNET_GETOPT_OPTION_END
1497 }; 1514 };
1498 int ret; 1515 int ret;
diff --git a/src/regex/gnunet-regex-simulation-profiler.c b/src/regex/gnunet-regex-simulation-profiler.c
index 025a70316..422e45565 100644
--- a/src/regex/gnunet-regex-simulation-profiler.c
+++ b/src/regex/gnunet-regex-simulation-profiler.c
@@ -691,13 +691,20 @@ run (void *cls,
691int 691int
692main (int argc, char *const *argv) 692main (int argc, char *const *argv)
693{ 693{
694 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 694 struct GNUNET_GETOPT_CommandLineOption options[] = {
695 {'t', "table", "TABLENAME", 695
696 gettext_noop ("name of the table to write DFAs"), 696 GNUNET_GETOPT_OPTION_STRING ('t',
697 1, &GNUNET_GETOPT_set_string, &table_name}, 697 "table",
698 {'p', "max-path-compression", "MAX_PATH_COMPRESSION", 698 "TABLENAME",
699 gettext_noop ("maximum path compression length"), 699 gettext_noop ("name of the table to write DFAs"),
700 1, &GNUNET_GETOPT_set_uint, &max_path_compression}, 700 &table_name),
701
702 GNUNET_GETOPT_OPTION_SET_UINT ('p',
703 "max-path-compression",
704 "MAX_PATH_COMPRESSION",
705 gettext_noop ("maximum path compression length"),
706 &max_path_compression),
707
701 GNUNET_GETOPT_OPTION_END 708 GNUNET_GETOPT_OPTION_END
702 }; 709 };
703 int ret; 710 int ret;
diff --git a/src/regex/gnunet-service-regex.c b/src/regex/gnunet-service-regex.c
index 294670be6..9a40a5264 100644
--- a/src/regex/gnunet-service-regex.c
+++ b/src/regex/gnunet-service-regex.c
@@ -37,19 +37,14 @@ struct ClientEntry
37{ 37{
38 38
39 /** 39 /**
40 * Kept in DLL. 40 * Queue for transmissions to @e client.
41 */ 41 */
42 struct ClientEntry *next; 42 struct GNUNET_MQ_Handle *mq;
43
44 /**
45 * Kept in DLL.
46 */
47 struct ClientEntry *prev;
48 43
49 /** 44 /**
50 * Handle identifying the client. 45 * Handle identifying the client.
51 */ 46 */
52 struct GNUNET_SERVER_Client *client; 47 struct GNUNET_SERVICE_Client *client;
53 48
54 /** 49 /**
55 * Search handle (if this client is searching). 50 * Search handle (if this client is searching).
@@ -69,7 +64,7 @@ struct ClientEntry
69 /** 64 /**
70 * Task for re-announcing. 65 * Task for re-announcing.
71 */ 66 */
72 struct GNUNET_SCHEDULER_Task * refresh_task; 67 struct GNUNET_SCHEDULER_Task *refresh_task;
73 68
74}; 69};
75 70
@@ -85,70 +80,12 @@ static struct GNUNET_DHT_Handle *dht;
85static struct GNUNET_STATISTICS_Handle *stats; 80static struct GNUNET_STATISTICS_Handle *stats;
86 81
87/** 82/**
88 * Head of list of clients.
89 */
90static struct ClientEntry *client_head;
91
92/**
93 * End of list of clients.
94 */
95static struct ClientEntry *client_tail;
96
97/**
98 * Our notification context, used to send back results to the client.
99 */
100static struct GNUNET_SERVER_NotificationContext *nc;
101
102/**
103 * Private key for this peer. 83 * Private key for this peer.
104 */ 84 */
105static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key; 85static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
106 86
107 87
108/** 88/**
109 * A client disconnected. Remove all of its data structure entries.
110 *
111 * @param cls closure, NULL
112 * @param client identification of the client
113 */
114static void
115handle_client_disconnect (void *cls,
116 struct GNUNET_SERVER_Client *client)
117{
118 struct ClientEntry *ce;
119 struct ClientEntry *nx;
120
121 nx = client_head;
122 for (ce = nx; NULL != ce; ce = nx)
123 {
124 nx = ce->next;
125 if (ce->client == client)
126 {
127 if (NULL != ce->refresh_task)
128 {
129 GNUNET_SCHEDULER_cancel (ce->refresh_task);
130 ce->refresh_task = NULL;
131 }
132 if (NULL != ce->ah)
133 {
134 REGEX_INTERNAL_announce_cancel (ce->ah);
135 ce->ah = NULL;
136 }
137 if (NULL != ce->sh)
138 {
139 REGEX_INTERNAL_search_cancel (ce->sh);
140 ce->sh = NULL;
141 }
142 GNUNET_CONTAINER_DLL_remove (client_head,
143 client_tail,
144 ce);
145 GNUNET_free (ce);
146 }
147 }
148}
149
150
151/**
152 * Task run during shutdown. 89 * Task run during shutdown.
153 * 90 *
154 * @param cls unused 91 * @param cls unused
@@ -156,17 +93,11 @@ handle_client_disconnect (void *cls,
156static void 93static void
157cleanup_task (void *cls) 94cleanup_task (void *cls)
158{ 95{
159 struct ClientEntry *ce;
160
161 while (NULL != (ce = client_head))
162 handle_client_disconnect (NULL,
163 ce->client);
164 GNUNET_DHT_disconnect (dht); 96 GNUNET_DHT_disconnect (dht);
165 dht = NULL; 97 dht = NULL;
166 GNUNET_STATISTICS_destroy (stats, GNUNET_NO); 98 GNUNET_STATISTICS_destroy (stats,
99 GNUNET_NO);
167 stats = NULL; 100 stats = NULL;
168 GNUNET_SERVER_notification_context_destroy (nc);
169 nc = NULL;
170 GNUNET_free (my_private_key); 101 GNUNET_free (my_private_key);
171 my_private_key = NULL; 102 my_private_key = NULL;
172} 103}
@@ -191,35 +122,51 @@ reannounce (void *cls)
191 122
192 123
193/** 124/**
194 * Handle ANNOUNCE message. 125 * Check ANNOUNCE message.
195 * 126 *
196 * @param cls closure 127 * @param cls identification of the client
197 * @param client identification of the client 128 * @param am the actual message
198 * @param message the actual message 129 * @return #GNUNET_OK if @am is well-formed
199 */ 130 */
200static void 131static int
201handle_announce (void *cls, 132check_announce (void *cls,
202 struct GNUNET_SERVER_Client *client, 133 const struct AnnounceMessage *am)
203 const struct GNUNET_MessageHeader *message)
204{ 134{
205 const struct AnnounceMessage *am; 135 struct ClientEntry *ce = cls;
206 const char *regex; 136 const char *regex;
207 struct ClientEntry *ce;
208 uint16_t size; 137 uint16_t size;
209 138
210 size = ntohs (message->size); 139 size = ntohs (am->header.size) - sizeof (*am);
211 am = (const struct AnnounceMessage *) message;
212 regex = (const char *) &am[1]; 140 regex = (const char *) &am[1];
213 if ( (size <= sizeof (struct AnnounceMessage)) || 141 if ('\0' != regex[size - 1])
214 ('\0' != regex[size - sizeof (struct AnnounceMessage) - 1]) )
215 { 142 {
216 GNUNET_break (0); 143 GNUNET_break (0);
217 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 144 return GNUNET_SYSERR;
218 return; 145 }
146 if (NULL != ce->ah)
147 {
148 /* only one announcement per client allowed */
149 GNUNET_break (0);
150 return GNUNET_SYSERR;
219 } 151 }
152 return GNUNET_OK;
153}
220 154
221 ce = GNUNET_new (struct ClientEntry); 155
222 ce->client = client; 156/**
157 * Handle ANNOUNCE message.
158 *
159 * @param cls identification of the client
160 * @param am the actual message
161 */
162static void
163handle_announce (void *cls,
164 const struct AnnounceMessage *am)
165{
166 struct ClientEntry *ce = cls;
167 const char *regex;
168
169 regex = (const char *) &am[1];
223 ce->frequency = GNUNET_TIME_relative_ntoh (am->refresh_delay); 170 ce->frequency = GNUNET_TIME_relative_ntoh (am->refresh_delay);
224 ce->refresh_task = GNUNET_SCHEDULER_add_delayed (ce->frequency, 171 ce->refresh_task = GNUNET_SCHEDULER_add_delayed (ce->frequency,
225 &reannounce, 172 &reannounce,
@@ -238,14 +185,11 @@ handle_announce (void *cls,
238 { 185 {
239 GNUNET_break (0); 186 GNUNET_break (0);
240 GNUNET_SCHEDULER_cancel (ce->refresh_task); 187 GNUNET_SCHEDULER_cancel (ce->refresh_task);
241 GNUNET_free (ce); 188 ce->refresh_task = NULL;
242 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 189 GNUNET_SERVICE_client_drop (ce->client);
243 return; 190 return;
244 } 191 }
245 GNUNET_CONTAINER_DLL_insert (client_head, 192 GNUNET_SERVICE_client_continue (ce->client);
246 client_tail,
247 ce);
248 GNUNET_SERVER_receive_done (client, GNUNET_OK);
249} 193}
250 194
251 195
@@ -268,6 +212,7 @@ handle_search_result (void *cls,
268 unsigned int put_path_length) 212 unsigned int put_path_length)
269{ 213{
270 struct ClientEntry *ce = cls; 214 struct ClientEntry *ce = cls;
215 struct GNUNET_MQ_Envelope *env;
271 struct ResultMessage *result; 216 struct ResultMessage *result;
272 struct GNUNET_PeerIdentity *gp; 217 struct GNUNET_PeerIdentity *gp;
273 uint16_t size; 218 uint16_t size;
@@ -275,64 +220,78 @@ handle_search_result (void *cls,
275 if ( (get_path_length >= 65536) || 220 if ( (get_path_length >= 65536) ||
276 (put_path_length >= 65536) || 221 (put_path_length >= 65536) ||
277 ( (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity)) 222 ( (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity))
278 + sizeof (struct ResultMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 223 + sizeof (struct ResultMessage) >= GNUNET_MAX_MESSAGE_SIZE)
279 { 224 {
280 GNUNET_break (0); 225 GNUNET_break (0);
281 return; 226 return;
282 } 227 }
283 size = (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity) + sizeof (struct ResultMessage); 228 size = (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity);
284 result = GNUNET_malloc (size); 229 env = GNUNET_MQ_msg_extra (result,
285 result->header.size = htons (size); 230 size,
286 result->header.type = htons (GNUNET_MESSAGE_TYPE_REGEX_RESULT); 231 GNUNET_MESSAGE_TYPE_REGEX_RESULT);
287 result->get_path_length = htons ((uint16_t) get_path_length); 232 result->get_path_length = htons ((uint16_t) get_path_length);
288 result->put_path_length = htons ((uint16_t) put_path_length); 233 result->put_path_length = htons ((uint16_t) put_path_length);
289 result->id = *id; 234 result->id = *id;
290 gp = &result->id; 235 gp = &result->id;
291 GNUNET_memcpy (&gp[1], 236 GNUNET_memcpy (&gp[1],
292 get_path, 237 get_path,
293 get_path_length * sizeof (struct GNUNET_PeerIdentity)); 238 get_path_length * sizeof (struct GNUNET_PeerIdentity));
294 GNUNET_memcpy (&gp[1 + get_path_length], 239 GNUNET_memcpy (&gp[1 + get_path_length],
295 put_path, 240 put_path,
296 put_path_length * sizeof (struct GNUNET_PeerIdentity)); 241 put_path_length * sizeof (struct GNUNET_PeerIdentity));
297 GNUNET_SERVER_notification_context_unicast (nc, 242 GNUNET_MQ_send (ce->mq,
298 ce->client, 243 env);
299 &result->header, GNUNET_NO);
300 GNUNET_free (result);
301} 244}
302 245
303 246
304/** 247/**
305 * Handle SEARCH message. 248 * Check SEARCH message.
306 * 249 *
307 * @param cls closure 250 * @param cls identification of the client
308 * @param client identification of the client
309 * @param message the actual message 251 * @param message the actual message
310 */ 252 */
311static void 253static int
312handle_search (void *cls, 254check_search (void *cls,
313 struct GNUNET_SERVER_Client *client, 255 const struct RegexSearchMessage *sm)
314 const struct GNUNET_MessageHeader *message)
315{ 256{
316 const struct RegexSearchMessage *sm; 257 struct ClientEntry *ce = cls;
317 const char *string; 258 const char *string;
318 struct ClientEntry *ce;
319 uint16_t size; 259 uint16_t size;
320 260
321 size = ntohs (message->size); 261 size = ntohs (sm->header.size) - sizeof (*sm);
322 sm = (const struct RegexSearchMessage *) message;
323 string = (const char *) &sm[1]; 262 string = (const char *) &sm[1];
324 if ( (size <= sizeof (struct RegexSearchMessage)) || 263 if ('\0' != string[size - 1])
325 ('\0' != string[size - sizeof (struct RegexSearchMessage) - 1]) )
326 { 264 {
327 GNUNET_break (0); 265 GNUNET_break (0);
328 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 266 return GNUNET_SYSERR;
329 return;
330 } 267 }
268 if (NULL != ce->sh)
269 {
270 /* only one search allowed per client */
271 GNUNET_break (0);
272 return GNUNET_SYSERR;
273 }
274 return GNUNET_OK;
275}
276
277
278/**
279 * Handle SEARCH message.
280 *
281 * @param cls identification of the client
282 * @param message the actual message
283 */
284static void
285handle_search (void *cls,
286 const struct RegexSearchMessage *sm)
287{
288 struct ClientEntry *ce = cls;
289 const char *string;
290
291 string = (const char *) &sm[1];
331 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 292 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
332 "Starting to search for `%s'\n", 293 "Starting to search for `%s'\n",
333 string); 294 string);
334 ce = GNUNET_new (struct ClientEntry);
335 ce->client = client;
336 ce->sh = REGEX_INTERNAL_search (dht, 295 ce->sh = REGEX_INTERNAL_search (dht,
337 string, 296 string,
338 &handle_search_result, 297 &handle_search_result,
@@ -341,15 +300,10 @@ handle_search (void *cls,
341 if (NULL == ce->sh) 300 if (NULL == ce->sh)
342 { 301 {
343 GNUNET_break (0); 302 GNUNET_break (0);
344 GNUNET_free (ce); 303 GNUNET_SERVICE_client_drop (ce->client);
345 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
346 return; 304 return;
347 } 305 }
348 GNUNET_CONTAINER_DLL_insert (client_head, 306 GNUNET_SERVICE_client_continue (ce->client);
349 client_tail,
350 ce);
351 GNUNET_SERVER_notification_context_add (nc, client);
352 GNUNET_SERVER_receive_done (client, GNUNET_OK);
353} 307}
354 308
355 309
@@ -357,19 +311,14 @@ handle_search (void *cls,
357 * Process regex requests. 311 * Process regex requests.
358 * 312 *
359 * @param cls closure 313 * @param cls closure
360 * @param server the initialized server
361 * @param cfg configuration to use 314 * @param cfg configuration to use
315 * @param service the initialized service
362 */ 316 */
363static void 317static void
364run (void *cls, struct GNUNET_SERVER_Handle *server, 318run (void *cls,
365 const struct GNUNET_CONFIGURATION_Handle *cfg) 319 const struct GNUNET_CONFIGURATION_Handle *cfg,
320 struct GNUNET_SERVICE_Handle *service)
366{ 321{
367 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
368 {&handle_announce, NULL, GNUNET_MESSAGE_TYPE_REGEX_ANNOUNCE, 0},
369 {&handle_search, NULL, GNUNET_MESSAGE_TYPE_REGEX_SEARCH, 0},
370 {NULL, NULL, 0, 0}
371 };
372
373 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg); 322 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
374 if (NULL == my_private_key) 323 if (NULL == my_private_key)
375 { 324 {
@@ -386,28 +335,84 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
386 } 335 }
387 GNUNET_SCHEDULER_add_shutdown (&cleanup_task, 336 GNUNET_SCHEDULER_add_shutdown (&cleanup_task,
388 NULL); 337 NULL);
389 nc = GNUNET_SERVER_notification_context_create (server, 1);
390 stats = GNUNET_STATISTICS_create ("regex", cfg); 338 stats = GNUNET_STATISTICS_create ("regex", cfg);
391 GNUNET_SERVER_add_handlers (server, handlers);
392 GNUNET_SERVER_disconnect_notify (server,
393 &handle_client_disconnect,
394 NULL);
395} 339}
396 340
397 341
398/** 342/**
399 * The main function for the regex service. 343 * Callback called when a client connects to the service.
400 * 344 *
401 * @param argc number of arguments from the command line 345 * @param cls closure for the service
402 * @param argv command line arguments 346 * @param c the new client that connected to the service
403 * @return 0 ok, 1 on error 347 * @param mq the message queue used to send messages to the client
348 * @return @a c
404 */ 349 */
405int 350static void *
406main (int argc, char *const *argv) 351client_connect_cb (void *cls,
352 struct GNUNET_SERVICE_Client *c,
353 struct GNUNET_MQ_Handle *mq)
407{ 354{
408 return (GNUNET_OK == 355 struct ClientEntry *ce;
409 GNUNET_SERVICE_run (argc, argv, "regex", 356
410 GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1; 357 ce = GNUNET_new (struct ClientEntry);
358 ce->client = c;
359 ce->mq = mq;
360 return ce;
411} 361}
412 362
363
364/**
365 * Callback called when a client disconnected from the service
366 *
367 * @param cls closure for the service
368 * @param c the client that disconnected
369 * @param internal_cls should be equal to @a c
370 */
371static void
372client_disconnect_cb (void *cls,
373 struct GNUNET_SERVICE_Client *c,
374 void *internal_cls)
375{
376 struct ClientEntry *ce = internal_cls;
377
378 if (NULL != ce->refresh_task)
379 {
380 GNUNET_SCHEDULER_cancel (ce->refresh_task);
381 ce->refresh_task = NULL;
382 }
383 if (NULL != ce->ah)
384 {
385 REGEX_INTERNAL_announce_cancel (ce->ah);
386 ce->ah = NULL;
387 }
388 if (NULL != ce->sh)
389 {
390 REGEX_INTERNAL_search_cancel (ce->sh);
391 ce->sh = NULL;
392 }
393 GNUNET_free (ce);
394}
395
396
397/**
398 * Define "main" method using service macro.
399 */
400GNUNET_SERVICE_MAIN
401("regex",
402 GNUNET_SERVICE_OPTION_NONE,
403 &run,
404 &client_connect_cb,
405 &client_disconnect_cb,
406 NULL,
407 GNUNET_MQ_hd_var_size (announce,
408 GNUNET_MESSAGE_TYPE_REGEX_ANNOUNCE,
409 struct AnnounceMessage,
410 NULL),
411 GNUNET_MQ_hd_var_size (search,
412 GNUNET_MESSAGE_TYPE_REGEX_SEARCH,
413 struct RegexSearchMessage,
414 NULL),
415 GNUNET_MQ_handler_end ());
416
417
413/* end of gnunet-service-regex.c */ 418/* end of gnunet-service-regex.c */
diff --git a/src/regex/regex_api_announce.c b/src/regex/regex_api_announce.c
index 70bf34bc8..8e018f26c 100644
--- a/src/regex/regex_api_announce.c
+++ b/src/regex/regex_api_announce.c
@@ -146,7 +146,7 @@ GNUNET_REGEX_announce (const struct GNUNET_CONFIGURATION_Handle *cfg,
146 size_t slen; 146 size_t slen;
147 147
148 slen = strlen (regex) + 1; 148 slen = strlen (regex) + 1;
149 if (slen + sizeof (struct AnnounceMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 149 if (slen + sizeof (struct AnnounceMessage) >= GNUNET_MAX_MESSAGE_SIZE)
150 { 150 {
151 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 151 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
152 _("Regex `%s' is too long!\n"), 152 _("Regex `%s' is too long!\n"),
diff --git a/src/regex/regex_api_search.c b/src/regex/regex_api_search.c
index b7a015f87..a5480ac7a 100644
--- a/src/regex/regex_api_search.c
+++ b/src/regex/regex_api_search.c
@@ -206,7 +206,7 @@ GNUNET_REGEX_search (const struct GNUNET_CONFIGURATION_Handle *cfg,
206 struct GNUNET_REGEX_Search *s; 206 struct GNUNET_REGEX_Search *s;
207 size_t slen = strlen (string) + 1; 207 size_t slen = strlen (string) + 1;
208 208
209 if (slen + sizeof (struct RegexSearchMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 209 if (slen + sizeof (struct RegexSearchMessage) >= GNUNET_MAX_MESSAGE_SIZE)
210 { 210 {
211 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 211 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
212 _("Search string `%s' is too long!\n"), 212 _("Search string `%s' is too long!\n"),
diff --git a/src/rest/gnunet-rest-server.c b/src/rest/gnunet-rest-server.c
index b115deb20..0b6c18267 100644
--- a/src/rest/gnunet-rest-server.c
+++ b/src/rest/gnunet-rest-server.c
@@ -66,7 +66,7 @@ static struct GNUNET_SCHEDULER_Task *httpd_task;
66/** 66/**
67 * The port the service is running on (default 7776) 67 * The port the service is running on (default 7776)
68 */ 68 */
69static unsigned long port = GNUNET_REST_SERVICE_PORT; 69static unsigned long long port = GNUNET_REST_SERVICE_PORT;
70 70
71/** 71/**
72 * The listen socket of the service for IPv4 72 * The listen socket of the service for IPv4
@@ -748,7 +748,7 @@ run (void *cls,
748 return; 748 return;
749 } 749 }
750 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 750 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
751 "Service listens on port %lu\n", 751 "Service listens on port %llu\n",
752 port); 752 port);
753 httpd = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET, 753 httpd = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET,
754 0, 754 0,
@@ -783,10 +783,12 @@ run (void *cls,
783int 783int
784main (int argc, char *const *argv) 784main (int argc, char *const *argv)
785{ 785{
786 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 786 struct GNUNET_GETOPT_CommandLineOption options[] = {
787 {'p', "port", NULL, 787 GNUNET_GETOPT_OPTION_SET_ULONG ('p',
788 gettext_noop ("listen on specified port (default: 7776)"), 1, 788 "port",
789 &GNUNET_GETOPT_set_ulong, &port}, 789 "PORT",
790 gettext_noop ("listen on specified port (default: 7776)"),
791 &port),
790 GNUNET_GETOPT_OPTION_END 792 GNUNET_GETOPT_OPTION_END
791 }; 793 };
792 static const char* err_page = 794 static const char* err_page =
diff --git a/src/revocation/gnunet-revocation.c b/src/revocation/gnunet-revocation.c
index 133468789..7b40c83d7 100644
--- a/src/revocation/gnunet-revocation.c
+++ b/src/revocation/gnunet-revocation.c
@@ -527,19 +527,31 @@ run (void *cls,
527int 527int
528main (int argc, char *const *argv) 528main (int argc, char *const *argv)
529{ 529{
530 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 530 struct GNUNET_GETOPT_CommandLineOption options[] = {
531 {'f', "filename", "NAME", 531
532 gettext_noop ("use NAME for the name of the revocation file"), 532 GNUNET_GETOPT_OPTION_STRING ('f',
533 1, &GNUNET_GETOPT_set_string, &filename}, 533 "filename",
534 {'R', "revoke", "NAME", 534 "NAME",
535 gettext_noop ("revoke the private key associated for the the private key associated with the ego NAME "), 535 gettext_noop ("use NAME for the name of the revocation file"),
536 1, &GNUNET_GETOPT_set_string, &revoke_ego}, 536 &filename),
537 {'p', "perform", NULL, 537
538 gettext_noop ("actually perform revocation, otherwise we just do the precomputation"), 538 GNUNET_GETOPT_OPTION_STRING ('R',
539 0, &GNUNET_GETOPT_set_one, &perform}, 539 "revoke",
540 {'t', "test", "KEY", 540 "NAME",
541 gettext_noop ("test if the public key KEY has been revoked"), 541 gettext_noop ("revoke the private key associated for the the private key associated with the ego NAME "),
542 1, &GNUNET_GETOPT_set_string, &test_ego}, 542 &revoke_ego),
543
544 GNUNET_GETOPT_OPTION_SET_ONE ('p',
545 "perform",
546 gettext_noop ("actually perform revocation, otherwise we just do the precomputation"),
547 &perform),
548
549 GNUNET_GETOPT_OPTION_STRING ('t',
550 "test",
551 "KEY",
552 gettext_noop ("test if the public key KEY has been revoked"),
553 &test_ego),
554
543 GNUNET_GETOPT_OPTION_END 555 GNUNET_GETOPT_OPTION_END
544 }; 556 };
545 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 557 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
diff --git a/src/rps/gnunet-rps.c b/src/rps/gnunet-rps.c
index 3dbb8053e..e36e547fa 100644
--- a/src/rps/gnunet-rps.c
+++ b/src/rps/gnunet-rps.c
@@ -43,43 +43,7 @@ static struct GNUNET_RPS_Request_Handle *req_handle;
43/** 43/**
44 * PeerID (Option --seed) 44 * PeerID (Option --seed)
45 */ 45 */
46static struct GNUNET_PeerIdentity *peer_id; 46static struct GNUNET_PeerIdentity peer_id;
47
48
49/**
50 * Set an option of type 'struct GNUNET_PeerIdentity *' from the command line.
51 * A pointer to this function should be passed as part of the
52 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
53 * of this type. It should be followed by a pointer to a value of
54 * type 'struct GNUNET_PeerIdentity *', which will be allocated with the requested string.
55 *
56 * @param ctx command line processing context
57 * @param scls additional closure (will point to the 'char *',
58 * which will be allocated)
59 * @param option name of the option
60 * @param value actual value of the option (a PeerID)
61 * @return #GNUNET_OK
62 */
63static int
64GNUNET_GETOPT_set_peerid (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
65 void *scls, const char *option, const char *value)
66{
67 struct GNUNET_PeerIdentity **val = (struct GNUNET_PeerIdentity **) scls;
68
69 GNUNET_assert (NULL != value);
70 GNUNET_free_non_null (*val);
71 /* Not quite sure whether that is a sane way */
72 *val = GNUNET_new (struct GNUNET_PeerIdentity);
73 if (GNUNET_OK !=
74 GNUNET_CRYPTO_eddsa_public_key_from_string (value,
75 strlen (value),
76 &((*val)->public_key)))
77 {
78 FPRINTF (stderr, "Invalid peer ID %s\n", value);
79 return GNUNET_SYSERR;
80 }
81 return GNUNET_OK;
82}
83 47
84 48
85/** 49/**
@@ -139,10 +103,13 @@ run (void *cls,
139 const struct GNUNET_CONFIGURATION_Handle *cfg) 103 const struct GNUNET_CONFIGURATION_Handle *cfg)
140{ 104{
141 static uint64_t num_peers; 105 static uint64_t num_peers;
106 static struct GNUNET_PeerIdentity zero_pid;
142 107
143 rps_handle = GNUNET_RPS_connect (cfg); 108 rps_handle = GNUNET_RPS_connect (cfg);
144 109
145 if (NULL == peer_id) 110 if (0 == memcmp (&zero_pid,
111 &peer_id,
112 sizeof (peer_id)))
146 { /* Request n PeerIDs */ 113 { /* Request n PeerIDs */
147 /* If number was specified use it, else request single peer. */ 114 /* If number was specified use it, else request single peer. */
148 num_peers = (NULL == args[0]) ? 1 : atoi (args[0]); 115 num_peers = (NULL == args[0]) ? 1 : atoi (args[0]);
@@ -153,8 +120,8 @@ run (void *cls,
153 } 120 }
154 else 121 else
155 { /* Seed PeerID */ 122 { /* Seed PeerID */
156 GNUNET_RPS_seed_ids (rps_handle, 1, peer_id); 123 GNUNET_RPS_seed_ids (rps_handle, 1, &peer_id);
157 FPRINTF (stdout, "Seeded PeerID %s\n", GNUNET_i2s_full (peer_id)); 124 FPRINTF (stdout, "Seeded PeerID %s\n", GNUNET_i2s_full (&peer_id));
158 ret = 0; 125 ret = 0;
159 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); 126 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
160 } 127 }
@@ -172,10 +139,12 @@ main (int argc, char *const *argv)
172{ 139{
173 const char helpstr[] = 140 const char helpstr[] =
174 "Get random GNUnet peers. If none is specified a single is requested."; 141 "Get random GNUnet peers. If none is specified a single is requested.";
175 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 142 struct GNUNET_GETOPT_CommandLineOption options[] = {
176 {'s', "seed", "PEER_ID", 143 GNUNET_GETOPT_OPTION_SET_BASE32_AUTO ('s',
177 gettext_noop ("Seed a PeerID"), 144 "seed",
178 GNUNET_YES, &GNUNET_GETOPT_set_peerid, &peer_id}, 145 "PEER_ID",
146 gettext_noop ("Seed a PeerID"),
147 &peer_id),
179 GNUNET_GETOPT_OPTION_END 148 GNUNET_GETOPT_OPTION_END
180 }; 149 };
181 return (GNUNET_OK == 150 return (GNUNET_OK ==
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c
index 4a2f96123..0a4543b30 100644
--- a/src/rps/gnunet-service-rps.c
+++ b/src/rps/gnunet-service-rps.c
@@ -1026,7 +1026,7 @@ client_respond (void *cls,
1026 size_needed = sizeof (struct GNUNET_RPS_CS_ReplyMessage) + 1026 size_needed = sizeof (struct GNUNET_RPS_CS_ReplyMessage) +
1027 num_peers * sizeof (struct GNUNET_PeerIdentity); 1027 num_peers * sizeof (struct GNUNET_PeerIdentity);
1028 1028
1029 GNUNET_assert (GNUNET_SERVER_MAX_MESSAGE_SIZE >= size_needed); 1029 GNUNET_assert (GNUNET_MAX_MESSAGE_SIZE >= size_needed);
1030 1030
1031 ev = GNUNET_MQ_msg_extra (out_msg, 1031 ev = GNUNET_MQ_msg_extra (out_msg,
1032 num_peers * sizeof (struct GNUNET_PeerIdentity), 1032 num_peers * sizeof (struct GNUNET_PeerIdentity),
@@ -1067,7 +1067,7 @@ handle_client_request (void *cls,
1067 size_needed = sizeof (struct GNUNET_RPS_CS_RequestMessage) + 1067 size_needed = sizeof (struct GNUNET_RPS_CS_RequestMessage) +
1068 num_peers * sizeof (struct GNUNET_PeerIdentity); 1068 num_peers * sizeof (struct GNUNET_PeerIdentity);
1069 1069
1070 if (GNUNET_SERVER_MAX_MESSAGE_SIZE < size_needed) 1070 if (GNUNET_MAX_MESSAGE_SIZE < size_needed)
1071 { 1071 {
1072 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1072 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1073 "Message received from client has size larger than expected\n"); 1073 "Message received from client has size larger than expected\n");
diff --git a/src/rps/rps_api.c b/src/rps/rps_api.c
index 504f28b92..ccd480086 100644
--- a/src/rps/rps_api.c
+++ b/src/rps/rps_api.c
@@ -389,12 +389,12 @@ GNUNET_RPS_seed_ids (struct GNUNET_RPS_Handle *h,
389 n * sizeof (struct GNUNET_PeerIdentity); 389 n * sizeof (struct GNUNET_PeerIdentity);
390 /* The number of peers that fits in one message together with 390 /* The number of peers that fits in one message together with
391 * the respective header */ 391 * the respective header */
392 num_peers_max = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 392 num_peers_max = (GNUNET_MAX_MESSAGE_SIZE -
393 sizeof (struct GNUNET_RPS_CS_SeedMessage)) / 393 sizeof (struct GNUNET_RPS_CS_SeedMessage)) /
394 sizeof (struct GNUNET_PeerIdentity); 394 sizeof (struct GNUNET_PeerIdentity);
395 tmp_peer_pointer = ids; 395 tmp_peer_pointer = ids;
396 396
397 while (GNUNET_SERVER_MAX_MESSAGE_SIZE < size_needed) 397 while (GNUNET_MAX_MESSAGE_SIZE < size_needed)
398 { 398 {
399 ev = GNUNET_MQ_msg_extra (msg, num_peers_max * sizeof (struct GNUNET_PeerIdentity), 399 ev = GNUNET_MQ_msg_extra (msg, num_peers_max * sizeof (struct GNUNET_PeerIdentity),
400 GNUNET_MESSAGE_TYPE_RPS_CS_SEED); 400 GNUNET_MESSAGE_TYPE_RPS_CS_SEED);
@@ -463,12 +463,12 @@ GNUNET_RPS_act_malicious (struct GNUNET_RPS_Handle *h,
463 num_peers * sizeof (struct GNUNET_PeerIdentity); 463 num_peers * sizeof (struct GNUNET_PeerIdentity);
464 /* The number of peers that fit in one message together with 464 /* The number of peers that fit in one message together with
465 * the respective header */ 465 * the respective header */
466 num_peers_max = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 466 num_peers_max = (GNUNET_MAX_MESSAGE_SIZE -
467 sizeof (struct GNUNET_RPS_CS_SeedMessage)) / 467 sizeof (struct GNUNET_RPS_CS_SeedMessage)) /
468 sizeof (struct GNUNET_PeerIdentity); 468 sizeof (struct GNUNET_PeerIdentity);
469 tmp_peer_pointer = peer_ids; 469 tmp_peer_pointer = peer_ids;
470 470
471 while (GNUNET_SERVER_MAX_MESSAGE_SIZE < size_needed) 471 while (GNUNET_MAX_MESSAGE_SIZE < size_needed)
472 { 472 {
473 LOG (GNUNET_ERROR_TYPE_DEBUG, 473 LOG (GNUNET_ERROR_TYPE_DEBUG,
474 "Too many peers to send at once, sending %" PRIu32 " (all we can so far)\n", 474 "Too many peers to send at once, sending %" PRIu32 " (all we can so far)\n",
diff --git a/src/rps/test_rps.c b/src/rps/test_rps.c
index 1ce174454..acd3a165d 100644
--- a/src/rps/test_rps.c
+++ b/src/rps/test_rps.c
@@ -546,7 +546,7 @@ seed_peers_big (void *cls)
546 unsigned int i; 546 unsigned int i;
547 547
548 seed_msg_size = 8; /* sizeof (struct GNUNET_RPS_CS_SeedMessage) */ 548 seed_msg_size = 8; /* sizeof (struct GNUNET_RPS_CS_SeedMessage) */
549 num_peers_max = (GNUNET_SERVER_MAX_MESSAGE_SIZE - seed_msg_size) / 549 num_peers_max = (GNUNET_MAX_MESSAGE_SIZE - seed_msg_size) /
550 sizeof (struct GNUNET_PeerIdentity); 550 sizeof (struct GNUNET_PeerIdentity);
551 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 551 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
552 "Peers that fit in one seed msg; %u\n", 552 "Peers that fit in one seed msg; %u\n",
@@ -980,7 +980,7 @@ seed_cb (struct RPSPeer *rps_peer)
980static void 980static void
981seed_big_cb (struct RPSPeer *rps_peer) 981seed_big_cb (struct RPSPeer *rps_peer)
982{ 982{
983 // TODO test seeding > GNUNET_SERVER_MAX_MESSAGE_SIZE peers 983 // TODO test seeding > GNUNET_MAX_MESSAGE_SIZE peers
984 GNUNET_SCHEDULER_add_delayed ( 984 GNUNET_SCHEDULER_add_delayed (
985 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2), 985 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2),
986 seed_peers_big, rps_peer); 986 seed_peers_big, rps_peer);
@@ -1457,7 +1457,7 @@ main (int argc, char *argv[])
1457 1457
1458 else if (strstr (argv[0], "_seed_big") != NULL) 1458 else if (strstr (argv[0], "_seed_big") != NULL)
1459 { 1459 {
1460 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test seeding (num_peers > GNUNET_SERVER_MAX_MESSAGE_SIZE)\n"); 1460 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test seeding (num_peers > GNUNET_MAX_MESSAGE_SIZE)\n");
1461 num_peers = 1; 1461 num_peers = 1;
1462 cur_test_run.name = "test-rps-seed-big"; 1462 cur_test_run.name = "test-rps-seed-big";
1463 cur_test_run.main_test = seed_big_cb; 1463 cur_test_run.main_test = seed_big_cb;
diff --git a/src/scalarproduct/gnunet-scalarproduct.c b/src/scalarproduct/gnunet-scalarproduct.c
index aa894b61d..5d0fce2b1 100644
--- a/src/scalarproduct/gnunet-scalarproduct.c
+++ b/src/scalarproduct/gnunet-scalarproduct.c
@@ -343,16 +343,32 @@ run (void *cls,
343int 343int
344main (int argc, char *const *argv) 344main (int argc, char *const *argv)
345{ 345{
346 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 346 struct GNUNET_GETOPT_CommandLineOption options[] = {
347 {'e', "elements", "\"key1,val1;key2,val2;...,keyn,valn;\"", 347
348 gettext_noop ("A comma separated list of elements to compare as vector with our remote peer."), 348 GNUNET_GETOPT_OPTION_STRING ('e',
349 1, &GNUNET_GETOPT_set_string, &input_elements}, 349 "elements",
350 {'p', "peer", "PEERID", 350 "\"key1,val1;key2,val2;...,keyn,valn;\"",
351 gettext_noop ("[Optional] peer to calculate our scalarproduct with. If this parameter is not given, the service will wait for a remote peer to compute the request."), 351 gettext_noop ("A comma separated list of elements to compare as vector with our remote peer."),
352 1, &GNUNET_GETOPT_set_string, &input_peer_id}, 352 &input_elements),
353 {'k', "key", "TRANSACTION_ID", 353
354 gettext_noop ("Transaction ID shared with peer."), 354 GNUNET_GETOPT_OPTION_STRING ('e',
355 1, &GNUNET_GETOPT_set_string, &input_session_key}, 355 "elements",
356 "\"key1,val1;key2,val2;...,keyn,valn;\"",
357 gettext_noop ("A comma separated list of elements to compare as vector with our remote peer."),
358 &input_elements),
359
360 GNUNET_GETOPT_OPTION_STRING ('p',
361 "peer",
362 "PEERID",
363 gettext_noop ("[Optional] peer to calculate our scalarproduct with. If this parameter is not given, the service will wait for a remote peer to compute the request."),
364 &input_peer_id),
365
366 GNUNET_GETOPT_OPTION_STRING ('k',
367 "key",
368 "TRANSACTION_ID",
369 gettext_noop ("Transaction ID shared with peer."),
370 &input_session_key),
371
356 GNUNET_GETOPT_OPTION_END 372 GNUNET_GETOPT_OPTION_END
357 }; 373 };
358 374
diff --git a/src/scalarproduct/scalarproduct_api.c b/src/scalarproduct/scalarproduct_api.c
index df9f8d196..05c122e74 100644
--- a/src/scalarproduct/scalarproduct_api.c
+++ b/src/scalarproduct/scalarproduct_api.c
@@ -268,7 +268,7 @@ GNUNET_SCALARPRODUCT_accept_computation (const struct GNUNET_CONFIGURATION_Handl
268 GNUNET_free (h); 268 GNUNET_free (h);
269 return NULL; 269 return NULL;
270 } 270 }
271 possible = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct BobComputationMessage)) 271 possible = (GNUNET_MAX_MESSAGE_SIZE - 1 - sizeof (struct BobComputationMessage))
272 / sizeof (struct GNUNET_SCALARPRODUCT_Element); 272 / sizeof (struct GNUNET_SCALARPRODUCT_Element);
273 todo = GNUNET_MIN (possible, 273 todo = GNUNET_MIN (possible,
274 element_count); 274 element_count);
@@ -285,7 +285,7 @@ GNUNET_SCALARPRODUCT_accept_computation (const struct GNUNET_CONFIGURATION_Handl
285 element_count_transfered = todo; 285 element_count_transfered = todo;
286 GNUNET_MQ_send (h->mq, 286 GNUNET_MQ_send (h->mq,
287 env); 287 env);
288 possible = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (*mmsg)) 288 possible = (GNUNET_MAX_MESSAGE_SIZE - 1 - sizeof (*mmsg))
289 / sizeof (struct GNUNET_SCALARPRODUCT_Element); 289 / sizeof (struct GNUNET_SCALARPRODUCT_Element);
290 while (element_count_transfered < element_count) 290 while (element_count_transfered < element_count)
291 { 291 {
@@ -426,7 +426,7 @@ GNUNET_SCALARPRODUCT_start_computation (const struct GNUNET_CONFIGURATION_Handle
426 h->cfg = cfg; 426 h->cfg = cfg;
427 h->key = *session_key; 427 h->key = *session_key;
428 428
429 possible = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct AliceComputationMessage)) 429 possible = (GNUNET_MAX_MESSAGE_SIZE - 1 - sizeof (struct AliceComputationMessage))
430 / sizeof (struct GNUNET_SCALARPRODUCT_Element); 430 / sizeof (struct GNUNET_SCALARPRODUCT_Element);
431 todo = GNUNET_MIN (possible, 431 todo = GNUNET_MIN (possible,
432 element_count); 432 element_count);
@@ -445,7 +445,7 @@ GNUNET_SCALARPRODUCT_start_computation (const struct GNUNET_CONFIGURATION_Handle
445 GNUNET_MQ_send (h->mq, 445 GNUNET_MQ_send (h->mq,
446 env); 446 env);
447 element_count_transfered = todo; 447 element_count_transfered = todo;
448 possible = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (*mmsg)) 448 possible = (GNUNET_MAX_MESSAGE_SIZE - 1 - sizeof (*mmsg))
449 / sizeof (struct GNUNET_SCALARPRODUCT_Element); 449 / sizeof (struct GNUNET_SCALARPRODUCT_Element);
450 while (element_count_transfered < element_count) 450 while (element_count_transfered < element_count)
451 { 451 {
diff --git a/src/secretsharing/gnunet-secretsharing-profiler.c b/src/secretsharing/gnunet-secretsharing-profiler.c
index 3ff5d7fdd..e66019dc6 100644
--- a/src/secretsharing/gnunet-secretsharing-profiler.c
+++ b/src/secretsharing/gnunet-secretsharing-profiler.c
@@ -41,7 +41,7 @@ static unsigned int threshold = 2;
41/** 41/**
42 * Should we try to decrypt a value after the key generation? 42 * Should we try to decrypt a value after the key generation?
43 */ 43 */
44static unsigned int decrypt = GNUNET_NO; 44static int decrypt = GNUNET_NO;
45 45
46/** 46/**
47 * When would we like to see the operation finished? 47 * When would we like to see the operation finished?
@@ -88,7 +88,7 @@ static unsigned int num_decrypted;
88 88
89static struct GNUNET_HashCode session_id; 89static struct GNUNET_HashCode session_id;
90 90
91static int verbose; 91static unsigned int verbose;
92 92
93static struct GNUNET_SECRETSHARING_Plaintext reference_plaintext; 93static struct GNUNET_SECRETSHARING_Plaintext reference_plaintext;
94 94
@@ -602,26 +602,41 @@ run (void *cls, char *const *args, const char *cfgfile,
602int 602int
603main (int argc, char **argv) 603main (int argc, char **argv)
604{ 604{
605 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 605 struct GNUNET_GETOPT_CommandLineOption options[] = {
606 { 'n', "num-peers", NULL, 606
607 gettext_noop ("number of peers in consensus"), 607 GNUNET_GETOPT_OPTION_SET_UINT ('n',
608 GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_peers }, 608 "num-peers",
609 { 'D', "delay", NULL, 609 NULL,
610 gettext_noop ("dkg start delay"), 610 gettext_noop ("number of peers in consensus"),
611 GNUNET_YES, &GNUNET_GETOPT_set_relative_time, &delay }, 611 &num_peers),
612 { 't', "timeout", NULL, 612
613 gettext_noop ("dkg timeout"), 613 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('D',
614 GNUNET_YES, &GNUNET_GETOPT_set_relative_time, &timeout }, 614 "delay",
615 { 'k', "threshold", NULL, 615 NULL,
616 gettext_noop ("threshold"), 616 gettext_noop ("dkg start delay"),
617 GNUNET_YES, &GNUNET_GETOPT_set_uint, &threshold }, 617 &delay),
618 { 'd', "decrypt", NULL, 618
619 gettext_noop ("also profile decryption"), 619 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('t',
620 GNUNET_NO, &GNUNET_GETOPT_set_one, &decrypt }, 620 "timeout",
621 { 'V', "verbose", NULL, 621 NULL,
622 gettext_noop ("be more verbose (print received values)"), 622 gettext_noop ("dkg timeout"),
623 GNUNET_NO, &GNUNET_GETOPT_set_one, &verbose }, 623 &timeout),
624 GNUNET_GETOPT_OPTION_END 624
625 GNUNET_GETOPT_OPTION_SET_UINT ('k',
626 "threshold",
627 NULL,
628 gettext_noop ("threshold"),
629 &threshold),
630
631 GNUNET_GETOPT_OPTION_SET_ONE ('d',
632 "descrypt",
633 gettext_noop ("also profile decryption"),
634 &decrypt),
635
636
637 GNUNET_GETOPT_OPTION_VERBOSE (&verbose),
638
639 GNUNET_GETOPT_OPTION_END
625 }; 640 };
626 delay = GNUNET_TIME_UNIT_ZERO; 641 delay = GNUNET_TIME_UNIT_ZERO;
627 timeout = GNUNET_TIME_UNIT_MINUTES; 642 timeout = GNUNET_TIME_UNIT_MINUTES;
diff --git a/src/secretsharing/gnunet-service-secretsharing.c b/src/secretsharing/gnunet-service-secretsharing.c
index fa35dc21b..ccdba12c2 100644
--- a/src/secretsharing/gnunet-service-secretsharing.c
+++ b/src/secretsharing/gnunet-service-secretsharing.c
@@ -719,9 +719,9 @@ keygen_round1_new_element (void *cls,
719 if (element->size != sizeof (struct GNUNET_SECRETSHARING_KeygenCommitData)) 719 if (element->size != sizeof (struct GNUNET_SECRETSHARING_KeygenCommitData))
720 { 720 {
721 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 721 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
722 "keygen commit data with wrong size (%u) in consensus, " 722 "keygen commit data with wrong size (%u) in consensus, %u expected\n",
723 " %lu expected\n", 723 (unsigned int) element->size,
724 element->size, sizeof (struct GNUNET_SECRETSHARING_KeygenCommitData)); 724 (unsigned int) sizeof (struct GNUNET_SECRETSHARING_KeygenCommitData));
725 return; 725 return;
726 } 726 }
727 727
@@ -1384,9 +1384,9 @@ keygen_round2_new_element (void *cls,
1384 if (element->size != expected_element_size) 1384 if (element->size != expected_element_size)
1385 { 1385 {
1386 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1386 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1387 "keygen round2 data with wrong size (%u) in consensus, " 1387 "keygen round2 data with wrong size (%u) in consensus, %u expected\n",
1388 " %lu expected\n", 1388 (unsigned int) element->size,
1389 element->size, expected_element_size); 1389 (unsigned int) expected_element_size);
1390 return; 1390 return;
1391 } 1391 }
1392 1392
@@ -1934,10 +1934,15 @@ decrypt_new_element (void *cls,
1934 { 1934 {
1935 char *tmp1_str; 1935 char *tmp1_str;
1936 char *tmp2_str; 1936 char *tmp2_str;
1937
1937 tmp1_str = mpi_to_str (tmp1); 1938 tmp1_str = mpi_to_str (tmp1);
1938 tmp2_str = mpi_to_str (tmp2); 1939 tmp2_str = mpi_to_str (tmp2);
1939 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "P%u: Received invalid partial decryption from P%ld (eqn 1), expected %s got %s\n", 1940 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1940 session->share->my_peer, info - session->info, tmp1_str, tmp2_str); 1941 "P%u: Received invalid partial decryption from P%u (eqn 1), expected %s got %s\n",
1942 session->share->my_peer,
1943 (unsigned int) (info - session->info),
1944 tmp1_str,
1945 tmp2_str);
1941 GNUNET_free (tmp1_str); 1946 GNUNET_free (tmp1_str);
1942 GNUNET_free (tmp2_str); 1947 GNUNET_free (tmp2_str);
1943 goto cleanup; 1948 goto cleanup;
@@ -1952,8 +1957,10 @@ decrypt_new_element (void *cls,
1952 1957
1953 if (0 != gcry_mpi_cmp (tmp1, tmp2)) 1958 if (0 != gcry_mpi_cmp (tmp1, tmp2))
1954 { 1959 {
1955 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "P%u: Received invalid partial decryption from P%ld (eqn 2)\n", 1960 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1956 session->share->my_peer, info - session->info); 1961 "P%u: Received invalid partial decryption from P%u (eqn 2)\n",
1962 session->share->my_peer,
1963 (unsigned int) (info - session->info));
1957 goto cleanup; 1964 goto cleanup;
1958 } 1965 }
1959 1966
diff --git a/src/set/gnunet-set-ibf-profiler.c b/src/set/gnunet-set-ibf-profiler.c
index 8d832e358..ac86a900d 100644
--- a/src/set/gnunet-set-ibf-profiler.c
+++ b/src/set/gnunet-set-ibf-profiler.c
@@ -244,24 +244,41 @@ run (void *cls,
244int 244int
245main (int argc, char **argv) 245main (int argc, char **argv)
246{ 246{
247 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 247 struct GNUNET_GETOPT_CommandLineOption options[] = {
248 {'A', "asize", NULL, 248
249 gettext_noop ("number of element in set A-B"), 1, 249 GNUNET_GETOPT_OPTION_SET_UINT ('A',
250 &GNUNET_GETOPT_set_uint, &asize}, 250 "asize",
251 {'B', "bsize", NULL, 251 NULL,
252 gettext_noop ("number of element in set B-A"), 1, 252 gettext_noop ("number of element in set A-B"),
253 &GNUNET_GETOPT_set_uint, &bsize}, 253 &asize),
254 {'C', "csize", NULL, 254
255 gettext_noop ("number of common elements in A and B"), 1, 255 GNUNET_GETOPT_OPTION_SET_UINT ('B',
256 &GNUNET_GETOPT_set_uint, &csize}, 256 "bsize",
257 {'k', "hash-num", NULL, 257 NULL,
258 gettext_noop ("hash num"), 1, 258 gettext_noop ("number of element in set B-A"),
259 &GNUNET_GETOPT_set_uint, &hash_num}, 259 &bsize),
260 {'s', "ibf-size", NULL, 260
261 gettext_noop ("ibf size"), 1, 261 GNUNET_GETOPT_OPTION_SET_UINT ('C',
262 &GNUNET_GETOPT_set_uint, &ibf_size}, 262 "csize",
263 NULL,
264 gettext_noop ("number of common elements in A and B"),
265 &csize),
266
267 GNUNET_GETOPT_OPTION_SET_UINT ('k',
268 "hash-num",
269 NULL,
270 gettext_noop ("hash num"),
271 &hash_num),
272
273 GNUNET_GETOPT_OPTION_SET_UINT ('s',
274 "ibf-size",
275 NULL,
276 gettext_noop ("ibf size"),
277 &ibf_size),
278
263 GNUNET_GETOPT_OPTION_END 279 GNUNET_GETOPT_OPTION_END
264 }; 280 };
281
265 GNUNET_PROGRAM_run2 (argc, argv, "gnunet-consensus-ibf", 282 GNUNET_PROGRAM_run2 (argc, argv, "gnunet-consensus-ibf",
266 "help", 283 "help",
267 options, &run, NULL, GNUNET_YES); 284 options, &run, NULL, GNUNET_YES);
diff --git a/src/set/gnunet-set-profiler.c b/src/set/gnunet-set-profiler.c
index 8404b191c..349bce6ea 100644
--- a/src/set/gnunet-set-profiler.c
+++ b/src/set/gnunet-set-profiler.c
@@ -59,8 +59,8 @@ static struct GNUNET_PeerIdentity local_peer;
59static struct GNUNET_SET_ListenHandle *set_listener; 59static struct GNUNET_SET_ListenHandle *set_listener;
60 60
61static int byzantine; 61static int byzantine;
62static int force_delta; 62static unsigned int force_delta;
63static int force_full; 63static unsigned int force_full;
64static unsigned int element_size = 32; 64static unsigned int element_size = 32;
65 65
66/** 66/**
@@ -426,34 +426,60 @@ pre_run (void *cls, char *const *args, const char *cfgfile,
426int 426int
427main (int argc, char **argv) 427main (int argc, char **argv)
428{ 428{
429 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 429 struct GNUNET_GETOPT_CommandLineOption options[] = {
430 { 'A', "num-first", NULL, 430 GNUNET_GETOPT_OPTION_SET_UINT ('A',
431 gettext_noop ("number of values"), 431 "num-first",
432 GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_a }, 432 NULL,
433 { 'B', "num-second", NULL, 433 gettext_noop ("number of values"),
434 gettext_noop ("number of values"), 434 &num_a),
435 GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_b }, 435
436 { 'b', "byzantine", NULL, 436 GNUNET_GETOPT_OPTION_SET_UINT ('B',
437 gettext_noop ("use byzantine mode"), 437 "num-second",
438 GNUNET_NO, &GNUNET_GETOPT_set_one, &byzantine }, 438 NULL,
439 { 'f', "force-full", NULL, 439 gettext_noop ("number of values"),
440 gettext_noop ("force sending full set"), 440 &num_b),
441 GNUNET_NO, &GNUNET_GETOPT_set_uint, &force_full }, 441
442 { 'd', "force-delta", NULL, 442 GNUNET_GETOPT_OPTION_SET_ONE ('b',
443 gettext_noop ("number delta operation"), 443 "byzantine",
444 GNUNET_NO, &GNUNET_GETOPT_set_uint, &force_delta }, 444 gettext_noop ("use byzantine mode"),
445 { 'C', "num-common", NULL, 445 &byzantine),
446 gettext_noop ("number of values"), 446
447 GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_c }, 447 GNUNET_GETOPT_OPTION_SET_UINT ('f',
448 { 'x', "operation", NULL, 448 "force-full",
449 gettext_noop ("operation to execute"), 449 NULL,
450 GNUNET_YES, &GNUNET_GETOPT_set_string, &op_str }, 450 gettext_noop ("force sending full set"),
451 { 'w', "element-size", NULL, 451 &force_full),
452 gettext_noop ("element size"), 452
453 GNUNET_YES, &GNUNET_GETOPT_set_uint, &element_size }, 453 GNUNET_GETOPT_OPTION_SET_UINT ('d',
454 { 's', "statistics", NULL, 454 "force-delta",
455 gettext_noop ("write statistics to file"), 455 NULL,
456 GNUNET_YES, &GNUNET_GETOPT_set_filename, &statistics_filename }, 456 gettext_noop ("number delta operation"),
457 &force_delta),
458
459 GNUNET_GETOPT_OPTION_SET_UINT ('C',
460 "num-common",
461 NULL,
462 gettext_noop ("number of values"),
463 &num_c),
464
465 GNUNET_GETOPT_OPTION_STRING ('x',
466 "operation",
467 NULL,
468 gettext_noop ("operation to execute"),
469 &op_str),
470
471 GNUNET_GETOPT_OPTION_SET_UINT ('w',
472 "element-size",
473 NULL,
474 gettext_noop ("element size"),
475 &element_size),
476
477 GNUNET_GETOPT_OPTION_FILENAME ('s',
478 "statistics",
479 "FILENAME",
480 gettext_noop ("write statistics to file"),
481 &statistics_filename),
482
457 GNUNET_GETOPT_OPTION_END 483 GNUNET_GETOPT_OPTION_END
458 }; 484 };
459 GNUNET_PROGRAM_run2 (argc, argv, "gnunet-set-profiler", 485 GNUNET_PROGRAM_run2 (argc, argv, "gnunet-set-profiler",
diff --git a/src/social/.gitignore b/src/social/.gitignore
index 41954615f..875aa1105 100644
--- a/src/social/.gitignore
+++ b/src/social/.gitignore
@@ -1,2 +1,3 @@
1gnunet-social 1gnunet-social
2gnunet-service-social 2gnunet-service-social
3test_social
diff --git a/src/social/gnunet-social.c b/src/social/gnunet-social.c
index b864b828e..4a46fdc99 100644
--- a/src/social/gnunet-social.c
+++ b/src/social/gnunet-social.c
@@ -67,10 +67,10 @@ static int op_guest_leave;
67static int op_guest_talk; 67static int op_guest_talk;
68 68
69/** --replay */ 69/** --replay */
70static char *op_replay; 70static int op_replay;
71 71
72/** --replay-latest */ 72/** --replay-latest */
73static char *op_replay_latest; 73static int op_replay_latest;
74 74
75/** --look-at */ 75/** --look-at */
76static int op_look_at; 76static int op_look_at;
@@ -116,13 +116,13 @@ static char *opt_data;
116static char *opt_name; 116static char *opt_name;
117 117
118/** --start */ 118/** --start */
119static uint64_t opt_start; 119static unsigned long long opt_start;
120 120
121/** --until */ 121/** --until */
122static uint64_t opt_until; 122static unsigned long long opt_until;
123 123
124/** --limit */ 124/** --limit */
125static int opt_limit; 125static unsigned long long opt_limit;
126 126
127 127
128/* global vars */ 128/* global vars */
@@ -1199,7 +1199,7 @@ int
1199main (int argc, char *const *argv) 1199main (int argc, char *const *argv)
1200{ 1200{
1201 int res; 1201 int res;
1202 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 1202 struct GNUNET_GETOPT_CommandLineOption options[] = {
1203 /* 1203 /*
1204 * gnunet program options in addition to the ones below: 1204 * gnunet program options in addition to the ones below:
1205 * 1205 *
@@ -1212,120 +1212,165 @@ main (int argc, char *const *argv)
1212 1212
1213 /* operations */ 1213 /* operations */
1214 1214
1215 { 'A', "host-assign", NULL, 1215 GNUNET_GETOPT_OPTION_SET_ONE ('A',
1216 gettext_noop ("assign --name in state to --data"), 1216 "host-assign",
1217 GNUNET_NO, &GNUNET_GETOPT_set_one, &op_host_assign }, 1217 gettext_noop ("assign --name in state to --data"),
1218 1218 &op_host_assign),
1219 { 'B', "guest-leave", NULL, 1219
1220 gettext_noop ("say good-bye and leave somebody else's place"), 1220 GNUNET_GETOPT_OPTION_SET_ONE ('B',
1221 GNUNET_NO, &GNUNET_GETOPT_set_one, &op_guest_leave }, 1221 "guest-leave",
1222 1222 gettext_noop ("say good-bye and leave somebody else's place"),
1223 { 'C', "host-enter", NULL, 1223 &op_guest_leave),
1224 gettext_noop ("create a place"), 1224
1225 GNUNET_NO, &GNUNET_GETOPT_set_one, &op_host_enter }, 1225 GNUNET_GETOPT_OPTION_SET_ONE ('C',
1226 1226 "host-enter",
1227 { 'D', "host-leave", NULL, 1227 gettext_noop ("create a place"),
1228 gettext_noop ("destroy a place we were hosting"), 1228 &op_host_enter),
1229 GNUNET_NO, &GNUNET_GETOPT_set_one, &op_host_leave }, 1229
1230 1230 GNUNET_GETOPT_OPTION_SET_ONE ('C',
1231 { 'E', "guest-enter", NULL, 1231 "host-enter",
1232 gettext_noop ("enter somebody else's place"), 1232 gettext_noop ("create a place"),
1233 GNUNET_NO, &GNUNET_GETOPT_set_one, &op_guest_enter }, 1233 &op_host_enter),
1234 1234
1235 { 'F', "look-for", NULL, 1235 GNUNET_GETOPT_OPTION_SET_ONE ('D',
1236 gettext_noop ("find state matching name prefix"), 1236 "host-leave",
1237 GNUNET_NO, &GNUNET_GETOPT_set_one, &op_look_for }, 1237 gettext_noop ("destroy a place we were hosting"),
1238 1238 &op_host_leave),
1239 { 'H', "replay-latest", NULL, 1239
1240 gettext_noop ("replay history of messages up to the given --limit"), 1240 GNUNET_GETOPT_OPTION_SET_ONE ('E',
1241 GNUNET_NO, &GNUNET_GETOPT_set_one, &op_replay_latest }, 1241 "guest-enter",
1242 1242 gettext_noop ("enter somebody else's place"),
1243 { 'N', "host-reconnect", NULL, 1243 &op_guest_enter),
1244 gettext_noop ("reconnect to a previously created place"), 1244
1245 GNUNET_NO, &GNUNET_GETOPT_set_one, &op_host_reconnect }, 1245
1246 1246 GNUNET_GETOPT_OPTION_SET_ONE ('F',
1247 { 'P', "host-announce", NULL, 1247 "look-for",
1248 gettext_noop ("publish something to a place we are hosting"), 1248 gettext_noop ("find state matching name prefix"),
1249 GNUNET_NO, &GNUNET_GETOPT_set_one, &op_host_announce }, 1249 &op_look_for),
1250 1250
1251 { 'R', "guest-reconnect", NULL, 1251 GNUNET_GETOPT_OPTION_SET_ONE ('H',
1252 gettext_noop ("reconnect to a previously entered place"), 1252 "replay-latest",
1253 GNUNET_NO, &GNUNET_GETOPT_set_one, &op_guest_reconnect }, 1253 gettext_noop ("replay history of messages up to the given --limit"),
1254 1254 &op_replay_latest),
1255 { 'S', "look-at", NULL, 1255
1256 gettext_noop ("search for state matching exact name"), 1256 GNUNET_GETOPT_OPTION_SET_ONE ('N',
1257 GNUNET_NO, &GNUNET_GETOPT_set_one, &op_look_at }, 1257 "host-reconnect",
1258 1258 gettext_noop ("reconnect to a previously created place"),
1259 { 'T', "guest-talk", NULL, 1259 &op_host_reconnect),
1260 gettext_noop ("submit something to somebody's place"), 1260
1261 GNUNET_NO, &GNUNET_GETOPT_set_one, &op_guest_talk }, 1261 GNUNET_GETOPT_OPTION_SET_ONE ('P',
1262 1262 "host-announce",
1263 { 'U', "status", NULL, 1263 gettext_noop ("publish something to a place we are hosting"),
1264 gettext_noop ("list of egos and subscribed places"), 1264 &op_host_announce),
1265 GNUNET_NO, &GNUNET_GETOPT_set_one, &op_status }, 1265
1266 1266 GNUNET_GETOPT_OPTION_SET_ONE ('R',
1267 { 'X', "replay", NULL, 1267 "guest-reconnect",
1268 gettext_noop ("extract and replay history between message IDs --start and --until"), 1268 gettext_noop ("reconnect to a previously entered place"),
1269 GNUNET_NO, &GNUNET_GETOPT_set_one, &op_replay }, 1269 &op_guest_reconnect),
1270
1271 GNUNET_GETOPT_OPTION_SET_ONE ('S',
1272 "look-at",
1273 gettext_noop ("search for state matching exact name"),
1274 &op_look_at),
1275
1276 GNUNET_GETOPT_OPTION_SET_ONE ('T',
1277 "guest-talk",
1278 gettext_noop ("submit something to somebody's place"),
1279 &op_guest_talk),
1280
1281 GNUNET_GETOPT_OPTION_SET_ONE ('U',
1282 "status",
1283 gettext_noop ("list of egos and subscribed places"),
1284 &op_status),
1285
1286 GNUNET_GETOPT_OPTION_SET_ONE ('X',
1287 "replay",
1288 gettext_noop ("extract and replay history between message IDs --start and --until"),
1289 &op_replay),
1270 1290
1271 1291
1272 /* options */ 1292 /* options */
1273 1293
1274 { 'a', "app", "APPLICATION_ID", 1294 GNUNET_GETOPT_OPTION_STRING ('a',
1275 gettext_noop ("application ID to use when connecting"), 1295 "app",
1276 GNUNET_YES, &GNUNET_GETOPT_set_string, &opt_app }, 1296 "APPLICATION_ID",
1277 1297 gettext_noop ("application ID to use when connecting"),
1278 { 'd', "data", "DATA", 1298 &opt_app),
1279 gettext_noop ("message body or state value"), 1299
1280 GNUNET_YES, &GNUNET_GETOPT_set_string, &opt_data }, 1300 GNUNET_GETOPT_OPTION_STRING ('d',
1281 1301 "data",
1282 { 'e', "ego", "NAME|PUBKEY", 1302 "DATA",
1283 gettext_noop ("name or public key of ego"), 1303 gettext_noop ("message body or state value"),
1284 GNUNET_YES, &GNUNET_GETOPT_set_string, &opt_ego }, 1304 &opt_data),
1285 1305
1286 { 'f', "follow", NULL, 1306 GNUNET_GETOPT_OPTION_STRING ('e',
1287 gettext_noop ("wait for incoming messages"), 1307 "ego",
1288 GNUNET_NO, &GNUNET_GETOPT_set_one, &opt_follow }, 1308 "NAME|PUBKEY",
1289 1309 gettext_noop ("name or public key of ego"),
1290 { 'g', "gns", "GNS_NAME", 1310 &opt_ego),
1291 gettext_noop ("GNS name"), 1311
1292 GNUNET_YES, &GNUNET_GETOPT_set_string, &opt_gns }, 1312 GNUNET_GETOPT_OPTION_SET_ONE ('f',
1293 1313 "follow",
1294 { 'i', "peer", "PEER_ID", 1314 gettext_noop ("wait for incoming messages"),
1295 gettext_noop ("peer ID for --guest-enter"), 1315 &opt_follow),
1296 GNUNET_YES, &GNUNET_GETOPT_set_string, &opt_peer }, 1316
1297 1317 GNUNET_GETOPT_OPTION_STRING ('g',
1298 { 'k', "name", "VAR_NAME", 1318 "gns",
1299 gettext_noop ("name (key) to query from state"), 1319 "GNS_NAME",
1300 GNUNET_YES, &GNUNET_GETOPT_set_string, &opt_name }, 1320 gettext_noop ("GNS name"),
1301 1321 &opt_gns),
1302 { 'm', "method", "METHOD_NAME", 1322
1303 gettext_noop ("method name"), 1323 GNUNET_GETOPT_OPTION_STRING ('i',
1304 GNUNET_YES, &GNUNET_GETOPT_set_string, &opt_method }, 1324 "peer",
1305 1325 "PEER_ID",
1306 { 'n', "limit", NULL, 1326 gettext_noop ("peer ID for --guest-enter"),
1307 gettext_noop ("number of messages to replay from history"), 1327 &opt_peer),
1308 GNUNET_YES, &GNUNET_GETOPT_set_ulong, &opt_limit }, 1328
1309 1329 GNUNET_GETOPT_OPTION_STRING ('k',
1310 { 'p', "place", "PUBKEY", 1330 "name",
1311 gettext_noop ("key address of place"), 1331 "VAR_NAME",
1312 GNUNET_YES, &GNUNET_GETOPT_set_string, &opt_place }, 1332 gettext_noop ("name (key) to query from state"),
1313 1333 &opt_name),
1314 { 's', "start", NULL, 1334
1315 gettext_noop ("start message ID for history replay"), 1335 GNUNET_GETOPT_OPTION_STRING ('m',
1316 GNUNET_YES, &GNUNET_GETOPT_set_ulong, &opt_start }, 1336 "method",
1317 1337 "METHOD_NAME",
1318 { 'w', "welcome", NULL, 1338 gettext_noop ("method name"),
1319 gettext_noop ("respond to entry requests by admitting all guests"), 1339 &opt_method),
1320 GNUNET_NO, &GNUNET_GETOPT_set_one, &opt_welcome }, 1340
1321 1341 GNUNET_GETOPT_OPTION_SET_ULONG ('n',
1322 { 'u', "until", NULL, 1342 "limit",
1323 gettext_noop ("end message ID for history replay"), 1343 NULL,
1324 GNUNET_YES, &GNUNET_GETOPT_set_ulong, &opt_until }, 1344 gettext_noop ("number of messages to replay from history"),
1325 1345 &opt_limit),
1326 { 'y', "deny", NULL, 1346
1327 gettext_noop ("respond to entry requests by refusing all guests"), 1347 GNUNET_GETOPT_OPTION_STRING ('p',
1328 GNUNET_NO, &GNUNET_GETOPT_set_one, &opt_deny }, 1348 "place",
1349 "PUBKEY",
1350 gettext_noop ("key address of place"),
1351 &opt_place),
1352
1353 GNUNET_GETOPT_OPTION_SET_ULONG ('s',
1354 "start",
1355 NULL,
1356 gettext_noop ("start message ID for history replay"),
1357 &opt_start),
1358
1359 GNUNET_GETOPT_OPTION_SET_ONE ('w',
1360 "welcome",
1361 gettext_noop ("respond to entry requests by admitting all guests"),
1362 &opt_welcome),
1363
1364 GNUNET_GETOPT_OPTION_SET_ULONG ('u',
1365 "until",
1366 NULL,
1367 gettext_noop ("end message ID for history replay"),
1368 &opt_until),
1369
1370 GNUNET_GETOPT_OPTION_SET_ONE ('y',
1371 "deny",
1372 gettext_noop ("respond to entry requests by refusing all guests"),
1373 &opt_deny),
1329 1374
1330 GNUNET_GETOPT_OPTION_END 1375 GNUNET_GETOPT_OPTION_END
1331 }; 1376 };
diff --git a/src/social/social_api.c b/src/social/social_api.c
index a7fe0916f..af1d6e57e 100644
--- a/src/social/social_api.c
+++ b/src/social/social_api.c
@@ -2110,7 +2110,7 @@ GNUNET_SOCIAL_place_msg_proc_set (struct GNUNET_SOCIAL_Place *plc,
2110 GNUNET_assert (NULL != method_prefix); 2110 GNUNET_assert (NULL != method_prefix);
2111 struct MsgProcRequest *mpreq; 2111 struct MsgProcRequest *mpreq;
2112 uint16_t method_size = strnlen (method_prefix, 2112 uint16_t method_size = strnlen (method_prefix,
2113 GNUNET_SERVER_MAX_MESSAGE_SIZE 2113 GNUNET_MAX_MESSAGE_SIZE
2114 - sizeof (*mpreq)) + 1; 2114 - sizeof (*mpreq)) + 1;
2115 GNUNET_assert ('\0' == method_prefix[method_size - 1]); 2115 GNUNET_assert ('\0' == method_prefix[method_size - 1]);
2116 2116
@@ -2159,7 +2159,7 @@ place_history_replay (struct GNUNET_SOCIAL_Place *plc,
2159 2159
2160 GNUNET_assert (NULL != method_prefix); 2160 GNUNET_assert (NULL != method_prefix);
2161 uint16_t method_size = strnlen (method_prefix, 2161 uint16_t method_size = strnlen (method_prefix,
2162 GNUNET_SERVER_MAX_MESSAGE_SIZE 2162 GNUNET_MAX_MESSAGE_SIZE
2163 - sizeof (*req)) + 1; 2163 - sizeof (*req)) + 1;
2164 GNUNET_assert ('\0' == method_prefix[method_size - 1]); 2164 GNUNET_assert ('\0' == method_prefix[method_size - 1]);
2165 2165
@@ -2285,7 +2285,7 @@ place_state_get (struct GNUNET_SOCIAL_Place *plc,
2285 look->op_id = GNUNET_OP_add (plc->op, &op_recv_state_result, look, NULL); 2285 look->op_id = GNUNET_OP_add (plc->op, &op_recv_state_result, look, NULL);
2286 2286
2287 GNUNET_assert (NULL != name); 2287 GNUNET_assert (NULL != name);
2288 size_t name_size = strnlen (name, GNUNET_SERVER_MAX_MESSAGE_SIZE 2288 size_t name_size = strnlen (name, GNUNET_MAX_MESSAGE_SIZE
2289 - sizeof (*req)) + 1; 2289 - sizeof (*req)) + 1;
2290 struct GNUNET_MQ_Envelope * 2290 struct GNUNET_MQ_Envelope *
2291 env = GNUNET_MQ_msg_extra (req, name_size, type); 2291 env = GNUNET_MQ_msg_extra (req, name_size, type);
@@ -2426,7 +2426,7 @@ GNUNET_SOCIAL_zone_add_place (const struct GNUNET_SOCIAL_App *app,
2426 size_t relay_size = relay_count * sizeof (*relays); 2426 size_t relay_size = relay_count * sizeof (*relays);
2427 size_t payload_size = name_size + password_size + relay_size; 2427 size_t payload_size = name_size + password_size + relay_size;
2428 2428
2429 if (GNUNET_SERVER_MAX_MESSAGE_SIZE < sizeof (*preq) + payload_size) 2429 if (GNUNET_MAX_MESSAGE_SIZE < sizeof (*preq) + payload_size)
2430 return GNUNET_SYSERR; 2430 return GNUNET_SYSERR;
2431 2431
2432 struct GNUNET_MQ_Envelope * 2432 struct GNUNET_MQ_Envelope *
@@ -2506,7 +2506,7 @@ GNUNET_SOCIAL_zone_add_nym (const struct GNUNET_SOCIAL_App *app,
2506 struct ZoneAddNymRequest *nreq; 2506 struct ZoneAddNymRequest *nreq;
2507 2507
2508 size_t name_size = strlen (name) + 1; 2508 size_t name_size = strlen (name) + 1;
2509 if (GNUNET_SERVER_MAX_MESSAGE_SIZE < sizeof (*nreq) + name_size) 2509 if (GNUNET_MAX_MESSAGE_SIZE < sizeof (*nreq) + name_size)
2510 return GNUNET_SYSERR; 2510 return GNUNET_SYSERR;
2511 2511
2512 struct GNUNET_MQ_Envelope * 2512 struct GNUNET_MQ_Envelope *
diff --git a/src/statistics/gnunet-service-statistics.c b/src/statistics/gnunet-service-statistics.c
index 85c84b89d..0cb136b99 100644
--- a/src/statistics/gnunet-service-statistics.c
+++ b/src/statistics/gnunet-service-statistics.c
@@ -359,7 +359,7 @@ transmit (struct ClientEntry *ce,
359 359
360 size = strlen (e->subsystem->service) + 1 + 360 size = strlen (e->subsystem->service) + 1 +
361 strlen (e->name) + 1; 361 strlen (e->name) + 1;
362 GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE); 362 GNUNET_assert (size < GNUNET_MAX_MESSAGE_SIZE);
363 env = GNUNET_MQ_msg_extra (m, 363 env = GNUNET_MQ_msg_extra (m,
364 size, 364 size,
365 GNUNET_MESSAGE_TYPE_STATISTICS_VALUE); 365 GNUNET_MESSAGE_TYPE_STATISTICS_VALUE);
diff --git a/src/statistics/gnunet-statistics.c b/src/statistics/gnunet-statistics.c
index ed0c3f27d..6cfc56171 100644
--- a/src/statistics/gnunet-statistics.c
+++ b/src/statistics/gnunet-statistics.c
@@ -378,28 +378,44 @@ run (void *cls,
378int 378int
379main (int argc, char *const *argv) 379main (int argc, char *const *argv)
380{ 380{
381 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 381 struct GNUNET_GETOPT_CommandLineOption options[] = {
382 {'n', "name", "NAME", 382 GNUNET_GETOPT_OPTION_STRING ('n',
383 gettext_noop ("limit output to statistics for the given NAME"), 1, 383 "name",
384 &GNUNET_GETOPT_set_string, &name}, 384 "NAME",
385 {'p', "persistent", NULL, 385 gettext_noop ("limit output to statistics for the given NAME"),
386 gettext_noop ("make the value being set persistent"), 0, 386 &name),
387 &GNUNET_GETOPT_set_one, &persistent}, 387
388 {'s', "subsystem", "SUBSYSTEM", 388 GNUNET_GETOPT_OPTION_SET_ONE ('p',
389 gettext_noop ("limit output to the given SUBSYSTEM"), 1, 389 "persistent",
390 &GNUNET_GETOPT_set_string, &subsystem}, 390 gettext_noop ("make the value being set persistent"),
391 {'q', "quiet", NULL, 391 &persistent),
392 gettext_noop ("just print the statistics value"), 0, 392
393 &GNUNET_GETOPT_set_one, &quiet}, 393 GNUNET_GETOPT_OPTION_STRING ('s',
394 {'w', "watch", NULL, 394 "subsystem",
395 gettext_noop ("watch value continuously"), 0, 395 "SUBSYSTEM",
396 &GNUNET_GETOPT_set_one, &watch}, 396 gettext_noop ("limit output to the given SUBSYSTEM"),
397 {'r', "remote", NULL, 397 &subsystem),
398 gettext_noop ("connect to remote host"), 1, 398
399 &GNUNET_GETOPT_set_string, &remote_host}, 399 GNUNET_GETOPT_OPTION_SET_ONE ('q',
400 {'o', "port", NULL, 400 "quiet",
401 gettext_noop ("port for remote host"), 1, 401 gettext_noop ("just print the statistics value"),
402 &GNUNET_GETOPT_set_uint, &remote_port}, 402 &quiet),
403
404 GNUNET_GETOPT_OPTION_SET_ONE ('w',
405 "watch",
406 gettext_noop ("watch value continuously"),
407 &watch),
408
409 GNUNET_GETOPT_OPTION_STRING ('r',
410 "remote",
411 "REMOTE",
412 gettext_noop ("connect to remote host"),
413 &remote_host),
414 GNUNET_GETOPT_OPTION_SET_ULONG ('o',
415 "port",
416 "PORT",
417 gettext_noop ("port for remote host"),
418 &remote_port),
403 GNUNET_GETOPT_OPTION_END 419 GNUNET_GETOPT_OPTION_END
404 }; 420 };
405 remote_port = 0; 421 remote_port = 0;
diff --git a/src/statistics/statistics_api.c b/src/statistics/statistics_api.c
index ad4453b2a..9d04e854f 100644
--- a/src/statistics/statistics_api.c
+++ b/src/statistics/statistics_api.c
@@ -349,7 +349,7 @@ schedule_watch_request (struct GNUNET_STATISTICS_Handle *h,
349 slen = strlen (watch->subsystem) + 1; 349 slen = strlen (watch->subsystem) + 1;
350 nlen = strlen (watch->name) + 1; 350 nlen = strlen (watch->name) + 1;
351 nsize = sizeof (struct GNUNET_MessageHeader) + slen + nlen; 351 nsize = sizeof (struct GNUNET_MessageHeader) + slen + nlen;
352 if (nsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 352 if (nsize >= GNUNET_MAX_MESSAGE_SIZE)
353 { 353 {
354 GNUNET_break (0); 354 GNUNET_break (0);
355 return; 355 return;
@@ -1098,7 +1098,7 @@ GNUNET_STATISTICS_get (struct GNUNET_STATISTICS_Handle *handle,
1098 slen1 = strlen (subsystem) + 1; 1098 slen1 = strlen (subsystem) + 1;
1099 slen2 = strlen (name) + 1; 1099 slen2 = strlen (name) + 1;
1100 GNUNET_assert (slen1 + slen2 + sizeof (struct GNUNET_MessageHeader) < 1100 GNUNET_assert (slen1 + slen2 + sizeof (struct GNUNET_MessageHeader) <
1101 GNUNET_SERVER_MAX_MESSAGE_SIZE); 1101 GNUNET_MAX_MESSAGE_SIZE);
1102 ai = GNUNET_new (struct GNUNET_STATISTICS_GetHandle); 1102 ai = GNUNET_new (struct GNUNET_STATISTICS_GetHandle);
1103 ai->sh = handle; 1103 ai->sh = handle;
1104 ai->subsystem = GNUNET_strdup (subsystem); 1104 ai->subsystem = GNUNET_strdup (subsystem);
@@ -1246,7 +1246,7 @@ add_setter_action (struct GNUNET_STATISTICS_Handle *h,
1246 slen = strlen (h->subsystem) + 1; 1246 slen = strlen (h->subsystem) + 1;
1247 nlen = strlen (name) + 1; 1247 nlen = strlen (name) + 1;
1248 nsize = sizeof (struct GNUNET_STATISTICS_SetMessage) + slen + nlen; 1248 nsize = sizeof (struct GNUNET_STATISTICS_SetMessage) + slen + nlen;
1249 if (nsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 1249 if (nsize >= GNUNET_MAX_MESSAGE_SIZE)
1250 { 1250 {
1251 GNUNET_break (0); 1251 GNUNET_break (0);
1252 return; 1252 return;
diff --git a/src/testbed-logger/gnunet-service-testbed-logger.c b/src/testbed-logger/gnunet-service-testbed-logger.c
index 1c250b306..f915e70af 100644
--- a/src/testbed-logger/gnunet-service-testbed-logger.c
+++ b/src/testbed-logger/gnunet-service-testbed-logger.c
@@ -40,42 +40,6 @@
40 LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) 40 LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
41 41
42/** 42/**
43 * The message queue for sending messages to clients
44 */
45struct MessageQueue
46{
47 /**
48 * The message to be sent
49 */
50 struct GNUNET_MessageHeader *msg;
51
52 /**
53 * The client to send the message to
54 */
55 struct GNUNET_SERVER_Client *client;
56
57 /**
58 * next pointer for DLL
59 */
60 struct MessageQueue *next;
61
62 /**
63 * prev pointer for DLL
64 */
65 struct MessageQueue *prev;
66};
67
68/**
69 * The message queue head
70 */
71static struct MessageQueue *mq_head;
72
73/**
74 * The message queue tail
75 */
76static struct MessageQueue *mq_tail;
77
78/**
79 * Handle for buffered writing. 43 * Handle for buffered writing.
80 */ 44 */
81struct GNUNET_BIO_WriteHandle *bio; 45struct GNUNET_BIO_WriteHandle *bio;
@@ -92,23 +56,38 @@ static int in_shutdown;
92 56
93 57
94/** 58/**
95 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_ADDHOST messages 59 * Check #GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_MSG messages
96 * 60 *
97 * @param cls NULL 61 * @param cls client identification of the client
98 * @param client identification of the client 62 * @param msg the actual message
63 * @return #GNUNET_OK (they are all always OK)
64 */
65static int
66check_log_msg (void *cls,
67 const struct GNUNET_MessageHeader *msg)
68{
69 return GNUNET_OK;
70}
71
72
73/**
74 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_MSG messages
75 *
76 * @param cls client identification of the client
99 * @param msg the actual message 77 * @param msg the actual message
100 */ 78 */
101static void 79static void
102handle_log_msg (void *cls, 80handle_log_msg (void *cls,
103 struct GNUNET_SERVER_Client *client,
104 const struct GNUNET_MessageHeader *msg) 81 const struct GNUNET_MessageHeader *msg)
105{ 82{
83 struct GNUNET_SERVICE_Client *client = cls;
106 uint16_t ms; 84 uint16_t ms;
107 85
108 ms = ntohs (msg->size); 86 ms = ntohs (msg->size) - sizeof (struct GNUNET_MessageHeader);
109 ms -= sizeof (struct GNUNET_MessageHeader); 87 GNUNET_BIO_write (bio,
110 GNUNET_BIO_write (bio, &msg[1], ms); 88 &msg[1],
111 GNUNET_SERVER_receive_done (client, GNUNET_OK); 89 ms);
90 GNUNET_SERVICE_client_continue (client);
112} 91}
113 92
114 93
@@ -120,69 +99,55 @@ handle_log_msg (void *cls,
120static void 99static void
121shutdown_task (void *cls) 100shutdown_task (void *cls)
122{ 101{
123 struct MessageQueue *mq_entry;
124
125 in_shutdown = GNUNET_YES; 102 in_shutdown = GNUNET_YES;
126 if (0 != nconn) 103 if (0 != nconn)
127 { 104 {
128 /* Delay shutdown if there are active connections */ 105 /* Delay shutdown if there are active connections */
129 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); 106 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
107 NULL);
130 return; 108 return;
131 } 109 }
132 while (NULL != (mq_entry = mq_head)) 110 GNUNET_break (GNUNET_OK ==
133 { 111 GNUNET_BIO_write_close (bio));
134 GNUNET_free (mq_entry->msg);
135 GNUNET_SERVER_client_drop (mq_entry->client);
136 GNUNET_CONTAINER_DLL_remove (mq_head,
137 mq_tail,
138 mq_entry);
139 GNUNET_free (mq_entry);
140 }
141 GNUNET_break (GNUNET_OK == GNUNET_BIO_write_close (bio));
142} 112}
143 113
144 114
145/** 115/**
146x * Functions with this signature are called whenever a client 116 * Callback called when a client connects to the service.
147 * is disconnected on the network level.
148 * 117 *
149 * @param cls closure 118 * @param cls closure for the service
150 * @param client identification of the client; NULL 119 * @param c the new client that connected to the service
151 * for the last call when the server is destroyed 120 * @param mq the message queue used to send messages to the client
121 * @return @a c
152 */ 122 */
153static void 123static void *
154client_disconnected (void *cls, 124client_connect_cb (void *cls,
155 struct GNUNET_SERVER_Client *client) 125 struct GNUNET_SERVICE_Client *c,
126 struct GNUNET_MQ_Handle *mq)
156{ 127{
157 if (NULL == client) 128 /* FIXME: is this really what we want here? */
158 { 129 GNUNET_SERVICE_client_persist (c);
159 GNUNET_break (0 == nconn); 130 nconn++;
160 return; 131 return c;
161 }
162 nconn--;
163 if (GNUNET_YES == in_shutdown)
164 GNUNET_SCHEDULER_shutdown ();
165} 132}
166 133
167 134
168/** 135/**
169 * Functions with this signature are called whenever a client 136 * Callback called when a client disconnected from the service
170 * is connected on the network level.
171 * 137 *
172 * @param cls closure 138 * @param cls closure for the service
173 * @param client identification of the client 139 * @param c the client that disconnected
140 * @param internal_cls should be equal to @a c
174 */ 141 */
175static void 142static void
176client_connected (void *cls, 143client_disconnect_cb (void *cls,
177 struct GNUNET_SERVER_Client *client) 144 struct GNUNET_SERVICE_Client *c,
145 void *internal_cls)
178{ 146{
179 if (NULL == client) 147 nconn--;
180 { 148 if (GNUNET_YES == in_shutdown)
181 GNUNET_break (0 == nconn); 149 GNUNET_SCHEDULER_shutdown ();
182 return; 150 GNUNET_assert (c == internal_cls);
183 }
184 GNUNET_SERVER_client_persist_ (client);
185 nconn++;
186} 151}
187 152
188 153
@@ -190,18 +155,14 @@ client_connected (void *cls,
190 * Testbed setup 155 * Testbed setup
191 * 156 *
192 * @param cls closure 157 * @param cls closure
193 * @param server the initialized server
194 * @param cfg configuration to use 158 * @param cfg configuration to use
159 * @param service the initialized service
195 */ 160 */
196static void 161static void
197logger_run (void *cls, 162logger_run (void *cls,
198 struct GNUNET_SERVER_Handle *server, 163 const struct GNUNET_CONFIGURATION_Handle *cfg,
199 const struct GNUNET_CONFIGURATION_Handle *cfg) 164 struct GNUNET_SERVICE_Handle *service)
200{ 165{
201 static const struct GNUNET_SERVER_MessageHandler message_handlers[] = {
202 {&handle_log_msg, NULL, GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_MSG, 0},
203 {NULL, NULL, 0, 0}
204 };
205 char *dir; 166 char *dir;
206 char *fn; 167 char *fn;
207 char *hname; 168 char *hname;
@@ -223,7 +184,8 @@ logger_run (void *cls,
223 pid = getpid (); 184 pid = getpid ();
224 hname_len = GNUNET_OS_get_hostname_max_length (); 185 hname_len = GNUNET_OS_get_hostname_max_length ();
225 hname = GNUNET_malloc (hname_len); 186 hname = GNUNET_malloc (hname_len);
226 if (0 != gethostname (hname, hname_len)) 187 if (0 != gethostname (hname,
188 hname_len))
227 { 189 {
228 LOG (GNUNET_ERROR_TYPE_ERROR, 190 LOG (GNUNET_ERROR_TYPE_ERROR,
229 "Cannot get hostname. Exiting\n"); 191 "Cannot get hostname. Exiting\n");
@@ -247,24 +209,27 @@ logger_run (void *cls,
247 return; 209 return;
248 } 210 }
249 GNUNET_free (fn); 211 GNUNET_free (fn);
250 GNUNET_SERVER_add_handlers (server, message_handlers); 212 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
251 GNUNET_SERVER_connect_notify (server, &client_connected, NULL); 213 NULL);
252 GNUNET_SERVER_disconnect_notify (server, &client_disconnected, NULL);
253 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
254 LOG_DEBUG ("TESTBED-LOGGER startup complete\n"); 214 LOG_DEBUG ("TESTBED-LOGGER startup complete\n");
255} 215}
256 216
257 217
258/** 218/**
259 * The starting point of execution 219 * Define "main" method using service macro.
260 */ 220 */
261int 221GNUNET_SERVICE_MAIN
262main (int argc, char *const *argv) 222("testbed-logger",
263{ 223 GNUNET_SERVICE_OPTION_NONE,
264 return (GNUNET_OK == 224 &logger_run,
265 GNUNET_SERVICE_run (argc, argv, "testbed-logger", 225 &client_connect_cb,
266 GNUNET_SERVICE_OPTION_NONE, 226 &client_disconnect_cb,
267 &logger_run, NULL)) ? 0 : 1; 227 NULL,
268} 228 GNUNET_MQ_hd_var_size (log_msg,
229 GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_MSG,
230 struct GNUNET_MessageHeader,
231 NULL),
232 GNUNET_MQ_handler_end ());
233
269 234
270/* end of gnunet-service-testbed-logger.c */ 235/* end of gnunet-service-testbed-logger.c */
diff --git a/src/testbed-logger/test_testbed_logger_api.c b/src/testbed-logger/test_testbed_logger_api.c
index 0ebe0c3f4..e627feeb4 100644
--- a/src/testbed-logger/test_testbed_logger_api.c
+++ b/src/testbed-logger/test_testbed_logger_api.c
@@ -258,11 +258,15 @@ main (int argc, char **argv)
258 GNUNET_log_setup ("test-testbed-logger-api", 258 GNUNET_log_setup ("test-testbed-logger-api",
259 "WARNING", 259 "WARNING",
260 NULL); 260 NULL);
261 GNUNET_break (GNUNET_OK ==
262 GNUNET_DISK_directory_remove ("/tmp/test-testbed"));
261 ret = GNUNET_TESTING_service_run ("test-testbed-logger", 263 ret = GNUNET_TESTING_service_run ("test-testbed-logger",
262 "testbed-logger", 264 "testbed-logger",
263 "test_testbed_logger_api.conf", 265 "test_testbed_logger_api.conf",
264 &test_main, 266 &test_main,
265 NULL); 267 NULL);
268 GNUNET_break (GNUNET_OK ==
269 GNUNET_DISK_directory_remove ("/tmp/test-testbed"));
266 if (0 != ret) 270 if (0 != ret)
267 return 1; 271 return 1;
268 if (GNUNET_OK != result) 272 if (GNUNET_OK != result)
diff --git a/src/testbed-logger/testbed_logger_api.c b/src/testbed-logger/testbed_logger_api.c
index 25494aed0..7aa4ade35 100644
--- a/src/testbed-logger/testbed_logger_api.c
+++ b/src/testbed-logger/testbed_logger_api.c
@@ -39,7 +39,7 @@
39/** 39/**
40 * The size of the buffer we fill before sending out the message 40 * The size of the buffer we fill before sending out the message
41 */ 41 */
42#define BUFFER_SIZE (GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_MessageHeader)) 42#define BUFFER_SIZE (GNUNET_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_MessageHeader))
43 43
44/** 44/**
45 * Connection handle for the logger service 45 * Connection handle for the logger service
diff --git a/src/testbed/generate-underlay-topology.c b/src/testbed/generate-underlay-topology.c
index 36580a2a3..ab7d81c8b 100644
--- a/src/testbed/generate-underlay-topology.c
+++ b/src/testbed/generate-underlay-topology.c
@@ -70,7 +70,7 @@ enum GNUNET_TESTBED_TopologyOption topology;
70/** 70/**
71 * The number of peers to include in the topology 71 * The number of peers to include in the topology
72 */ 72 */
73static int num_peers; 73static unsigned int num_peers;
74 74
75/** 75/**
76 * program result 76 * program result
@@ -335,11 +335,15 @@ int
335main (int argc, char *const argv[]) 335main (int argc, char *const argv[])
336{ 336{
337 struct GNUNET_GETOPT_CommandLineOption option[] = { 337 struct GNUNET_GETOPT_CommandLineOption option[] = {
338 {'p', "num-peers", "COUNT", 338
339 gettext_noop ("create COUNT number of peers"), 339 GNUNET_GETOPT_OPTION_SET_UINT ('p',
340 GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_peers}, 340 "num-peers",
341 "COUNT",
342 gettext_noop ("create COUNT number of peers"),
343 &num_peers),
341 GNUNET_GETOPT_OPTION_END 344 GNUNET_GETOPT_OPTION_END
342 }; 345 };
346
343 int ret; 347 int ret;
344 348
345 exit_result = GNUNET_SYSERR; 349 exit_result = GNUNET_SYSERR;
diff --git a/src/testbed/gnunet-helper-testbed.c b/src/testbed/gnunet-helper-testbed.c
index 6368fb74b..d2a3a98b7 100644
--- a/src/testbed/gnunet-helper-testbed.c
+++ b/src/testbed/gnunet-helper-testbed.c
@@ -495,7 +495,7 @@ error:
495static void 495static void
496read_task (void *cls) 496read_task (void *cls)
497{ 497{
498 char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE]; 498 char buf[GNUNET_MAX_MESSAGE_SIZE];
499 ssize_t sread; 499 ssize_t sread;
500 500
501 read_task_id = NULL; 501 read_task_id = NULL;
diff --git a/src/testbed/gnunet-service-testbed_barriers.c b/src/testbed/gnunet-service-testbed_barriers.c
index a201d22bb..681ed6df2 100644
--- a/src/testbed/gnunet-service-testbed_barriers.c
+++ b/src/testbed/gnunet-service-testbed_barriers.c
@@ -478,7 +478,7 @@ GST_barriers_init (struct GNUNET_CONFIGURATION_Handle *cfg)
478 LOG_DEBUG ("Launching testbed-barrier service\n"); 478 LOG_DEBUG ("Launching testbed-barrier service\n");
479 barrier_map = GNUNET_CONTAINER_multihashmap_create (3, 479 barrier_map = GNUNET_CONTAINER_multihashmap_create (3,
480 GNUNET_YES); 480 GNUNET_YES);
481 ctx = GNUNET_SERVICE_starT ("testbed-barrier", 481 ctx = GNUNET_SERVICE_start ("testbed-barrier",
482 cfg, 482 cfg,
483 &connect_cb, 483 &connect_cb,
484 &disconnect_cb, 484 &disconnect_cb,
@@ -524,7 +524,7 @@ GST_barriers_destroy ()
524 NULL)); 524 NULL));
525 GNUNET_CONTAINER_multihashmap_destroy (barrier_map); 525 GNUNET_CONTAINER_multihashmap_destroy (barrier_map);
526 GNUNET_assert (NULL != ctx); 526 GNUNET_assert (NULL != ctx);
527 GNUNET_SERVICE_stoP (ctx); 527 GNUNET_SERVICE_stop (ctx);
528} 528}
529 529
530 530
diff --git a/src/testbed/gnunet-testbed-profiler.c b/src/testbed/gnunet-testbed-profiler.c
index 9468b3c91..29f77193d 100644
--- a/src/testbed/gnunet-testbed-profiler.c
+++ b/src/testbed/gnunet-testbed-profiler.c
@@ -276,23 +276,34 @@ run (void *cls, char *const *args, const char *cfgfile,
276int 276int
277main (int argc, char *const *argv) 277main (int argc, char *const *argv)
278{ 278{
279 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 279 struct GNUNET_GETOPT_CommandLineOption options[] = {
280 {'p', "num-peers", "COUNT", 280
281 gettext_noop ("create COUNT number of peers"), 281 GNUNET_GETOPT_OPTION_SET_UINT ('p',
282 GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_peers}, 282 "num-peers",
283 {'e', "num-errors", "COUNT", 283 "COUNT",
284 gettext_noop ("tolerate COUNT number of continious timeout failures"), 284 gettext_noop ("create COUNT number of peers"),
285 GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_cont_fails}, 285 &num_peers),
286 {'n', "non-interactive", NULL, 286
287 gettext_noop ("run profiler in non-interactive mode where upon " 287 GNUNET_GETOPT_OPTION_SET_UINT ('e',
288 "testbed setup the profiler does not wait for a " 288 "num-errors",
289 "keystroke but continues to run until a termination " 289 "COUNT",
290 "signal is received"), 290 gettext_noop ("tolerate COUNT number of continious timeout failures"),
291 GNUNET_NO, &GNUNET_GETOPT_set_one, &noninteractive}, 291 &num_cont_fails),
292
293 GNUNET_GETOPT_OPTION_SET_ONE ('n',
294 "non-interactive",
295 gettext_noop ("run profiler in non-interactive mode where upon "
296 "testbed setup the profiler does not wait for a "
297 "keystroke but continues to run until a termination "
298 "signal is received"),
299 &noninteractive),
300
292#if !ENABLE_SUPERMUC 301#if !ENABLE_SUPERMUC
293 {'H', "hosts", "FILENAME", 302 GNUNET_GETOPT_OPTION_STRING ('H',
294 gettext_noop ("name of the file with the login information for the testbed"), 303 "hosts",
295 GNUNET_YES, &GNUNET_GETOPT_set_string, &hosts_file}, 304 "FILENAME",
305 gettext_noop ("name of the file with the login information for the testbed"),
306 &hosts_file),
296#endif 307#endif
297 GNUNET_GETOPT_OPTION_END 308 GNUNET_GETOPT_OPTION_END
298 }; 309 };
diff --git a/src/testbed/test_gnunet_helper_testbed.c b/src/testbed/test_gnunet_helper_testbed.c
index 7a2dce8a5..7ba9e7c31 100644
--- a/src/testbed/test_gnunet_helper_testbed.c
+++ b/src/testbed/test_gnunet_helper_testbed.c
@@ -121,10 +121,12 @@ do_abort (void *cls)
121 * #GNUNET_SYSERR during GNUNET_HELPER_stop() 121 * #GNUNET_SYSERR during GNUNET_HELPER_stop()
122 */ 122 */
123static void 123static void
124cont_cb (void *cls, int result) 124cont_cb (void *cls,
125 int result)
125{ 126{
126 shandle = NULL; 127 shandle = NULL;
127 LOG (GNUNET_ERROR_TYPE_DEBUG, "Message sent\n"); 128 LOG (GNUNET_ERROR_TYPE_DEBUG,
129 "Message sent\n");
128 GNUNET_assert (GNUNET_OK == result); 130 GNUNET_assert (GNUNET_OK == result);
129} 131}
130 132
@@ -138,11 +140,11 @@ cont_cb (void *cls, int result)
138 * @param cls closure 140 * @param cls closure
139 * @param client identification of the client 141 * @param client identification of the client
140 * @param message the actual message 142 * @param message the actual message
141 *
142 * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing 143 * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
143 */ 144 */
144static int 145static int
145mst_cb (void *cls, void *client, const struct GNUNET_MessageHeader *message) 146mst_cb (void *cls,
147 const struct GNUNET_MessageHeader *message)
146{ 148{
147 const struct GNUNET_TESTBED_HelperReply *msg; 149 const struct GNUNET_TESTBED_HelperReply *msg;
148 char *config; 150 char *config;
@@ -207,8 +209,12 @@ run (void *cls, char *const *args, const char *cfgfile,
207 const char *trusted_ip = "127.0.0.1"; 209 const char *trusted_ip = "127.0.0.1";
208 210
209 helper = 211 helper =
210 GNUNET_HELPER_start (GNUNET_YES, "gnunet-helper-testbed", binary_argv, 212 GNUNET_HELPER_start (GNUNET_YES,
211 &mst_cb, &exp_cb, NULL); 213 "gnunet-helper-testbed",
214 binary_argv,
215 &mst_cb,
216 &exp_cb,
217 NULL);
212 GNUNET_assert (NULL != helper); 218 GNUNET_assert (NULL != helper);
213 cfg = GNUNET_CONFIGURATION_dup (cfg2); 219 cfg = GNUNET_CONFIGURATION_dup (cfg2);
214 msg = GNUNET_TESTBED_create_helper_init_msg_ (trusted_ip, NULL, cfg); 220 msg = GNUNET_TESTBED_create_helper_init_msg_ (trusted_ip, NULL, cfg);
diff --git a/src/testbed/testbed_api_hosts.c b/src/testbed/testbed_api_hosts.c
index 731944bc4..5d2c1cc37 100644
--- a/src/testbed/testbed_api_hosts.c
+++ b/src/testbed/testbed_api_hosts.c
@@ -952,10 +952,11 @@ gen_rsh_suffix_args (const char * const *append_args)
952 * @param client identification of the client 952 * @param client identification of the client
953 * @param message the actual message 953 * @param message the actual message
954 * 954 *
955 * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing 955 * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
956 */ 956 */
957static int 957static int
958helper_mst (void *cls, void *client, const struct GNUNET_MessageHeader *message) 958helper_mst (void *cls,
959 const struct GNUNET_MessageHeader *message)
959{ 960{
960 struct GNUNET_TESTBED_ControllerProc *cp = cls; 961 struct GNUNET_TESTBED_ControllerProc *cp = cls;
961 const struct GNUNET_TESTBED_HelperReply *msg; 962 const struct GNUNET_TESTBED_HelperReply *msg;
diff --git a/src/testbed/testbed_api_peers.c b/src/testbed/testbed_api_peers.c
index 2af62b44a..871e554a9 100644
--- a/src/testbed/testbed_api_peers.c
+++ b/src/testbed/testbed_api_peers.c
@@ -969,7 +969,7 @@ GNUNET_TESTBED_peer_manage_service (void *op_cls,
969 GNUNET_assert (TESTBED_PS_STARTED == peer->state); /* peer is not running? */ 969 GNUNET_assert (TESTBED_PS_STARTED == peer->state); /* peer is not running? */
970 msize = strlen (service_name) + 1; 970 msize = strlen (service_name) + 1;
971 msize += sizeof (struct GNUNET_TESTBED_ManagePeerServiceMessage); 971 msize += sizeof (struct GNUNET_TESTBED_ManagePeerServiceMessage);
972 if (GNUNET_SERVER_MAX_MESSAGE_SIZE < msize) 972 if (GNUNET_MAX_MESSAGE_SIZE < msize)
973 return NULL; 973 return NULL;
974 data = GNUNET_new (struct ManageServiceData); 974 data = GNUNET_new (struct ManageServiceData);
975 data->cb = cb; 975 data->cb = cb;
diff --git a/src/testing/gnunet-testing.c b/src/testing/gnunet-testing.c
index 07f1560cb..686b38192 100644
--- a/src/testing/gnunet-testing.c
+++ b/src/testing/gnunet-testing.c
@@ -348,17 +348,35 @@ run_no_scheduler (void *cls, char *const *args, const char *cfgfile,
348int 348int
349main (int argc, char *const *argv) 349main (int argc, char *const *argv)
350{ 350{
351 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 351 struct GNUNET_GETOPT_CommandLineOption options[] = {
352 {'C', "cfg", NULL, gettext_noop ("create unique configuration files"), 352 GNUNET_GETOPT_OPTION_SET_ONE ('C',
353 GNUNET_NO, &GNUNET_GETOPT_set_one, &create_cfg}, 353 "cfg",
354 {'k', "key", "FILENAME", gettext_noop ("extract hostkey file from pre-computed hostkey list"), 354 gettext_noop ("create unique configuration files"),
355 GNUNET_YES, &GNUNET_GETOPT_set_string, &create_hostkey}, 355 &create_cfg),
356 {'n', "number", "NUMBER", gettext_noop ("number of unique configuration files to create, or number of the hostkey to extract"), 356 GNUNET_GETOPT_OPTION_STRING ('k',
357 GNUNET_YES, &GNUNET_GETOPT_set_uint, &create_no}, 357 "key",
358 {'t', "template", "FILENAME", gettext_noop ("configuration template"), 358 "FILENAME",
359 GNUNET_YES, &GNUNET_GETOPT_set_string, &create_cfg_template}, 359 gettext_noop ("extract hostkey file from pre-computed hostkey list"),
360 {'r', "run", "SERVICE", gettext_noop ("run the given service, wait on stdin for 'r' (restart) or 'q' (quit)"), 360 &create_hostkey),
361 GNUNET_YES, &GNUNET_GETOPT_set_string, &run_service_name}, 361
362 GNUNET_GETOPT_OPTION_SET_UINT ('n',
363 "number",
364 "NUMBER",
365 gettext_noop ("number of unique configuration files to create, or number of the hostkey to extract"),
366 &create_no),
367
368
369 GNUNET_GETOPT_OPTION_STRING ('t',
370 "template",
371 "FILENAME",
372 gettext_noop ("configuration template"),
373 &create_cfg_template),
374
375 GNUNET_GETOPT_OPTION_STRING ('r',
376 "run",
377 "SERVICE",
378 gettext_noop ("run the given service, wait on stdin for 'r' (restart) or 'q' (quit)"),
379 &run_service_name),
362 GNUNET_GETOPT_OPTION_END 380 GNUNET_GETOPT_OPTION_END
363 }; 381 };
364 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 382 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
diff --git a/src/testing/list-keys.c b/src/testing/list-keys.c
index 1fd46ebf2..cfb49460a 100644
--- a/src/testing/list-keys.c
+++ b/src/testing/list-keys.c
@@ -6,10 +6,6 @@ static unsigned int nkeys;
6static unsigned int nskip; 6static unsigned int nskip;
7static int result; 7static int result;
8 8
9
10
11
12
13/** 9/**
14 * Main run function. 10 * Main run function.
15 * 11 *
@@ -87,12 +83,11 @@ run (void *cls, char *const *args, const char *cfgfile,
87int main (int argc, char *argv[]) 83int main (int argc, char *argv[])
88{ 84{
89 struct GNUNET_GETOPT_CommandLineOption option[] = { 85 struct GNUNET_GETOPT_CommandLineOption option[] = {
90 {'n', "num-keys", "COUNT", 86 GNUNET_GETOPT_OPTION_SET_UINT ('n',
91 gettext_noop ("list COUNT number of keys"), 87 "num-keys",
92 GNUNET_YES, &GNUNET_GETOPT_set_uint, &nkeys}, 88 "COUNT",
93 {'s', "skip", "COUNT", 89 gettext_noop ("list COUNT number of keys"),
94 gettext_noop ("skip COUNT number of keys in the beginning"), 90 &nkeys),
95 GNUNET_YES, &GNUNET_GETOPT_set_uint, &nskip},
96 GNUNET_GETOPT_OPTION_END 91 GNUNET_GETOPT_OPTION_END
97 }; 92 };
98 int ret; 93 int ret;
diff --git a/src/topology/gnunet-daemon-topology.c b/src/topology/gnunet-daemon-topology.c
index 067ebce23..537ffe059 100644
--- a/src/topology/gnunet-daemon-topology.c
+++ b/src/topology/gnunet-daemon-topology.c
@@ -499,7 +499,7 @@ schedule_next_hello (void *cls)
499 /* find applicable HELLOs */ 499 /* find applicable HELLOs */
500 fah.peer = pl; 500 fah.peer = pl;
501 fah.result = NULL; 501 fah.result = NULL;
502 fah.max_size = GNUNET_SERVER_MAX_MESSAGE_SIZE - 1; 502 fah.max_size = GNUNET_MAX_MESSAGE_SIZE - 1;
503 fah.next_adv = GNUNET_TIME_UNIT_FOREVER_REL; 503 fah.next_adv = GNUNET_TIME_UNIT_FOREVER_REL;
504 GNUNET_CONTAINER_multipeermap_iterate (peers, 504 GNUNET_CONTAINER_multipeermap_iterate (peers,
505 &find_advertisable_hello, 505 &find_advertisable_hello,
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index acc2557c6..7687f2348 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -191,6 +191,8 @@ libexec_PROGRAMS = \
191 $(BT_BIN) \ 191 $(BT_BIN) \
192 gnunet-service-transport 192 gnunet-service-transport
193 193
194
195
194bin_PROGRAMS = \ 196bin_PROGRAMS = \
195 gnunet-transport \ 197 gnunet-transport \
196 gnunet-transport-certificate-creation 198 gnunet-transport-certificate-creation
@@ -561,7 +563,7 @@ TESTS = \
561 $(HTTP_API_TIMEOUT_TEST) \ 563 $(HTTP_API_TIMEOUT_TEST) \
562 $(HTTPS_API_TIMEOUT_TEST) \ 564 $(HTTPS_API_TIMEOUT_TEST) \
563 $(WLAN_TIMEOUT_TEST) \ 565 $(WLAN_TIMEOUT_TEST) \
564 $(BT_TIMEOUT_TEST) 566 $(BT_TIMEOUT_TEST)
565if HAVE_GETOPT_BINARY 567if HAVE_GETOPT_BINARY
566TESTS += \ 568TESTS += \
567test_transport_api_slow_ats 569test_transport_api_slow_ats
diff --git a/src/transport/gnunet-helper-transport-wlan-dummy.c b/src/transport/gnunet-helper-transport-wlan-dummy.c
index 684546314..63ed9c4b7 100644
--- a/src/transport/gnunet-helper-transport-wlan-dummy.c
+++ b/src/transport/gnunet-helper-transport-wlan-dummy.c
@@ -120,11 +120,11 @@ send_mac_to_plugin (char *buffer, struct GNUNET_TRANSPORT_WLAN_MacAddress *mac)
120 * type to the output forward and copy it to the buffer for stdout. 120 * type to the output forward and copy it to the buffer for stdout.
121 * 121 *
122 * @param cls the 'struct SendBuffer' to copy the converted message to 122 * @param cls the 'struct SendBuffer' to copy the converted message to
123 * @param client unused
124 * @param hdr inbound message from the FIFO 123 * @param hdr inbound message from the FIFO
125 */ 124 */
126static int 125static int
127stdin_send (void *cls, void *client, const struct GNUNET_MessageHeader *hdr) 126stdin_send (void *cls,
127 const struct GNUNET_MessageHeader *hdr)
128{ 128{
129 struct SendBuffer *write_pout = cls; 129 struct SendBuffer *write_pout = cls;
130 const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *in; 130 const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *in;
@@ -166,11 +166,11 @@ stdin_send (void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
166 * We read a full message from stdin. Copy it to our send buffer. 166 * We read a full message from stdin. Copy it to our send buffer.
167 * 167 *
168 * @param cls the 'struct SendBuffer' to copy to 168 * @param cls the 'struct SendBuffer' to copy to
169 * @param client unused
170 * @param hdr the message we received to copy to the buffer 169 * @param hdr the message we received to copy to the buffer
171 */ 170 */
172static int 171static int
173file_in_send (void *cls, void *client, const struct GNUNET_MessageHeader *hdr) 172file_in_send (void *cls,
173 const struct GNUNET_MessageHeader *hdr)
174{ 174{
175 struct SendBuffer *write_std = cls; 175 struct SendBuffer *write_std = cls;
176 uint16_t sendsize; 176 uint16_t sendsize;
@@ -213,8 +213,8 @@ main (int argc, char *argv[])
213 fd_set wfds; 213 fd_set wfds;
214 struct timeval tv; 214 struct timeval tv;
215 int retval; 215 int retval;
216 struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst = NULL; 216 struct GNUNET_MessageStreamTokenizer *stdin_mst = NULL;
217 struct GNUNET_SERVER_MessageStreamTokenizer *file_in_mst = NULL; 217 struct GNUNET_MessageStreamTokenizer *file_in_mst = NULL;
218 struct GNUNET_TRANSPORT_WLAN_MacAddress macaddr; 218 struct GNUNET_TRANSPORT_WLAN_MacAddress macaddr;
219 int first; 219 int first;
220 220
@@ -340,8 +340,8 @@ main (int argc, char *argv[])
340 write_std.pos = 0; 340 write_std.pos = 0;
341 write_pout.size = 0; 341 write_pout.size = 0;
342 write_pout.pos = 0; 342 write_pout.pos = 0;
343 stdin_mst = GNUNET_SERVER_mst_create (&stdin_send, &write_pout); 343 stdin_mst = GNUNET_MST_create (&stdin_send, &write_pout);
344 file_in_mst = GNUNET_SERVER_mst_create (&file_in_send, &write_std); 344 file_in_mst = GNUNET_MST_create (&file_in_send, &write_std);
345 345
346 /* Send 'random' mac address */ 346 /* Send 'random' mac address */
347 macaddr.mac[0] = 0x13; 347 macaddr.mac[0] = 0x13;
@@ -453,8 +453,9 @@ main (int argc, char *argv[])
453 } 453 }
454 else if (0 < readsize) 454 else if (0 < readsize)
455 { 455 {
456 GNUNET_SERVER_mst_receive (stdin_mst, NULL, readbuf, readsize, 456 GNUNET_MST_from_buffer (stdin_mst,
457 GNUNET_NO, GNUNET_NO); 457 readbuf, readsize,
458 GNUNET_NO, GNUNET_NO);
458 459
459 } 460 }
460 else 461 else
@@ -475,8 +476,9 @@ main (int argc, char *argv[])
475 } 476 }
476 else if (0 < readsize) 477 else if (0 < readsize)
477 { 478 {
478 GNUNET_SERVER_mst_receive (file_in_mst, NULL, readbuf, readsize, 479 GNUNET_MST_from_buffer (file_in_mst,
479 GNUNET_NO, GNUNET_NO); 480 readbuf, readsize,
481 GNUNET_NO, GNUNET_NO);
480 } 482 }
481 else 483 else
482 { 484 {
@@ -489,9 +491,9 @@ main (int argc, char *argv[])
489end: 491end:
490 /* clean up */ 492 /* clean up */
491 if (NULL != stdin_mst) 493 if (NULL != stdin_mst)
492 GNUNET_SERVER_mst_destroy (stdin_mst); 494 GNUNET_MST_destroy (stdin_mst);
493 if (NULL != file_in_mst) 495 if (NULL != file_in_mst)
494 GNUNET_SERVER_mst_destroy (file_in_mst); 496 GNUNET_MST_destroy (file_in_mst);
495 497
496 if (NULL != fpout) 498 if (NULL != fpout)
497 fclose (fpout); 499 fclose (fpout);
diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c
index 505626b59..4a6d427be 100644
--- a/src/transport/gnunet-service-transport_validation.c
+++ b/src/transport/gnunet-service-transport_validation.c
@@ -599,7 +599,7 @@ transmit_ping_if_allowed (void *cls,
599 ping.challenge = htonl (ve->challenge); 599 ping.challenge = htonl (ve->challenge);
600 ping.target = *pid; 600 ping.target = *pid;
601 601
602 if (tsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 602 if (tsize >= GNUNET_MAX_MESSAGE_SIZE)
603 { 603 {
604 GNUNET_break (0); 604 GNUNET_break (0);
605 hsize = 0; 605 hsize = 0;
diff --git a/src/transport/gnunet-transport-profiler.c b/src/transport/gnunet-transport-profiler.c
index dceff7e3b..9292c42d4 100644
--- a/src/transport/gnunet-transport-profiler.c
+++ b/src/transport/gnunet-transport-profiler.c
@@ -151,7 +151,7 @@ static struct GNUNET_PeerIdentity pid;
151/** 151/**
152 * Selected level of verbosity. 152 * Selected level of verbosity.
153 */ 153 */
154static int verbosity; 154static unsigned int verbosity;
155 155
156 156
157/** 157/**
@@ -520,7 +520,7 @@ run (void *cls,
520 cfg = (struct GNUNET_CONFIGURATION_Handle *) mycfg; 520 cfg = (struct GNUNET_CONFIGURATION_Handle *) mycfg;
521 521
522 ret = 1; 522 ret = 1;
523 if (GNUNET_SERVER_MAX_MESSAGE_SIZE <= benchmark_size) 523 if (GNUNET_MAX_MESSAGE_SIZE <= benchmark_size)
524 { 524 {
525 FPRINTF (stderr, 525 FPRINTF (stderr,
526 "Message size too big!\n"); 526 "Message size too big!\n");
@@ -610,26 +610,36 @@ main (int argc, char * const *argv)
610 benchmark_iterations = DEFAULT_ITERATION_COUNT; 610 benchmark_iterations = DEFAULT_ITERATION_COUNT;
611 benchmark_running = GNUNET_NO; 611 benchmark_running = GNUNET_NO;
612 612
613 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 613 struct GNUNET_GETOPT_CommandLineOption options[] = {
614 614
615 { 's', "send", NULL, 615 GNUNET_GETOPT_OPTION_SET_ONE ('s',
616 gettext_noop ("send data to peer"), 616 "send",
617 0, &GNUNET_GETOPT_set_one, &benchmark_send}, 617 gettext_noop ("send data to peer"),
618 { 'r', "receive", NULL, gettext_noop 618 &benchmark_send),
619 ("receive data from peer"), 0, 619 GNUNET_GETOPT_OPTION_SET_ONE ('r',
620 &GNUNET_GETOPT_set_one, &benchmark_receive}, 620 "receive",
621 { 'i', "iterations", NULL, gettext_noop 621 gettext_noop ("receive data from peer"),
622 ("iterations"), 1, 622 &benchmark_receive),
623 &GNUNET_GETOPT_set_uint, &benchmark_iterations}, 623 GNUNET_GETOPT_OPTION_SET_UINT ('i',
624 { 'n', "number", NULL, gettext_noop 624 "iterations",
625 ("number of messages to send"), 1, 625 NULL,
626 &GNUNET_GETOPT_set_uint, &benchmark_count}, 626 gettext_noop ("iterations"),
627 { 'm', "messagesize", NULL, gettext_noop 627 &benchmark_iterations),
628 ("message size to use"), 1, 628 GNUNET_GETOPT_OPTION_SET_UINT ('n',
629 &GNUNET_GETOPT_set_uint, &benchmark_size}, 629 "number",
630 { 'p', "peer", "PEER", 630 NULL,
631 gettext_noop ("peer identity"), 1, &GNUNET_GETOPT_set_string, 631 gettext_noop ("number of messages to send"),
632 &cpid }, 632 &benchmark_count),
633 GNUNET_GETOPT_OPTION_SET_UINT ('m',
634 "messagesize",
635 NULL,
636 gettext_noop ("message size to use"),
637 &benchmark_size),
638 GNUNET_GETOPT_OPTION_STRING ('p',
639 "peer",
640 "PEER",
641 gettext_noop ("peer identity"),
642 &cpid),
633 GNUNET_GETOPT_OPTION_VERBOSE (&verbosity), 643 GNUNET_GETOPT_OPTION_VERBOSE (&verbosity),
634 GNUNET_GETOPT_OPTION_END 644 GNUNET_GETOPT_OPTION_END
635 }; 645 };
diff --git a/src/transport/gnunet-transport.c b/src/transport/gnunet-transport.c
index fcfc94ac8..8624b09b4 100644
--- a/src/transport/gnunet-transport.c
+++ b/src/transport/gnunet-transport.c
@@ -167,11 +167,6 @@ struct PeerResolutionContext
167#define BLOCKSIZE 4 167#define BLOCKSIZE 4
168 168
169/** 169/**
170 * Which peer should we connect to?
171 */
172static char *cpid;
173
174/**
175 * Handle to transport service. 170 * Handle to transport service.
176 */ 171 */
177static struct GNUNET_TRANSPORT_CoreHandle *handle; 172static struct GNUNET_TRANSPORT_CoreHandle *handle;
@@ -283,7 +278,7 @@ static struct GNUNET_TRANSPORT_PluginMonitor *pm;
283 278
284/** 279/**
285 * Identity of the peer we transmit to / connect to. 280 * Identity of the peer we transmit to / connect to.
286 * (equivalent to 'cpid' string). 281 * ('-p' command-line option).
287 */ 282 */
288static struct GNUNET_PeerIdentity pid; 283static struct GNUNET_PeerIdentity pid;
289 284
@@ -295,7 +290,7 @@ static struct GNUNET_SCHEDULER_Task *op_timeout;
295/** 290/**
296 * Selected level of verbosity. 291 * Selected level of verbosity.
297 */ 292 */
298static int verbosity; 293static unsigned int verbosity;
299 294
300/** 295/**
301 * Resolver process handle. 296 * Resolver process handle.
@@ -485,7 +480,7 @@ operation_timeout (void *cls)
485 _("Failed to resolve address for peer `%s'\n"), 480 _("Failed to resolve address for peer `%s'\n"),
486 GNUNET_i2s (&cur->addrcp->peer)); 481 GNUNET_i2s (&cur->addrcp->peer));
487 482
488 GNUNET_CONTAINER_DLL_remove(rc_head, 483 GNUNET_CONTAINER_DLL_remove(rc_head,
489 rc_tail, 484 rc_tail,
490 cur); 485 cur);
491 GNUNET_TRANSPORT_address_to_string_cancel (cur->asc); 486 GNUNET_TRANSPORT_address_to_string_cancel (cur->asc);
@@ -729,7 +724,7 @@ print_info (const struct GNUNET_PeerIdentity *id,
729 GNUNET_STRINGS_absolute_time_to_string (state_timeout)); 724 GNUNET_STRINGS_absolute_time_to_string (state_timeout));
730 } 725 }
731 else if ( (GNUNET_YES == iterate_connections) && 726 else if ( (GNUNET_YES == iterate_connections) &&
732 (GNUNET_TRANSPORT_is_connected(state)) ) 727 (GNUNET_TRANSPORT_is_connected(state)) )
733 { 728 {
734 /* Only connected peers, skip state */ 729 /* Only connected peers, skip state */
735 FPRINTF (stdout, 730 FPRINTF (stdout,
@@ -1089,10 +1084,9 @@ plugin_monitoring_cb (void *cls,
1089 } 1084 }
1090 return; /* shutdown */ 1085 return; /* shutdown */
1091 } 1086 }
1092 if ( (NULL != cpid) && 1087 if (0 != memcmp (&info->address->peer,
1093 (0 != memcmp (&info->address->peer, 1088 &pid,
1094 cpid, 1089 sizeof (struct GNUNET_PeerIdentity)))
1095 sizeof (struct GNUNET_PeerIdentity))) )
1096 return; /* filtered */ 1090 return; /* filtered */
1097 if (NULL == addr) 1091 if (NULL == addr)
1098 { 1092 {
@@ -1241,21 +1235,11 @@ run (void *cls,
1241 const char *cfgfile, 1235 const char *cfgfile,
1242 const struct GNUNET_CONFIGURATION_Handle *mycfg) 1236 const struct GNUNET_CONFIGURATION_Handle *mycfg)
1243{ 1237{
1238 static struct GNUNET_PeerIdentity zero_pid;
1244 int counter = 0; 1239 int counter = 0;
1245 ret = 1; 1240 ret = 1;
1246 1241
1247 cfg = (struct GNUNET_CONFIGURATION_Handle *) mycfg; 1242 cfg = (struct GNUNET_CONFIGURATION_Handle *) mycfg;
1248 if ( (NULL != cpid) &&
1249 (GNUNET_OK !=
1250 GNUNET_CRYPTO_eddsa_public_key_from_string (cpid,
1251 strlen (cpid),
1252 &pid.public_key)))
1253 {
1254 FPRINTF (stderr,
1255 _("Failed to parse peer identity `%s'\n"),
1256 cpid);
1257 return;
1258 }
1259 1243
1260 counter = benchmark_send + benchmark_receive + iterate_connections 1244 counter = benchmark_send + benchmark_receive + iterate_connections
1261 + monitor_connections + monitor_connects + do_disconnect + 1245 + monitor_connections + monitor_connects + do_disconnect +
@@ -1290,7 +1274,9 @@ run (void *cls,
1290 1274
1291 if (do_disconnect) /* -D: Disconnect from peer */ 1275 if (do_disconnect) /* -D: Disconnect from peer */
1292 { 1276 {
1293 if (NULL == cpid) 1277 if (0 == memcmp (&zero_pid,
1278 &pid,
1279 sizeof (pid)))
1294 { 1280 {
1295 FPRINTF (stderr, 1281 FPRINTF (stderr,
1296 _("Option `%s' makes no sense without option `%s'.\n"), 1282 _("Option `%s' makes no sense without option `%s'.\n"),
@@ -1315,7 +1301,9 @@ run (void *cls,
1315 } 1301 }
1316 else if (benchmark_send) /* -s: Benchmark sending */ 1302 else if (benchmark_send) /* -s: Benchmark sending */
1317 { 1303 {
1318 if (NULL == cpid) 1304 if (0 == memcmp (&zero_pid,
1305 &pid,
1306 sizeof (pid)))
1319 { 1307 {
1320 FPRINTF (stderr, 1308 FPRINTF (stderr,
1321 _("Option `%s' makes no sense without option `%s'.\n"), 1309 _("Option `%s' makes no sense without option `%s'.\n"),
@@ -1352,7 +1340,7 @@ run (void *cls,
1352 NULL), 1340 NULL),
1353 GNUNET_MQ_handler_end () 1341 GNUNET_MQ_handler_end ()
1354 }; 1342 };
1355 1343
1356 handle = GNUNET_TRANSPORT_core_connect (cfg, 1344 handle = GNUNET_TRANSPORT_core_connect (cfg,
1357 NULL, 1345 NULL,
1358 handlers, 1346 handlers,
@@ -1378,7 +1366,7 @@ run (void *cls,
1378 else if (iterate_connections) /* -i: List information about peers once */ 1366 else if (iterate_connections) /* -i: List information about peers once */
1379 { 1367 {
1380 pic = GNUNET_TRANSPORT_monitor_peers (cfg, 1368 pic = GNUNET_TRANSPORT_monitor_peers (cfg,
1381 (NULL == cpid) ? NULL : &pid, 1369 &pid,
1382 GNUNET_YES, 1370 GNUNET_YES,
1383 &process_peer_iteration_cb, 1371 &process_peer_iteration_cb,
1384 (void *) cfg); 1372 (void *) cfg);
@@ -1391,7 +1379,7 @@ run (void *cls,
1391 monitored_peers = GNUNET_CONTAINER_multipeermap_create (10, 1379 monitored_peers = GNUNET_CONTAINER_multipeermap_create (10,
1392 GNUNET_NO); 1380 GNUNET_NO);
1393 pic = GNUNET_TRANSPORT_monitor_peers (cfg, 1381 pic = GNUNET_TRANSPORT_monitor_peers (cfg,
1394 (NULL == cpid) ? NULL : &pid, 1382 &pid,
1395 GNUNET_NO, 1383 GNUNET_NO,
1396 &process_peer_monitoring_cb, 1384 &process_peer_monitoring_cb,
1397 NULL); 1385 NULL);
@@ -1439,37 +1427,49 @@ main (int argc,
1439 char * const *argv) 1427 char * const *argv)
1440{ 1428{
1441 int res; 1429 int res;
1442 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 1430 struct GNUNET_GETOPT_CommandLineOption options[] = {
1443 { 'a', "all", NULL, 1431 GNUNET_GETOPT_OPTION_SET_ONE ('a',
1444 gettext_noop ("print information for all peers (instead of only connected peers)"), 1432 "all",
1445 0, &GNUNET_GETOPT_set_one, &iterate_all }, 1433 gettext_noop ("print information for all peers (instead of only connected peers)"),
1446 { 'b', "benchmark", NULL, 1434 &iterate_all),
1447 gettext_noop ("measure how fast we are receiving data from all peers (until CTRL-C)"), 1435 GNUNET_GETOPT_OPTION_SET_ONE ('b',
1448 0, &GNUNET_GETOPT_set_one, &benchmark_receive }, 1436 "benchmark",
1449 { 'D', "disconnect", 1437 gettext_noop ("measure how fast we are receiving data from all peers (until CTRL-C)"),
1450 NULL, gettext_noop ("disconnect from a peer"), 0, 1438 &benchmark_receive),
1451 &GNUNET_GETOPT_set_one, &do_disconnect }, 1439 GNUNET_GETOPT_OPTION_SET_ONE ('D',
1452 { 'i', "information", NULL, 1440 "disconnect",
1453 gettext_noop ("provide information about all current connections (once)"), 1441 gettext_noop ("disconnect from a peer"),
1454 0, &GNUNET_GETOPT_set_one, &iterate_connections }, 1442 &do_disconnect),
1455 { 'm', "monitor", NULL, 1443 GNUNET_GETOPT_OPTION_SET_ONE ('i',
1456 gettext_noop ("provide information about all current connections (continuously)"), 1444 "information",
1457 0, &GNUNET_GETOPT_set_one, &monitor_connections }, 1445 gettext_noop ("provide information about all current connections (once)"),
1458 { 'e', "events", NULL, 1446 &iterate_connections),
1459 gettext_noop ("provide information about all connects and disconnect events (continuously)"), 1447 GNUNET_GETOPT_OPTION_SET_ONE ('m',
1460 0, &GNUNET_GETOPT_set_one, &monitor_connects }, 1448 "monitor",
1461 { 'n', "numeric", 1449 gettext_noop ("provide information about all current connections (continuously)"),
1462 NULL, gettext_noop ("do not resolve hostnames"), 0, 1450 &monitor_connections),
1463 &GNUNET_GETOPT_set_one, &numeric }, 1451 GNUNET_GETOPT_OPTION_SET_ONE ('e',
1464 { 'p', "peer", "PEER", 1452 "events",
1465 gettext_noop ("peer identity"), 1, &GNUNET_GETOPT_set_string, 1453 gettext_noop ("provide information about all connects and disconnect events (continuously)"),
1466 &cpid }, 1454 &monitor_connects),
1467 { 'P', "plugins", NULL, 1455 GNUNET_GETOPT_OPTION_SET_ONE ('n',
1468 gettext_noop ("monitor plugin sessions"), 0, &GNUNET_GETOPT_set_one, 1456 "numeric",
1469 &monitor_plugins }, 1457 gettext_noop ("do not resolve hostnames"),
1470 { 's', "send", NULL, gettext_noop 1458 &numeric),
1471 ("send data for benchmarking to the other peer (until CTRL-C)"), 0, 1459 GNUNET_GETOPT_OPTION_SET_BASE32_AUTO ('p',
1472 &GNUNET_GETOPT_set_one, &benchmark_send }, 1460 "peer",
1461 "PEER",
1462 gettext_noop ("peer identity"),
1463 &pid),
1464 GNUNET_GETOPT_OPTION_SET_ONE ('P',
1465 "plugins",
1466 gettext_noop ("monitor plugin sessions"),
1467 &monitor_plugins),
1468 GNUNET_GETOPT_OPTION_SET_ONE ('s',
1469 "send",
1470 gettext_noop
1471 ("send data for benchmarking to the other peer (until CTRL-C)"),
1472 &benchmark_send),
1473 GNUNET_GETOPT_OPTION_VERBOSE (&verbosity), 1473 GNUNET_GETOPT_OPTION_VERBOSE (&verbosity),
1474 GNUNET_GETOPT_OPTION_END 1474 GNUNET_GETOPT_OPTION_END
1475 }; 1475 };
diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c
index ceed94af8..e20948c5a 100644
--- a/src/transport/plugin_transport_http_client.c
+++ b/src/transport/plugin_transport_http_client.c
@@ -221,7 +221,7 @@ struct GNUNET_ATS_Session
221 /** 221 /**
222 * Message stream tokenizer for incoming data 222 * Message stream tokenizer for incoming data
223 */ 223 */
224 struct GNUNET_SERVER_MessageStreamTokenizer *msg_tk; 224 struct GNUNET_MessageStreamTokenizer *msg_tk;
225 225
226 /** 226 /**
227 * Session timeout task 227 * Session timeout task
@@ -528,7 +528,7 @@ client_delete_session (struct GNUNET_ATS_Session *s)
528 GNUNET_TRANSPORT_SS_DONE); 528 GNUNET_TRANSPORT_SS_DONE);
529 if (NULL != s->msg_tk) 529 if (NULL != s->msg_tk)
530 { 530 {
531 GNUNET_SERVER_mst_destroy (s->msg_tk); 531 GNUNET_MST_destroy (s->msg_tk);
532 s->msg_tk = NULL; 532 s->msg_tk = NULL;
533 } 533 }
534 GNUNET_HELLO_address_free (s->address); 534 GNUNET_HELLO_address_free (s->address);
@@ -1158,13 +1158,11 @@ client_wake_up (void *cls)
1158 * Callback for message stream tokenizer 1158 * Callback for message stream tokenizer
1159 * 1159 *
1160 * @param cls the session 1160 * @param cls the session
1161 * @param client not used
1162 * @param message the message received 1161 * @param message the message received
1163 * @return always #GNUNET_OK 1162 * @return always #GNUNET_OK
1164 */ 1163 */
1165static int 1164static int
1166client_receive_mst_cb (void *cls, 1165client_receive_mst_cb (void *cls,
1167 void *client,
1168 const struct GNUNET_MessageHeader *message) 1166 const struct GNUNET_MessageHeader *message)
1169{ 1167{
1170 struct GNUNET_ATS_Session *s = cls; 1168 struct GNUNET_ATS_Session *s = cls;
@@ -1274,14 +1272,13 @@ client_receive (void *stream,
1274 return CURL_WRITEFUNC_PAUSE; 1272 return CURL_WRITEFUNC_PAUSE;
1275 } 1273 }
1276 if (NULL == s->msg_tk) 1274 if (NULL == s->msg_tk)
1277 s->msg_tk = GNUNET_SERVER_mst_create (&client_receive_mst_cb, 1275 s->msg_tk = GNUNET_MST_create (&client_receive_mst_cb,
1278 s); 1276 s);
1279 GNUNET_SERVER_mst_receive (s->msg_tk, 1277 GNUNET_MST_from_buffer (s->msg_tk,
1280 s, 1278 stream,
1281 stream, 1279 len,
1282 len, 1280 GNUNET_NO,
1283 GNUNET_NO, 1281 GNUNET_NO);
1284 GNUNET_NO);
1285 return len; 1282 return len;
1286} 1283}
1287 1284
@@ -1641,7 +1638,7 @@ client_connect_get (struct GNUNET_ATS_Session *s)
1641 CURLOPT_CONNECTTIMEOUT_MS, 1638 CURLOPT_CONNECTTIMEOUT_MS,
1642 (long) (HTTP_CLIENT_NOT_VALIDATED_TIMEOUT.rel_value_us / 1000LL)); 1639 (long) (HTTP_CLIENT_NOT_VALIDATED_TIMEOUT.rel_value_us / 1000LL));
1643 curl_easy_setopt (s->get.easyhandle, CURLOPT_BUFFERSIZE, 1640 curl_easy_setopt (s->get.easyhandle, CURLOPT_BUFFERSIZE,
1644 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE); 1641 2 * GNUNET_MAX_MESSAGE_SIZE);
1645#if CURL_TCP_NODELAY 1642#if CURL_TCP_NODELAY
1646 curl_easy_setopt (ps->recv_endpoint, 1643 curl_easy_setopt (ps->recv_endpoint,
1647 CURLOPT_TCP_NODELAY, 1644 CURLOPT_TCP_NODELAY,
@@ -1818,7 +1815,7 @@ client_connect_put (struct GNUNET_ATS_Session *s)
1818 CURLOPT_CONNECTTIMEOUT_MS, 1815 CURLOPT_CONNECTTIMEOUT_MS,
1819 (long) (HTTP_CLIENT_NOT_VALIDATED_TIMEOUT.rel_value_us / 1000LL)); 1816 (long) (HTTP_CLIENT_NOT_VALIDATED_TIMEOUT.rel_value_us / 1000LL));
1820 curl_easy_setopt (s->put.easyhandle, CURLOPT_BUFFERSIZE, 1817 curl_easy_setopt (s->put.easyhandle, CURLOPT_BUFFERSIZE,
1821 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE); 1818 2 * GNUNET_MAX_MESSAGE_SIZE);
1822#if CURL_TCP_NODELAY 1819#if CURL_TCP_NODELAY
1823 curl_easy_setopt (s->put.easyhandle, CURLOPT_TCP_NODELAY, 1); 1820 curl_easy_setopt (s->put.easyhandle, CURLOPT_TCP_NODELAY, 1);
1824#endif 1821#endif
diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c
index 63c67b81c..ff2d68602 100644
--- a/src/transport/plugin_transport_http_server.c
+++ b/src/transport/plugin_transport_http_server.c
@@ -201,7 +201,7 @@ struct GNUNET_ATS_Session
201 /** 201 /**
202 * Message stream tokenizer for incoming data 202 * Message stream tokenizer for incoming data
203 */ 203 */
204 struct GNUNET_SERVER_MessageStreamTokenizer *msg_tk; 204 struct GNUNET_MessageStreamTokenizer *msg_tk;
205 205
206 /** 206 /**
207 * Client recv handle 207 * Client recv handle
@@ -608,7 +608,7 @@ server_delete_session (struct GNUNET_ATS_Session *s)
608 } 608 }
609 if (NULL != s->msg_tk) 609 if (NULL != s->msg_tk)
610 { 610 {
611 GNUNET_SERVER_mst_destroy (s->msg_tk); 611 GNUNET_MST_destroy (s->msg_tk);
612 s->msg_tk = NULL; 612 s->msg_tk = NULL;
613 } 613 }
614 GNUNET_HELLO_address_free (s->address); 614 GNUNET_HELLO_address_free (s->address);
@@ -1621,13 +1621,11 @@ server_send_callback (void *cls,
1621 * Callback called by MessageStreamTokenizer when a message has arrived 1621 * Callback called by MessageStreamTokenizer when a message has arrived
1622 * 1622 *
1623 * @param cls current session as closure 1623 * @param cls current session as closure
1624 * @param client client
1625 * @param message the message to be forwarded to transport service 1624 * @param message the message to be forwarded to transport service
1626 * @return #GNUNET_OK 1625 * @return #GNUNET_OK
1627 */ 1626 */
1628static int 1627static int
1629server_receive_mst_cb (void *cls, 1628server_receive_mst_cb (void *cls,
1630 void *client,
1631 const struct GNUNET_MessageHeader *message) 1629 const struct GNUNET_MessageHeader *message)
1632{ 1630{
1633 struct GNUNET_ATS_Session *s = cls; 1631 struct GNUNET_ATS_Session *s = cls;
@@ -1847,13 +1845,16 @@ server_access_cb (void *cls,
1847 *upload_data_size); 1845 *upload_data_size);
1848 if (s->msg_tk == NULL) 1846 if (s->msg_tk == NULL)
1849 { 1847 {
1850 s->msg_tk = GNUNET_SERVER_mst_create (&server_receive_mst_cb, s); 1848 s->msg_tk = GNUNET_MST_create (&server_receive_mst_cb,
1849 s);
1851 } 1850 }
1852 GNUNET_SERVER_mst_receive (s->msg_tk, s, upload_data, *upload_data_size, 1851 GNUNET_MST_from_buffer (s->msg_tk,
1853 GNUNET_NO, GNUNET_NO); 1852 upload_data,
1853 *upload_data_size,
1854 GNUNET_NO, GNUNET_NO);
1854 server_mhd_connection_timeout (plugin, s, 1855 server_mhd_connection_timeout (plugin, s,
1855 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value_us / 1000LL 1856 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value_us / 1000LL
1856 / 1000LL); 1857 / 1000LL);
1857 (*upload_data_size) = 0; 1858 (*upload_data_size) = 0;
1858 } 1859 }
1859 else 1860 else
@@ -1935,7 +1936,7 @@ server_disconnect_cb (void *cls,
1935 sc->session->server_recv = NULL; 1936 sc->session->server_recv = NULL;
1936 if (NULL != sc->session->msg_tk) 1937 if (NULL != sc->session->msg_tk)
1937 { 1938 {
1938 GNUNET_SERVER_mst_destroy (sc->session->msg_tk); 1939 GNUNET_MST_destroy (sc->session->msg_tk);
1939 sc->session->msg_tk = NULL; 1940 sc->session->msg_tk = NULL;
1940 } 1941 }
1941 } 1942 }
@@ -2223,7 +2224,7 @@ run_mhd_start_daemon (struct HTTP_Server_Plugin *plugin,
2223 timeout, 2224 timeout,
2224 MHD_OPTION_CONNECTION_MEMORY_LIMIT, 2225 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
2225 (size_t) (2 * 2226 (size_t) (2 *
2226 GNUNET_SERVER_MAX_MESSAGE_SIZE), 2227 GNUNET_MAX_MESSAGE_SIZE),
2227 MHD_OPTION_NOTIFY_COMPLETED, 2228 MHD_OPTION_NOTIFY_COMPLETED,
2228 &server_disconnect_cb, plugin, 2229 &server_disconnect_cb, plugin,
2229 MHD_OPTION_EXTERNAL_LOGGER, 2230 MHD_OPTION_EXTERNAL_LOGGER,
@@ -2757,7 +2758,7 @@ server_start_report_addresses (struct HTTP_Server_Plugin *plugin)
2757 return; 2758 return;
2758 } 2759 }
2759 2760
2760 plugin->nat 2761 plugin->nat
2761 = GNUNET_NAT_register (plugin->env->cfg, 2762 = GNUNET_NAT_register (plugin->env->cfg,
2762 "transport-http_server", 2763 "transport-http_server",
2763 IPPROTO_TCP, 2764 IPPROTO_TCP,
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c
index 34bbd00e0..a63013caa 100644
--- a/src/transport/plugin_transport_tcp.c
+++ b/src/transport/plugin_transport_tcp.c
@@ -45,10 +45,538 @@
45 */ 45 */
46#define NAT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) 46#define NAT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
47 47
48GNUNET_NETWORK_STRUCT_BEGIN 48/**
49 * Opaque handle that can be used to cancel
50 * a transmit-ready notification.
51 */
52struct GNUNET_CONNECTION_TransmitHandle;
53
54/**
55 * @brief handle for a server
56 */
57struct GNUNET_SERVER_Handle;
58
59/**
60 * @brief opaque handle for a client of the server
61 */
62struct GNUNET_SERVER_Client;
63
64/**
65 * @brief opaque handle server returns for aborting transmission to a client.
66 */
67struct GNUNET_SERVER_TransmitHandle;
68
69/**
70 * @brief handle for a network connection
71 */
72struct GNUNET_CONNECTION_Handle;
73
74/**
75 * @brief handle for a network service
76 */
77struct LEGACY_SERVICE_Context;
78
79
80/**
81 * Stops a service that was started with #GNUNET_SERVICE_start().
82 *
83 * @param srv service to stop
84 */
85void
86LEGACY_SERVICE_stop (struct LEGACY_SERVICE_Context *srv);
87
88
89
90/**
91 * Function called to notify a client about the connection begin ready
92 * to queue more data. @a buf will be NULL and @a size zero if the
93 * connection was closed for writing in the meantime.
94 *
95 * @param cls closure
96 * @param size number of bytes available in @a buf
97 * @param buf where the callee should write the message
98 * @return number of bytes written to @a buf
99 */
100typedef size_t
101(*GNUNET_CONNECTION_TransmitReadyNotify) (void *cls,
102 size_t size,
103 void *buf);
104
105/**
106 * Credentials for UNIX domain sockets.
107 */
108struct GNUNET_CONNECTION_Credentials
109{
110 /**
111 * UID of the other end of the connection.
112 */
113 uid_t uid;
114
115 /**
116 * GID of the other end of the connection.
117 */
118 gid_t gid;
119};
120
121
122/**
123 * Functions with this signature are called whenever a client
124 * is disconnected on the network level.
125 *
126 * @param cls closure
127 * @param client identification of the client; NULL
128 * for the last call when the server is destroyed
129 */
130typedef void
131(*GNUNET_SERVER_DisconnectCallback) (void *cls,
132 struct GNUNET_SERVER_Client *client);
133
134
135/**
136 * Functions with this signature are called whenever a client
137 * is connected on the network level.
138 *
139 * @param cls closure
140 * @param client identification of the client
141 */
142typedef void
143(*GNUNET_SERVER_ConnectCallback) (void *cls,
144 struct GNUNET_SERVER_Client *client);
145
146
147
148
149/**
150 * Function to call for access control checks.
151 *
152 * @param cls closure
153 * @param ucred credentials, if available, otherwise NULL
154 * @param addr address
155 * @param addrlen length of address
156 * @return GNUNET_YES to allow, GNUNET_NO to deny, GNUNET_SYSERR
157 * for unknown address family (will be denied).
158 */
159typedef int
160(*GNUNET_CONNECTION_AccessCheck) (void *cls,
161 const struct
162 GNUNET_CONNECTION_Credentials *
163 ucred,
164 const struct sockaddr * addr,
165 socklen_t addrlen);
166
167/**
168 * Callback function for data received from the network. Note that
169 * both "available" and "err" would be 0 if the read simply timed out.
170 *
171 * @param cls closure
172 * @param buf pointer to received data
173 * @param available number of bytes availabe in "buf",
174 * possibly 0 (on errors)
175 * @param addr address of the sender
176 * @param addrlen size of addr
177 * @param errCode value of errno (on errors receiving)
178 */
179typedef void
180(*GNUNET_CONNECTION_Receiver) (void *cls, const void *buf,
181 size_t available,
182 const struct sockaddr * addr,
183 socklen_t addrlen, int errCode);
184
185
186
187/**
188 * Close the connection and free associated resources. There must
189 * not be any pending requests for reading or writing to the
190 * connection at this time.
191 *
192 * @param connection connection to destroy
193 */
194void
195GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection);
196
197
198/**
199 * Signature of a function to create a custom tokenizer.
200 *
201 * @param cls closure from #GNUNET_SERVER_set_callbacks
202 * @param client handle to client the tokenzier will be used for
203 * @return handle to custom tokenizer ('mst')
204 */
205typedef void*
206(*GNUNET_SERVER_MstCreateCallback) (void *cls,
207 struct GNUNET_SERVER_Client *client);
208
209
210/**
211 * Signature of a function to destroy a custom tokenizer.
212 *
213 * @param cls closure from #GNUNET_SERVER_set_callbacks
214 * @param mst custom tokenizer handle
215 */
216typedef void
217(*GNUNET_SERVER_MstDestroyCallback) (void *cls,
218 void *mst);
219
220/**
221 * Signature of a function to receive data for a custom tokenizer.
222 *
223 * @param cls closure from #GNUNET_SERVER_set_callbacks
224 * @param mst custom tokenizer handle
225 * @param client_identity ID of client for which this is a buffer,
226 * can be NULL (will be passed back to 'cb')
227 * @param buf input data to add
228 * @param size number of bytes in @a buf
229 * @param purge should any excess bytes in the buffer be discarded
230 * (i.e. for packet-based services like UDP)
231 * @param one_shot only call callback once, keep rest of message in buffer
232 * @return #GNUNET_OK if we are done processing (need more data)
233 * #GNUNET_NO if one_shot was set and we have another message ready
234 * #GNUNET_SYSERR if the data stream is corrupt
235 */
236typedef int
237(*GNUNET_SERVER_MstReceiveCallback) (void *cls, void *mst,
238 struct GNUNET_SERVER_Client *client,
239 const char *buf,
240 size_t size,
241 int purge,
242 int one_shot);
243/**
244 * Functions with this signature are called whenever a message is
245 * received.
246 *
247 * @param cls closure
248 * @param client identification of the client
249 * @param message the actual message
250 */
251typedef void
252(*GNUNET_SERVER_MessageCallback) (void *cls,
253 struct GNUNET_SERVER_Client *client,
254 const struct GNUNET_MessageHeader *message);
255
256/**
257 * Message handler. Each struct specifies how to handle on particular
258 * type of message received.
259 */
260struct GNUNET_SERVER_MessageHandler
261{
262 /**
263 * Function to call for messages of "type".
264 */
265 GNUNET_SERVER_MessageCallback callback;
266
267 /**
268 * Closure argument for @e callback.
269 */
270 void *callback_cls;
271
272 /**
273 * Type of the message this handler covers.
274 */
275 uint16_t type;
276
277 /**
278 * Expected size of messages of this type. Use 0 for
279 * variable-size. If non-zero, messages of the given
280 * type will be discarded (and the connection closed)
281 * if they do not have the right size.
282 */
283 uint16_t expected_size;
284
285};
286
287
288/**
289 * Options for the service (bitmask).
290 */
291enum LEGACY_SERVICE_Options
292{
293 /**
294 * Use defaults. Terminates all client connections and the listen
295 * sockets immediately upon receiving the shutdown signal.
296 */
297 LEGACY_SERVICE_OPTION_NONE = 0,
298
299 /**
300 * Do not trigger server shutdown on signal at all; instead, allow
301 * for the user to terminate the server explicitly when needed
302 * by calling #LEGACY_SERVICE_shutdown().
303 */
304 LEGACY_SERVICE_OPTION_MANUAL_SHUTDOWN = 1,
305
306 /**
307 * Trigger a SOFT server shutdown on signals, allowing active
308 * non-monitor clients to complete their transactions.
309 */
310 LEGACY_SERVICE_OPTION_SOFT_SHUTDOWN = 2
311};
312
313
314
315/**
316 * Ask the server to disconnect from the given client. This is the
317 * same as passing #GNUNET_SYSERR to #GNUNET_SERVER_receive_done,
318 * except that it allows dropping of a client even when not handling a
319 * message from that client.
320 *
321 * @param client the client to disconnect from
322 */
323void
324GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client);
325
326/**
327 * Return user context associated with the given client.
328 * Note: you should probably use the macro (call without the underscore).
329 *
330 * @param client client to query
331 * @param size number of bytes in user context struct (for verification only)
332 * @return pointer to user context
333 */
334void *
335GNUNET_SERVER_client_get_user_context_ (struct GNUNET_SERVER_Client *client,
336 size_t size);
337
338
339/**
340 * Functions with this signature are called whenever a
341 * complete message is received by the tokenizer.
342 *
343 * Do not call #GNUNET_SERVER_mst_destroy from within
344 * the scope of this callback.
345 *
346 * @param cls closure
347 * @param client identification of the client
348 * @param message the actual message
349 * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
350 */
351typedef int
352(*GNUNET_SERVER_MessageTokenizerCallback) (void *cls,
353 void *client,
354 const struct GNUNET_MessageHeader *message);
355
356
357/**
358 * Create a message stream tokenizer.
359 *
360 * @param cb function to call on completed messages
361 * @param cb_cls closure for @a cb
362 * @return handle to tokenizer
363 */
364struct GNUNET_SERVER_MessageStreamTokenizer *
365GNUNET_SERVER_mst_create (GNUNET_SERVER_MessageTokenizerCallback cb,
366 void *cb_cls);
367
368/**
369 * Add incoming data to the receive buffer and call the
370 * callback for all complete messages.
371 *
372 * @param mst tokenizer to use
373 * @param client_identity ID of client for which this is a buffer,
374 * can be NULL (will be passed back to 'cb')
375 * @param buf input data to add
376 * @param size number of bytes in @a buf
377 * @param purge should any excess bytes in the buffer be discarded
378 * (i.e. for packet-based services like UDP)
379 * @param one_shot only call callback once, keep rest of message in buffer
380 * @return #GNUNET_OK if we are done processing (need more data)
381 * #GNUNET_NO if one_shot was set and we have another message ready
382 * #GNUNET_SYSERR if the data stream is corrupt
383 */
384int
385GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
386 void *client_identity,
387 const char *buf, size_t size,
388 int purge, int one_shot);
389
390
391
392/**
393 * Destroys a tokenizer.
394 *
395 * @param mst tokenizer to destroy
396 */
397void
398GNUNET_SERVER_mst_destroy (struct GNUNET_SERVER_MessageStreamTokenizer *mst);
49 399
50 400
51/** 401/**
402 * Set user context to be associated with the given client.
403 * Note: you should probably use the macro (call without the underscore).
404 *
405 * @param client client to query
406 * @param ptr pointer to user context
407 * @param size number of bytes in user context struct (for verification only)
408 */
409void
410GNUNET_SERVER_client_set_user_context_ (struct GNUNET_SERVER_Client *client,
411 void *ptr,
412 size_t size);
413/**
414 * Return user context associated with the given client.
415 *
416 * @param client client to query
417 * @param type expected return type (i.e. 'struct Foo')
418 * @return pointer to user context of type 'type *'.
419 */
420#define GNUNET_SERVER_client_get_user_context(client,type) \
421 (type *) GNUNET_SERVER_client_get_user_context_ (client, sizeof (type))
422
423/**
424 * Set user context to be associated with the given client.
425 *
426 * @param client client to query
427 * @param value pointer to user context
428 */
429#define GNUNET_SERVER_client_set_user_context(client,value) \
430 GNUNET_SERVER_client_set_user_context_ (client, value, sizeof (*value))
431
432
433
434/**
435 * Notify us when the server has enough space to transmit
436 * a message of the given size to the given client.
437 *
438 * @param client client to transmit message to
439 * @param size requested amount of buffer space
440 * @param timeout after how long should we give up (and call
441 * notify with buf NULL and size 0)?
442 * @param callback function to call when space is available
443 * @param callback_cls closure for @a callback
444 * @return non-NULL if the notify callback was queued; can be used
445 * to cancel the request using
446 * #GNUNET_SERVER_notify_transmit_ready_cancel.
447 * NULL if we are already going to notify someone else (busy)
448 */
449struct GNUNET_SERVER_TransmitHandle *
450GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
451 size_t size,
452 struct GNUNET_TIME_Relative timeout,
453 GNUNET_CONNECTION_TransmitReadyNotify callback,
454 void *callback_cls);
455
456/**
457 * Abort transmission request.
458 *
459 * @param th request to abort
460 */
461void
462GNUNET_SERVER_notify_transmit_ready_cancel (struct GNUNET_SERVER_TransmitHandle *th);
463
464
465
466
467/**
468 * Notify the server that the given client handle should
469 * be kept (keeps the connection up if possible, increments
470 * the internal reference counter).
471 *
472 * @param client the client to keep
473 */
474void
475GNUNET_SERVER_client_keep (struct GNUNET_SERVER_Client *client);
476
477
478/**
479 * Notify the server that the given client handle is no
480 * longer required. Decrements the reference counter. If
481 * that counter reaches zero an inactive connection maybe
482 * closed.
483 *
484 * @param client the client to drop
485 */
486void
487GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client);
488
489
490/**
491 * Function called by the service's run
492 * method to run service-specific setup code.
493 *
494 * @param cls closure
495 * @param server the initialized server
496 * @param cfg configuration to use
497 */
498typedef void
499(*LEGACY_SERVICE_Main) (void *cls,
500 struct GNUNET_SERVER_Handle *server,
501 const struct GNUNET_CONFIGURATION_Handle *cfg);
502
503
504
505/**
506 * Suspend accepting connections from the listen socket temporarily.
507 * Resume activity using #GNUNET_SERVER_resume.
508 *
509 * @param server server to stop accepting connections.
510 */
511void
512GNUNET_SERVER_suspend (struct GNUNET_SERVER_Handle *server);
513
514/**
515 * Notify us when the server has enough space to transmit
516 * a message of the given size to the given client.
517 *
518 * @param client client to transmit message to
519 * @param size requested amount of buffer space
520 * @param timeout after how long should we give up (and call
521 * notify with buf NULL and size 0)?
522 * @param callback function to call when space is available
523 * @param callback_cls closure for @a callback
524 * @return non-NULL if the notify callback was queued; can be used
525 * to cancel the request using
526 * #GNUNET_SERVER_notify_transmit_ready_cancel.
527 * NULL if we are already going to notify someone else (busy)
528 */
529struct GNUNET_SERVER_TransmitHandle *
530GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
531 size_t size,
532 struct GNUNET_TIME_Relative timeout,
533 GNUNET_CONNECTION_TransmitReadyNotify callback,
534 void *callback_cls);
535
536
537/**
538 * Add a TCP socket-based connection to the set of handles managed by
539 * this server. Use this function for outgoing (P2P) connections that
540 * we initiated (and where this server should process incoming
541 * messages).
542 *
543 * @param server the server to use
544 * @param connection the connection to manage (client must
545 * stop using this connection from now on)
546 * @return the client handle
547 */
548struct GNUNET_SERVER_Client *
549GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server,
550 struct GNUNET_CONNECTION_Handle *connection);
551
552
553/**
554 * Resume accepting connections from the listen socket.
555 *
556 * @param server server to resume accepting connections.
557 */
558void
559GNUNET_SERVER_resume (struct GNUNET_SERVER_Handle *server);
560
561/**
562 * Free resources held by this server.
563 *
564 * @param server server to destroy
565 */
566void
567GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *server);
568
569
570
571
572#include "tcp_connection_legacy.c"
573#include "tcp_server_mst_legacy.c"
574#include "tcp_server_legacy.c"
575#include "tcp_service_legacy.c"
576
577GNUNET_NETWORK_STRUCT_BEGIN
578
579/**
52 * Initial handshake message for a session. 580 * Initial handshake message for a session.
53 */ 581 */
54struct WelcomeMessage 582struct WelcomeMessage
@@ -434,7 +962,7 @@ struct Plugin
434 /** 962 /**
435 * Handle to the network service. 963 * Handle to the network service.
436 */ 964 */
437 struct GNUNET_SERVICE_Context *service; 965 struct LEGACY_SERVICE_Context *service;
438 966
439 /** 967 /**
440 * Handle to the server for this service. 968 * Handle to the server for this service.
@@ -521,47 +1049,6 @@ struct Plugin
521}; 1049};
522 1050
523 1051
524/* begin of ancient copy-and-pasted code that should be
525 specialized for TCP ...*/
526/**
527 * Add the given UNIX domain path as an address to the
528 * list (as the first entry).
529 *
530 * @param saddrs array to update
531 * @param saddrlens where to store the address length
532 * @param unixpath path to add
533 * @param abstract #GNUNET_YES to add an abstract UNIX domain socket. This
534 * parameter is ignore on systems other than LINUX
535 */
536static void
537add_unixpath (struct sockaddr **saddrs,
538 socklen_t *saddrlens,
539 const char *unixpath,
540 int abstract)
541{
542#ifdef AF_UNIX
543 struct sockaddr_un *un;
544
545 un = GNUNET_new (struct sockaddr_un);
546 un->sun_family = AF_UNIX;
547 strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1);
548#ifdef LINUX
549 if (GNUNET_YES == abstract)
550 un->sun_path[0] = '\0';
551#endif
552#if HAVE_SOCKADDR_UN_SUN_LEN
553 un->sun_len = (u_char) sizeof (struct sockaddr_un);
554#endif
555 *saddrs = (struct sockaddr *) un;
556 *saddrlens = sizeof (struct sockaddr_un);
557#else
558 /* this function should never be called
559 * unless AF_UNIX is defined! */
560 GNUNET_assert (0);
561#endif
562}
563
564
565/** 1052/**
566 * Get the list of addresses that a server for the given service 1053 * Get the list of addresses that a server for the given service
567 * should bind to. 1054 * should bind to.
@@ -3289,7 +3776,7 @@ libgnunet_plugin_transport_tcp_init (void *cls)
3289 struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; 3776 struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
3290 struct GNUNET_TRANSPORT_PluginFunctions *api; 3777 struct GNUNET_TRANSPORT_PluginFunctions *api;
3291 struct Plugin *plugin; 3778 struct Plugin *plugin;
3292 struct GNUNET_SERVICE_Context *service; 3779 struct LEGACY_SERVICE_Context *service;
3293 unsigned long long aport; 3780 unsigned long long aport;
3294 unsigned long long bport; 3781 unsigned long long bport;
3295 unsigned long long max_connections; 3782 unsigned long long max_connections;
@@ -3344,9 +3831,9 @@ libgnunet_plugin_transport_tcp_init (void *cls)
3344 aport = 0; 3831 aport = 0;
3345 if (0 != bport) 3832 if (0 != bport)
3346 { 3833 {
3347 service = GNUNET_SERVICE_start ("transport-tcp", 3834 service = LEGACY_SERVICE_start ("transport-tcp",
3348 env->cfg, 3835 env->cfg,
3349 GNUNET_SERVICE_OPTION_NONE); 3836 LEGACY_SERVICE_OPTION_NONE);
3350 if (NULL == service) 3837 if (NULL == service)
3351 { 3838 {
3352 LOG (GNUNET_ERROR_TYPE_WARNING, 3839 LOG (GNUNET_ERROR_TYPE_WARNING,
@@ -3377,7 +3864,7 @@ libgnunet_plugin_transport_tcp_init (void *cls)
3377 { 3864 {
3378#ifdef TCP_STEALTH 3865#ifdef TCP_STEALTH
3379 plugin->myoptions |= TCP_OPTIONS_TCP_STEALTH; 3866 plugin->myoptions |= TCP_OPTIONS_TCP_STEALTH;
3380 lsocks = GNUNET_SERVICE_get_listen_sockets (service); 3867 lsocks = LEGACY_SERVICE_get_listen_sockets (service);
3381 if (NULL != lsocks) 3868 if (NULL != lsocks)
3382 { 3869 {
3383 uint32_t len = sizeof (struct WelcomeMessage); 3870 uint32_t len = sizeof (struct WelcomeMessage);
@@ -3470,7 +3957,7 @@ libgnunet_plugin_transport_tcp_init (void *cls)
3470 plugin->service = service; 3957 plugin->service = service;
3471 if (NULL != service) 3958 if (NULL != service)
3472 { 3959 {
3473 plugin->server = GNUNET_SERVICE_get_server (service); 3960 plugin->server = LEGACY_SERVICE_get_server (service);
3474 } 3961 }
3475 else 3962 else
3476 { 3963 {
@@ -3533,7 +4020,7 @@ libgnunet_plugin_transport_tcp_init (void *cls)
3533 GNUNET_NAT_unregister (plugin->nat); 4020 GNUNET_NAT_unregister (plugin->nat);
3534 GNUNET_CONTAINER_multipeermap_destroy (plugin->sessionmap); 4021 GNUNET_CONTAINER_multipeermap_destroy (plugin->sessionmap);
3535 if (NULL != service) 4022 if (NULL != service)
3536 GNUNET_SERVICE_stop (service); 4023 LEGACY_SERVICE_stop (service);
3537 GNUNET_free (plugin); 4024 GNUNET_free (plugin);
3538 GNUNET_free_non_null (api); 4025 GNUNET_free_non_null (api);
3539 return NULL; 4026 return NULL;
@@ -3586,7 +4073,7 @@ libgnunet_plugin_transport_tcp_done (void *cls)
3586 } 4073 }
3587 4074
3588 if (NULL != plugin->service) 4075 if (NULL != plugin->service)
3589 GNUNET_SERVICE_stop (plugin->service); 4076 LEGACY_SERVICE_stop (plugin->service);
3590 else 4077 else
3591 GNUNET_SERVER_destroy (plugin->server); 4078 GNUNET_SERVER_destroy (plugin->server);
3592 GNUNET_free (plugin->handlers); 4079 GNUNET_free (plugin->handlers);
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index eb48341b7..1ff962544 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -159,6 +159,11 @@ struct GNUNET_ATS_Session
159 struct GNUNET_PeerIdentity target; 159 struct GNUNET_PeerIdentity target;
160 160
161 /** 161 /**
162 * Tokenizer for inbound messages.
163 */
164 struct GNUNET_MessageStreamTokenizer *mst;
165
166 /**
162 * Plugin this session belongs to. 167 * Plugin this session belongs to.
163 */ 168 */
164 struct Plugin *plugin; 169 struct Plugin *plugin;
@@ -626,6 +631,11 @@ free_session (struct GNUNET_ATS_Session *s)
626 GNUNET_free (s->frag_ctx); 631 GNUNET_free (s->frag_ctx);
627 s->frag_ctx = NULL; 632 s->frag_ctx = NULL;
628 } 633 }
634 if (NULL != s->mst)
635 {
636 GNUNET_MST_destroy (s->mst);
637 s->mst = NULL;
638 }
629 GNUNET_free (s); 639 GNUNET_free (s);
630} 640}
631 641
@@ -2051,7 +2061,7 @@ udp_plugin_send (void *cls,
2051 if ( (sizeof(struct IPv4UdpAddress) == s->address->address_length) && 2061 if ( (sizeof(struct IPv4UdpAddress) == s->address->address_length) &&
2052 (NULL == plugin->sockv4) ) 2062 (NULL == plugin->sockv4) )
2053 return GNUNET_SYSERR; 2063 return GNUNET_SYSERR;
2054 if (udpmlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 2064 if (udpmlen >= GNUNET_MAX_MESSAGE_SIZE)
2055 { 2065 {
2056 GNUNET_break (0); 2066 GNUNET_break (0);
2057 return GNUNET_SYSERR; 2067 return GNUNET_SYSERR;
@@ -2499,18 +2509,16 @@ read_process_ack (struct Plugin *plugin,
2499 * Message tokenizer has broken up an incomming message. Pass it on 2509 * Message tokenizer has broken up an incomming message. Pass it on
2500 * to the service. 2510 * to the service.
2501 * 2511 *
2502 * @param cls the `struct Plugin *` 2512 * @param cls the `struct GNUNET_ATS_Session *`
2503 * @param client the `struct GNUNET_ATS_Session *`
2504 * @param hdr the actual message 2513 * @param hdr the actual message
2505 * @return #GNUNET_OK (always) 2514 * @return #GNUNET_OK (always)
2506 */ 2515 */
2507static int 2516static int
2508process_inbound_tokenized_messages (void *cls, 2517process_inbound_tokenized_messages (void *cls,
2509 void *client,
2510 const struct GNUNET_MessageHeader *hdr) 2518 const struct GNUNET_MessageHeader *hdr)
2511{ 2519{
2512 struct Plugin *plugin = cls; 2520 struct GNUNET_ATS_Session *session = cls;
2513 struct GNUNET_ATS_Session *session = client; 2521 struct Plugin *plugin = session->plugin;
2514 2522
2515 if (GNUNET_YES == session->in_destroy) 2523 if (GNUNET_YES == session->in_destroy)
2516 return GNUNET_OK; 2524 return GNUNET_OK;
@@ -2626,6 +2634,8 @@ udp_plugin_create_session (void *cls,
2626 struct GNUNET_ATS_Session *s; 2634 struct GNUNET_ATS_Session *s;
2627 2635
2628 s = GNUNET_new (struct GNUNET_ATS_Session); 2636 s = GNUNET_new (struct GNUNET_ATS_Session);
2637 s->mst = GNUNET_MST_create (&process_inbound_tokenized_messages,
2638 s);
2629 s->plugin = plugin; 2639 s->plugin = plugin;
2630 s->address = GNUNET_HELLO_address_copy (address); 2640 s->address = GNUNET_HELLO_address_copy (address);
2631 s->target = address->peer; 2641 s->target = address->peer;
@@ -2792,12 +2802,11 @@ process_udp_message (struct Plugin *plugin,
2792 GNUNET_free (address); 2802 GNUNET_free (address);
2793 2803
2794 s->rc++; 2804 s->rc++;
2795 GNUNET_SERVER_mst_receive (plugin->mst, 2805 GNUNET_MST_from_buffer (s->mst,
2796 s, 2806 (const char *) &msg[1],
2797 (const char *) &msg[1], 2807 ntohs (msg->header.size) - sizeof(struct UDPMessage),
2798 ntohs (msg->header.size) - sizeof(struct UDPMessage), 2808 GNUNET_YES,
2799 GNUNET_YES, 2809 GNUNET_NO);
2800 GNUNET_NO);
2801 s->rc--; 2810 s->rc--;
2802 if ( (0 == s->rc) && 2811 if ( (0 == s->rc) &&
2803 (GNUNET_YES == s->in_destroy) ) 2812 (GNUNET_YES == s->in_destroy) )
@@ -3990,8 +3999,6 @@ libgnunet_plugin_transport_udp_init (void *cls)
3990 p->sessions = GNUNET_CONTAINER_multipeermap_create (16, 3999 p->sessions = GNUNET_CONTAINER_multipeermap_create (16,
3991 GNUNET_NO); 4000 GNUNET_NO);
3992 p->defrag_ctxs = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 4001 p->defrag_ctxs = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
3993 p->mst = GNUNET_SERVER_mst_create (&process_inbound_tokenized_messages,
3994 p);
3995 GNUNET_BANDWIDTH_tracker_init (&p->tracker, 4002 GNUNET_BANDWIDTH_tracker_init (&p->tracker,
3996 NULL, 4003 NULL,
3997 NULL, 4004 NULL,
@@ -4008,7 +4015,6 @@ libgnunet_plugin_transport_udp_init (void *cls)
4008 _("Failed to create UDP network sockets\n")); 4015 _("Failed to create UDP network sockets\n"));
4009 GNUNET_CONTAINER_multipeermap_destroy (p->sessions); 4016 GNUNET_CONTAINER_multipeermap_destroy (p->sessions);
4010 GNUNET_CONTAINER_heap_destroy (p->defrag_ctxs); 4017 GNUNET_CONTAINER_heap_destroy (p->defrag_ctxs);
4011 GNUNET_SERVER_mst_destroy (p->mst);
4012 if (NULL != p->nat) 4018 if (NULL != p->nat)
4013 GNUNET_NAT_unregister (p->nat); 4019 GNUNET_NAT_unregister (p->nat);
4014 GNUNET_free (p); 4020 GNUNET_free (p);
@@ -4120,11 +4126,6 @@ libgnunet_plugin_transport_udp_done (void *cls)
4120 GNUNET_CONTAINER_heap_destroy (plugin->defrag_ctxs); 4126 GNUNET_CONTAINER_heap_destroy (plugin->defrag_ctxs);
4121 plugin->defrag_ctxs = NULL; 4127 plugin->defrag_ctxs = NULL;
4122 } 4128 }
4123 if (NULL != plugin->mst)
4124 {
4125 GNUNET_SERVER_mst_destroy (plugin->mst);
4126 plugin->mst = NULL;
4127 }
4128 while (NULL != (udpw = plugin->ipv4_queue_head)) 4129 while (NULL != (udpw = plugin->ipv4_queue_head))
4129 { 4130 {
4130 dequeue (plugin, 4131 dequeue (plugin,
diff --git a/src/transport/plugin_transport_udp.h b/src/transport/plugin_transport_udp.h
index 152b16099..48c7365c7 100644
--- a/src/transport/plugin_transport_udp.h
+++ b/src/transport/plugin_transport_udp.h
@@ -164,11 +164,6 @@ struct Plugin
164 struct GNUNET_SCHEDULER_Task *select_task_v6; 164 struct GNUNET_SCHEDULER_Task *select_task_v6;
165 165
166 /** 166 /**
167 * Tokenizer for inbound messages.
168 */
169 struct GNUNET_SERVER_MessageStreamTokenizer *mst;
170
171 /**
172 * Bandwidth tracker to limit global UDP traffic. 167 * Bandwidth tracker to limit global UDP traffic.
173 */ 168 */
174 struct GNUNET_BANDWIDTH_Tracker tracker; 169 struct GNUNET_BANDWIDTH_Tracker tracker;
@@ -192,7 +187,7 @@ struct Plugin
192 * Handle to NAT traversal support. 187 * Handle to NAT traversal support.
193 */ 188 */
194 struct GNUNET_NAT_STUN_Handle *stun; 189 struct GNUNET_NAT_STUN_Handle *stun;
195 190
196 /** 191 /**
197 * The read socket for IPv4 192 * The read socket for IPv4
198 */ 193 */
@@ -204,11 +199,6 @@ struct Plugin
204 struct GNUNET_NETWORK_Handle *sockv6; 199 struct GNUNET_NETWORK_Handle *sockv6;
205 200
206 /** 201 /**
207 * Tokenizer for inbound messages.
208 */
209 struct GNUNET_SERVER_MessageStreamTokenizer *broadcast_mst;
210
211 /**
212 * Head of DLL of broadcast addresses 202 * Head of DLL of broadcast addresses
213 */ 203 */
214 struct BroadcastAddress *broadcast_tail; 204 struct BroadcastAddress *broadcast_tail;
diff --git a/src/transport/plugin_transport_udp_broadcasting.c b/src/transport/plugin_transport_udp_broadcasting.c
index a440830fd..c6ddbce9b 100644
--- a/src/transport/plugin_transport_udp_broadcasting.c
+++ b/src/transport/plugin_transport_udp_broadcasting.c
@@ -133,11 +133,10 @@ struct MstContext
133 */ 133 */
134static int 134static int
135broadcast_mst_cb (void *cls, 135broadcast_mst_cb (void *cls,
136 void *client,
137 const struct GNUNET_MessageHeader *message) 136 const struct GNUNET_MessageHeader *message)
138{ 137{
139 struct Plugin *plugin = cls; 138 struct MstContext *mc = cls;
140 struct MstContext *mc = client; 139 struct Plugin *plugin = mc->plugin;
141 struct GNUNET_HELLO_Address *address; 140 struct GNUNET_HELLO_Address *address;
142 const struct GNUNET_MessageHeader *hello; 141 const struct GNUNET_MessageHeader *hello;
143 const struct UDP_Beacon_Message *msg; 142 const struct UDP_Beacon_Message *msg;
@@ -191,16 +190,20 @@ udp_broadcast_receive (struct Plugin *plugin,
191 size_t udp_addr_len, 190 size_t udp_addr_len,
192 enum GNUNET_ATS_Network_Type network_type) 191 enum GNUNET_ATS_Network_Type network_type)
193{ 192{
193 struct GNUNET_MessageStreamTokenizer *broadcast_mst;
194 struct MstContext mc; 194 struct MstContext mc;
195 195
196 broadcast_mst = GNUNET_MST_create (&broadcast_mst_cb,
197 &mc);
198 mc.plugin = plugin;
196 mc.udp_addr = udp_addr; 199 mc.udp_addr = udp_addr;
197 mc.udp_addr_len = udp_addr_len; 200 mc.udp_addr_len = udp_addr_len;
198 mc.ats_address_network_type = network_type; 201 mc.ats_address_network_type = network_type;
199 GNUNET_SERVER_mst_receive (plugin->broadcast_mst, 202 GNUNET_MST_from_buffer (broadcast_mst,
200 &mc, 203 buf, size,
201 buf, size, 204 GNUNET_NO,
202 GNUNET_NO, 205 GNUNET_NO);
203 GNUNET_NO); 206 GNUNET_MST_destroy (broadcast_mst);
204} 207}
205 208
206 209
@@ -546,10 +549,6 @@ setup_broadcast (struct Plugin *plugin,
546 return; 549 return;
547 } 550 }
548 551
549 /* always create tokenizers */
550 plugin->broadcast_mst =
551 GNUNET_SERVER_mst_create (&broadcast_mst_cb, plugin);
552
553 if (GNUNET_YES != plugin->enable_broadcasting) 552 if (GNUNET_YES != plugin->enable_broadcasting)
554 return; /* We do not send, just receive */ 553 return; /* We do not send, just receive */
555 554
@@ -636,13 +635,6 @@ stop_broadcast (struct Plugin *plugin)
636 GNUNET_free (p); 635 GNUNET_free (p);
637 } 636 }
638 } 637 }
639
640 /* Destroy MSTs */
641 if (NULL != plugin->broadcast_mst)
642 {
643 GNUNET_SERVER_mst_destroy (plugin->broadcast_mst);
644 plugin->broadcast_mst = NULL;
645 }
646} 638}
647 639
648/* end of plugin_transport_udp_broadcasting.c */ 640/* end of plugin_transport_udp_broadcasting.c */
diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c
index 376065d24..b23739d3c 100644
--- a/src/transport/plugin_transport_wlan.c
+++ b/src/transport/plugin_transport_wlan.c
@@ -38,6 +38,7 @@
38#include "gnunet_fragmentation_lib.h" 38#include "gnunet_fragmentation_lib.h"
39#include "gnunet_constants.h" 39#include "gnunet_constants.h"
40 40
41
41#if BUILD_WLAN 42#if BUILD_WLAN
42/* begin case wlan */ 43/* begin case wlan */
43#define PLUGIN_NAME "wlan" 44#define PLUGIN_NAME "wlan"
@@ -48,6 +49,7 @@
48#define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_wlan_done 49#define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_wlan_done
49#define LOG(kind,...) GNUNET_log_from (kind, "transport-wlan",__VA_ARGS__) 50#define LOG(kind,...) GNUNET_log_from (kind, "transport-wlan",__VA_ARGS__)
50 51
52
51/** 53/**
52 * time out of a mac endpoint 54 * time out of a mac endpoint
53 */ 55 */
@@ -92,6 +94,30 @@
92#error need to build wlan or bluetooth 94#error need to build wlan or bluetooth
93#endif 95#endif
94 96
97
98
99/**
100 * Functions with this signature are called whenever a
101 * complete message is received by the tokenizer.
102 *
103 * Do not call #GNUNET_SERVER_mst_destroy from within
104 * the scope of this callback.
105 *
106 * @param cls closure
107 * @param client identification of the client
108 * @param message the actual message
109 * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
110 */
111typedef int
112(*GNUNET_SERVER_MessageTokenizerCallback) (void *cls,
113 void *client,
114 const struct GNUNET_MessageHeader *message);
115
116
117/* Include legacy message stream tokenizer that was removed from util (for now) */
118#include "tcp_server_mst_legacy.c"
119
120
95/** 121/**
96 * Max size of packet (that we give to the WLAN driver for transmission) 122 * Max size of packet (that we give to the WLAN driver for transmission)
97 */ 123 */
@@ -718,7 +744,7 @@ send_ack (void *cls,
718 GNUNET_break (0); 744 GNUNET_break (0);
719 return; 745 return;
720 } 746 }
721 if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 747 if (size >= GNUNET_MAX_MESSAGE_SIZE)
722 { 748 {
723 GNUNET_break (0); 749 GNUNET_break (0);
724 return; 750 return;
@@ -1728,11 +1754,10 @@ send_hello_beacon (void *cls)
1728 * Function used for to process the data from the suid process 1754 * Function used for to process the data from the suid process
1729 * 1755 *
1730 * @param cls the plugin handle 1756 * @param cls the plugin handle
1731 * @param client client that send the data (not used)
1732 * @param hdr header of the GNUNET_MessageHeader 1757 * @param hdr header of the GNUNET_MessageHeader
1733 */ 1758 */
1734static int 1759static int
1735handle_helper_message (void *cls, void *client, 1760handle_helper_message (void *cls,
1736 const struct GNUNET_MessageHeader *hdr) 1761 const struct GNUNET_MessageHeader *hdr)
1737{ 1762{
1738 struct Plugin *plugin = cls; 1763 struct Plugin *plugin = cls;
diff --git a/src/util/connection.c b/src/transport/tcp_connection_legacy.c
index e822b264f..5b219a467 100644
--- a/src/util/connection.c
+++ b/src/transport/tcp_connection_legacy.c
@@ -35,7 +35,15 @@
35#include "gnunet_resolver_service.h" 35#include "gnunet_resolver_service.h"
36 36
37 37
38#define LOG(kind,...) GNUNET_log_from (kind, "util-connection", __VA_ARGS__) 38/**
39 * Timeout we use on TCP connect before trying another
40 * result from the DNS resolver. Actual value used
41 * is this value divided by the number of address families.
42 * Default is 5s.
43 */
44#define CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
45
46
39 47
40#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-connection", syscall) 48#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-connection", syscall)
41 49
@@ -305,7 +313,7 @@ GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle *osSocket)
305 struct GNUNET_CONNECTION_Handle *connection; 313 struct GNUNET_CONNECTION_Handle *connection;
306 314
307 connection = GNUNET_new (struct GNUNET_CONNECTION_Handle); 315 connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
308 connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; 316 connection->write_buffer_size = GNUNET_MIN_MESSAGE_SIZE;
309 connection->write_buffer = GNUNET_malloc (connection->write_buffer_size); 317 connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
310 connection->sock = osSocket; 318 connection->sock = osSocket;
311 return connection; 319 return connection;
@@ -452,7 +460,7 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access_cb,
452 return NULL; 460 return NULL;
453 } 461 }
454 connection = GNUNET_new (struct GNUNET_CONNECTION_Handle); 462 connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
455 connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; 463 connection->write_buffer_size = GNUNET_MIN_MESSAGE_SIZE;
456 connection->write_buffer = GNUNET_malloc (connection->write_buffer_size); 464 connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
457 connection->addr = uaddr; 465 connection->addr = uaddr;
458 connection->addrlen = addrlen; 466 connection->addrlen = addrlen;
@@ -825,7 +833,7 @@ try_connect_using_address (void *cls,
825 return; 833 return;
826 } 834 }
827 GNUNET_CONTAINER_DLL_insert (connection->ap_head, connection->ap_tail, ap); 835 GNUNET_CONTAINER_DLL_insert (connection->ap_head, connection->ap_tail, ap);
828 delay = GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT; 836 delay = CONNECT_RETRY_TIMEOUT;
829 if (NULL != connection->nth.notify_ready) 837 if (NULL != connection->nth.notify_ready)
830 delay = GNUNET_TIME_relative_min (delay, 838 delay = GNUNET_TIME_relative_min (delay,
831 GNUNET_TIME_absolute_get_remaining (connection->nth.transmit_timeout)); 839 GNUNET_TIME_absolute_get_remaining (connection->nth.transmit_timeout));
@@ -859,14 +867,14 @@ GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle
859 GNUNET_assert (0 < strlen (hostname)); /* sanity check */ 867 GNUNET_assert (0 < strlen (hostname)); /* sanity check */
860 connection = GNUNET_new (struct GNUNET_CONNECTION_Handle); 868 connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
861 connection->cfg = cfg; 869 connection->cfg = cfg;
862 connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; 870 connection->write_buffer_size = GNUNET_MIN_MESSAGE_SIZE;
863 connection->write_buffer = GNUNET_malloc (connection->write_buffer_size); 871 connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
864 connection->port = port; 872 connection->port = port;
865 connection->hostname = GNUNET_strdup (hostname); 873 connection->hostname = GNUNET_strdup (hostname);
866 connection->dns_active = 874 connection->dns_active =
867 GNUNET_RESOLVER_ip_get (connection->hostname, 875 GNUNET_RESOLVER_ip_get (connection->hostname,
868 AF_UNSPEC, 876 AF_UNSPEC,
869 GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT, 877 CONNECT_RETRY_TIMEOUT,
870 &try_connect_using_address, 878 &try_connect_using_address,
871 connection); 879 connection);
872 return connection; 880 return connection;
@@ -910,7 +918,7 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct GNUNET_CONFIGURA
910#endif 918#endif
911 connection = GNUNET_new (struct GNUNET_CONNECTION_Handle); 919 connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
912 connection->cfg = cfg; 920 connection->cfg = cfg;
913 connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; 921 connection->write_buffer_size = GNUNET_MIN_MESSAGE_SIZE;
914 connection->write_buffer = GNUNET_malloc (connection->write_buffer_size); 922 connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
915 connection->port = 0; 923 connection->port = 0;
916 connection->hostname = NULL; 924 connection->hostname = NULL;
@@ -1536,7 +1544,7 @@ GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connec
1536 return NULL; 1544 return NULL;
1537 } 1545 }
1538 GNUNET_assert (NULL != notify); 1546 GNUNET_assert (NULL != notify);
1539 GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE); 1547 GNUNET_assert (size < GNUNET_MAX_MESSAGE_SIZE);
1540 GNUNET_assert (connection->write_buffer_off <= connection->write_buffer_size); 1548 GNUNET_assert (connection->write_buffer_off <= connection->write_buffer_size);
1541 GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size); 1549 GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size);
1542 GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_off); 1550 GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_off);
diff --git a/src/util/server.c b/src/transport/tcp_server_legacy.c
index 83c30e328..6b4daa525 100644
--- a/src/util/server.c
+++ b/src/transport/tcp_server_legacy.c
@@ -28,10 +28,6 @@
28#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
29#include "gnunet_protocols.h" 29#include "gnunet_protocols.h"
30 30
31#define LOG(kind,...) GNUNET_log_from (kind, "util-server", __VA_ARGS__)
32
33#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-server", syscall)
34
35#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-server", syscall, filename) 31#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-server", syscall, filename)
36 32
37 33
@@ -1049,7 +1045,7 @@ process_mst (struct GNUNET_SERVER_Client *client,
1049 GNUNET_STRINGS_relative_time_to_string (client->idle_timeout, GNUNET_YES)); 1045 GNUNET_STRINGS_relative_time_to_string (client->idle_timeout, GNUNET_YES));
1050 client->receive_pending = GNUNET_YES; 1046 client->receive_pending = GNUNET_YES;
1051 GNUNET_CONNECTION_receive (client->connection, 1047 GNUNET_CONNECTION_receive (client->connection,
1052 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, 1048 GNUNET_MAX_MESSAGE_SIZE - 1,
1053 client->idle_timeout, 1049 client->idle_timeout,
1054 &process_incoming, 1050 &process_incoming,
1055 client); 1051 client);
@@ -1128,7 +1124,7 @@ process_incoming (void *cls,
1128 client); 1124 client);
1129 client->receive_pending = GNUNET_YES; 1125 client->receive_pending = GNUNET_YES;
1130 GNUNET_CONNECTION_receive (client->connection, 1126 GNUNET_CONNECTION_receive (client->connection,
1131 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, 1127 GNUNET_MAX_MESSAGE_SIZE - 1,
1132 GNUNET_TIME_absolute_get_remaining (end), 1128 GNUNET_TIME_absolute_get_remaining (end),
1133 &process_incoming, 1129 &process_incoming,
1134 client); 1130 client);
@@ -1204,7 +1200,7 @@ restart_processing (void *cls)
1204 LOG (GNUNET_ERROR_TYPE_DEBUG, "Server begins to read again from client.\n"); 1200 LOG (GNUNET_ERROR_TYPE_DEBUG, "Server begins to read again from client.\n");
1205 client->receive_pending = GNUNET_YES; 1201 client->receive_pending = GNUNET_YES;
1206 GNUNET_CONNECTION_receive (client->connection, 1202 GNUNET_CONNECTION_receive (client->connection,
1207 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, 1203 GNUNET_MAX_MESSAGE_SIZE - 1,
1208 client->idle_timeout, 1204 client->idle_timeout,
1209 &process_incoming, 1205 &process_incoming,
1210 client); 1206 client);
@@ -1292,7 +1288,7 @@ GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server,
1292 n->callback (n->callback_cls, client); 1288 n->callback (n->callback_cls, client);
1293 client->receive_pending = GNUNET_YES; 1289 client->receive_pending = GNUNET_YES;
1294 GNUNET_CONNECTION_receive (client->connection, 1290 GNUNET_CONNECTION_receive (client->connection,
1295 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, 1291 GNUNET_MAX_MESSAGE_SIZE - 1,
1296 client->idle_timeout, 1292 client->idle_timeout,
1297 &process_incoming, 1293 &process_incoming,
1298 client); 1294 client);
diff --git a/src/util/server_mst.c b/src/transport/tcp_server_mst_legacy.c
index 5155b54da..78e04c1b1 100644
--- a/src/util/server_mst.c
+++ b/src/transport/tcp_server_mst_legacy.c
@@ -34,8 +34,6 @@
34#define ALIGN_FACTOR 8 34#define ALIGN_FACTOR 8
35#endif 35#endif
36 36
37#define LOG(kind,...) GNUNET_log_from (kind, "util-server-mst", __VA_ARGS__)
38
39 37
40/** 38/**
41 * Handle to a message stream tokenizer. 39 * Handle to a message stream tokenizer.
@@ -91,8 +89,8 @@ GNUNET_SERVER_mst_create (GNUNET_SERVER_MessageTokenizerCallback cb,
91 struct GNUNET_SERVER_MessageStreamTokenizer *ret; 89 struct GNUNET_SERVER_MessageStreamTokenizer *ret;
92 90
93 ret = GNUNET_new (struct GNUNET_SERVER_MessageStreamTokenizer); 91 ret = GNUNET_new (struct GNUNET_SERVER_MessageStreamTokenizer);
94 ret->hdr = GNUNET_malloc (GNUNET_SERVER_MIN_BUFFER_SIZE); 92 ret->hdr = GNUNET_malloc (GNUNET_MIN_MESSAGE_SIZE);
95 ret->curr_buf = GNUNET_SERVER_MIN_BUFFER_SIZE; 93 ret->curr_buf = GNUNET_MIN_MESSAGE_SIZE;
96 ret->cb = cb; 94 ret->cb = cb;
97 ret->cb_cls = cb_cls; 95 ret->cb_cls = cb_cls;
98 return ret; 96 return ret;
diff --git a/src/transport/tcp_service_legacy.c b/src/transport/tcp_service_legacy.c
new file mode 100644
index 000000000..7c2d3e55a
--- /dev/null
+++ b/src/transport/tcp_service_legacy.c
@@ -0,0 +1,1688 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2012 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file util/service.c
23 * @brief functions related to starting services
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_protocols.h"
29#include "gnunet_constants.h"
30#include "gnunet_resolver_service.h"
31
32#if HAVE_MALLINFO
33#include <malloc.h>
34#include "gauger.h"
35#endif
36
37
38/* ******************* access control ******************** */
39
40/**
41 * Check if the given IP address is in the list of IP addresses.
42 *
43 * @param list a list of networks
44 * @param add the IP to check (in network byte order)
45 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
46 */
47static int
48check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list,
49 const struct in_addr *add)
50{
51 unsigned int i;
52
53 if (NULL == list)
54 return GNUNET_NO;
55 i = 0;
56 while ((list[i].network.s_addr != 0) || (list[i].netmask.s_addr != 0))
57 {
58 if ((add->s_addr & list[i].netmask.s_addr) ==
59 (list[i].network.s_addr & list[i].netmask.s_addr))
60 return GNUNET_YES;
61 i++;
62 }
63 return GNUNET_NO;
64}
65
66
67/**
68 * Check if the given IP address is in the list of IP addresses.
69 *
70 * @param list a list of networks
71 * @param ip the IP to check (in network byte order)
72 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
73 */
74static int
75check_ipv6_listed (const struct GNUNET_STRINGS_IPv6NetworkPolicy *list,
76 const struct in6_addr *ip)
77{
78 unsigned int i;
79 unsigned int j;
80 struct in6_addr zero;
81
82 if (NULL == list)
83 return GNUNET_NO;
84 memset (&zero, 0, sizeof (struct in6_addr));
85 i = 0;
86NEXT:
87 while (0 != memcmp (&zero, &list[i].network, sizeof (struct in6_addr)))
88 {
89 for (j = 0; j < sizeof (struct in6_addr) / sizeof (int); j++)
90 if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
91 (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
92 {
93 i++;
94 goto NEXT;
95 }
96 return GNUNET_YES;
97 }
98 return GNUNET_NO;
99}
100
101
102/* ****************** service struct ****************** */
103
104
105/**
106 * Context for "service_task".
107 */
108struct LEGACY_SERVICE_Context
109{
110 /**
111 * Our configuration.
112 */
113 const struct GNUNET_CONFIGURATION_Handle *cfg;
114
115 /**
116 * Handle for the server.
117 */
118 struct GNUNET_SERVER_Handle *server;
119
120 /**
121 * NULL-terminated array of addresses to bind to, NULL if we got pre-bound
122 * listen sockets.
123 */
124 struct sockaddr **addrs;
125
126 /**
127 * Name of our service.
128 */
129 const char *service_name;
130
131 /**
132 * Main service-specific task to run.
133 */
134 LEGACY_SERVICE_Main task;
135
136 /**
137 * Closure for @e task.
138 */
139 void *task_cls;
140
141 /**
142 * IPv4 addresses that are not allowed to connect.
143 */
144 struct GNUNET_STRINGS_IPv4NetworkPolicy *v4_denied;
145
146 /**
147 * IPv6 addresses that are not allowed to connect.
148 */
149 struct GNUNET_STRINGS_IPv6NetworkPolicy *v6_denied;
150
151 /**
152 * IPv4 addresses that are allowed to connect (if not
153 * set, all are allowed).
154 */
155 struct GNUNET_STRINGS_IPv4NetworkPolicy *v4_allowed;
156
157 /**
158 * IPv6 addresses that are allowed to connect (if not
159 * set, all are allowed).
160 */
161 struct GNUNET_STRINGS_IPv6NetworkPolicy *v6_allowed;
162
163 /**
164 * My (default) message handlers. Adjusted copy
165 * of "defhandlers".
166 */
167 struct GNUNET_SERVER_MessageHandler *my_handlers;
168
169 /**
170 * Array of the lengths of the entries in addrs.
171 */
172 socklen_t *addrlens;
173
174 /**
175 * NULL-terminated array of listen sockets we should take over.
176 */
177 struct GNUNET_NETWORK_Handle **lsocks;
178
179 /**
180 * Task ID of the shutdown task.
181 */
182 struct GNUNET_SCHEDULER_Task *shutdown_task;
183
184 /**
185 * Idle timeout for server.
186 */
187 struct GNUNET_TIME_Relative timeout;
188
189 /**
190 * Overall success/failure of the service start.
191 */
192 int ret;
193
194 /**
195 * If we are daemonizing, this FD is set to the
196 * pipe to the parent. Send '.' if we started
197 * ok, '!' if not. -1 if we are not daemonizing.
198 */
199 int ready_confirm_fd;
200
201 /**
202 * Do we close connections if we receive messages
203 * for which we have no handler?
204 */
205 int require_found;
206
207 /**
208 * Do we require a matching UID for UNIX domain socket connections?
209 * #GNUNET_NO means that the UID does not have to match (however,
210 * @e match_gid may still impose other access control checks).
211 */
212 int match_uid;
213
214 /**
215 * Do we require a matching GID for UNIX domain socket connections?
216 * Ignored if @e match_uid is #GNUNET_YES. Note that this is about
217 * checking that the client's UID is in our group OR that the
218 * client's GID is our GID. If both "match_gid" and @e match_uid are
219 * #GNUNET_NO, all users on the local system have access.
220 */
221 int match_gid;
222
223 /**
224 * Our options.
225 */
226 enum LEGACY_SERVICE_Options options;
227
228};
229
230
231/* ****************** message handlers ****************** */
232
233/**
234 * Send a 'TEST' message back to the client.
235 *
236 * @param cls the 'struct GNUNET_SERVER_Client' to send TEST to
237 * @param size number of bytes available in 'buf'
238 * @param buf where to copy the message
239 * @return number of bytes written to 'buf'
240 */
241static size_t
242write_test (void *cls, size_t size, void *buf)
243{
244 struct GNUNET_SERVER_Client *client = cls;
245 struct GNUNET_MessageHeader *msg;
246
247 if (size < sizeof (struct GNUNET_MessageHeader))
248 {
249 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
250 return 0; /* client disconnected */
251 }
252 msg = (struct GNUNET_MessageHeader *) buf;
253 msg->type = htons (GNUNET_MESSAGE_TYPE_TEST);
254 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
255 GNUNET_SERVER_receive_done (client, GNUNET_OK);
256 return sizeof (struct GNUNET_MessageHeader);
257}
258
259
260/**
261 * Handler for TEST message.
262 *
263 * @param cls closure (refers to service)
264 * @param client identification of the client
265 * @param message the actual message
266 */
267static void
268handle_test (void *cls, struct GNUNET_SERVER_Client *client,
269 const struct GNUNET_MessageHeader *message)
270{
271 /* simply bounce message back to acknowledge */
272 if (NULL ==
273 GNUNET_SERVER_notify_transmit_ready (client,
274 sizeof (struct GNUNET_MessageHeader),
275 GNUNET_TIME_UNIT_FOREVER_REL,
276 &write_test, client))
277 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
278}
279
280
281/**
282 * Default handlers for all services. Will be copied and the
283 * "callback_cls" fields will be replaced with the specific service
284 * struct.
285 */
286static const struct GNUNET_SERVER_MessageHandler defhandlers[] = {
287 {&handle_test, NULL, GNUNET_MESSAGE_TYPE_TEST,
288 sizeof (struct GNUNET_MessageHeader)},
289 {NULL, NULL, 0, 0}
290};
291
292
293/* ****************** service core routines ************** */
294
295
296/**
297 * Check if access to the service is allowed from the given address.
298 *
299 * @param cls closure
300 * @param uc credentials, if available, otherwise NULL
301 * @param addr address
302 * @param addrlen length of address
303 * @return #GNUNET_YES to allow, #GNUNET_NO to deny, #GNUNET_SYSERR
304 * for unknown address family (will be denied).
305 */
306static int
307check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc,
308 const struct sockaddr *addr, socklen_t addrlen)
309{
310 struct LEGACY_SERVICE_Context *sctx = cls;
311 const struct sockaddr_in *i4;
312 const struct sockaddr_in6 *i6;
313 int ret;
314
315 switch (addr->sa_family)
316 {
317 case AF_INET:
318 GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
319 i4 = (const struct sockaddr_in *) addr;
320 ret = ((NULL == sctx->v4_allowed) ||
321 (check_ipv4_listed (sctx->v4_allowed, &i4->sin_addr))) &&
322 ((NULL == sctx->v4_denied) ||
323 (!check_ipv4_listed (sctx->v4_denied, &i4->sin_addr)));
324 break;
325 case AF_INET6:
326 GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
327 i6 = (const struct sockaddr_in6 *) addr;
328 ret = ((NULL == sctx->v6_allowed) ||
329 (check_ipv6_listed (sctx->v6_allowed, &i6->sin6_addr))) &&
330 ((NULL == sctx->v6_denied) ||
331 (!check_ipv6_listed (sctx->v6_denied, &i6->sin6_addr)));
332 break;
333#ifndef WINDOWS
334 case AF_UNIX:
335 ret = GNUNET_OK; /* controlled using file-system ACL now */
336 break;
337#endif
338 default:
339 LOG (GNUNET_ERROR_TYPE_WARNING, _("Unknown address family %d\n"),
340 addr->sa_family);
341 return GNUNET_SYSERR;
342 }
343 if (GNUNET_OK != ret)
344 {
345 LOG (GNUNET_ERROR_TYPE_WARNING,
346 _("Access from `%s' denied to service `%s'\n"),
347 GNUNET_a2s (addr, addrlen),
348 sctx->service_name);
349 }
350 return ret;
351}
352
353
354/**
355 * Get the name of the file where we will
356 * write the PID of the service.
357 *
358 * @param sctx service context
359 * @return name of the file for the process ID
360 */
361static char *
362get_pid_file_name (struct LEGACY_SERVICE_Context *sctx)
363{
364 char *pif;
365
366 if (GNUNET_OK !=
367 GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->service_name,
368 "PIDFILE", &pif))
369 return NULL;
370 return pif;
371}
372
373
374/**
375 * Parse an IPv4 access control list.
376 *
377 * @param ret location where to write the ACL (set)
378 * @param sctx service context to use to get the configuration
379 * @param option name of the ACL option to parse
380 * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
381 * no ACL configured)
382 */
383static int
384process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret,
385 struct LEGACY_SERVICE_Context *sctx,
386 const char *option)
387{
388 char *opt;
389
390 if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option))
391 {
392 *ret = NULL;
393 return GNUNET_OK;
394 }
395 GNUNET_break (GNUNET_OK ==
396 GNUNET_CONFIGURATION_get_value_string (sctx->cfg,
397 sctx->service_name,
398 option, &opt));
399 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt)))
400 {
401 LOG (GNUNET_ERROR_TYPE_WARNING,
402 _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
403 opt, sctx->service_name, option);
404 GNUNET_free (opt);
405 return GNUNET_SYSERR;
406 }
407 GNUNET_free (opt);
408 return GNUNET_OK;
409}
410
411
412/**
413 * Parse an IPv6 access control list.
414 *
415 * @param ret location where to write the ACL (set)
416 * @param sctx service context to use to get the configuration
417 * @param option name of the ACL option to parse
418 * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
419 * no ACL configured)
420 */
421static int
422process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret,
423 struct LEGACY_SERVICE_Context *sctx,
424 const char *option)
425{
426 char *opt;
427
428 if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option))
429 {
430 *ret = NULL;
431 return GNUNET_OK;
432 }
433 GNUNET_break (GNUNET_OK ==
434 GNUNET_CONFIGURATION_get_value_string (sctx->cfg,
435 sctx->service_name,
436 option, &opt));
437 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt)))
438 {
439 LOG (GNUNET_ERROR_TYPE_WARNING,
440 _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
441 opt, sctx->service_name, option);
442 GNUNET_free (opt);
443 return GNUNET_SYSERR;
444 }
445 GNUNET_free (opt);
446 return GNUNET_OK;
447}
448
449
450/**
451 * Add the given UNIX domain path as an address to the
452 * list (as the first entry).
453 *
454 * @param saddrs array to update
455 * @param saddrlens where to store the address length
456 * @param unixpath path to add
457 * @param abstract #GNUNET_YES to add an abstract UNIX domain socket. This
458 * parameter is ignore on systems other than LINUX
459 */
460static void
461add_unixpath (struct sockaddr **saddrs,
462 socklen_t *saddrlens,
463 const char *unixpath,
464 int abstract)
465{
466#ifdef AF_UNIX
467 struct sockaddr_un *un;
468
469 un = GNUNET_new (struct sockaddr_un);
470 un->sun_family = AF_UNIX;
471 strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1);
472#ifdef LINUX
473 if (GNUNET_YES == abstract)
474 un->sun_path[0] = '\0';
475#endif
476#if HAVE_SOCKADDR_UN_SUN_LEN
477 un->sun_len = (u_char) sizeof (struct sockaddr_un);
478#endif
479 *saddrs = (struct sockaddr *) un;
480 *saddrlens = sizeof (struct sockaddr_un);
481#else
482 /* this function should never be called
483 * unless AF_UNIX is defined! */
484 GNUNET_assert (0);
485#endif
486}
487
488
489/**
490 * Get the list of addresses that a server for the given service
491 * should bind to.
492 *
493 * @param service_name name of the service
494 * @param cfg configuration (which specifies the addresses)
495 * @param addrs set (call by reference) to an array of pointers to the
496 * addresses the server should bind to and listen on; the
497 * array will be NULL-terminated (on success)
498 * @param addr_lens set (call by reference) to an array of the lengths
499 * of the respective `struct sockaddr` struct in the @a addrs
500 * array (on success)
501 * @return number of addresses found on success,
502 * #GNUNET_SYSERR if the configuration
503 * did not specify reasonable finding information or
504 * if it specified a hostname that could not be resolved;
505 * #GNUNET_NO if the number of addresses configured is
506 * zero (in this case, `*addrs` and `*addr_lens` will be
507 * set to NULL).
508 */
509int
510LEGACY_SERVICE_get_server_addresses (const char *service_name,
511 const struct GNUNET_CONFIGURATION_Handle *cfg,
512 struct sockaddr ***addrs,
513 socklen_t ** addr_lens)
514{
515 int disablev6;
516 struct GNUNET_NETWORK_Handle *desc;
517 unsigned long long port;
518 char *unixpath;
519 struct addrinfo hints;
520 struct addrinfo *res;
521 struct addrinfo *pos;
522 struct addrinfo *next;
523 unsigned int i;
524 int resi;
525 int ret;
526 int abstract;
527 struct sockaddr **saddrs;
528 socklen_t *saddrlens;
529 char *hostname;
530
531 *addrs = NULL;
532 *addr_lens = NULL;
533 desc = NULL;
534 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "DISABLEV6"))
535 {
536 if (GNUNET_SYSERR ==
537 (disablev6 =
538 GNUNET_CONFIGURATION_get_value_yesno (cfg, service_name, "DISABLEV6")))
539 return GNUNET_SYSERR;
540 }
541 else
542 disablev6 = GNUNET_NO;
543
544 if (! disablev6)
545 {
546 /* probe IPv6 support */
547 desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
548 if (NULL == desc)
549 {
550 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
551 (EACCES == errno))
552 {
553 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
554 return GNUNET_SYSERR;
555 }
556 LOG (GNUNET_ERROR_TYPE_INFO,
557 _("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
558 service_name, STRERROR (errno));
559 disablev6 = GNUNET_YES;
560 }
561 else
562 {
563 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
564 desc = NULL;
565 }
566 }
567
568 port = 0;
569 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT"))
570 {
571 if (GNUNET_OK !=
572 GNUNET_CONFIGURATION_get_value_number (cfg, service_name,
573 "PORT", &port))
574 {
575 LOG (GNUNET_ERROR_TYPE_ERROR,
576 _("Require valid port number for service `%s' in configuration!\n"),
577 service_name);
578 }
579 if (port > 65535)
580 {
581 LOG (GNUNET_ERROR_TYPE_ERROR,
582 _("Require valid port number for service `%s' in configuration!\n"),
583 service_name);
584 return GNUNET_SYSERR;
585 }
586 }
587
588 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO"))
589 {
590 GNUNET_break (GNUNET_OK ==
591 GNUNET_CONFIGURATION_get_value_string (cfg, service_name,
592 "BINDTO", &hostname));
593 }
594 else
595 hostname = NULL;
596
597 unixpath = NULL;
598 abstract = GNUNET_NO;
599#ifdef AF_UNIX
600 if ((GNUNET_YES ==
601 GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) &&
602 (GNUNET_OK ==
603 GNUNET_CONFIGURATION_get_value_filename (cfg, service_name, "UNIXPATH",
604 &unixpath)) &&
605 (0 < strlen (unixpath)))
606 {
607 /* probe UNIX support */
608 struct sockaddr_un s_un;
609
610 if (strlen (unixpath) >= sizeof (s_un.sun_path))
611 {
612 LOG (GNUNET_ERROR_TYPE_WARNING,
613 _("UNIXPATH `%s' too long, maximum length is %llu\n"), unixpath,
614 (unsigned long long) sizeof (s_un.sun_path));
615 unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
616 LOG (GNUNET_ERROR_TYPE_INFO,
617 _("Using `%s' instead\n"),
618 unixpath);
619 }
620#ifdef LINUX
621 abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
622 "TESTING",
623 "USE_ABSTRACT_SOCKETS");
624 if (GNUNET_SYSERR == abstract)
625 abstract = GNUNET_NO;
626#endif
627 if ((GNUNET_YES != abstract)
628 && (GNUNET_OK !=
629 GNUNET_DISK_directory_create_for_file (unixpath)))
630 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
631 "mkdir",
632 unixpath);
633 }
634 if (NULL != unixpath)
635 {
636 desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
637 if (NULL == desc)
638 {
639 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
640 (EACCES == errno))
641 {
642 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
643 GNUNET_free_non_null (hostname);
644 GNUNET_free (unixpath);
645 return GNUNET_SYSERR;
646 }
647 LOG (GNUNET_ERROR_TYPE_INFO,
648 _("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
649 service_name,
650 STRERROR (errno));
651 GNUNET_free (unixpath);
652 unixpath = NULL;
653 }
654 else
655 {
656 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
657 desc = NULL;
658 }
659 }
660#endif
661
662 if ((0 == port) && (NULL == unixpath))
663 {
664 LOG (GNUNET_ERROR_TYPE_ERROR,
665 _("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
666 service_name);
667 GNUNET_free_non_null (hostname);
668 return GNUNET_SYSERR;
669 }
670 if (0 == port)
671 {
672 saddrs = GNUNET_malloc (2 * sizeof (struct sockaddr *));
673 saddrlens = GNUNET_malloc (2 * sizeof (socklen_t));
674 add_unixpath (saddrs, saddrlens, unixpath, abstract);
675 GNUNET_free_non_null (unixpath);
676 GNUNET_free_non_null (hostname);
677 *addrs = saddrs;
678 *addr_lens = saddrlens;
679 return 1;
680 }
681
682 if (NULL != hostname)
683 {
684 LOG (GNUNET_ERROR_TYPE_DEBUG,
685 "Resolving `%s' since that is where `%s' will bind to.\n",
686 hostname,
687 service_name);
688 memset (&hints, 0, sizeof (struct addrinfo));
689 if (disablev6)
690 hints.ai_family = AF_INET;
691 hints.ai_protocol = IPPROTO_TCP;
692 if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
693 (NULL == res))
694 {
695 LOG (GNUNET_ERROR_TYPE_ERROR,
696 _("Failed to resolve `%s': %s\n"),
697 hostname,
698 gai_strerror (ret));
699 GNUNET_free (hostname);
700 GNUNET_free_non_null (unixpath);
701 return GNUNET_SYSERR;
702 }
703 next = res;
704 i = 0;
705 while (NULL != (pos = next))
706 {
707 next = pos->ai_next;
708 if ((disablev6) && (pos->ai_family == AF_INET6))
709 continue;
710 i++;
711 }
712 if (0 == i)
713 {
714 LOG (GNUNET_ERROR_TYPE_ERROR,
715 _("Failed to find %saddress for `%s'.\n"),
716 disablev6 ? "IPv4 " : "",
717 hostname);
718 freeaddrinfo (res);
719 GNUNET_free (hostname);
720 GNUNET_free_non_null (unixpath);
721 return GNUNET_SYSERR;
722 }
723 resi = i;
724 if (NULL != unixpath)
725 resi++;
726 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
727 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
728 i = 0;
729 if (NULL != unixpath)
730 {
731 add_unixpath (saddrs, saddrlens, unixpath, abstract);
732 i++;
733 }
734 next = res;
735 while (NULL != (pos = next))
736 {
737 next = pos->ai_next;
738 if ((disablev6) && (AF_INET6 == pos->ai_family))
739 continue;
740 if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
741 continue; /* not TCP */
742 if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
743 continue; /* huh? */
744 LOG (GNUNET_ERROR_TYPE_DEBUG, "Service `%s' will bind to `%s'\n",
745 service_name, GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
746 if (AF_INET == pos->ai_family)
747 {
748 GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen);
749 saddrlens[i] = pos->ai_addrlen;
750 saddrs[i] = GNUNET_malloc (saddrlens[i]);
751 GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
752 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
753 }
754 else
755 {
756 GNUNET_assert (AF_INET6 == pos->ai_family);
757 GNUNET_assert (sizeof (struct sockaddr_in6) == pos->ai_addrlen);
758 saddrlens[i] = pos->ai_addrlen;
759 saddrs[i] = GNUNET_malloc (saddrlens[i]);
760 GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
761 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
762 }
763 i++;
764 }
765 GNUNET_free (hostname);
766 freeaddrinfo (res);
767 resi = i;
768 }
769 else
770 {
771 /* will bind against everything, just set port */
772 if (disablev6)
773 {
774 /* V4-only */
775 resi = 1;
776 if (NULL != unixpath)
777 resi++;
778 i = 0;
779 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
780 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
781 if (NULL != unixpath)
782 {
783 add_unixpath (saddrs, saddrlens, unixpath, abstract);
784 i++;
785 }
786 saddrlens[i] = sizeof (struct sockaddr_in);
787 saddrs[i] = GNUNET_malloc (saddrlens[i]);
788#if HAVE_SOCKADDR_IN_SIN_LEN
789 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
790#endif
791 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
792 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
793 }
794 else
795 {
796 /* dual stack */
797 resi = 2;
798 if (NULL != unixpath)
799 resi++;
800 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
801 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
802 i = 0;
803 if (NULL != unixpath)
804 {
805 add_unixpath (saddrs, saddrlens, unixpath, abstract);
806 i++;
807 }
808 saddrlens[i] = sizeof (struct sockaddr_in6);
809 saddrs[i] = GNUNET_malloc (saddrlens[i]);
810#if HAVE_SOCKADDR_IN_SIN_LEN
811 ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
812#endif
813 ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
814 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
815 i++;
816 saddrlens[i] = sizeof (struct sockaddr_in);
817 saddrs[i] = GNUNET_malloc (saddrlens[i]);
818#if HAVE_SOCKADDR_IN_SIN_LEN
819 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
820#endif
821 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
822 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
823 }
824 }
825 GNUNET_free_non_null (unixpath);
826 *addrs = saddrs;
827 *addr_lens = saddrlens;
828 return resi;
829}
830
831
832#ifdef MINGW
833/**
834 * Read listen sockets from the parent process (ARM).
835 *
836 * @param sctx service context to initialize
837 * @return #GNUNET_YES if ok, #GNUNET_NO if not ok (must bind yourself),
838 * and #GNUNET_SYSERR on error.
839 */
840static int
841receive_sockets_from_parent (struct LEGACY_SERVICE_Context *sctx)
842{
843 const char *env_buf;
844 int fail;
845 uint64_t count;
846 uint64_t i;
847 HANDLE lsocks_pipe;
848
849 env_buf = getenv ("GNUNET_OS_READ_LSOCKS");
850 if ((NULL == env_buf) || (strlen (env_buf) <= 0))
851 return GNUNET_NO;
852 /* Using W32 API directly here, because this pipe will
853 * never be used outside of this function, and it's just too much of a bother
854 * to create a GNUnet API that boxes a HANDLE (the way it is done with socks)
855 */
856 lsocks_pipe = (HANDLE) strtoul (env_buf, NULL, 10);
857 if ( (0 == lsocks_pipe) || (INVALID_HANDLE_VALUE == lsocks_pipe))
858 return GNUNET_NO;
859 fail = 1;
860 do
861 {
862 int ret;
863 int fail2;
864 DWORD rd;
865
866 ret = ReadFile (lsocks_pipe, &count, sizeof (count), &rd, NULL);
867 if ((0 == ret) || (sizeof (count) != rd) || (0 == count))
868 break;
869 sctx->lsocks =
870 GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (count + 1));
871
872 fail2 = 1;
873 for (i = 0; i < count; i++)
874 {
875 WSAPROTOCOL_INFOA pi;
876 uint64_t size;
877 SOCKET s;
878
879 ret = ReadFile (lsocks_pipe, &size, sizeof (size), &rd, NULL);
880 if ( (0 == ret) || (sizeof (size) != rd) || (sizeof (pi) != size) )
881 break;
882 ret = ReadFile (lsocks_pipe, &pi, sizeof (pi), &rd, NULL);
883 if ( (0 == ret) || (sizeof (pi) != rd))
884 break;
885 s = WSASocketA (pi.iAddressFamily, pi.iSocketType, pi.iProtocol, &pi, 0, WSA_FLAG_OVERLAPPED);
886 sctx->lsocks[i] = GNUNET_NETWORK_socket_box_native (s);
887 if (NULL == sctx->lsocks[i])
888 break;
889 else if (i == count - 1)
890 fail2 = 0;
891 }
892 if (fail2)
893 break;
894 sctx->lsocks[count] = NULL;
895 fail = 0;
896 }
897 while (fail);
898
899 CloseHandle (lsocks_pipe);
900
901 if (fail)
902 {
903 LOG (GNUNET_ERROR_TYPE_ERROR,
904 _("Could not access a pre-bound socket, will try to bind myself\n"));
905 for (i = 0; (i < count) && (NULL != sctx->lsocks[i]); i++)
906 GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[i]));
907 GNUNET_free_non_null (sctx->lsocks);
908 sctx->lsocks = NULL;
909 return GNUNET_NO;
910 }
911 return GNUNET_YES;
912}
913#endif
914
915
916/**
917 * Setup addr, addrlen, idle_timeout
918 * based on configuration!
919 *
920 * Configuration may specify:
921 * - PORT (where to bind to for TCP)
922 * - UNIXPATH (where to bind to for UNIX domain sockets)
923 * - TIMEOUT (after how many ms does an inactive service timeout);
924 * - DISABLEV6 (disable support for IPv6, otherwise we use dual-stack)
925 * - BINDTO (hostname or IP address to bind to, otherwise we take everything)
926 * - ACCEPT_FROM (only allow connections from specified IPv4 subnets)
927 * - ACCEPT_FROM6 (only allow connections from specified IPv6 subnets)
928 * - REJECT_FROM (disallow allow connections from specified IPv4 subnets)
929 * - REJECT_FROM6 (disallow allow connections from specified IPv6 subnets)
930 *
931 * @param sctx service context to initialize
932 * @return #GNUNET_OK if configuration succeeded
933 */
934static int
935setup_service (struct LEGACY_SERVICE_Context *sctx)
936{
937 struct GNUNET_TIME_Relative idleout;
938 int tolerant;
939
940#ifndef MINGW
941 const char *nfds;
942 unsigned int cnt;
943 int flags;
944#endif
945
946 if (GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, "TIMEOUT"))
947 {
948 if (GNUNET_OK !=
949 GNUNET_CONFIGURATION_get_value_time (sctx->cfg, sctx->service_name,
950 "TIMEOUT", &idleout))
951 {
952 LOG (GNUNET_ERROR_TYPE_ERROR,
953 _("Specified value for `%s' of service `%s' is invalid\n"),
954 "TIMEOUT", sctx->service_name);
955 return GNUNET_SYSERR;
956 }
957 sctx->timeout = idleout;
958 }
959 else
960 sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
961
962 if (GNUNET_CONFIGURATION_have_value
963 (sctx->cfg, sctx->service_name, "TOLERANT"))
964 {
965 if (GNUNET_SYSERR ==
966 (tolerant =
967 GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name,
968 "TOLERANT")))
969 {
970 LOG (GNUNET_ERROR_TYPE_ERROR,
971 _("Specified value for `%s' of service `%s' is invalid\n"),
972 "TOLERANT", sctx->service_name);
973 return GNUNET_SYSERR;
974 }
975 }
976 else
977 tolerant = GNUNET_NO;
978
979#ifndef MINGW
980 errno = 0;
981 if ((NULL != (nfds = getenv ("LISTEN_FDS"))) &&
982 (1 == SSCANF (nfds, "%u", &cnt)) && (cnt > 0) && (cnt < FD_SETSIZE) &&
983 (cnt + 4 < FD_SETSIZE))
984 {
985 sctx->lsocks =
986 GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (cnt + 1));
987 while (0 < cnt--)
988 {
989 flags = fcntl (3 + cnt, F_GETFD);
990 if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) ||
991 (NULL ==
992 (sctx->lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
993 {
994 LOG (GNUNET_ERROR_TYPE_ERROR,
995 _
996 ("Could not access pre-bound socket %u, will try to bind myself\n"),
997 (unsigned int) 3 + cnt);
998 cnt++;
999 while (sctx->lsocks[cnt] != NULL)
1000 GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[cnt++]));
1001 GNUNET_free (sctx->lsocks);
1002 sctx->lsocks = NULL;
1003 break;
1004 }
1005 }
1006 unsetenv ("LISTEN_FDS");
1007 }
1008#else
1009 if (getenv ("GNUNET_OS_READ_LSOCKS") != NULL)
1010 {
1011 receive_sockets_from_parent (sctx);
1012 putenv ("GNUNET_OS_READ_LSOCKS=");
1013 }
1014#endif
1015
1016 if ((NULL == sctx->lsocks) &&
1017 (GNUNET_SYSERR ==
1018 LEGACY_SERVICE_get_server_addresses (sctx->service_name, sctx->cfg,
1019 &sctx->addrs, &sctx->addrlens)))
1020 return GNUNET_SYSERR;
1021 sctx->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
1022 sctx->match_uid =
1023 GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name,
1024 "UNIX_MATCH_UID");
1025 sctx->match_gid =
1026 GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name,
1027 "UNIX_MATCH_GID");
1028 process_acl4 (&sctx->v4_denied, sctx, "REJECT_FROM");
1029 process_acl4 (&sctx->v4_allowed, sctx, "ACCEPT_FROM");
1030 process_acl6 (&sctx->v6_denied, sctx, "REJECT_FROM6");
1031 process_acl6 (&sctx->v6_allowed, sctx, "ACCEPT_FROM6");
1032
1033 return GNUNET_OK;
1034}
1035
1036
1037/**
1038 * Get the name of the user that'll be used
1039 * to provide the service.
1040 *
1041 * @param sctx service context
1042 * @return value of the 'USERNAME' option
1043 */
1044static char *
1045get_user_name (struct LEGACY_SERVICE_Context *sctx)
1046{
1047 char *un;
1048
1049 if (GNUNET_OK !=
1050 GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->service_name,
1051 "USERNAME", &un))
1052 return NULL;
1053 return un;
1054}
1055
1056
1057/**
1058 * Write PID file.
1059 *
1060 * @param sctx service context
1061 * @param pid PID to write (should be equal to 'getpid()'
1062 * @return #GNUNET_OK on success (including no work to be done)
1063 */
1064static int
1065write_pid_file (struct LEGACY_SERVICE_Context *sctx, pid_t pid)
1066{
1067 FILE *pidfd;
1068 char *pif;
1069 char *user;
1070 char *rdir;
1071 int len;
1072
1073 if (NULL == (pif = get_pid_file_name (sctx)))
1074 return GNUNET_OK; /* no file desired */
1075 user = get_user_name (sctx);
1076 rdir = GNUNET_strdup (pif);
1077 len = strlen (rdir);
1078 while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
1079 len--;
1080 rdir[len] = '\0';
1081 if (0 != ACCESS (rdir, F_OK))
1082 {
1083 /* we get to create a directory -- and claim it
1084 * as ours! */
1085 (void) GNUNET_DISK_directory_create (rdir);
1086 if ((NULL != user) && (0 < strlen (user)))
1087 GNUNET_DISK_file_change_owner (rdir, user);
1088 }
1089 if (0 != ACCESS (rdir, W_OK | X_OK))
1090 {
1091 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", rdir);
1092 GNUNET_free (rdir);
1093 GNUNET_free_non_null (user);
1094 GNUNET_free (pif);
1095 return GNUNET_SYSERR;
1096 }
1097 GNUNET_free (rdir);
1098 pidfd = FOPEN (pif, "w");
1099 if (NULL == pidfd)
1100 {
1101 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "fopen", pif);
1102 GNUNET_free (pif);
1103 GNUNET_free_non_null (user);
1104 return GNUNET_SYSERR;
1105 }
1106 if (0 > FPRINTF (pidfd, "%u", pid))
1107 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fprintf", pif);
1108 GNUNET_break (0 == FCLOSE (pidfd));
1109 if ((NULL != user) && (0 < strlen (user)))
1110 GNUNET_DISK_file_change_owner (pif, user);
1111 GNUNET_free_non_null (user);
1112 GNUNET_free (pif);
1113 return GNUNET_OK;
1114}
1115
1116
1117/**
1118 * Task run during shutdown. Stops the server/service.
1119 *
1120 * @param cls the `struct LEGACY_SERVICE_Context`
1121 */
1122static void
1123shutdown_task (void *cls)
1124{
1125 struct LEGACY_SERVICE_Context *service = cls;
1126 struct GNUNET_SERVER_Handle *server = service->server;
1127
1128 service->shutdown_task = NULL;
1129 if (0 != (service->options & LEGACY_SERVICE_OPTION_SOFT_SHUTDOWN))
1130 GNUNET_SERVER_stop_listening (server);
1131 else
1132 GNUNET_SERVER_destroy (server);
1133}
1134
1135
1136/**
1137 * Initial task for the service.
1138 *
1139 * @param cls service context
1140 */
1141static void
1142service_task (void *cls)
1143{
1144 struct LEGACY_SERVICE_Context *sctx = cls;
1145 unsigned int i;
1146
1147 GNUNET_RESOLVER_connect (sctx->cfg);
1148 if (NULL != sctx->lsocks)
1149 sctx->server
1150 = GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks,
1151 sctx->timeout, sctx->require_found);
1152 else
1153 sctx->server
1154 = GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens,
1155 sctx->timeout, sctx->require_found);
1156 if (NULL == sctx->server)
1157 {
1158 if (NULL != sctx->addrs)
1159 for (i = 0; NULL != sctx->addrs[i]; i++)
1160 LOG (GNUNET_ERROR_TYPE_INFO,
1161 _("Failed to start `%s' at `%s'\n"),
1162 sctx->service_name, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
1163 sctx->ret = GNUNET_SYSERR;
1164 return;
1165 }
1166#ifndef WINDOWS
1167 if (NULL != sctx->addrs)
1168 for (i = 0; NULL != sctx->addrs[i]; i++)
1169 if ((AF_UNIX == sctx->addrs[i]->sa_family)
1170 && ('\0' != ((const struct sockaddr_un *)sctx->addrs[i])->sun_path[0]))
1171 GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path,
1172 sctx->match_uid,
1173 sctx->match_gid);
1174#endif
1175
1176
1177 if (0 == (sctx->options & LEGACY_SERVICE_OPTION_MANUAL_SHUTDOWN))
1178 {
1179 /* install a task that will kill the server
1180 * process if the scheduler ever gets a shutdown signal */
1181 sctx->shutdown_task = GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1182 sctx);
1183 }
1184 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
1185 GNUNET_memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
1186 i = 0;
1187 while (NULL != sctx->my_handlers[i].callback)
1188 sctx->my_handlers[i++].callback_cls = sctx;
1189 GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers);
1190 if (-1 != sctx->ready_confirm_fd)
1191 {
1192 GNUNET_break (1 == WRITE (sctx->ready_confirm_fd, ".", 1));
1193 GNUNET_break (0 == CLOSE (sctx->ready_confirm_fd));
1194 sctx->ready_confirm_fd = -1;
1195 write_pid_file (sctx, getpid ());
1196 }
1197 if (NULL != sctx->addrs)
1198 {
1199 i = 0;
1200 while (NULL != sctx->addrs[i])
1201 {
1202 LOG (GNUNET_ERROR_TYPE_INFO, _("Service `%s' runs at %s\n"),
1203 sctx->service_name, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
1204 i++;
1205 }
1206 }
1207 sctx->task (sctx->task_cls, sctx->server, sctx->cfg);
1208}
1209
1210
1211/**
1212 * Detach from terminal.
1213 *
1214 * @param sctx service context
1215 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1216 */
1217static int
1218detach_terminal (struct LEGACY_SERVICE_Context *sctx)
1219{
1220#ifndef MINGW
1221 pid_t pid;
1222 int nullfd;
1223 int filedes[2];
1224
1225 if (0 != PIPE (filedes))
1226 {
1227 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "pipe");
1228 return GNUNET_SYSERR;
1229 }
1230 pid = fork ();
1231 if (pid < 0)
1232 {
1233 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork");
1234 return GNUNET_SYSERR;
1235 }
1236 if (0 != pid)
1237 {
1238 /* Parent */
1239 char c;
1240
1241 GNUNET_break (0 == CLOSE (filedes[1]));
1242 c = 'X';
1243 if (1 != READ (filedes[0], &c, sizeof (char)))
1244 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "read");
1245 fflush (stdout);
1246 switch (c)
1247 {
1248 case '.':
1249 exit (0);
1250 case 'I':
1251 LOG (GNUNET_ERROR_TYPE_INFO, _("Service process failed to initialize\n"));
1252 break;
1253 case 'S':
1254 LOG (GNUNET_ERROR_TYPE_INFO,
1255 _("Service process could not initialize server function\n"));
1256 break;
1257 case 'X':
1258 LOG (GNUNET_ERROR_TYPE_INFO,
1259 _("Service process failed to report status\n"));
1260 break;
1261 }
1262 exit (1); /* child reported error */
1263 }
1264 GNUNET_break (0 == CLOSE (0));
1265 GNUNET_break (0 == CLOSE (1));
1266 GNUNET_break (0 == CLOSE (filedes[0]));
1267 nullfd = OPEN ("/dev/null", O_RDWR | O_APPEND);
1268 if (nullfd < 0)
1269 return GNUNET_SYSERR;
1270 /* set stdin/stdout to /dev/null */
1271 if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0))
1272 {
1273 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2");
1274 (void) CLOSE (nullfd);
1275 return GNUNET_SYSERR;
1276 }
1277 (void) CLOSE (nullfd);
1278 /* Detach from controlling terminal */
1279 pid = setsid ();
1280 if (-1 == pid)
1281 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "setsid");
1282 sctx->ready_confirm_fd = filedes[1];
1283#else
1284 /* FIXME: we probably need to do something else
1285 * elsewhere in order to fork the process itself... */
1286 FreeConsole ();
1287#endif
1288 return GNUNET_OK;
1289}
1290
1291
1292/**
1293 * Set user ID.
1294 *
1295 * @param sctx service context
1296 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1297 */
1298static int
1299set_user_id (struct LEGACY_SERVICE_Context *sctx)
1300{
1301 char *user;
1302
1303 if (NULL == (user = get_user_name (sctx)))
1304 return GNUNET_OK; /* keep */
1305#ifndef MINGW
1306 struct passwd *pws;
1307
1308 errno = 0;
1309 pws = getpwnam (user);
1310 if (NULL == pws)
1311 {
1312 LOG (GNUNET_ERROR_TYPE_ERROR,
1313 _("Cannot obtain information about user `%s': %s\n"), user,
1314 errno == 0 ? _("No such user") : STRERROR (errno));
1315 GNUNET_free (user);
1316 return GNUNET_SYSERR;
1317 }
1318 if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) ||
1319#if HAVE_INITGROUPS
1320 (0 != initgroups (user, pws->pw_gid)) ||
1321#endif
1322 (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid)))
1323 {
1324 if ((0 != setregid (pws->pw_gid, pws->pw_gid)) ||
1325 (0 != setreuid (pws->pw_uid, pws->pw_uid)))
1326 {
1327 LOG (GNUNET_ERROR_TYPE_ERROR, _("Cannot change user/group to `%s': %s\n"),
1328 user, STRERROR (errno));
1329 GNUNET_free (user);
1330 return GNUNET_SYSERR;
1331 }
1332 }
1333#endif
1334 GNUNET_free (user);
1335 return GNUNET_OK;
1336}
1337
1338
1339/**
1340 * Delete the PID file that was created by our parent.
1341 *
1342 * @param sctx service context
1343 */
1344static void
1345pid_file_delete (struct LEGACY_SERVICE_Context *sctx)
1346{
1347 char *pif = get_pid_file_name (sctx);
1348
1349 if (NULL == pif)
1350 return; /* no PID file */
1351 if (0 != UNLINK (pif))
1352 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", pif);
1353 GNUNET_free (pif);
1354}
1355
1356
1357/**
1358 * Run a standard GNUnet service startup sequence (initialize loggers
1359 * and configuration, parse options).
1360 *
1361 * @param argc number of command line arguments
1362 * @param argv command line arguments
1363 * @param service_name our service name
1364 * @param options service options
1365 * @param task main task of the service
1366 * @param task_cls closure for @a task
1367 * @return #GNUNET_SYSERR on error, #GNUNET_OK
1368 * if we shutdown nicely
1369 */
1370int
1371LEGACY_SERVICE_run (int argc, char *const *argv,
1372 const char *service_name,
1373 enum LEGACY_SERVICE_Options options,
1374 LEGACY_SERVICE_Main task,
1375 void *task_cls)
1376{
1377#define HANDLE_ERROR do { GNUNET_break (0); goto shutdown; } while (0)
1378
1379 int err;
1380 int ret;
1381 char *cfg_fn;
1382 char *opt_cfg_fn;
1383 char *loglev;
1384 char *logfile;
1385 int do_daemonize;
1386 unsigned int i;
1387 unsigned long long skew_offset;
1388 unsigned long long skew_variance;
1389 long long clock_offset;
1390 struct LEGACY_SERVICE_Context sctx;
1391 struct GNUNET_CONFIGURATION_Handle *cfg;
1392 const char *xdg;
1393
1394 struct GNUNET_GETOPT_CommandLineOption service_options[] = {
1395 GNUNET_GETOPT_OPTION_CFG_FILE (&opt_cfg_fn),
1396 GNUNET_GETOPT_OPTION_SET_ONE ('d',
1397 "daemonize",
1398 gettext_noop ("do daemonize (detach from terminal)"),
1399 &do_daemonize),
1400 GNUNET_GETOPT_OPTION_HELP (NULL),
1401 GNUNET_GETOPT_OPTION_LOGLEVEL (&loglev),
1402 GNUNET_GETOPT_OPTION_LOGFILE (&logfile),
1403 GNUNET_GETOPT_OPTION_VERSION (PACKAGE_VERSION " " VCS_VERSION),
1404 GNUNET_GETOPT_OPTION_END
1405 };
1406 err = 1;
1407 do_daemonize = 0;
1408 logfile = NULL;
1409 loglev = NULL;
1410 opt_cfg_fn = NULL;
1411 xdg = getenv ("XDG_CONFIG_HOME");
1412 if (NULL != xdg)
1413 GNUNET_asprintf (&cfg_fn,
1414 "%s%s%s",
1415 xdg,
1416 DIR_SEPARATOR_STR,
1417 GNUNET_OS_project_data_get ()->config_file);
1418 else
1419 cfg_fn = GNUNET_strdup (GNUNET_OS_project_data_get ()->user_config_file);
1420 memset (&sctx, 0, sizeof (sctx));
1421 sctx.options = options;
1422 sctx.ready_confirm_fd = -1;
1423 sctx.ret = GNUNET_OK;
1424 sctx.timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1425 sctx.task = task;
1426 sctx.task_cls = task_cls;
1427 sctx.service_name = service_name;
1428 sctx.cfg = cfg = GNUNET_CONFIGURATION_create ();
1429
1430 /* setup subsystems */
1431 ret = GNUNET_GETOPT_run (service_name, service_options, argc, argv);
1432 if (GNUNET_SYSERR == ret)
1433 goto shutdown;
1434 if (GNUNET_NO == ret)
1435 {
1436 err = 0;
1437 goto shutdown;
1438 }
1439 if (GNUNET_OK != GNUNET_log_setup (service_name, loglev, logfile))
1440 HANDLE_ERROR;
1441 if (NULL == opt_cfg_fn)
1442 opt_cfg_fn = GNUNET_strdup (cfg_fn);
1443 if (GNUNET_YES == GNUNET_DISK_file_test (opt_cfg_fn))
1444 {
1445 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_fn))
1446 {
1447 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1448 _("Malformed configuration file `%s', exit ...\n"),
1449 opt_cfg_fn);
1450 goto shutdown;
1451 }
1452 }
1453 else
1454 {
1455 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL))
1456 {
1457 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1458 _("Malformed configuration, exit ...\n"));
1459 goto shutdown;
1460 }
1461 if (0 != strcmp (opt_cfg_fn, cfg_fn))
1462 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1463 _("Could not access configuration file `%s'\n"),
1464 opt_cfg_fn);
1465 }
1466 if (GNUNET_OK != setup_service (&sctx))
1467 goto shutdown;
1468 if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sctx)))
1469 HANDLE_ERROR;
1470 if (GNUNET_OK != set_user_id (&sctx))
1471 goto shutdown;
1472 LOG (GNUNET_ERROR_TYPE_DEBUG,
1473 "Service `%s' runs with configuration from `%s'\n",
1474 service_name,
1475 opt_cfg_fn);
1476 if ((GNUNET_OK ==
1477 GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING",
1478 "SKEW_OFFSET", &skew_offset)) &&
1479 (GNUNET_OK ==
1480 GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING",
1481 "SKEW_VARIANCE", &skew_variance)))
1482 {
1483 clock_offset = skew_offset - skew_variance;
1484 GNUNET_TIME_set_offset (clock_offset);
1485 LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset);
1486 }
1487 /* actually run service */
1488 err = 0;
1489 GNUNET_SCHEDULER_run (&service_task, &sctx);
1490 /* shutdown */
1491 if ((1 == do_daemonize) && (NULL != sctx.server))
1492 pid_file_delete (&sctx);
1493 GNUNET_free_non_null (sctx.my_handlers);
1494
1495shutdown:
1496 if (-1 != sctx.ready_confirm_fd)
1497 {
1498 if (1 != WRITE (sctx.ready_confirm_fd, err ? "I" : "S", 1))
1499 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write");
1500 GNUNET_break (0 == CLOSE (sctx.ready_confirm_fd));
1501 }
1502#if HAVE_MALLINFO
1503 {
1504 char *counter;
1505
1506 if ( (GNUNET_YES ==
1507 GNUNET_CONFIGURATION_have_value (sctx.cfg, service_name,
1508 "GAUGER_HEAP")) &&
1509 (GNUNET_OK ==
1510 GNUNET_CONFIGURATION_get_value_string (sctx.cfg, service_name,
1511 "GAUGER_HEAP",
1512 &counter)) )
1513 {
1514 struct mallinfo mi;
1515
1516 mi = mallinfo ();
1517 GAUGER (service_name, counter, mi.usmblks, "blocks");
1518 GNUNET_free (counter);
1519 }
1520 }
1521#endif
1522 GNUNET_CONFIGURATION_destroy (cfg);
1523 i = 0;
1524 if (NULL != sctx.addrs)
1525 while (NULL != sctx.addrs[i])
1526 GNUNET_free (sctx.addrs[i++]);
1527 GNUNET_free_non_null (sctx.addrs);
1528 GNUNET_free_non_null (sctx.addrlens);
1529 GNUNET_free_non_null (logfile);
1530 GNUNET_free_non_null (loglev);
1531 GNUNET_free (cfg_fn);
1532 GNUNET_free_non_null (opt_cfg_fn);
1533 GNUNET_free_non_null (sctx.v4_denied);
1534 GNUNET_free_non_null (sctx.v6_denied);
1535 GNUNET_free_non_null (sctx.v4_allowed);
1536 GNUNET_free_non_null (sctx.v6_allowed);
1537
1538 return err ? GNUNET_SYSERR : sctx.ret;
1539}
1540
1541
1542/**
1543 * Run a service startup sequence within an existing
1544 * initialized system.
1545 *
1546 * @param service_name our service name
1547 * @param cfg configuration to use
1548 * @param options service options
1549 * @return NULL on error, service handle
1550 */
1551struct LEGACY_SERVICE_Context *
1552LEGACY_SERVICE_start (const char *service_name,
1553 const struct GNUNET_CONFIGURATION_Handle *cfg,
1554 enum LEGACY_SERVICE_Options options)
1555{
1556 int i;
1557 struct LEGACY_SERVICE_Context *sctx;
1558
1559 sctx = GNUNET_new (struct LEGACY_SERVICE_Context);
1560 sctx->ready_confirm_fd = -1; /* no daemonizing */
1561 sctx->ret = GNUNET_OK;
1562 sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1563 sctx->service_name = service_name;
1564 sctx->cfg = cfg;
1565 sctx->options = options;
1566
1567 /* setup subsystems */
1568 if (GNUNET_OK != setup_service (sctx))
1569 {
1570 LEGACY_SERVICE_stop (sctx);
1571 return NULL;
1572 }
1573 if (NULL != sctx->lsocks)
1574 sctx->server =
1575 GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks,
1576 sctx->timeout, sctx->require_found);
1577 else
1578 sctx->server =
1579 GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens,
1580 sctx->timeout, sctx->require_found);
1581
1582 if (NULL == sctx->server)
1583 {
1584 LEGACY_SERVICE_stop (sctx);
1585 return NULL;
1586 }
1587#ifndef WINDOWS
1588 if (NULL != sctx->addrs)
1589 for (i = 0; NULL != sctx->addrs[i]; i++)
1590 if ((AF_UNIX == sctx->addrs[i]->sa_family)
1591 && ('\0' != ((const struct sockaddr_un *)sctx->addrs[i])->sun_path[0]))
1592 GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path,
1593 sctx->match_uid,
1594 sctx->match_gid);
1595#endif
1596 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
1597 GNUNET_memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
1598 i = 0;
1599 while ((sctx->my_handlers[i].callback != NULL))
1600 sctx->my_handlers[i++].callback_cls = sctx;
1601 GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers);
1602 return sctx;
1603}
1604
1605
1606/**
1607 * Obtain the server used by a service. Note that the server must NOT
1608 * be destroyed by the caller.
1609 *
1610 * @param ctx the service context returned from the start function
1611 * @return handle to the server for this service, NULL if there is none
1612 */
1613struct GNUNET_SERVER_Handle *
1614LEGACY_SERVICE_get_server (struct LEGACY_SERVICE_Context *ctx)
1615{
1616 return ctx->server;
1617}
1618
1619
1620/**
1621 * Get the NULL-terminated array of listen sockets for this service.
1622 *
1623 * @param ctx service context to query
1624 * @return NULL if there are no listen sockets, otherwise NULL-terminated
1625 * array of listen sockets.
1626 */
1627struct GNUNET_NETWORK_Handle *const*
1628LEGACY_SERVICE_get_listen_sockets (struct LEGACY_SERVICE_Context *ctx)
1629{
1630 return ctx->lsocks;
1631}
1632
1633
1634/**
1635 * Stop a service that was started with "LEGACY_SERVICE_start".
1636 *
1637 * @param sctx the service context returned from the start function
1638 */
1639void
1640LEGACY_SERVICE_stop (struct LEGACY_SERVICE_Context *sctx)
1641{
1642 unsigned int i;
1643
1644#if HAVE_MALLINFO
1645 {
1646 char *counter;
1647
1648 if ( (GNUNET_YES ==
1649 GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name,
1650 "GAUGER_HEAP")) &&
1651 (GNUNET_OK ==
1652 GNUNET_CONFIGURATION_get_value_string (sctx->cfg, sctx->service_name,
1653 "GAUGER_HEAP",
1654 &counter)) )
1655 {
1656 struct mallinfo mi;
1657
1658 mi = mallinfo ();
1659 GAUGER (sctx->service_name, counter, mi.usmblks, "blocks");
1660 GNUNET_free (counter);
1661 }
1662 }
1663#endif
1664 if (NULL != sctx->shutdown_task)
1665 {
1666 GNUNET_SCHEDULER_cancel (sctx->shutdown_task);
1667 sctx->shutdown_task = NULL;
1668 }
1669 if (NULL != sctx->server)
1670 GNUNET_SERVER_destroy (sctx->server);
1671 GNUNET_free_non_null (sctx->my_handlers);
1672 if (NULL != sctx->addrs)
1673 {
1674 i = 0;
1675 while (NULL != sctx->addrs[i])
1676 GNUNET_free (sctx->addrs[i++]);
1677 GNUNET_free (sctx->addrs);
1678 }
1679 GNUNET_free_non_null (sctx->addrlens);
1680 GNUNET_free_non_null (sctx->v4_denied);
1681 GNUNET_free_non_null (sctx->v6_denied);
1682 GNUNET_free_non_null (sctx->v4_allowed);
1683 GNUNET_free_non_null (sctx->v6_allowed);
1684 GNUNET_free (sctx);
1685}
1686
1687
1688/* end of service.c */
diff --git a/src/transport/test_plugin_transport.c b/src/transport/test_plugin_transport.c
index be79d5499..1d92588ea 100644
--- a/src/transport/test_plugin_transport.c
+++ b/src/transport/test_plugin_transport.c
@@ -552,7 +552,7 @@ setup_plugin_environment ()
552 552
553 553
554static int 554static int
555handle_helper_message (void *cls, void *client, 555handle_helper_message (void *cls,
556 const struct GNUNET_MessageHeader *hdr) 556 const struct GNUNET_MessageHeader *hdr)
557{ 557{
558 return GNUNET_OK; 558 return GNUNET_OK;
diff --git a/src/transport/test_transport_api_reliability.c b/src/transport/test_transport_api_reliability.c
index 375a935c8..e5ba2831b 100644
--- a/src/transport/test_transport_api_reliability.c
+++ b/src/transport/test_transport_api_reliability.c
@@ -217,7 +217,7 @@ notify_receive (void *cls,
217{ 217{
218 static int n; 218 static int n;
219 unsigned int s; 219 unsigned int s;
220 char cbuf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; 220 char cbuf[GNUNET_MAX_MESSAGE_SIZE - 1];
221 221
222 if (GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE != ntohs (hdr->header.type)) 222 if (GNUNET_TRANSPORT_TESTING_SIMPLE_MTYPE != ntohs (hdr->header.type))
223 return; 223 return;
diff --git a/src/transport/transport_api_address_to_string.c b/src/transport/transport_api_address_to_string.c
index b9c72dcb3..902764a8f 100644
--- a/src/transport/transport_api_address_to_string.c
+++ b/src/transport/transport_api_address_to_string.c
@@ -199,10 +199,10 @@ GNUNET_TRANSPORT_address_to_string (const struct GNUNET_CONFIGURATION_Handle *cf
199 199
200 alen = address->address_length; 200 alen = address->address_length;
201 slen = strlen (address->transport_name) + 1; 201 slen = strlen (address->transport_name) + 1;
202 if ( (alen + slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE 202 if ( (alen + slen >= GNUNET_MAX_MESSAGE_SIZE
203 - sizeof (struct AddressLookupMessage)) || 203 - sizeof (struct AddressLookupMessage)) ||
204 (alen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || 204 (alen >= GNUNET_MAX_MESSAGE_SIZE) ||
205 (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ) 205 (slen >= GNUNET_MAX_MESSAGE_SIZE) )
206 { 206 {
207 GNUNET_break (0); 207 GNUNET_break (0);
208 GNUNET_free (alc); 208 GNUNET_free (alc);
diff --git a/src/transport/transport_api_core.c b/src/transport/transport_api_core.c
index c99ade92f..9c29d4908 100644
--- a/src/transport/transport_api_core.c
+++ b/src/transport/transport_api_core.c
@@ -425,7 +425,7 @@ mq_send_impl (struct GNUNET_MQ_Handle *mq,
425 425
426 GNUNET_assert (GNUNET_YES == n->is_ready); 426 GNUNET_assert (GNUNET_YES == n->is_ready);
427 msize = ntohs (msg->size); 427 msize = ntohs (msg->size);
428 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*obm)) 428 if (msize >= GNUNET_MAX_MESSAGE_SIZE - sizeof (*obm))
429 { 429 {
430 GNUNET_break (0); 430 GNUNET_break (0);
431 GNUNET_MQ_impl_send_continue (mq); 431 GNUNET_MQ_impl_send_continue (mq);
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index df319fe77..9be572bb6 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -30,10 +30,9 @@ W32CONSOLEHELPER = gnunet-helper-w32-console
30endif 30endif
31 31
32if !MINGW 32if !MINGW
33 SERVER_CLIENT_UNIX = test_server_with_client_unix 33 TEST_CLIENT_UNIX_NC = test_client_unix.nc
34 TEST_CLIENT_UNIC_NC = test_client_unix.nc
35else 34else
36 TEST_CLIENT_UNIC_NC = 35 TEST_CLIENT_UNIX_NC =
37endif 36endif
38 37
39if USE_COVERAGE 38if USE_COVERAGE
@@ -68,7 +67,6 @@ libgnunetutil_la_SOURCES = \
68 common_logging.c \ 67 common_logging.c \
69 configuration.c \ 68 configuration.c \
70 configuration_loader.c \ 69 configuration_loader.c \
71 connection.c \
72 container_bloomfilter.c \ 70 container_bloomfilter.c \
73 container_heap.c \ 71 container_heap.c \
74 container_meta_data.c \ 72 container_meta_data.c \
@@ -108,16 +106,10 @@ libgnunetutil_la_SOURCES = \
108 program.c \ 106 program.c \
109 resolver_api.c resolver.h \ 107 resolver_api.c resolver.h \
110 scheduler.c \ 108 scheduler.c \
111 server.c \
112 server_mst.c \
113 server_nc.c \
114 server_tc.c \
115 service.c \ 109 service.c \
116 service_new.c \
117 signal.c \ 110 signal.c \
118 strings.c \ 111 strings.c \
119 time.c \ 112 time.c \
120 socks.c \
121 speedup.c speedup.h 113 speedup.c speedup.h
122 114
123libgnunetutil_la_LIBADD = \ 115libgnunetutil_la_LIBADD = \
@@ -263,14 +255,13 @@ if HAVE_BENCHMARKS
263endif 255endif
264 256
265if HAVE_SSH_KEY 257if HAVE_SSH_KEY
266 SSH_USING_TESTS = test_socks.nc 258# SSH_USING_TESTS = test_socks.nc
267endif 259endif
268 260
269check_PROGRAMS = \ 261check_PROGRAMS = \
270 test_bio \ 262 test_bio \
271 test_client.nc \ 263 test_client.nc \
272 $(TEST_CLIENT_UNIX_NC) \ 264 $(TEST_CLIENT_UNIX_NC) \
273 $(SSH_USING_TESTS) \
274 test_common_allocation \ 265 test_common_allocation \
275 test_common_endian \ 266 test_common_endian \
276 test_common_logging \ 267 test_common_logging \
@@ -298,12 +289,6 @@ check_PROGRAMS = \
298 test_crypto_rsa \ 289 test_crypto_rsa \
299 test_disk \ 290 test_disk \
300 test_getopt \ 291 test_getopt \
301 test_connection.nc \
302 test_connection_addressing.nc \
303 test_connection_receive_cancel.nc \
304 test_connection_timeout.nc \
305 test_connection_timeout_no_connect.nc \
306 test_connection_transmit_cancel.nc \
307 test_mq \ 292 test_mq \
308 test_os_network \ 293 test_os_network \
309 test_peer \ 294 test_peer \
@@ -312,11 +297,6 @@ check_PROGRAMS = \
312 test_resolver_api.nc \ 297 test_resolver_api.nc \
313 test_scheduler \ 298 test_scheduler \
314 test_scheduler_delay \ 299 test_scheduler_delay \
315 test_server.nc \
316 test_server_disconnect.nc \
317 test_server_with_client.nc \
318 test_server_mst_interrupt.nc \
319 $(SERVER_CLIENT_UNIX) \
320 test_service \ 300 test_service \
321 test_strings \ 301 test_strings \
322 test_strings_to_data \ 302 test_strings_to_data \
@@ -330,18 +310,7 @@ check_PROGRAMS = \
330# Declare .nc (NO-CONCURRENCY) as a test extension so that we can impart 310# Declare .nc (NO-CONCURRENCY) as a test extension so that we can impart
331# sequential execution order for them 311# sequential execution order for them
332TEST_EXTENSIONS = .nc 312TEST_EXTENSIONS = .nc
333test_connection.log: test_client.log 313test_test_client_unix.log: test_client.log
334test_connection_addressing.log: test_connection.log
335test_connection_timeout_no_connect.log: test_connection_addressing.log
336test_connection_transmit_cancel.log: test_connection_timeout_no_connect.log
337test_connection_receive_cancel.log: test_connection_transmit_cancel.log
338test_connection_timeout.log: test_connection_receive_cancel.log
339test_resolver_api.log: test_connection_timeout.log
340test_server.log: test_resolver_api.log
341test_server_disconnect.log: test_server.log
342test_server_with_client.log: test_server_disconnect.log
343test_server_mst_interrupt.log: test_server_with_client.log
344test_client_unix.log: test_server_mst_interrupt.log
345 314
346test_bio_SOURCES = \ 315test_bio_SOURCES = \
347 test_bio.c 316 test_bio.c
@@ -518,36 +487,6 @@ test_getopt_SOURCES = \
518test_getopt_LDADD = \ 487test_getopt_LDADD = \
519 libgnunetutil.la 488 libgnunetutil.la
520 489
521test_connection_nc_SOURCES = \
522 test_connection.c
523test_connection_nc_LDADD = \
524 libgnunetutil.la
525
526test_connection_addressing_nc_SOURCES = \
527 test_connection_addressing.c
528test_connection_addressing_nc_LDADD = \
529 libgnunetutil.la
530
531test_connection_receive_cancel_nc_SOURCES = \
532 test_connection_receive_cancel.c
533test_connection_receive_cancel_nc_LDADD = \
534 libgnunetutil.la
535
536test_connection_timeout_nc_SOURCES = \
537 test_connection_timeout.c
538test_connection_timeout_nc_LDADD = \
539 libgnunetutil.la
540
541test_connection_timeout_no_connect_nc_SOURCES = \
542 test_connection_timeout_no_connect.c
543test_connection_timeout_no_connect_nc_LDADD = \
544 libgnunetutil.la
545
546test_connection_transmit_cancel_nc_SOURCES = \
547 test_connection_transmit_cancel.c
548test_connection_transmit_cancel_nc_LDADD = \
549 libgnunetutil.la
550
551test_mq_SOURCES = \ 490test_mq_SOURCES = \
552 test_mq.c 491 test_mq.c
553test_mq_LDADD = \ 492test_mq_LDADD = \
@@ -588,32 +527,6 @@ test_scheduler_delay_SOURCES = \
588test_scheduler_delay_LDADD = \ 527test_scheduler_delay_LDADD = \
589 libgnunetutil.la 528 libgnunetutil.la
590 529
591test_server_mst_interrupt_nc_SOURCES = \
592 test_server_mst_interrupt.c
593test_server_mst_interrupt_nc_LDADD = \
594 libgnunetutil.la
595
596test_server_nc_SOURCES = \
597 test_server.c
598test_server_nc_LDADD = \
599 libgnunetutil.la
600
601test_server_disconnect_nc_SOURCES = \
602 test_server_disconnect.c
603test_server_disconnect_nc_LDADD = \
604 libgnunetutil.la
605
606test_server_with_client_nc_SOURCES = \
607 test_server_with_client.c
608test_server_with_client_nc_LDADD = \
609 libgnunetutil.la
610
611test_server_with_client_unix_SOURCES = \
612 test_server_with_client_unix.c
613test_server_with_client_unix_LDADD = \
614 libgnunetutil.la
615
616
617test_service_SOURCES = \ 530test_service_SOURCES = \
618 test_service.c 531 test_service.c
619test_service_LDADD = \ 532test_service_LDADD = \
@@ -624,7 +537,6 @@ test_strings_SOURCES = \
624test_strings_LDADD = \ 537test_strings_LDADD = \
625 libgnunetutil.la 538 libgnunetutil.la
626 539
627
628test_strings_to_data_SOURCES = \ 540test_strings_to_data_SOURCES = \
629 test_strings_to_data.c 541 test_strings_to_data.c
630test_strings_to_data_LDADD = \ 542test_strings_to_data_LDADD = \
diff --git a/src/util/bandwidth.c b/src/util/bandwidth.c
index a059fc738..bc0c3b9b4 100644
--- a/src/util/bandwidth.c
+++ b/src/util/bandwidth.c
@@ -184,8 +184,8 @@ update_excess (struct GNUNET_BANDWIDTH_Tracker *av)
184 } 184 }
185 /* negative current_consumption means that we have savings */ 185 /* negative current_consumption means that we have savings */
186 max_carry = ((uint64_t) av->available_bytes_per_s__) * av->max_carry_s__; 186 max_carry = ((uint64_t) av->available_bytes_per_s__) * av->max_carry_s__;
187 if (max_carry < GNUNET_SERVER_MAX_MESSAGE_SIZE) 187 if (max_carry < GNUNET_MAX_MESSAGE_SIZE)
188 max_carry = GNUNET_SERVER_MAX_MESSAGE_SIZE; 188 max_carry = GNUNET_MAX_MESSAGE_SIZE;
189 if (max_carry > INT64_MAX) 189 if (max_carry > INT64_MAX)
190 max_carry = INT64_MAX; 190 max_carry = INT64_MAX;
191 left_bytes = current_consumption + max_carry; 191 left_bytes = current_consumption + max_carry;
@@ -224,10 +224,10 @@ update_excess (struct GNUNET_BANDWIDTH_Tracker *av)
224/** 224/**
225 * Initialize bandwidth tracker. Note that in addition to the 225 * Initialize bandwidth tracker. Note that in addition to the
226 * 'max_carry_s' limit, we also always allow at least 226 * 'max_carry_s' limit, we also always allow at least
227 * #GNUNET_SERVER_MAX_MESSAGE_SIZE to accumulate. So if the 227 * #GNUNET_MAX_MESSAGE_SIZE to accumulate. So if the
228 * bytes-per-second limit is so small that within 'max_carry_s' not 228 * bytes-per-second limit is so small that within 'max_carry_s' not
229 * even #GNUNET_SERVER_MAX_MESSAGE_SIZE is allowed to accumulate, it is 229 * even #GNUNET_MAX_MESSAGE_SIZE is allowed to accumulate, it is
230 * ignored and replaced by #GNUNET_SERVER_MAX_MESSAGE_SIZE (which is in 230 * ignored and replaced by #GNUNET_MAX_MESSAGE_SIZE (which is in
231 * bytes). 231 * bytes).
232 * 232 *
233 * To stop notifications about updates and excess callbacks use 233 * To stop notifications about updates and excess callbacks use
@@ -271,10 +271,10 @@ GNUNET_BANDWIDTH_tracker_init2 (struct GNUNET_BANDWIDTH_Tracker *av,
271/** 271/**
272 * Initialize bandwidth tracker. Note that in addition to the 272 * Initialize bandwidth tracker. Note that in addition to the
273 * 'max_carry_s' limit, we also always allow at least 273 * 'max_carry_s' limit, we also always allow at least
274 * #GNUNET_SERVER_MAX_MESSAGE_SIZE to accumulate. So if the 274 * #GNUNET_MAX_MESSAGE_SIZE to accumulate. So if the
275 * bytes-per-second limit is so small that within 'max_carry_s' not 275 * bytes-per-second limit is so small that within 'max_carry_s' not
276 * even #GNUNET_SERVER_MAX_MESSAGE_SIZE is allowed to accumulate, it is 276 * even #GNUNET_MAX_MESSAGE_SIZE is allowed to accumulate, it is
277 * ignored and replaced by #GNUNET_SERVER_MAX_MESSAGE_SIZE (which is in 277 * ignored and replaced by #GNUNET_MAX_MESSAGE_SIZE (which is in
278 * bytes). 278 * bytes).
279 * 279 *
280 * @param av tracker to initialize 280 * @param av tracker to initialize
@@ -345,8 +345,8 @@ update_tracker (struct GNUNET_BANDWIDTH_Tracker *av)
345 left_bytes = - av->consumption_since_last_update__; 345 left_bytes = - av->consumption_since_last_update__;
346 max_carry = ((unsigned long long) av->available_bytes_per_s__) * 346 max_carry = ((unsigned long long) av->available_bytes_per_s__) *
347 av->max_carry_s__; 347 av->max_carry_s__;
348 if (max_carry < GNUNET_SERVER_MAX_MESSAGE_SIZE) 348 if (max_carry < GNUNET_MAX_MESSAGE_SIZE)
349 max_carry = GNUNET_SERVER_MAX_MESSAGE_SIZE; 349 max_carry = GNUNET_MAX_MESSAGE_SIZE;
350 if (max_carry > INT64_MAX) 350 if (max_carry > INT64_MAX)
351 max_carry = INT64_MAX; 351 max_carry = INT64_MAX;
352 if (max_carry > left_bytes) 352 if (max_carry > left_bytes)
diff --git a/src/util/client.c b/src/util/client.c
index 163ae6eb9..3d74bff33 100644
--- a/src/util/client.c
+++ b/src/util/client.c
@@ -35,6 +35,15 @@
35 35
36#define LOG(kind,...) GNUNET_log_from (kind, "util-client",__VA_ARGS__) 36#define LOG(kind,...) GNUNET_log_from (kind, "util-client",__VA_ARGS__)
37 37
38/**
39 * Timeout we use on TCP connect before trying another
40 * result from the DNS resolver. Actual value used
41 * is this value divided by the number of address families.
42 * Default is 5s.
43 */
44#define CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
45
46
38 47
39/** 48/**
40 * Internal state for a client connected to a GNUnet service. 49 * Internal state for a client connected to a GNUnet service.
@@ -656,7 +665,7 @@ try_connect_using_address (void *cls,
656 GNUNET_CONTAINER_DLL_insert (cstate->ap_head, 665 GNUNET_CONTAINER_DLL_insert (cstate->ap_head,
657 cstate->ap_tail, 666 cstate->ap_tail,
658 ap); 667 ap);
659 ap->task = GNUNET_SCHEDULER_add_write_net (GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT, 668 ap->task = GNUNET_SCHEDULER_add_write_net (CONNECT_RETRY_TIMEOUT,
660 ap->sock, 669 ap->sock,
661 &connect_probe_continuation, 670 &connect_probe_continuation,
662 ap); 671 ap);
@@ -760,7 +769,7 @@ start_connect (void *cls)
760 cstate->dns_active 769 cstate->dns_active
761 = GNUNET_RESOLVER_ip_get (cstate->hostname, 770 = GNUNET_RESOLVER_ip_get (cstate->hostname,
762 AF_UNSPEC, 771 AF_UNSPEC,
763 GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT, 772 CONNECT_RETRY_TIMEOUT,
764 &try_connect_using_address, 773 &try_connect_using_address,
765 cstate); 774 cstate);
766} 775}
diff --git a/src/util/getopt.c b/src/util/getopt.c
index ff62dba9b..036e0f4be 100644
--- a/src/util/getopt.c
+++ b/src/util/getopt.c
@@ -26,7 +26,7 @@ USA.
26 26
27 27
28This code was heavily modified for GNUnet. 28This code was heavily modified for GNUnet.
29Copyright Copyright (C) 2006 Christian Grothoff 29Copyright Copyright (C) 2006, 2017 Christian Grothoff
30*/ 30*/
31 31
32/** 32/**
@@ -845,9 +845,13 @@ GN_getopt_internal (int argc, char *const *argv, const char *optstring,
845 } 845 }
846} 846}
847 847
848
848static int 849static int
849GNgetopt_long (int argc, char *const *argv, const char *options, 850GNgetopt_long (int argc,
850 const struct GNoption *long_options, int *opt_index) 851 char *const *argv,
852 const char *options,
853 const struct GNoption *long_options,
854 int *opt_index)
851{ 855{
852 return GN_getopt_internal (argc, argv, options, long_options, opt_index, 0); 856 return GN_getopt_internal (argc, argv, options, long_options, opt_index, 0);
853} 857}
@@ -867,16 +871,17 @@ GNgetopt_long (int argc, char *const *argv, const char *options,
867int 871int
868GNUNET_GETOPT_run (const char *binaryOptions, 872GNUNET_GETOPT_run (const char *binaryOptions,
869 const struct GNUNET_GETOPT_CommandLineOption *allOptions, 873 const struct GNUNET_GETOPT_CommandLineOption *allOptions,
870 unsigned int argc, char *const *argv) 874 unsigned int argc,
875 char *const *argv)
871{ 876{
872 struct GNoption *long_options; 877 struct GNoption *long_options;
873 struct GNUNET_GETOPT_CommandLineProcessorContext clpc; 878 struct GNUNET_GETOPT_CommandLineProcessorContext clpc;
874 int count; 879 int count;
875 int i;
876 char *shorts; 880 char *shorts;
877 int spos; 881 int spos;
878 int cont; 882 int cont;
879 int c; 883 int c;
884 uint8_t *seen;
880 885
881 GNUNET_assert (argc > 0); 886 GNUNET_assert (argc > 0);
882 GNoptind = 0; 887 GNoptind = 0;
@@ -885,13 +890,15 @@ GNUNET_GETOPT_run (const char *binaryOptions,
885 clpc.allOptions = allOptions; 890 clpc.allOptions = allOptions;
886 clpc.argv = argv; 891 clpc.argv = argv;
887 clpc.argc = argc; 892 clpc.argc = argc;
888 count = 0; 893 for (count = 0; NULL != allOptions[count].name; count++) ;
889 while (allOptions[count].name != NULL) 894
890 count++; 895 long_options = GNUNET_new_array (count + 1,
891 long_options = GNUNET_malloc (sizeof (struct GNoption) * (count + 1)); 896 struct GNoption);
897 seen = GNUNET_new_array (count,
898 uint8_t);
892 shorts = GNUNET_malloc (count * 2 + 1); 899 shorts = GNUNET_malloc (count * 2 + 1);
893 spos = 0; 900 spos = 0;
894 for (i = 0; i < count; i++) 901 for (unsigned i = 0; i < count; i++)
895 { 902 {
896 long_options[i].name = allOptions[i].name; 903 long_options[i].name = allOptions[i].name;
897 long_options[i].has_arg = allOptions[i].require_argument; 904 long_options[i].has_arg = allOptions[i].require_argument;
@@ -907,13 +914,17 @@ GNUNET_GETOPT_run (const char *binaryOptions,
907 long_options[count].val = '\0'; 914 long_options[count].val = '\0';
908 shorts[spos] = '\0'; 915 shorts[spos] = '\0';
909 cont = GNUNET_OK; 916 cont = GNUNET_OK;
917
910 /* main getopt loop */ 918 /* main getopt loop */
911 while (cont == GNUNET_OK) 919 while (GNUNET_OK == cont)
912 { 920 {
913 int option_index = 0; 921 int option_index = 0;
922 unsigned int i;
914 923
915 c = GNgetopt_long (argc, argv, shorts, long_options, &option_index); 924 c = GNgetopt_long (argc, argv,
916 925 shorts,
926 long_options,
927 &option_index);
917 if (c == GNUNET_SYSERR) 928 if (c == GNUNET_SYSERR)
918 break; /* No more flags to process */ 929 break; /* No more flags to process */
919 930
@@ -922,25 +933,46 @@ GNUNET_GETOPT_run (const char *binaryOptions,
922 clpc.currentArgument = GNoptind - 1; 933 clpc.currentArgument = GNoptind - 1;
923 if ((char) c == allOptions[i].shortName) 934 if ((char) c == allOptions[i].shortName)
924 { 935 {
925 cont = 936 cont = allOptions[i].processor (&clpc,
926 allOptions[i].processor (&clpc, allOptions[i].scls, 937 allOptions[i].scls,
927 allOptions[i].name, GNoptarg); 938 allOptions[i].name,
939 GNoptarg);
940 seen[i] = 1;
928 break; 941 break;
929 } 942 }
930 } 943 }
931 if (i == count) 944 if (i == count)
932 { 945 {
933 FPRINTF (stderr, _("Use %s to get a list of options.\n"), "--help"); 946 FPRINTF (stderr,
947 _("Use %s to get a list of options.\n"),
948 "--help");
934 cont = GNUNET_SYSERR; 949 cont = GNUNET_SYSERR;
935 } 950 }
936 } 951 }
937
938 GNUNET_free (shorts); 952 GNUNET_free (shorts);
939 GNUNET_free (long_options); 953 GNUNET_free (long_options);
940 if (cont != GNUNET_OK) 954
955 if (GNUNET_YES == cont)
941 { 956 {
942 return cont; 957 for (count = 0; NULL != allOptions[count].name; count++)
958 if ( (0 == seen[count]) &&
959 (allOptions[count].option_mandatory) )
960 {
961 FPRINTF (stderr,
962 _("Missing mandatory option `%s'.\n"),
963 allOptions[count].name);
964 cont = GNUNET_SYSERR;
965 }
943 } 966 }
967 GNUNET_free (seen);
968
969 /* call cleaners, if available */
970 for (count = 0; NULL != allOptions[count].name; count++)
971 if (NULL != allOptions[count].cleaner)
972 allOptions[count].cleaner (allOptions[count].scls);
973
974 if (GNUNET_OK != cont)
975 return cont;
944 return GNoptind; 976 return GNoptind;
945} 977}
946 978
diff --git a/src/util/getopt_helpers.c b/src/util/getopt_helpers.c
index 4d7104503..76342a6c9 100644
--- a/src/util/getopt_helpers.c
+++ b/src/util/getopt_helpers.c
@@ -38,11 +38,11 @@
38 * @param value not used (NULL) 38 * @param value not used (NULL)
39 * @return #GNUNET_NO (do not continue, not an error) 39 * @return #GNUNET_NO (do not continue, not an error)
40 */ 40 */
41int 41static int
42GNUNET_GETOPT_print_version_ (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 42print_version (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
43 void *scls, 43 void *scls,
44 const char *option, 44 const char *option,
45 const char *value) 45 const char *value)
46{ 46{
47 const char *version = scls; 47 const char *version = scls;
48 48
@@ -54,6 +54,26 @@ GNUNET_GETOPT_print_version_ (struct GNUNET_GETOPT_CommandLineProcessorContext *
54 54
55 55
56/** 56/**
57 * Define the option to print the version of
58 * the application (-v option)
59 *
60 * @param version string with the version number
61 */
62struct GNUNET_GETOPT_CommandLineOption
63GNUNET_GETOPT_OPTION_VERSION (const char *version)
64{
65 struct GNUNET_GETOPT_CommandLineOption clo = {
66 .shortName = 'v',
67 .name = "version",
68 .description = gettext_noop("print the version number"),
69 .processor = &print_version,
70 .scls = (void *) version
71 };
72 return clo;
73}
74
75
76/**
57 * At what offset does the help text start? 77 * At what offset does the help text start?
58 */ 78 */
59#define BORDER 29 79#define BORDER 29
@@ -67,11 +87,11 @@ GNUNET_GETOPT_print_version_ (struct GNUNET_GETOPT_CommandLineProcessorContext *
67 * @param value not used (NULL) 87 * @param value not used (NULL)
68 * @return #GNUNET_NO (do not continue, not an error) 88 * @return #GNUNET_NO (do not continue, not an error)
69 */ 89 */
70int 90static int
71GNUNET_GETOPT_format_help_ (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 91format_help (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
72 void *scls, 92 void *scls,
73 const char *option, 93 const char *option,
74 const char *value) 94 const char *value)
75{ 95{
76 const char *about = scls; 96 const char *about = scls;
77 size_t slen; 97 size_t slen;
@@ -165,6 +185,27 @@ OUTER:
165 185
166 186
167/** 187/**
188 * Defining the option to print the command line
189 * help text (-h option).
190 *
191 * @param about string with brief description of the application
192 */
193struct GNUNET_GETOPT_CommandLineOption
194GNUNET_GETOPT_OPTION_HELP (const char *about)
195{
196 struct GNUNET_GETOPT_CommandLineOption clo = {
197 .shortName = 'h',
198 .name = "help",
199 .description = gettext_noop("print this help"),
200 .processor = format_help,
201 .scls = (void *) about
202 };
203
204 return clo;
205}
206
207
208/**
168 * Set an option of type 'unsigned int' from the command line. Each 209 * Set an option of type 'unsigned int' from the command line. Each
169 * time the option flag is given, the value is incremented by one. 210 * time the option flag is given, the value is incremented by one.
170 * A pointer to this function should be passed as part of the 211 * A pointer to this function should be passed as part of the
@@ -173,17 +214,18 @@ OUTER:
173 * type 'int'. 214 * type 'int'.
174 * 215 *
175 * @param ctx command line processing context 216 * @param ctx command line processing context
176 * @param scls additional closure (will point to the 'int') 217 * @param scls additional closure (will point to the 'unsigned int')
177 * @param option name of the option 218 * @param option name of the option
178 * @param value not used (NULL) 219 * @param value not used (NULL)
179 * @return #GNUNET_OK 220 * @return #GNUNET_OK
180 */ 221 */
181int 222static int
182GNUNET_GETOPT_increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext 223increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
183 *ctx, void *scls, const char *option, 224 void *scls,
184 const char *value) 225 const char *option,
226 const char *value)
185{ 227{
186 int *val = scls; 228 unsigned int *val = scls;
187 229
188 (*val)++; 230 (*val)++;
189 return GNUNET_OK; 231 return GNUNET_OK;
@@ -191,6 +233,54 @@ GNUNET_GETOPT_increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext
191 233
192 234
193/** 235/**
236 * Increment @a val each time the option flag is given by one.
237 *
238 * @param shortName short name of the option
239 * @param name long name of the option
240 * @param argumentHelp help text for the option argument
241 * @param description long help text for the option
242 * @param[out] val increment by 1 each time the option is present
243 */
244struct GNUNET_GETOPT_CommandLineOption
245GNUNET_GETOPT_OPTION_INCREMENT_VALUE (char shortName,
246 const char *name,
247 const char *description,
248 unsigned int *val)
249{
250 struct GNUNET_GETOPT_CommandLineOption clo = {
251 .shortName = shortName,
252 .name = name,
253 .description = description,
254 .processor = &increment_value,
255 .scls = (void *) val
256 };
257
258 return clo;
259}
260
261
262/**
263 * Define the '-V' verbosity option. Using the option more
264 * than once increments @a level each time.
265 *
266 * @param[out] level set to the verbosity level
267 */
268struct GNUNET_GETOPT_CommandLineOption
269GNUNET_GETOPT_OPTION_VERBOSE (unsigned int *level)
270{
271 struct GNUNET_GETOPT_CommandLineOption clo = {
272 .shortName = 'V',
273 .name = "verbose",
274 .description = gettext_noop("be verbose"),
275 .processor = &increment_value,
276 .scls = (void *) level
277 };
278
279 return clo;
280}
281
282
283/**
194 * Set an option of type 'int' from the command line to 1 if the 284 * Set an option of type 'int' from the command line to 1 if the
195 * given option is present. 285 * given option is present.
196 * A pointer to this function should be passed as part of the 286 * A pointer to this function should be passed as part of the
@@ -204,9 +294,11 @@ GNUNET_GETOPT_increment_value (struct GNUNET_GETOPT_CommandLineProcessorContext
204 * @param value not used (NULL) 294 * @param value not used (NULL)
205 * @return #GNUNET_OK 295 * @return #GNUNET_OK
206 */ 296 */
207int 297static int
208GNUNET_GETOPT_set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 298set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
209 void *scls, const char *option, const char *value) 299 void *scls,
300 const char *option,
301 const char *value)
210{ 302{
211 int *val = scls; 303 int *val = scls;
212 304
@@ -216,6 +308,34 @@ GNUNET_GETOPT_set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
216 308
217 309
218/** 310/**
311 * Allow user to specify a flag (which internally means setting
312 * an integer to 1/#GNUNET_YES/#GNUNET_OK.
313 *
314 * @param shortName short name of the option
315 * @param name long name of the option
316 * @param argumentHelp help text for the option argument
317 * @param description long help text for the option
318 * @param[out] val set to 1 if the option is present
319 */
320struct GNUNET_GETOPT_CommandLineOption
321GNUNET_GETOPT_OPTION_SET_ONE (char shortName,
322 const char *name,
323 const char *description,
324 int *val)
325{
326 struct GNUNET_GETOPT_CommandLineOption clo = {
327 .shortName = shortName,
328 .name = name,
329 .description = description,
330 .processor = &set_one,
331 .scls = (void *) val
332 };
333
334 return clo;
335}
336
337
338/**
219 * Set an option of type 'char *' from the command line. 339 * Set an option of type 'char *' from the command line.
220 * A pointer to this function should be passed as part of the 340 * A pointer to this function should be passed as part of the
221 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options 341 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
@@ -229,31 +349,174 @@ GNUNET_GETOPT_set_one (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
229 * @param value actual value of the option (a string) 349 * @param value actual value of the option (a string)
230 * @return #GNUNET_OK 350 * @return #GNUNET_OK
231 */ 351 */
232int 352static int
233GNUNET_GETOPT_set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 353set_string (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
234 void *scls, const char *option, const char *value) 354 void *scls,
355 const char *option,
356 const char *value)
235{ 357{
236 char **val = scls; 358 char **val = scls;
237 359
238 GNUNET_assert (value != NULL); 360 GNUNET_assert (NULL != value);
239 GNUNET_free_non_null (*val); 361 GNUNET_free_non_null (*val);
240 *val = GNUNET_strdup (value); 362 *val = GNUNET_strdup (value);
241 return GNUNET_OK; 363 return GNUNET_OK;
242} 364}
243 365
244 366
245int 367/**
246GNUNET_GETOPT_set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 368 * Allow user to specify a string.
247 void *scls, const char *option, const char *value) 369 *
370 * @param shortName short name of the option
371 * @param name long name of the option
372 * @param argumentHelp help text for the option argument
373 * @param description long help text for the option
374 * @param[out] str set to the string
375 */
376struct GNUNET_GETOPT_CommandLineOption
377GNUNET_GETOPT_OPTION_STRING (char shortName,
378 const char *name,
379 const char *argumentHelp,
380 const char *description,
381 char **str)
382{
383 struct GNUNET_GETOPT_CommandLineOption clo = {
384 .shortName = shortName,
385 .name = name,
386 .argumentHelp = argumentHelp,
387 .description = description,
388 .require_argument = 1,
389 .processor = &set_string,
390 .scls = (void *) str
391 };
392
393 return clo;
394}
395
396
397/**
398 * Define the '-L' log level option. Note that we do not check
399 * that the log level is valid here.
400 *
401 * @param[out] level set to the log level
402 */
403struct GNUNET_GETOPT_CommandLineOption
404GNUNET_GETOPT_OPTION_LOGLEVEL (char **level)
405{
406 struct GNUNET_GETOPT_CommandLineOption clo = {
407 .shortName = 'L',
408 .name = "log",
409 .argumentHelp = "LOGLEVEL",
410 .description = gettext_noop("configure logging to use LOGLEVEL"),
411 .require_argument = 1,
412 .processor = &set_string,
413 .scls = (void *) level
414 };
415
416 return clo;
417}
418
419
420/**
421 * Set an option of type 'char *' from the command line with
422 * filename expansion a la #GNUNET_STRINGS_filename_expand().
423 *
424 * @param ctx command line processing context
425 * @param scls additional closure (will point to the `char *`,
426 * which will be allocated)
427 * @param option name of the option
428 * @param value actual value of the option (a string)
429 * @return #GNUNET_OK
430 */
431static int
432set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
433 void *scls,
434 const char *option,
435 const char *value)
248{ 436{
249 char **val = scls; 437 char **val = scls;
250 438
251 GNUNET_assert (value != NULL); 439 GNUNET_assert (NULL != value);
252 GNUNET_free_non_null (*val); 440 GNUNET_free_non_null (*val);
253 *val = GNUNET_STRINGS_filename_expand (value); 441 *val = GNUNET_STRINGS_filename_expand (value);
254 return GNUNET_OK; 442 return GNUNET_OK;
255} 443}
256 444
445
446/**
447 * Allow user to specify a filename (automatically path expanded).
448 *
449 * @param shortName short name of the option
450 * @param name long name of the option
451 * @param argumentHelp help text for the option argument
452 * @param description long help text for the option
453 * @param[out] str set to the string
454 */
455struct GNUNET_GETOPT_CommandLineOption
456GNUNET_GETOPT_OPTION_FILENAME (char shortName,
457 const char *name,
458 const char *argumentHelp,
459 const char *description,
460 char **str)
461{
462 struct GNUNET_GETOPT_CommandLineOption clo = {
463 .shortName = shortName,
464 .name = name,
465 .argumentHelp = argumentHelp,
466 .description = description,
467 .require_argument = 1,
468 .processor = &set_filename,
469 .scls = (void *) str
470 };
471
472 return clo;
473}
474
475
476/**
477 * Allow user to specify log file name (-l option)
478 *
479 * @param[out] logfn set to the name of the logfile
480 */
481struct GNUNET_GETOPT_CommandLineOption
482GNUNET_GETOPT_OPTION_LOGFILE (char **logfn)
483{
484 struct GNUNET_GETOPT_CommandLineOption clo = {
485 .shortName = 'l',
486 .name = "logfile",
487 .argumentHelp = "FILENAME",
488 .description = gettext_noop ("configure logging to write logs to FILENAME"),
489 .require_argument = 1,
490 .processor = &set_filename,
491 .scls = (void *) logfn
492 };
493
494 return clo;
495}
496
497
498/**
499 * Allow user to specify configuration file name (-c option)
500 *
501 * @param[out] fn set to the name of the configuration file
502 */
503struct GNUNET_GETOPT_CommandLineOption
504GNUNET_GETOPT_OPTION_CFG_FILE (char **fn)
505{
506 struct GNUNET_GETOPT_CommandLineOption clo = {
507 .shortName = 'c',
508 .name = "config",
509 .argumentHelp = "FILENAME",
510 .description = gettext_noop("use configuration file FILENAME"),
511 .require_argument = 1,
512 .processor = &set_filename,
513 .scls = (void *) fn
514 };
515
516 return clo;
517}
518
519
257/** 520/**
258 * Set an option of type 'unsigned long long' from the command line. 521 * Set an option of type 'unsigned long long' from the command line.
259 * A pointer to this function should be passed as part of the 522 * A pointer to this function should be passed as part of the
@@ -267,15 +530,21 @@ GNUNET_GETOPT_set_filename (struct GNUNET_GETOPT_CommandLineProcessorContext *ct
267 * @param value actual value of the option as a string. 530 * @param value actual value of the option as a string.
268 * @return #GNUNET_OK if parsing the value worked 531 * @return #GNUNET_OK if parsing the value worked
269 */ 532 */
270int 533static int
271GNUNET_GETOPT_set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 534set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
272 void *scls, const char *option, const char *value) 535 void *scls,
536 const char *option,
537 const char *value)
273{ 538{
274 unsigned long long *val = scls; 539 unsigned long long *val = scls;
275 540
276 if (1 != SSCANF (value, "%llu", val)) 541 if (1 != SSCANF (value,
542 "%llu",
543 val))
277 { 544 {
278 FPRINTF (stderr, _("You must pass a number to the `%s' option.\n"), option); 545 FPRINTF (stderr,
546 _("You must pass a number to the `%s' option.\n"),
547 option);
279 return GNUNET_SYSERR; 548 return GNUNET_SYSERR;
280 } 549 }
281 return GNUNET_OK; 550 return GNUNET_OK;
@@ -283,6 +552,36 @@ GNUNET_GETOPT_set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
283 552
284 553
285/** 554/**
555 * Allow user to specify an `unsigned long long`
556 *
557 * @param shortName short name of the option
558 * @param name long name of the option
559 * @param argumentHelp help text for the option argument
560 * @param description long help text for the option
561 * @param[out] val set to the value specified at the command line
562 */
563struct GNUNET_GETOPT_CommandLineOption
564GNUNET_GETOPT_OPTION_SET_ULONG (char shortName,
565 const char *name,
566 const char *argumentHelp,
567 const char *description,
568 unsigned long long *val)
569{
570 struct GNUNET_GETOPT_CommandLineOption clo = {
571 .shortName = shortName,
572 .name = name,
573 .argumentHelp = argumentHelp,
574 .description = description,
575 .require_argument = 1,
576 .processor = &set_ulong,
577 .scls = (void *) val
578 };
579
580 return clo;
581}
582
583
584/**
286 * Set an option of type 'struct GNUNET_TIME_Relative' from the command line. 585 * Set an option of type 'struct GNUNET_TIME_Relative' from the command line.
287 * A pointer to this function should be passed as part of the 586 * A pointer to this function should be passed as part of the
288 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options 587 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
@@ -295,9 +594,11 @@ GNUNET_GETOPT_set_ulong (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
295 * @param value actual value of the option as a string. 594 * @param value actual value of the option as a string.
296 * @return #GNUNET_OK if parsing the value worked 595 * @return #GNUNET_OK if parsing the value worked
297 */ 596 */
298int 597static int
299GNUNET_GETOPT_set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 598set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
300 void *scls, const char *option, const char *value) 599 void *scls,
600 const char *option,
601 const char *value)
301{ 602{
302 struct GNUNET_TIME_Relative *val = scls; 603 struct GNUNET_TIME_Relative *val = scls;
303 604
@@ -305,7 +606,74 @@ GNUNET_GETOPT_set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContex
305 GNUNET_STRINGS_fancy_time_to_relative (value, 606 GNUNET_STRINGS_fancy_time_to_relative (value,
306 val)) 607 val))
307 { 608 {
308 FPRINTF (stderr, _("You must pass relative time to the `%s' option.\n"), option); 609 FPRINTF (stderr,
610 _("You must pass relative time to the `%s' option.\n"),
611 option);
612 return GNUNET_SYSERR;
613 }
614 return GNUNET_OK;
615}
616
617
618/**
619 * Allow user to specify a `struct GNUNET_TIME_Relative`
620 * (using human-readable "fancy" time).
621 *
622 * @param shortName short name of the option
623 * @param name long name of the option
624 * @param argumentHelp help text for the option argument
625 * @param description long help text for the option
626 * @param[out] val set to the time specified at the command line
627 */
628struct GNUNET_GETOPT_CommandLineOption
629GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME (char shortName,
630 const char *name,
631 const char *argumentHelp,
632 const char *description,
633 struct GNUNET_TIME_Relative *val)
634{
635 struct GNUNET_GETOPT_CommandLineOption clo = {
636 .shortName = shortName,
637 .name = name,
638 .argumentHelp = argumentHelp,
639 .description = description,
640 .require_argument = 1,
641 .processor = &set_relative_time,
642 .scls = (void *) val
643 };
644
645 return clo;
646}
647
648
649/**
650 * Set an option of type 'struct GNUNET_TIME_Absolute' from the command line.
651 * A pointer to this function should be passed as part of the
652 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
653 * of this type. It should be followed by a pointer to a value of
654 * type 'struct GNUNET_TIME_Absolute'.
655 *
656 * @param ctx command line processing context
657 * @param scls additional closure (will point to the `struct GNUNET_TIME_Absolute`)
658 * @param option name of the option
659 * @param value actual value of the option as a string.
660 * @return #GNUNET_OK if parsing the value worked
661 */
662static int
663set_absolute_time (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
664 void *scls,
665 const char *option,
666 const char *value)
667{
668 struct GNUNET_TIME_Absolute *val = scls;
669
670 if (GNUNET_OK !=
671 GNUNET_STRINGS_fancy_time_to_absolute (value,
672 val))
673 {
674 FPRINTF (stderr,
675 _("You must pass absolute time to the `%s' option.\n"),
676 option);
309 return GNUNET_SYSERR; 677 return GNUNET_SYSERR;
310 } 678 }
311 return GNUNET_OK; 679 return GNUNET_OK;
@@ -313,6 +681,37 @@ GNUNET_GETOPT_set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContex
313 681
314 682
315/** 683/**
684 * Allow user to specify a `struct GNUNET_TIME_Absolute`
685 * (using human-readable "fancy" time).
686 *
687 * @param shortName short name of the option
688 * @param name long name of the option
689 * @param argumentHelp help text for the option argument
690 * @param description long help text for the option
691 * @param[out] val set to the time specified at the command line
692 */
693struct GNUNET_GETOPT_CommandLineOption
694GNUNET_GETOPT_OPTION_SET_ABSOLUTE_TIME (char shortName,
695 const char *name,
696 const char *argumentHelp,
697 const char *description,
698 struct GNUNET_TIME_Absolute *val)
699{
700 struct GNUNET_GETOPT_CommandLineOption clo = {
701 .shortName = shortName,
702 .name = name,
703 .argumentHelp = argumentHelp,
704 .description = description,
705 .require_argument = 1,
706 .processor = &set_absolute_time,
707 .scls = (void *) val
708 };
709
710 return clo;
711}
712
713
714/**
316 * Set an option of type 'unsigned int' from the command line. 715 * Set an option of type 'unsigned int' from the command line.
317 * A pointer to this function should be passed as part of the 716 * A pointer to this function should be passed as part of the
318 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options 717 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
@@ -325,19 +724,172 @@ GNUNET_GETOPT_set_relative_time (struct GNUNET_GETOPT_CommandLineProcessorContex
325 * @param value actual value of the option as a string. 724 * @param value actual value of the option as a string.
326 * @return #GNUNET_OK if parsing the value worked 725 * @return #GNUNET_OK if parsing the value worked
327 */ 726 */
328int 727static int
329GNUNET_GETOPT_set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, 728set_uint (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
330 void *scls, const char *option, const char *value) 729 void *scls,
730 const char *option,
731 const char *value)
331{ 732{
332 unsigned int *val = scls; 733 unsigned int *val = scls;
333 734
334 if (1 != SSCANF (value, "%u", val)) 735 if (1 != SSCANF (value,
736 "%u",
737 val))
335 { 738 {
336 FPRINTF (stderr, _("You must pass a number to the `%s' option.\n"), option); 739 FPRINTF (stderr,
740 _("You must pass a number to the `%s' option.\n"),
741 option);
337 return GNUNET_SYSERR; 742 return GNUNET_SYSERR;
338 } 743 }
339 return GNUNET_OK; 744 return GNUNET_OK;
340} 745}
341 746
342 747
748/**
749 * Allow user to specify an unsigned integer.
750 *
751 * @param shortName short name of the option
752 * @param name long name of the option
753 * @param argumentHelp help text for the option argument
754 * @param description long help text for the option
755 * @param[out] val set to the value specified at the command line
756 */
757struct GNUNET_GETOPT_CommandLineOption
758GNUNET_GETOPT_OPTION_SET_UINT (char shortName,
759 const char *name,
760 const char *argumentHelp,
761 const char *description,
762 unsigned int *val)
763{
764 struct GNUNET_GETOPT_CommandLineOption clo = {
765 .shortName = shortName,
766 .name = name,
767 .argumentHelp = argumentHelp,
768 .description = description,
769 .require_argument = 1,
770 .processor = &set_uint,
771 .scls = (void *) val
772 };
773
774 return clo;
775}
776
777
778/**
779 * Closure for #set_base32().
780 */
781struct Base32Context
782{
783 /**
784 * Value to initialize (already allocated)
785 */
786 void *val;
787
788 /**
789 * Number of bytes expected for @e val.
790 */
791 size_t val_size;
792};
793
794
795/**
796 * Set an option of type 'unsigned int' from the command line.
797 * A pointer to this function should be passed as part of the
798 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
799 * of this type. It should be followed by a pointer to a value of
800 * type 'unsigned int'.
801 *
802 * @param ctx command line processing context
803 * @param scls additional closure (will point to the 'unsigned int')
804 * @param option name of the option
805 * @param value actual value of the option as a string.
806 * @return #GNUNET_OK if parsing the value worked
807 */
808static int
809set_base32 (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
810 void *scls,
811 const char *option,
812 const char *value)
813{
814 struct Base32Context *bc = scls;
815
816 if (GNUNET_OK !=
817 GNUNET_STRINGS_string_to_data (value,
818 strlen (value),
819 bc->val,
820 bc->val_size))
821 {
822 fprintf (stderr,
823 _("Argument `%s' malformed. Expected base32 (Crockford) encoded value.\n"),
824 option);
825 return GNUNET_SYSERR;
826 }
827 return GNUNET_OK;
828}
829
830
831/**
832 * Helper function to clean up after
833 * #GNUNET_GETOPT_OPTION_SET_BASE32_FIXED_SIZE.
834 *
835 * @param cls value to GNUNET_free()
836 */
837static void
838free_bc (void *cls)
839{
840 GNUNET_free (cls);
841}
842
843
844/**
845 * Allow user to specify a binary value using Crockford
846 * Base32 encoding.
847 *
848 * @param shortName short name of the option
849 * @param name long name of the option
850 * @param argumentHelp help text for the option argument
851 * @param description long help text for the option
852 * @param[out] val binary value decoded from Crockford Base32-encoded argument
853 * @param val_size size of @a val in bytes
854 */
855struct GNUNET_GETOPT_CommandLineOption
856GNUNET_GETOPT_OPTION_SET_BASE32_FIXED_SIZE (char shortName,
857 const char *name,
858 const char *argumentHelp,
859 const char *description,
860 void *val,
861 size_t val_size)
862{
863 struct Base32Context *bc = GNUNET_new (struct Base32Context);
864 struct GNUNET_GETOPT_CommandLineOption clo = {
865 .shortName = shortName,
866 .name = name,
867 .argumentHelp = argumentHelp,
868 .description = description,
869 .require_argument = 1,
870 .processor = &set_base32,
871 .cleaner = &free_bc,
872 .scls = (void *) bc
873 };
874
875 bc->val = val;
876 bc->val_size = val_size;
877 return clo;
878}
879
880
881/**
882 * Make the given option mandatory.
883 *
884 * @param opt option to modify
885 * @return @a opt with the mandatory flag set.
886 */
887struct GNUNET_GETOPT_CommandLineOption
888GNUNET_GETOPT_OPTION_MANDATORY (struct GNUNET_GETOPT_CommandLineOption opt)
889{
890 opt.option_mandatory = 1;
891 return opt;
892}
893
894
343/* end of getopt_helpers.c */ 895/* end of getopt_helpers.c */
diff --git a/src/util/gnunet-config.c b/src/util/gnunet-config.c
index 7ec7162f1..2beb772a9 100644
--- a/src/util/gnunet-config.c
+++ b/src/util/gnunet-config.c
@@ -223,34 +223,48 @@ run (void *cls,
223int 223int
224main (int argc, char *const *argv) 224main (int argc, char *const *argv)
225{ 225{
226 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 226 struct GNUNET_GETOPT_CommandLineOption options[] = {
227 { 'f', "filename", NULL, 227 GNUNET_GETOPT_OPTION_SET_ONE ('f',
228 gettext_noop ("obtain option of value as a filename (with $-expansion)"), 228 "filename",
229 0, &GNUNET_GETOPT_set_one, &is_filename }, 229 gettext_noop ("obtain option of value as a filename (with $-expansion)"),
230 { 's', "section", "SECTION", 230 &is_filename),
231 gettext_noop ("name of the section to access"), 231 GNUNET_GETOPT_OPTION_STRING ('s',
232 1, &GNUNET_GETOPT_set_string, &section }, 232 "section",
233 { 'o', "option", "OPTION", 233 "SECTION",
234 gettext_noop ("name of the option to access"), 234 gettext_noop ("name of the section to access"),
235 1, &GNUNET_GETOPT_set_string, &option }, 235 &section),
236 { 'V', "value", "VALUE", 236 GNUNET_GETOPT_OPTION_STRING ('o',
237 gettext_noop ("value to set"), 237 "option",
238 1, &GNUNET_GETOPT_set_string, &value }, 238 "OPTION",
239 { 'S', "list-sections", NULL, 239 gettext_noop ("name of the option to access"),
240 gettext_noop ("print available configuration sections"), 240 &option),
241 0, &GNUNET_GETOPT_set_one, &list_sections }, 241 GNUNET_GETOPT_OPTION_STRING ('V',
242 { 'w', "rewrite", NULL, 242 "value",
243 gettext_noop ("write configuration file that only contains delta to defaults"), 243 "VALUE",
244 0, &GNUNET_GETOPT_set_one, &rewrite }, 244 gettext_noop ("value to set"),
245 &value),
246 GNUNET_GETOPT_OPTION_SET_ONE ('S',
247 "list-sections",
248 gettext_noop ("print available configuration sections"),
249 &list_sections),
250 GNUNET_GETOPT_OPTION_SET_ONE ('w',
251 "rewrite",
252 gettext_noop ("write configuration file that only contains delta to defaults"),
253 &rewrite),
245 GNUNET_GETOPT_OPTION_END 254 GNUNET_GETOPT_OPTION_END
246 }; 255 };
247 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 256 if (GNUNET_OK !=
257 GNUNET_STRINGS_get_utf8_args (argc, argv,
258 &argc, &argv))
248 return 2; 259 return 2;
249 260
250 ret = (GNUNET_OK == 261 ret = (GNUNET_OK ==
251 GNUNET_PROGRAM_run (argc, argv, "gnunet-config [OPTIONS]", 262 GNUNET_PROGRAM_run (argc,
263 argv,
264 "gnunet-config [OPTIONS]",
252 gettext_noop ("Manipulate GNUnet configuration files"), 265 gettext_noop ("Manipulate GNUnet configuration files"),
253 options, &run, NULL)) ? 0 : ret; 266 options,
267 &run, NULL)) ? 0 : ret;
254 GNUNET_free ((void*) argv); 268 GNUNET_free ((void*) argv);
255 return ret; 269 return ret;
256} 270}
diff --git a/src/util/gnunet-ecc.c b/src/util/gnunet-ecc.c
index ddfd9b1c3..732228b52 100644
--- a/src/util/gnunet-ecc.c
+++ b/src/util/gnunet-ecc.c
@@ -41,7 +41,7 @@ static int list_keys;
41/** 41/**
42 * Flag for listing public key. 42 * Flag for listing public key.
43 */ 43 */
44static int list_keys_count; 44static unsigned int list_keys_count;
45 45
46/** 46/**
47 * Flag for printing public key. 47 * Flag for printing public key.
@@ -406,36 +406,50 @@ run (void *cls, char *const *args, const char *cfgfile,
406 * @return 0 ok, 1 on error 406 * @return 0 ok, 1 on error
407 */ 407 */
408int 408int
409main (int argc, char *const *argv) 409main (int argc,
410 char *const *argv)
410{ 411{
411 list_keys_count = UINT32_MAX; 412 list_keys_count = UINT32_MAX;
412 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 413 struct GNUNET_GETOPT_CommandLineOption options[] = {
413 { 'i', "iterate", "FILE", 414 GNUNET_GETOPT_OPTION_SET_ONE ('i',
414 gettext_noop ("list keys included in a file (for testing)"), 415 "iterate",
415 0, &GNUNET_GETOPT_set_one, &list_keys }, 416 gettext_noop ("list keys included in a file (for testing)"),
416 { 'e', "end=", "COUNT", 417 &list_keys),
417 gettext_noop ("number of keys to list included in a file (for testing)"), 418 GNUNET_GETOPT_OPTION_SET_UINT ('e',
418 1, &GNUNET_GETOPT_set_uint, &list_keys_count }, 419 "end=",
419 { 'g', "generate-keys", "COUNT", 420 "COUNT",
420 gettext_noop ("create COUNT public-private key pairs (for testing)"), 421 gettext_noop ("number of keys to list included in a file (for testing)"),
421 1, &GNUNET_GETOPT_set_uint, &make_keys }, 422 &list_keys_count),
422 { 'p', "print-public-key", NULL, 423 GNUNET_GETOPT_OPTION_SET_UINT ('g',
423 gettext_noop ("print the public key in ASCII format"), 424 "generate-keys",
424 0, &GNUNET_GETOPT_set_one, &print_public_key }, 425 "COUNT",
425 { 'E', "examples", NULL, 426 gettext_noop ("create COUNT public-private key pairs (for testing)"),
426 gettext_noop ("print examples of ECC operations (used for compatibility testing)"), 427 &make_keys),
427 0, &GNUNET_GETOPT_set_one, &print_examples_flag }, 428 GNUNET_GETOPT_OPTION_SET_ONE ('p',
429 "print-public-key",
430 gettext_noop ("print the public key in ASCII format"),
431 &print_public_key),
432 GNUNET_GETOPT_OPTION_SET_ONE ('E',
433 "examples",
434 gettext_noop ("print examples of ECC operations (used for compatibility testing)"),
435 &print_examples_flag),
428 GNUNET_GETOPT_OPTION_END 436 GNUNET_GETOPT_OPTION_END
429 }; 437 };
430 int ret; 438 int ret;
431 439
432 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 440 if (GNUNET_OK !=
441 GNUNET_STRINGS_get_utf8_args (argc, argv,
442 &argc, &argv))
433 return 2; 443 return 2;
434 444
435 ret = (GNUNET_OK == 445 ret = (GNUNET_OK ==
436 GNUNET_PROGRAM_run (argc, argv, "gnunet-ecc [OPTIONS] keyfile [VANITY_PREFIX]", 446 GNUNET_PROGRAM_run (argc,
447 argv,
448 "gnunet-ecc [OPTIONS] keyfile [VANITY_PREFIX]",
437 gettext_noop ("Manipulate GNUnet private ECC key files"), 449 gettext_noop ("Manipulate GNUnet private ECC key files"),
438 options, &run, NULL)) ? 0 : 1; 450 options,
451 &run,
452 NULL)) ? 0 : 1;
439 GNUNET_free ((void*) argv); 453 GNUNET_free ((void*) argv);
440 return ret; 454 return ret;
441} 455}
diff --git a/src/util/gnunet-resolver.c b/src/util/gnunet-resolver.c
index e84a2332f..563cf9fce 100644
--- a/src/util/gnunet-resolver.c
+++ b/src/util/gnunet-resolver.c
@@ -144,10 +144,11 @@ run (void *cls, char *const *args, const char *cfgfile,
144int 144int
145main (int argc, char *const *argv) 145main (int argc, char *const *argv)
146{ 146{
147 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 147 struct GNUNET_GETOPT_CommandLineOption options[] = {
148 { 'r', "reverse", NULL, 148 GNUNET_GETOPT_OPTION_SET_ONE ('r',
149 gettext_noop ("perform a reverse lookup"), 149 "reverse",
150 0, &GNUNET_GETOPT_set_one, &reverse }, 150 gettext_noop ("perform a reverse lookup"),
151 &reverse),
151 GNUNET_GETOPT_OPTION_END 152 GNUNET_GETOPT_OPTION_END
152 }; 153 };
153 int ret; 154 int ret;
diff --git a/src/util/gnunet-scrypt.c b/src/util/gnunet-scrypt.c
index ab0cf92e0..7c73cfe1e 100644
--- a/src/util/gnunet-scrypt.c
+++ b/src/util/gnunet-scrypt.c
@@ -307,21 +307,30 @@ run (void *cls,
307 * @return 0 ok, 1 on error 307 * @return 0 ok, 1 on error
308 */ 308 */
309int 309int
310main (int argc, char *const *argv) 310main (int argc,
311 char *const *argv)
311{ 312{
312 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 313 struct GNUNET_GETOPT_CommandLineOption options[] = {
313 { 'b', "bits", "BITS", 314 GNUNET_GETOPT_OPTION_SET_ULONG ('b',
314 gettext_noop ("number of bits to require for the proof of work"), 315 "bits",
315 1, &GNUNET_GETOPT_set_ulong, &nse_work_required }, 316 "BITS",
316 { 'k', "keyfile", "FILE", 317 gettext_noop ("number of bits to require for the proof of work"),
317 gettext_noop ("file with private key, otherwise default is used"), 318 &nse_work_required),
318 1, &GNUNET_GETOPT_set_filename, &pkfn }, 319 GNUNET_GETOPT_OPTION_FILENAME ('k',
319 { 'o', "outfile", "FILE", 320 "keyfile",
320 gettext_noop ("file with proof of work, otherwise default is used"), 321 "FILE",
321 1, &GNUNET_GETOPT_set_filename, &pwfn }, 322 gettext_noop ("file with private key, otherwise default is used"),
322 { 't', "timeout", "TIME", 323 &pkfn),
323 gettext_noop ("time to wait between calculations"), 324 GNUNET_GETOPT_OPTION_FILENAME ('o',
324 1, &GNUNET_GETOPT_set_relative_time, &proof_find_delay }, 325 "outfile",
326 "FILE",
327 gettext_noop ("file with proof of work, otherwise default is used"),
328 &pwfn),
329 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('t',
330 "timeout",
331 "TIME",
332 gettext_noop ("time to wait between calculations"),
333 &proof_find_delay),
325 GNUNET_GETOPT_OPTION_END 334 GNUNET_GETOPT_OPTION_END
326 }; 335 };
327 int ret; 336 int ret;
@@ -334,7 +343,9 @@ main (int argc, char *const *argv)
334 GNUNET_PROGRAM_run (argc, argv, 343 GNUNET_PROGRAM_run (argc, argv,
335 "gnunet-scrypt [OPTIONS] prooffile", 344 "gnunet-scrypt [OPTIONS] prooffile",
336 gettext_noop ("Manipulate GNUnet proof of work files"), 345 gettext_noop ("Manipulate GNUnet proof of work files"),
337 options, &run, NULL)) ? 0 : 1; 346 options,
347 &run,
348 NULL)) ? 0 : 1;
338 GNUNET_free ((void*) argv); 349 GNUNET_free ((void*) argv);
339 GNUNET_free_non_null (pwfn); 350 GNUNET_free_non_null (pwfn);
340 return ret; 351 return ret;
diff --git a/src/util/helper.c b/src/util/helper.c
index cdb1b01d4..a84b06e66 100644
--- a/src/util/helper.c
+++ b/src/util/helper.c
@@ -27,6 +27,7 @@
27 */ 27 */
28#include "platform.h" 28#include "platform.h"
29#include "gnunet_util_lib.h" 29#include "gnunet_util_lib.h"
30#include "gnunet_mst_lib.h"
30 31
31 32
32/** 33/**
@@ -107,7 +108,7 @@ struct GNUNET_HELPER_Handle
107 /** 108 /**
108 * The Message-Tokenizer that tokenizes the messages comming from the helper 109 * The Message-Tokenizer that tokenizes the messages comming from the helper
109 */ 110 */
110 struct GNUNET_SERVER_MessageStreamTokenizer *mst; 111 struct GNUNET_MessageStreamTokenizer *mst;
111 112
112 /** 113 /**
113 * The exception callback 114 * The exception callback
@@ -272,7 +273,10 @@ GNUNET_HELPER_wait (struct GNUNET_HELPER_Handle *h)
272 } 273 }
273 /* purge MST buffer */ 274 /* purge MST buffer */
274 if (NULL != h->mst) 275 if (NULL != h->mst)
275 (void) GNUNET_SERVER_mst_receive (h->mst, NULL, NULL, 0, GNUNET_YES, GNUNET_NO); 276 (void) GNUNET_MST_from_buffer (h->mst,
277 NULL, 0,
278 GNUNET_YES,
279 GNUNET_NO);
276 return ret; 280 return ret;
277} 281}
278 282
@@ -319,7 +323,7 @@ static void
319helper_read (void *cls) 323helper_read (void *cls)
320{ 324{
321 struct GNUNET_HELPER_Handle *h = cls; 325 struct GNUNET_HELPER_Handle *h = cls;
322 char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE] GNUNET_ALIGN; 326 char buf[GNUNET_MAX_MESSAGE_SIZE] GNUNET_ALIGN;
323 ssize_t t; 327 ssize_t t;
324 328
325 h->read_task = NULL; 329 h->read_task = NULL;
@@ -373,10 +377,10 @@ helper_read (void *cls)
373 h->fh_from_helper, 377 h->fh_from_helper,
374 &helper_read, h); 378 &helper_read, h);
375 if (GNUNET_SYSERR == 379 if (GNUNET_SYSERR ==
376 GNUNET_SERVER_mst_receive (h->mst, 380 GNUNET_MST_from_buffer (h->mst,
377 NULL, 381 buf, t,
378 buf, t, 382 GNUNET_NO,
379 GNUNET_NO, GNUNET_NO)) 383 GNUNET_NO))
380 { 384 {
381 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 385 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
382 _("Failed to parse inbound message from helper `%s'\n"), 386 _("Failed to parse inbound message from helper `%s'\n"),
@@ -487,7 +491,7 @@ struct GNUNET_HELPER_Handle *
487GNUNET_HELPER_start (int with_control_pipe, 491GNUNET_HELPER_start (int with_control_pipe,
488 const char *binary_name, 492 const char *binary_name,
489 char *const binary_argv[], 493 char *const binary_argv[],
490 GNUNET_SERVER_MessageTokenizerCallback cb, 494 GNUNET_MessageTokenizerCallback cb,
491 GNUNET_HELPER_ExceptionCallback exp_cb, 495 GNUNET_HELPER_ExceptionCallback exp_cb,
492 void *cb_cls) 496 void *cb_cls)
493{ 497{
@@ -508,7 +512,8 @@ GNUNET_HELPER_start (int with_control_pipe,
508 h->binary_argv[c] = NULL; 512 h->binary_argv[c] = NULL;
509 h->cb_cls = cb_cls; 513 h->cb_cls = cb_cls;
510 if (NULL != cb) 514 if (NULL != cb)
511 h->mst = GNUNET_SERVER_mst_create (cb, h->cb_cls); 515 h->mst = GNUNET_MST_create (cb,
516 h->cb_cls);
512 h->exp_cb = exp_cb; 517 h->exp_cb = exp_cb;
513 h->retry_back_off = 0; 518 h->retry_back_off = 0;
514 start_helper (h); 519 start_helper (h);
@@ -544,7 +549,7 @@ GNUNET_HELPER_destroy (struct GNUNET_HELPER_Handle *h)
544 GNUNET_free (sh); 549 GNUNET_free (sh);
545 } 550 }
546 if (NULL != h->mst) 551 if (NULL != h->mst)
547 GNUNET_SERVER_mst_destroy (h->mst); 552 GNUNET_MST_destroy (h->mst);
548 GNUNET_free (h->binary_name); 553 GNUNET_free (h->binary_name);
549 for (c = 0; h->binary_argv[c] != NULL; c++) 554 for (c = 0; h->binary_argv[c] != NULL; c++)
550 GNUNET_free (h->binary_argv[c]); 555 GNUNET_free (h->binary_argv[c]);
diff --git a/src/util/mq.c b/src/util/mq.c
index 25cf24e11..90b2aa968 100644
--- a/src/util/mq.c
+++ b/src/util/mq.c
@@ -202,24 +202,6 @@ struct GNUNET_MQ_Handle
202 202
203 203
204/** 204/**
205 * Implementation-specific state for connection to
206 * client (MQ for server).
207 */
208struct ServerClientSocketState
209{
210 /**
211 * Handle of the client that connected to the server.
212 */
213 struct GNUNET_SERVER_Client *client;
214
215 /**
216 * Active transmission request to the client.
217 */
218 struct GNUNET_SERVER_TransmitHandle *th;
219};
220
221
222/**
223 * Call the message message handler that was registered 205 * Call the message message handler that was registered
224 * for the type of the given message in the given message queue. 206 * for the type of the given message in the given message queue.
225 * 207 *
@@ -708,92 +690,6 @@ GNUNET_MQ_msg_nested_mh_ (struct GNUNET_MessageHeader **mhp,
708 690
709 691
710/** 692/**
711 * Transmit a queued message to the session's client.
712 *
713 * @param cls consensus session
714 * @param size number of bytes available in @a buf
715 * @param buf where the callee should write the message
716 * @return number of bytes written to @a buf
717 */
718static size_t
719transmit_queued (void *cls,
720 size_t size,
721 void *buf)
722{
723 struct GNUNET_MQ_Handle *mq = cls;
724 struct ServerClientSocketState *state = GNUNET_MQ_impl_state (mq);
725 const struct GNUNET_MessageHeader *msg = GNUNET_MQ_impl_current (mq);
726 size_t msg_size;
727
728 GNUNET_assert (NULL != buf);
729 msg_size = ntohs (msg->size);
730 GNUNET_assert (size >= msg_size);
731 GNUNET_memcpy (buf, msg, msg_size);
732 state->th = NULL;
733
734 GNUNET_MQ_impl_send_continue (mq);
735
736 return msg_size;
737}
738
739
740static void
741server_client_destroy_impl (struct GNUNET_MQ_Handle *mq,
742 void *impl_state)
743{
744 struct ServerClientSocketState *state = impl_state;
745
746 if (NULL != state->th)
747 {
748 GNUNET_SERVER_notify_transmit_ready_cancel (state->th);
749 state->th = NULL;
750 }
751
752 GNUNET_assert (NULL != mq);
753 GNUNET_assert (NULL != state);
754 GNUNET_SERVER_client_drop (state->client);
755 GNUNET_free (state);
756}
757
758
759static void
760server_client_send_impl (struct GNUNET_MQ_Handle *mq,
761 const struct GNUNET_MessageHeader *msg,
762 void *impl_state)
763{
764 GNUNET_assert (NULL != mq);
765
766 LOG (GNUNET_ERROR_TYPE_DEBUG,
767 "Sending message of type %u and size %u\n",
768 ntohs (msg->type), ntohs (msg->size));
769
770 struct ServerClientSocketState *state = impl_state;
771 state->th = GNUNET_SERVER_notify_transmit_ready (state->client,
772 ntohs (msg->size),
773 GNUNET_TIME_UNIT_FOREVER_REL,
774 &transmit_queued,
775 mq);
776}
777
778
779struct GNUNET_MQ_Handle *
780GNUNET_MQ_queue_for_server_client (struct GNUNET_SERVER_Client *client)
781{
782 struct GNUNET_MQ_Handle *mq;
783 struct ServerClientSocketState *scss;
784
785 mq = GNUNET_new (struct GNUNET_MQ_Handle);
786 scss = GNUNET_new (struct ServerClientSocketState);
787 mq->impl_state = scss;
788 scss->client = client;
789 GNUNET_SERVER_client_keep (client);
790 mq->send_impl = &server_client_send_impl;
791 mq->destroy_impl = &server_client_destroy_impl;
792 return mq;
793}
794
795
796/**
797 * Associate the assoc_data in mq with a unique request id. 693 * Associate the assoc_data in mq with a unique request id.
798 * 694 *
799 * @param mq message queue, id will be unique for the queue 695 * @param mq message queue, id will be unique for the queue
diff --git a/src/util/mst.c b/src/util/mst.c
index 9f1d30d7a..0d90c5d10 100644
--- a/src/util/mst.c
+++ b/src/util/mst.c
@@ -90,8 +90,8 @@ GNUNET_MST_create (GNUNET_MessageTokenizerCallback cb,
90 struct GNUNET_MessageStreamTokenizer *ret; 90 struct GNUNET_MessageStreamTokenizer *ret;
91 91
92 ret = GNUNET_new (struct GNUNET_MessageStreamTokenizer); 92 ret = GNUNET_new (struct GNUNET_MessageStreamTokenizer);
93 ret->hdr = GNUNET_malloc (GNUNET_SERVER_MIN_BUFFER_SIZE); 93 ret->hdr = GNUNET_malloc (GNUNET_MIN_MESSAGE_SIZE);
94 ret->curr_buf = GNUNET_SERVER_MIN_BUFFER_SIZE; 94 ret->curr_buf = GNUNET_MIN_MESSAGE_SIZE;
95 ret->cb = cb; 95 ret->cb = cb;
96 ret->cb_cls = cb_cls; 96 ret->cb_cls = cb_cls;
97 return ret; 97 return ret;
diff --git a/src/util/resolver_api.c b/src/util/resolver_api.c
index f33c31f1c..0c915932c 100644
--- a/src/util/resolver_api.c
+++ b/src/util/resolver_api.c
@@ -876,7 +876,7 @@ GNUNET_RESOLVER_ip_get (const char *hostname,
876 876
877 slen = strlen (hostname) + 1; 877 slen = strlen (hostname) + 1;
878 if (slen + sizeof (struct GNUNET_RESOLVER_GetMessage) >= 878 if (slen + sizeof (struct GNUNET_RESOLVER_GetMessage) >=
879 GNUNET_SERVER_MAX_MESSAGE_SIZE) 879 GNUNET_MAX_MESSAGE_SIZE)
880 { 880 {
881 GNUNET_break (0); 881 GNUNET_break (0);
882 return NULL; 882 return NULL;
diff --git a/src/util/server_nc.c b/src/util/server_nc.c
deleted file mode 100644
index a95cd7f6d..000000000
--- a/src/util/server_nc.c
+++ /dev/null
@@ -1,472 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file util/server_nc.c
23 * @brief convenience functions for transmission of
24 * a notification stream
25 * @author Christian Grothoff
26 */
27
28#include "platform.h"
29#include "gnunet_util_lib.h"
30
31#define LOG(kind,...) GNUNET_log_from (kind, "util-server-nc", __VA_ARGS__)
32
33
34/**
35 * Entry in list of messages pending to be transmitted.
36 */
37struct PendingMessageList
38{
39
40 /**
41 * This is a doubly-linked list.
42 */
43 struct PendingMessageList *next;
44
45 /**
46 * This is a doubly-linked list.
47 */
48 struct PendingMessageList *prev;
49
50 /**
51 * Message to transmit (allocated at the end of this
52 * struct, do not free)
53 */
54 const struct GNUNET_MessageHeader *msg;
55
56 /**
57 * Can this message be dropped?
58 */
59 int can_drop;
60
61};
62
63
64/**
65 * Lists of clients we manage for notifications.
66 */
67struct ClientList
68{
69
70 /**
71 * This is a doubly linked list.
72 */
73 struct ClientList *next;
74
75 /**
76 * This is a doubly linked list.
77 */
78 struct ClientList *prev;
79
80 /**
81 * Overall context this client belongs to.
82 */
83 struct GNUNET_SERVER_NotificationContext *nc;
84
85 /**
86 * Handle to the client.
87 */
88 struct GNUNET_SERVER_Client *client;
89
90 /**
91 * Handle for pending transmission request to the client (or NULL).
92 */
93 struct GNUNET_SERVER_TransmitHandle *th;
94
95 /**
96 * Head of linked list of requests queued for transmission.
97 */
98 struct PendingMessageList *pending_head;
99
100 /**
101 * Tail of linked list of requests queued for transmission.
102 */
103 struct PendingMessageList *pending_tail;
104
105 /**
106 * Number of messages currently in the list.
107 */
108 unsigned int num_pending;
109
110};
111
112
113/**
114 * The notification context is the key datastructure for a convenience
115 * API used for transmission of notifications to the client until the
116 * client disconnects (or the notification context is destroyed, in
117 * which case we disconnect these clients). Essentially, all
118 * (notification) messages are queued up until the client is able to
119 * read them.
120 */
121struct GNUNET_SERVER_NotificationContext
122{
123
124 /**
125 * Server we do notifications for.
126 */
127 struct GNUNET_SERVER_Handle *server;
128
129 /**
130 * Head of list of clients receiving notifications.
131 */
132 struct ClientList *clients_head;
133
134 /**
135 * Tail of list of clients receiving notifications.
136 */
137 struct ClientList *clients_tail;
138
139 /**
140 * Maximum number of optional messages to queue per client.
141 */
142 unsigned int queue_length;
143
144};
145
146
147/**
148 * Client has disconnected, clean up.
149 *
150 * @param cls our `struct GNUNET_SERVER_NotificationContext *`
151 * @param client handle of client that disconnected
152 */
153static void
154handle_client_disconnect (void *cls,
155 struct GNUNET_SERVER_Client *client)
156{
157 struct GNUNET_SERVER_NotificationContext *nc = cls;
158 struct ClientList *pos;
159 struct PendingMessageList *pml;
160
161 if (NULL == client)
162 {
163 nc->server = NULL;
164 return;
165 }
166 for (pos = nc->clients_head; NULL != pos; pos = pos->next)
167 if (pos->client == client)
168 break;
169 if (NULL == pos)
170 return;
171 LOG (GNUNET_ERROR_TYPE_DEBUG,
172 "Client disconnected, cleaning up %u messages in NC queue\n",
173 pos->num_pending);
174 GNUNET_CONTAINER_DLL_remove (nc->clients_head,
175 nc->clients_tail,
176 pos);
177 while (NULL != (pml = pos->pending_head))
178 {
179 GNUNET_CONTAINER_DLL_remove (pos->pending_head,
180 pos->pending_tail,
181 pml);
182 GNUNET_free (pml);
183 pos->num_pending--;
184 }
185 if (NULL != pos->th)
186 {
187 GNUNET_SERVER_notify_transmit_ready_cancel (pos->th);
188 pos->th = NULL;
189 }
190 GNUNET_SERVER_client_drop (client);
191 GNUNET_assert (0 == pos->num_pending);
192 GNUNET_free (pos);
193}
194
195
196/**
197 * Create a new notification context.
198 *
199 * @param server server for which this function creates the context
200 * @param queue_length maximum number of messages to keep in
201 * the notification queue; optional messages are dropped
202 * if the queue gets longer than this number of messages
203 * @return handle to the notification context
204 */
205struct GNUNET_SERVER_NotificationContext *
206GNUNET_SERVER_notification_context_create (struct GNUNET_SERVER_Handle *server,
207 unsigned int queue_length)
208{
209 struct GNUNET_SERVER_NotificationContext *ret;
210
211 ret = GNUNET_new (struct GNUNET_SERVER_NotificationContext);
212 ret->server = server;
213 ret->queue_length = queue_length;
214 GNUNET_SERVER_disconnect_notify (server,
215 &handle_client_disconnect,
216 ret);
217 return ret;
218}
219
220
221/**
222 * Destroy the context, force disconnect for all clients.
223 *
224 * @param nc context to destroy.
225 */
226void
227GNUNET_SERVER_notification_context_destroy (struct GNUNET_SERVER_NotificationContext *nc)
228{
229 struct ClientList *pos;
230 struct PendingMessageList *pml;
231
232 while (NULL != (pos = nc->clients_head))
233 {
234 GNUNET_CONTAINER_DLL_remove (nc->clients_head,
235 nc->clients_tail,
236 pos);
237 if (NULL != pos->th)
238 {
239 GNUNET_SERVER_notify_transmit_ready_cancel (pos->th);
240 pos->th = NULL;
241 }
242 GNUNET_SERVER_client_drop (pos->client);
243 while (NULL != (pml = pos->pending_head))
244 {
245 GNUNET_CONTAINER_DLL_remove (pos->pending_head,
246 pos->pending_tail,
247 pml);
248 GNUNET_free (pml);
249 pos->num_pending--;
250 }
251 GNUNET_assert (0 == pos->num_pending);
252 GNUNET_free (pos);
253 }
254 if (NULL != nc->server)
255 GNUNET_SERVER_disconnect_notify_cancel (nc->server,
256 &handle_client_disconnect,
257 nc);
258 GNUNET_free (nc);
259}
260
261
262/**
263 * Add a client to the notification context.
264 *
265 * @param nc context to modify
266 * @param client client to add
267 */
268void
269GNUNET_SERVER_notification_context_add (struct GNUNET_SERVER_NotificationContext *nc,
270 struct GNUNET_SERVER_Client *client)
271{
272 struct ClientList *cl;
273
274 for (cl = nc->clients_head; NULL != cl; cl = cl->next)
275 if (cl->client == client)
276 return; /* already present */
277 cl = GNUNET_new (struct ClientList);
278 GNUNET_CONTAINER_DLL_insert (nc->clients_head,
279 nc->clients_tail,
280 cl);
281 cl->nc = nc;
282 cl->client = client;
283 GNUNET_SERVER_client_keep (client);
284}
285
286
287/**
288 * Function called to notify a client about the socket begin ready to
289 * queue more data. @a buf will be NULL and @a size zero if the socket
290 * was closed for writing in the meantime.
291 *
292 * @param cls the `struct ClientList *`
293 * @param size number of bytes available in @a buf
294 * @param buf where the callee should write the message
295 * @return number of bytes written to buf
296 */
297static size_t
298transmit_message (void *cls,
299 size_t size,
300 void *buf)
301{
302 struct ClientList *cl = cls;
303 char *cbuf = buf;
304 struct PendingMessageList *pml;
305 uint16_t msize;
306 size_t ret;
307
308 cl->th = NULL;
309 if (NULL == buf)
310 {
311 /* 'cl' should be freed via disconnect notification shortly */
312 LOG (GNUNET_ERROR_TYPE_DEBUG,
313 "Failed to transmit message from NC queue to client\n");
314 return 0;
315 }
316 ret = 0;
317 while (NULL != (pml = cl->pending_head))
318 {
319 msize = ntohs (pml->msg->size);
320 if (size < msize)
321 break;
322 GNUNET_CONTAINER_DLL_remove (cl->pending_head,
323 cl->pending_tail,
324 pml);
325 LOG (GNUNET_ERROR_TYPE_DEBUG,
326 "Copying message of type %u and size %u from pending queue to transmission buffer\n",
327 ntohs (pml->msg->type),
328 msize);
329 GNUNET_memcpy (&cbuf[ret], pml->msg, msize);
330 ret += msize;
331 size -= msize;
332 GNUNET_free (pml);
333 cl->num_pending--;
334 }
335 if (NULL != pml)
336 {
337 LOG (GNUNET_ERROR_TYPE_DEBUG,
338 "Have %u messages left in NC queue, will try transmission again\n",
339 cl->num_pending);
340 cl->th =
341 GNUNET_SERVER_notify_transmit_ready (cl->client,
342 ntohs (pml->msg->size),
343 GNUNET_TIME_UNIT_FOREVER_REL,
344 &transmit_message, cl);
345 }
346 else
347 {
348 GNUNET_assert (0 == cl->num_pending);
349 }
350 return ret;
351}
352
353
354/**
355 * Send a message to a particular client.
356 *
357 * @param nc context to modify
358 * @param client client to transmit to
359 * @param msg message to send
360 * @param can_drop can this message be dropped due to queue length limitations
361 */
362static void
363do_unicast (struct GNUNET_SERVER_NotificationContext *nc,
364 struct ClientList *client,
365 const struct GNUNET_MessageHeader *msg,
366 int can_drop)
367{
368 struct PendingMessageList *pml;
369 uint16_t size;
370
371 if ( (client->num_pending > nc->queue_length) &&
372 (GNUNET_YES == can_drop) )
373 {
374 LOG (GNUNET_ERROR_TYPE_INFO,
375 "Dropping message of type %u and size %u due to full queue (%u entries)\n",
376 ntohs (msg->type), ntohs (msg->size), (unsigned int) nc->queue_length);
377 return; /* drop! */
378 }
379 if (client->num_pending > nc->queue_length)
380 {
381 /* FIXME: consider checking for other messages in the
382 * queue that are 'droppable' */
383 }
384 client->num_pending++;
385 size = ntohs (msg->size);
386 pml = GNUNET_malloc (sizeof (struct PendingMessageList) + size);
387 pml->msg = (const struct GNUNET_MessageHeader *) &pml[1];
388 pml->can_drop = can_drop;
389 LOG (GNUNET_ERROR_TYPE_DEBUG,
390 "Adding message of type %u and size %u to pending queue (which has %u entries)\n",
391 ntohs (msg->type),
392 ntohs (msg->size),
393 (unsigned int) nc->queue_length);
394 GNUNET_memcpy (&pml[1], msg, size);
395 /* append */
396 GNUNET_CONTAINER_DLL_insert_tail (client->pending_head,
397 client->pending_tail,
398 pml);
399 if (NULL == client->th)
400 client->th =
401 GNUNET_SERVER_notify_transmit_ready (client->client,
402 ntohs (client->pending_head->
403 msg->size),
404 GNUNET_TIME_UNIT_FOREVER_REL,
405 &transmit_message, client);
406}
407
408
409/**
410 * Send a message to a particular client; must have
411 * already been added to the notification context.
412 *
413 * @param nc context to modify
414 * @param client client to transmit to
415 * @param msg message to send
416 * @param can_drop can this message be dropped due to queue length limitations
417 */
418void
419GNUNET_SERVER_notification_context_unicast (struct GNUNET_SERVER_NotificationContext *nc,
420 struct GNUNET_SERVER_Client *client,
421 const struct GNUNET_MessageHeader *msg,
422 int can_drop)
423{
424 struct ClientList *pos;
425
426 for (pos = nc->clients_head; NULL != pos; pos = pos->next)
427 if (pos->client == client)
428 break;
429 GNUNET_assert (NULL != pos);
430 do_unicast (nc, pos, msg, can_drop);
431}
432
433
434/**
435 * Send a message to all clients of this context.
436 *
437 * @param nc context to modify
438 * @param msg message to send
439 * @param can_drop can this message be dropped due to queue length limitations
440 */
441void
442GNUNET_SERVER_notification_context_broadcast (struct
443 GNUNET_SERVER_NotificationContext *nc,
444 const struct GNUNET_MessageHeader *msg,
445 int can_drop)
446{
447 struct ClientList *pos;
448
449 for (pos = nc->clients_head; NULL != pos; pos = pos->next)
450 do_unicast (nc, pos, msg, can_drop);
451}
452
453
454/**
455 * Return active number of subscribers in this context.
456 *
457 * @param nc context to query
458 * @return number of current subscribers
459 */
460unsigned int
461GNUNET_SERVER_notification_context_get_size (struct GNUNET_SERVER_NotificationContext *nc)
462{
463 unsigned int num;
464 struct ClientList *pos;
465
466 num = 0;
467 for (pos = nc->clients_head; NULL != pos; pos = pos->next)
468 num++;
469 return num;
470}
471
472/* end of server_nc.c */
diff --git a/src/util/server_tc.c b/src/util/server_tc.c
deleted file mode 100644
index 8ae380a85..000000000
--- a/src/util/server_tc.c
+++ /dev/null
@@ -1,242 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file util/server_tc.c
23 * @brief convenience functions for transmission of
24 * complex responses as a server
25 * @author Christian Grothoff
26 */
27
28#include "platform.h"
29#include "gnunet_util_lib.h"
30
31
32#define LOG(kind,...) GNUNET_log_from (kind, "util-server-tc", __VA_ARGS__)
33
34
35/**
36 * How much buffer space do we want to have at least
37 * before transmitting another increment?
38 */
39#define MIN_BLOCK_SIZE 128
40
41
42
43struct GNUNET_SERVER_TransmitContext
44{
45 /**
46 * Which client are we transmitting to?
47 */
48 struct GNUNET_SERVER_Client *client;
49
50 /**
51 * Transmission buffer. (current offset for writing).
52 */
53 char *buf;
54
55 /**
56 * Number of bytes in buf.
57 */
58 size_t total;
59
60 /**
61 * Offset for writing in buf.
62 */
63 size_t off;
64
65 /**
66 * Timeout for this request.
67 */
68 struct GNUNET_TIME_Absolute timeout;
69};
70
71
72/**
73 * Helper function for incremental transmission of the response.
74 */
75static size_t
76transmit_response (void *cls, size_t size, void *buf)
77{
78 struct GNUNET_SERVER_TransmitContext *tc = cls;
79 size_t msize;
80
81 if (NULL == buf)
82 {
83 GNUNET_SERVER_transmit_context_destroy (tc, GNUNET_SYSERR);
84 return 0;
85 }
86 if (tc->total - tc->off > size)
87 msize = size;
88 else
89 msize = tc->total - tc->off;
90 GNUNET_memcpy (buf, &tc->buf[tc->off], msize);
91 tc->off += msize;
92 if (tc->total == tc->off)
93 {
94 GNUNET_SERVER_receive_done (tc->client, GNUNET_OK);
95 GNUNET_SERVER_client_drop (tc->client);
96 GNUNET_free_non_null (tc->buf);
97 GNUNET_free (tc);
98 }
99 else
100 {
101 if (NULL ==
102 GNUNET_SERVER_notify_transmit_ready (tc->client,
103 GNUNET_MIN (MIN_BLOCK_SIZE,
104 tc->total - tc->off),
105 GNUNET_TIME_absolute_get_remaining
106 (tc->timeout), &transmit_response,
107 tc))
108 {
109 GNUNET_break (0);
110 GNUNET_SERVER_transmit_context_destroy (tc, GNUNET_SYSERR);
111 }
112 }
113 return msize;
114}
115
116
117/**
118 * Create a new transmission context for the
119 * given client.
120 *
121 * @param client client to create the context for.
122 * @return NULL on error
123 */
124struct GNUNET_SERVER_TransmitContext *
125GNUNET_SERVER_transmit_context_create (struct GNUNET_SERVER_Client *client)
126{
127 struct GNUNET_SERVER_TransmitContext *tc;
128
129 GNUNET_assert (NULL != client);
130 tc = GNUNET_new (struct GNUNET_SERVER_TransmitContext);
131 GNUNET_SERVER_client_keep (client);
132 tc->client = client;
133 return tc;
134}
135
136
137/**
138 * Append a message to the transmission context.
139 * All messages in the context will be sent by
140 * the transmit_context_run method.
141 *
142 * @param tc context to use
143 * @param data what to append to the result message
144 * @param length length of data
145 * @param type type of the message
146 */
147void
148GNUNET_SERVER_transmit_context_append_data (struct GNUNET_SERVER_TransmitContext
149 *tc, const void *data,
150 size_t length, uint16_t type)
151{
152 struct GNUNET_MessageHeader *msg;
153 size_t size;
154
155 GNUNET_assert (length < GNUNET_SERVER_MAX_MESSAGE_SIZE);
156 size = length + sizeof (struct GNUNET_MessageHeader);
157 GNUNET_assert (size > length);
158 tc->buf = GNUNET_realloc (tc->buf, tc->total + size);
159 msg = (struct GNUNET_MessageHeader *) &tc->buf[tc->total];
160 tc->total += size;
161 msg->size = htons (size);
162 msg->type = htons (type);
163 GNUNET_memcpy (&msg[1], data, length);
164}
165
166
167/**
168 * Append a message to the transmission context.
169 * All messages in the context will be sent by
170 * the transmit_context_run method.
171 *
172 * @param tc context to use
173 * @param msg message to append
174 */
175void
176GNUNET_SERVER_transmit_context_append_message (struct
177 GNUNET_SERVER_TransmitContext
178 *tc,
179 const struct GNUNET_MessageHeader
180 *msg)
181{
182 struct GNUNET_MessageHeader *m;
183 uint16_t size;
184
185 size = ntohs (msg->size);
186 tc->buf = GNUNET_realloc (tc->buf, tc->total + size);
187 m = (struct GNUNET_MessageHeader *) &tc->buf[tc->total];
188 tc->total += size;
189 GNUNET_memcpy (m, msg, size);
190}
191
192
193/**
194 * Execute a transmission context. If there is
195 * an error in the transmission, the #GNUNET_SERVER_receive_done()
196 * method will be called with an error code (#GNUNET_SYSERR),
197 * otherwise with #GNUNET_OK.
198 *
199 * @param tc transmission context to use
200 * @param timeout when to time out and abort the transmission
201 */
202void
203GNUNET_SERVER_transmit_context_run (struct GNUNET_SERVER_TransmitContext *tc,
204 struct GNUNET_TIME_Relative timeout)
205{
206 tc->timeout = GNUNET_TIME_relative_to_absolute (timeout);
207 if (NULL ==
208 GNUNET_SERVER_notify_transmit_ready (tc->client,
209 GNUNET_MIN (MIN_BLOCK_SIZE,
210 tc->total), timeout,
211 &transmit_response, tc))
212 {
213 GNUNET_break (0);
214 GNUNET_SERVER_transmit_context_destroy (tc, GNUNET_SYSERR);
215 }
216}
217
218
219/**
220 * Destroy a transmission context. This function must not be called
221 * after 'GNUNET_SERVER_transmit_context_run'.
222 *
223 * @param tc transmission context to destroy
224 * @param success code to give to 'GNUNET_SERVER_receive_done' for
225 * the client: GNUNET_OK to keep the connection open and
226 * continue to receive
227 * GNUNET_NO to close the connection (normal behavior)
228 * GNUNET_SYSERR to close the connection (signal
229 * serious error)
230 */
231void
232GNUNET_SERVER_transmit_context_destroy (struct GNUNET_SERVER_TransmitContext
233 *tc, int success)
234{
235 GNUNET_SERVER_receive_done (tc->client, success);
236 GNUNET_SERVER_client_drop (tc->client);
237 GNUNET_free_non_null (tc->buf);
238 GNUNET_free (tc);
239}
240
241
242/* end of server_tc.c */
diff --git a/src/util/service.c b/src/util/service.c
index 496904fb1..800d09a42 100644
--- a/src/util/service.c
+++ b/src/util/service.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2009, 2012 GNUnet e.V. 3 Copyright (C) 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -19,9 +19,10 @@
19*/ 19*/
20 20
21/** 21/**
22 * @file util/service.c 22 * @file util/service_new.c
23 * @brief functions related to starting services 23 * @brief functions related to starting services (redesign)
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * @author Florian Dold
25 */ 26 */
26#include "platform.h" 27#include "platform.h"
27#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
@@ -43,77 +44,44 @@
43#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-service", syscall, filename) 44#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-service", syscall, filename)
44 45
45 46
46/* ******************* access control ******************** */
47
48/** 47/**
49 * Check if the given IP address is in the list of IP addresses. 48 * Information the service tracks per listen operation.
50 *
51 * @param list a list of networks
52 * @param add the IP to check (in network byte order)
53 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
54 */ 49 */
55static int 50struct ServiceListenContext
56check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list,
57 const struct in_addr *add)
58{ 51{
59 unsigned int i;
60 52
61 if (NULL == list) 53 /**
62 return GNUNET_NO; 54 * Kept in a DLL.
63 i = 0; 55 */
64 while ((list[i].network.s_addr != 0) || (list[i].netmask.s_addr != 0)) 56 struct ServiceListenContext *next;
65 {
66 if ((add->s_addr & list[i].netmask.s_addr) ==
67 (list[i].network.s_addr & list[i].netmask.s_addr))
68 return GNUNET_YES;
69 i++;
70 }
71 return GNUNET_NO;
72}
73 57
58 /**
59 * Kept in a DLL.
60 */
61 struct ServiceListenContext *prev;
74 62
75/** 63 /**
76 * Check if the given IP address is in the list of IP addresses. 64 * Service this listen context belongs to.
77 * 65 */
78 * @param list a list of networks 66 struct GNUNET_SERVICE_Handle *sh;
79 * @param ip the IP to check (in network byte order)
80 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
81 */
82static int
83check_ipv6_listed (const struct GNUNET_STRINGS_IPv6NetworkPolicy *list,
84 const struct in6_addr *ip)
85{
86 unsigned int i;
87 unsigned int j;
88 struct in6_addr zero;
89 67
90 if (NULL == list) 68 /**
91 return GNUNET_NO; 69 * Socket we are listening on.
92 memset (&zero, 0, sizeof (struct in6_addr)); 70 */
93 i = 0; 71 struct GNUNET_NETWORK_Handle *listen_socket;
94NEXT:
95 while (0 != memcmp (&zero, &list[i].network, sizeof (struct in6_addr)))
96 {
97 for (j = 0; j < sizeof (struct in6_addr) / sizeof (int); j++)
98 if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
99 (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
100 {
101 i++;
102 goto NEXT;
103 }
104 return GNUNET_YES;
105 }
106 return GNUNET_NO;
107}
108 72
73 /**
74 * Task scheduled to do the listening.
75 */
76 struct GNUNET_SCHEDULER_Task *listen_task;
109 77
110/* ****************** service struct ****************** */ 78};
111 79
112 80
113/** 81/**
114 * Context for "service_task". 82 * Handle to a service.
115 */ 83 */
116struct GNUNET_SERVICE_Context 84struct GNUNET_SERVICE_Handle
117{ 85{
118 /** 86 /**
119 * Our configuration. 87 * Our configuration.
@@ -121,25 +89,54 @@ struct GNUNET_SERVICE_Context
121 const struct GNUNET_CONFIGURATION_Handle *cfg; 89 const struct GNUNET_CONFIGURATION_Handle *cfg;
122 90
123 /** 91 /**
124 * Handle for the server. 92 * Name of our service.
125 */ 93 */
126 struct GNUNET_SERVER_Handle *server; 94 const char *service_name;
127 95
128 /** 96 /**
129 * NULL-terminated array of addresses to bind to, NULL if we got pre-bound 97 * Main service-specific task to run.
130 * listen sockets.
131 */ 98 */
132 struct sockaddr **addrs; 99 GNUNET_SERVICE_InitCallback service_init_cb;
133 100
134 /** 101 /**
135 * Name of our service. 102 * Function to call when clients connect.
136 */ 103 */
137 const char *service_name; 104 GNUNET_SERVICE_ConnectHandler connect_cb;
138 105
139 /** 106 /**
140 * Main service-specific task to run. 107 * Function to call when clients disconnect / are disconnected.
141 */ 108 */
142 GNUNET_SERVICE_Main task; 109 GNUNET_SERVICE_DisconnectHandler disconnect_cb;
110
111 /**
112 * Closure for @e service_init_cb, @e connect_cb, @e disconnect_cb.
113 */
114 void *cb_cls;
115
116 /**
117 * DLL of listen sockets used to accept new connections.
118 */
119 struct ServiceListenContext *slc_head;
120
121 /**
122 * DLL of listen sockets used to accept new connections.
123 */
124 struct ServiceListenContext *slc_tail;
125
126 /**
127 * Our clients, kept in a DLL.
128 */
129 struct GNUNET_SERVICE_Client *clients_head;
130
131 /**
132 * Our clients, kept in a DLL.
133 */
134 struct GNUNET_SERVICE_Client *clients_tail;
135
136 /**
137 * Message handlers to use for all clients.
138 */
139 struct GNUNET_MQ_MessageHandler *handlers;
143 140
144 /** 141 /**
145 * Closure for @e task. 142 * Closure for @e task.
@@ -169,30 +166,38 @@ struct GNUNET_SERVICE_Context
169 struct GNUNET_STRINGS_IPv6NetworkPolicy *v6_allowed; 166 struct GNUNET_STRINGS_IPv6NetworkPolicy *v6_allowed;
170 167
171 /** 168 /**
172 * My (default) message handlers. Adjusted copy 169 * Do we require a matching UID for UNIX domain socket connections?
173 * of "defhandlers". 170 * #GNUNET_NO means that the UID does not have to match (however,
171 * @e match_gid may still impose other access control checks).
174 */ 172 */
175 struct GNUNET_SERVER_MessageHandler *my_handlers; 173 int match_uid;
176 174
177 /** 175 /**
178 * Array of the lengths of the entries in addrs. 176 * Do we require a matching GID for UNIX domain socket connections?
177 * Ignored if @e match_uid is #GNUNET_YES. Note that this is about
178 * checking that the client's UID is in our group OR that the
179 * client's GID is our GID. If both "match_gid" and @e match_uid are
180 * #GNUNET_NO, all users on the local system have access.
179 */ 181 */
180 socklen_t *addrlens; 182 int match_gid;
181 183
182 /** 184 /**
183 * NULL-terminated array of listen sockets we should take over. 185 * Set to #GNUNET_YES if we got a shutdown signal and terminate
186 * the service if #have_non_monitor_clients() returns #GNUNET_YES.
184 */ 187 */
185 struct GNUNET_NETWORK_Handle **lsocks; 188 int got_shutdown;
186 189
187 /** 190 /**
188 * Task ID of the shutdown task. 191 * Our options.
189 */ 192 */
190 struct GNUNET_SCHEDULER_Task *shutdown_task; 193 enum GNUNET_SERVICE_Options options;
191 194
192 /** 195 /**
193 * Idle timeout for server. 196 * If we are daemonizing, this FD is set to the
197 * pipe to the parent. Send '.' if we started
198 * ok, '!' if not. -1 if we are not daemonizing.
194 */ 199 */
195 struct GNUNET_TIME_Relative timeout; 200 int ready_confirm_fd;
196 201
197 /** 202 /**
198 * Overall success/failure of the service start. 203 * Overall success/failure of the service start.
@@ -200,182 +205,203 @@ struct GNUNET_SERVICE_Context
200 int ret; 205 int ret;
201 206
202 /** 207 /**
203 * If we are daemonizing, this FD is set to the 208 * If #GNUNET_YES, consider unknown message types an error where the
204 * pipe to the parent. Send '.' if we started 209 * client is disconnected.
205 * ok, '!' if not. -1 if we are not daemonizing.
206 */ 210 */
207 int ready_confirm_fd; 211 int require_found;
212};
213
214
215/**
216 * Handle to a client that is connected to a service.
217 */
218struct GNUNET_SERVICE_Client
219{
208 220
209 /** 221 /**
210 * Do we close connections if we receive messages 222 * Kept in a DLL.
211 * for which we have no handler?
212 */ 223 */
213 int require_found; 224 struct GNUNET_SERVICE_Client *next;
214 225
215 /** 226 /**
216 * Do we require a matching UID for UNIX domain socket connections? 227 * Kept in a DLL.
217 * #GNUNET_NO means that the UID does not have to match (however,
218 * @e match_gid may still impose other access control checks).
219 */ 228 */
220 int match_uid; 229 struct GNUNET_SERVICE_Client *prev;
221 230
222 /** 231 /**
223 * Do we require a matching GID for UNIX domain socket connections? 232 * Service that this client belongs to.
224 * Ignored if @e match_uid is #GNUNET_YES. Note that this is about
225 * checking that the client's UID is in our group OR that the
226 * client's GID is our GID. If both "match_gid" and @e match_uid are
227 * #GNUNET_NO, all users on the local system have access.
228 */ 233 */
229 int match_gid; 234 struct GNUNET_SERVICE_Handle *sh;
230 235
231 /** 236 /**
232 * Our options. 237 * Socket of this client.
233 */ 238 */
234 enum GNUNET_SERVICE_Options options; 239 struct GNUNET_NETWORK_Handle *sock;
235 240
236}; 241 /**
242 * Message queue for the client.
243 */
244 struct GNUNET_MQ_Handle *mq;
245
246 /**
247 * Tokenizer we use for processing incoming data.
248 */
249 struct GNUNET_MessageStreamTokenizer *mst;
250
251 /**
252 * Task that warns about missing calls to
253 * #GNUNET_SERVICE_client_continue().
254 */
255 struct GNUNET_SCHEDULER_Task *warn_task;
237 256
257 /**
258 * Task run to finish dropping the client after the stack has
259 * properly unwound.
260 */
261 struct GNUNET_SCHEDULER_Task *drop_task;
262
263 /**
264 * Task that receives data from the client to
265 * pass it to the handlers.
266 */
267 struct GNUNET_SCHEDULER_Task *recv_task;
268
269 /**
270 * Task that transmit data to the client.
271 */
272 struct GNUNET_SCHEDULER_Task *send_task;
273
274 /**
275 * Pointer to the message to be transmitted by @e send_task.
276 */
277 const struct GNUNET_MessageHeader *msg;
278
279 /**
280 * User context value, value returned from
281 * the connect callback.
282 */
283 void *user_context;
284
285 /**
286 * Time when we last gave a message from this client
287 * to the application.
288 */
289 struct GNUNET_TIME_Absolute warn_start;
290
291 /**
292 * Current position in @e msg at which we are transmitting.
293 */
294 size_t msg_pos;
295
296 /**
297 * Persist the file handle for this client no matter what happens,
298 * force the OS to close once the process actually dies. Should only
299 * be used in special cases!
300 */
301 int persist;
302
303 /**
304 * Is this client a 'monitor' client that should not be counted
305 * when deciding on destroying the server during soft shutdown?
306 * (see also #GNUNET_SERVICE_start)
307 */
308 int is_monitor;
309
310 /**
311 * Are we waiting for the application to call #GNUNET_SERVICE_client_continue()?
312 */
313 int needs_continue;
314
315 /**
316 * Type of last message processed (for warn_no_receive_done).
317 */
318 uint16_t warn_type;
319};
238 320
239/* ****************** message handlers ****************** */
240 321
241/** 322/**
242 * Send a 'TEST' message back to the client. 323 * Check if any of the clients we have left are unrelated to
324 * monitoring.
243 * 325 *
244 * @param cls the 'struct GNUNET_SERVER_Client' to send TEST to 326 * @param sh service to check clients for
245 * @param size number of bytes available in 'buf' 327 * @return #GNUNET_YES if we have non-monitoring clients left
246 * @param buf where to copy the message
247 * @return number of bytes written to 'buf'
248 */ 328 */
249static size_t 329static int
250write_test (void *cls, size_t size, void *buf) 330have_non_monitor_clients (struct GNUNET_SERVICE_Handle *sh)
251{ 331{
252 struct GNUNET_SERVER_Client *client = cls; 332 struct GNUNET_SERVICE_Client *client;
253 struct GNUNET_MessageHeader *msg;
254 333
255 if (size < sizeof (struct GNUNET_MessageHeader)) 334 for (client = sh->clients_head;NULL != client; client = client->next)
256 { 335 {
257 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 336 if (client->is_monitor)
258 return 0; /* client disconnected */ 337 continue;
338 return GNUNET_YES;
259 } 339 }
260 msg = (struct GNUNET_MessageHeader *) buf; 340 return GNUNET_NO;
261 msg->type = htons (GNUNET_MESSAGE_TYPE_TEST);
262 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
263 GNUNET_SERVER_receive_done (client, GNUNET_OK);
264 return sizeof (struct GNUNET_MessageHeader);
265} 341}
266 342
267 343
268/** 344/**
269 * Handler for TEST message. 345 * Shutdown task triggered when a service should be terminated.
346 * This considers active clients and the service options to see
347 * how this specific service is to be terminated, and depending
348 * on this proceeds with the shutdown logic.
270 * 349 *
271 * @param cls closure (refers to service) 350 * @param cls our `struct GNUNET_SERVICE_Handle`
272 * @param client identification of the client
273 * @param message the actual message
274 */ 351 */
275static void 352static void
276handle_test (void *cls, struct GNUNET_SERVER_Client *client, 353service_shutdown (void *cls)
277 const struct GNUNET_MessageHeader *message)
278{ 354{
279 /* simply bounce message back to acknowledge */ 355 struct GNUNET_SERVICE_Handle *sh = cls;
280 if (NULL ==
281 GNUNET_SERVER_notify_transmit_ready (client,
282 sizeof (struct GNUNET_MessageHeader),
283 GNUNET_TIME_UNIT_FOREVER_REL,
284 &write_test, client))
285 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
286}
287
288
289/**
290 * Default handlers for all services. Will be copied and the
291 * "callback_cls" fields will be replaced with the specific service
292 * struct.
293 */
294static const struct GNUNET_SERVER_MessageHandler defhandlers[] = {
295 {&handle_test, NULL, GNUNET_MESSAGE_TYPE_TEST,
296 sizeof (struct GNUNET_MessageHeader)},
297 {NULL, NULL, 0, 0}
298};
299
300
301/* ****************** service core routines ************** */
302 356
303 357 switch (sh->options)
304/**
305 * Check if access to the service is allowed from the given address.
306 *
307 * @param cls closure
308 * @param uc credentials, if available, otherwise NULL
309 * @param addr address
310 * @param addrlen length of address
311 * @return #GNUNET_YES to allow, #GNUNET_NO to deny, #GNUNET_SYSERR
312 * for unknown address family (will be denied).
313 */
314static int
315check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc,
316 const struct sockaddr *addr, socklen_t addrlen)
317{
318 struct GNUNET_SERVICE_Context *sctx = cls;
319 const struct sockaddr_in *i4;
320 const struct sockaddr_in6 *i6;
321 int ret;
322
323 switch (addr->sa_family)
324 { 358 {
325 case AF_INET: 359 case GNUNET_SERVICE_OPTION_NONE:
326 GNUNET_assert (addrlen == sizeof (struct sockaddr_in)); 360 GNUNET_SERVICE_shutdown (sh);
327 i4 = (const struct sockaddr_in *) addr;
328 ret = ((NULL == sctx->v4_allowed) ||
329 (check_ipv4_listed (sctx->v4_allowed, &i4->sin_addr))) &&
330 ((NULL == sctx->v4_denied) ||
331 (!check_ipv4_listed (sctx->v4_denied, &i4->sin_addr)));
332 break; 361 break;
333 case AF_INET6: 362 case GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN:
334 GNUNET_assert (addrlen == sizeof (struct sockaddr_in6)); 363 /* This task should never be run if we are using
335 i6 = (const struct sockaddr_in6 *) addr; 364 the manual shutdown. */
336 ret = ((NULL == sctx->v6_allowed) || 365 GNUNET_assert (0);
337 (check_ipv6_listed (sctx->v6_allowed, &i6->sin6_addr))) &&
338 ((NULL == sctx->v6_denied) ||
339 (!check_ipv6_listed (sctx->v6_denied, &i6->sin6_addr)));
340 break; 366 break;
341#ifndef WINDOWS 367 case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN:
342 case AF_UNIX: 368 sh->got_shutdown = GNUNET_YES;
343 ret = GNUNET_OK; /* controlled using file-system ACL now */ 369 GNUNET_SERVICE_suspend (sh);
370 if (GNUNET_NO == have_non_monitor_clients (sh))
371 GNUNET_SERVICE_shutdown (sh);
344 break; 372 break;
345#endif
346 default:
347 LOG (GNUNET_ERROR_TYPE_WARNING, _("Unknown address family %d\n"),
348 addr->sa_family);
349 return GNUNET_SYSERR;
350 }
351 if (GNUNET_OK != ret)
352 {
353 LOG (GNUNET_ERROR_TYPE_WARNING,
354 _("Access from `%s' denied to service `%s'\n"),
355 GNUNET_a2s (addr, addrlen),
356 sctx->service_name);
357 } 373 }
358 return ret;
359} 374}
360 375
361 376
362/** 377/**
363 * Get the name of the file where we will 378 * First task run by any service. Initializes our shutdown task,
364 * write the PID of the service. 379 * starts the listening operation on our listen sockets and launches
380 * the custom logic of the application service.
365 * 381 *
366 * @param sctx service context 382 * @param cls our `struct GNUNET_SERVICE_Handle`
367 * @return name of the file for the process ID
368 */ 383 */
369static char * 384static void
370get_pid_file_name (struct GNUNET_SERVICE_Context *sctx) 385service_main (void *cls)
371{ 386{
372 char *pif; 387 struct GNUNET_SERVICE_Handle *sh = cls;
373 388
374 if (GNUNET_OK != 389 if (GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN != sh->options)
375 GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->service_name, 390 GNUNET_SCHEDULER_add_shutdown (&service_shutdown,
376 "PIDFILE", &pif)) 391 sh);
377 return NULL; 392 GNUNET_SERVICE_resume (sh);
378 return pif; 393
394 if (-1 != sh->ready_confirm_fd)
395 {
396 GNUNET_break (1 == WRITE (sh->ready_confirm_fd, ".", 1));
397 GNUNET_break (0 == CLOSE (sh->ready_confirm_fd));
398 sh->ready_confirm_fd = -1;
399 }
400
401 if (NULL != sh->service_init_cb)
402 sh->service_init_cb (sh->cb_cls,
403 sh->cfg,
404 sh);
379} 405}
380 406
381 407
@@ -383,32 +409,37 @@ get_pid_file_name (struct GNUNET_SERVICE_Context *sctx)
383 * Parse an IPv4 access control list. 409 * Parse an IPv4 access control list.
384 * 410 *
385 * @param ret location where to write the ACL (set) 411 * @param ret location where to write the ACL (set)
386 * @param sctx service context to use to get the configuration 412 * @param sh service context to use to get the configuration
387 * @param option name of the ACL option to parse 413 * @param option name of the ACL option to parse
388 * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including 414 * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
389 * no ACL configured) 415 * no ACL configured)
390 */ 416 */
391static int 417static int
392process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, 418process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret,
393 struct GNUNET_SERVICE_Context *sctx, 419 struct GNUNET_SERVICE_Handle *sh,
394 const char *option) 420 const char *option)
395{ 421{
396 char *opt; 422 char *opt;
397 423
398 if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option)) 424 if (! GNUNET_CONFIGURATION_have_value (sh->cfg,
425 sh->service_name,
426 option))
399 { 427 {
400 *ret = NULL; 428 *ret = NULL;
401 return GNUNET_OK; 429 return GNUNET_OK;
402 } 430 }
403 GNUNET_break (GNUNET_OK == 431 GNUNET_break (GNUNET_OK ==
404 GNUNET_CONFIGURATION_get_value_string (sctx->cfg, 432 GNUNET_CONFIGURATION_get_value_string (sh->cfg,
405 sctx->service_name, 433 sh->service_name,
406 option, &opt)); 434 option,
435 &opt));
407 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt))) 436 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt)))
408 { 437 {
409 LOG (GNUNET_ERROR_TYPE_WARNING, 438 LOG (GNUNET_ERROR_TYPE_WARNING,
410 _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"), 439 _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
411 opt, sctx->service_name, option); 440 opt,
441 sh->service_name,
442 option);
412 GNUNET_free (opt); 443 GNUNET_free (opt);
413 return GNUNET_SYSERR; 444 return GNUNET_SYSERR;
414 } 445 }
@@ -421,32 +452,37 @@ process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret,
421 * Parse an IPv6 access control list. 452 * Parse an IPv6 access control list.
422 * 453 *
423 * @param ret location where to write the ACL (set) 454 * @param ret location where to write the ACL (set)
424 * @param sctx service context to use to get the configuration 455 * @param sh service context to use to get the configuration
425 * @param option name of the ACL option to parse 456 * @param option name of the ACL option to parse
426 * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including 457 * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
427 * no ACL configured) 458 * no ACL configured)
428 */ 459 */
429static int 460static int
430process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, 461process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret,
431 struct GNUNET_SERVICE_Context *sctx, 462 struct GNUNET_SERVICE_Handle *sh,
432 const char *option) 463 const char *option)
433{ 464{
434 char *opt; 465 char *opt;
435 466
436 if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option)) 467 if (! GNUNET_CONFIGURATION_have_value (sh->cfg,
468 sh->service_name,
469 option))
437 { 470 {
438 *ret = NULL; 471 *ret = NULL;
439 return GNUNET_OK; 472 return GNUNET_OK;
440 } 473 }
441 GNUNET_break (GNUNET_OK == 474 GNUNET_break (GNUNET_OK ==
442 GNUNET_CONFIGURATION_get_value_string (sctx->cfg, 475 GNUNET_CONFIGURATION_get_value_string (sh->cfg,
443 sctx->service_name, 476 sh->service_name,
444 option, &opt)); 477 option,
478 &opt));
445 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt))) 479 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt)))
446 { 480 {
447 LOG (GNUNET_ERROR_TYPE_WARNING, 481 LOG (GNUNET_ERROR_TYPE_WARNING,
448 _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"), 482 _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
449 opt, sctx->service_name, option); 483 opt,
484 sh->service_name,
485 option);
450 GNUNET_free (opt); 486 GNUNET_free (opt);
451 return GNUNET_SYSERR; 487 return GNUNET_SYSERR;
452 } 488 }
@@ -476,7 +512,9 @@ add_unixpath (struct sockaddr **saddrs,
476 512
477 un = GNUNET_new (struct sockaddr_un); 513 un = GNUNET_new (struct sockaddr_un);
478 un->sun_family = AF_UNIX; 514 un->sun_family = AF_UNIX;
479 strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1); 515 strncpy (un->sun_path,
516 unixpath,
517 sizeof (un->sun_path) - 1);
480#ifdef LINUX 518#ifdef LINUX
481 if (GNUNET_YES == abstract) 519 if (GNUNET_YES == abstract)
482 un->sun_path[0] = '\0'; 520 un->sun_path[0] = '\0';
@@ -514,11 +552,11 @@ add_unixpath (struct sockaddr **saddrs,
514 * zero (in this case, `*addrs` and `*addr_lens` will be 552 * zero (in this case, `*addrs` and `*addr_lens` will be
515 * set to NULL). 553 * set to NULL).
516 */ 554 */
517int 555static int
518GNUNET_SERVICE_get_server_addresses (const char *service_name, 556get_server_addresses (const char *service_name,
519 const struct GNUNET_CONFIGURATION_Handle *cfg, 557 const struct GNUNET_CONFIGURATION_Handle *cfg,
520 struct sockaddr ***addrs, 558 struct sockaddr ***addrs,
521 socklen_t ** addr_lens) 559 socklen_t **addr_lens)
522{ 560{
523 int disablev6; 561 int disablev6;
524 struct GNUNET_NETWORK_Handle *desc; 562 struct GNUNET_NETWORK_Handle *desc;
@@ -539,11 +577,15 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
539 *addrs = NULL; 577 *addrs = NULL;
540 *addr_lens = NULL; 578 *addr_lens = NULL;
541 desc = NULL; 579 desc = NULL;
542 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "DISABLEV6")) 580 if (GNUNET_CONFIGURATION_have_value (cfg,
581 service_name,
582 "DISABLEV6"))
543 { 583 {
544 if (GNUNET_SYSERR == 584 if (GNUNET_SYSERR ==
545 (disablev6 = 585 (disablev6 =
546 GNUNET_CONFIGURATION_get_value_yesno (cfg, service_name, "DISABLEV6"))) 586 GNUNET_CONFIGURATION_get_value_yesno (cfg,
587 service_name,
588 "DISABLEV6")))
547 return GNUNET_SYSERR; 589 return GNUNET_SYSERR;
548 } 590 }
549 else 591 else
@@ -552,33 +594,44 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
552 if (! disablev6) 594 if (! disablev6)
553 { 595 {
554 /* probe IPv6 support */ 596 /* probe IPv6 support */
555 desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); 597 desc = GNUNET_NETWORK_socket_create (PF_INET6,
598 SOCK_STREAM,
599 0);
556 if (NULL == desc) 600 if (NULL == desc)
557 { 601 {
558 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || 602 if ( (ENOBUFS == errno) ||
559 (EACCES == errno)) 603 (ENOMEM == errno) ||
604 (ENFILE == errno) ||
605 (EACCES == errno) )
560 { 606 {
561 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); 607 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
608 "socket");
562 return GNUNET_SYSERR; 609 return GNUNET_SYSERR;
563 } 610 }
564 LOG (GNUNET_ERROR_TYPE_INFO, 611 LOG (GNUNET_ERROR_TYPE_INFO,
565 _("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"), 612 _("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
566 service_name, STRERROR (errno)); 613 service_name,
614 STRERROR (errno));
567 disablev6 = GNUNET_YES; 615 disablev6 = GNUNET_YES;
568 } 616 }
569 else 617 else
570 { 618 {
571 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); 619 GNUNET_break (GNUNET_OK ==
620 GNUNET_NETWORK_socket_close (desc));
572 desc = NULL; 621 desc = NULL;
573 } 622 }
574 } 623 }
575 624
576 port = 0; 625 port = 0;
577 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT")) 626 if (GNUNET_CONFIGURATION_have_value (cfg,
627 service_name,
628 "PORT"))
578 { 629 {
579 if (GNUNET_OK != 630 if (GNUNET_OK !=
580 GNUNET_CONFIGURATION_get_value_number (cfg, service_name, 631 GNUNET_CONFIGURATION_get_value_number (cfg,
581 "PORT", &port)) 632 service_name,
633 "PORT",
634 &port))
582 { 635 {
583 LOG (GNUNET_ERROR_TYPE_ERROR, 636 LOG (GNUNET_ERROR_TYPE_ERROR,
584 _("Require valid port number for service `%s' in configuration!\n"), 637 _("Require valid port number for service `%s' in configuration!\n"),
@@ -593,11 +646,15 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
593 } 646 }
594 } 647 }
595 648
596 if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO")) 649 if (GNUNET_CONFIGURATION_have_value (cfg,
650 service_name,
651 "BINDTO"))
597 { 652 {
598 GNUNET_break (GNUNET_OK == 653 GNUNET_break (GNUNET_OK ==
599 GNUNET_CONFIGURATION_get_value_string (cfg, service_name, 654 GNUNET_CONFIGURATION_get_value_string (cfg,
600 "BINDTO", &hostname)); 655 service_name,
656 "BINDTO",
657 &hostname));
601 } 658 }
602 else 659 else
603 hostname = NULL; 660 hostname = NULL;
@@ -606,10 +663,14 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
606 abstract = GNUNET_NO; 663 abstract = GNUNET_NO;
607#ifdef AF_UNIX 664#ifdef AF_UNIX
608 if ((GNUNET_YES == 665 if ((GNUNET_YES ==
609 GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) && 666 GNUNET_CONFIGURATION_have_value (cfg,
667 service_name,
668 "UNIXPATH")) &&
610 (GNUNET_OK == 669 (GNUNET_OK ==
611 GNUNET_CONFIGURATION_get_value_filename (cfg, service_name, "UNIXPATH", 670 GNUNET_CONFIGURATION_get_value_filename (cfg,
612 &unixpath)) && 671 service_name,
672 "UNIXPATH",
673 &unixpath)) &&
613 (0 < strlen (unixpath))) 674 (0 < strlen (unixpath)))
614 { 675 {
615 /* probe UNIX support */ 676 /* probe UNIX support */
@@ -618,7 +679,8 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
618 if (strlen (unixpath) >= sizeof (s_un.sun_path)) 679 if (strlen (unixpath) >= sizeof (s_un.sun_path))
619 { 680 {
620 LOG (GNUNET_ERROR_TYPE_WARNING, 681 LOG (GNUNET_ERROR_TYPE_WARNING,
621 _("UNIXPATH `%s' too long, maximum length is %llu\n"), unixpath, 682 _("UNIXPATH `%s' too long, maximum length is %llu\n"),
683 unixpath,
622 (unsigned long long) sizeof (s_un.sun_path)); 684 (unsigned long long) sizeof (s_un.sun_path));
623 unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath); 685 unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
624 LOG (GNUNET_ERROR_TYPE_INFO, 686 LOG (GNUNET_ERROR_TYPE_INFO,
@@ -632,22 +694,27 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
632 if (GNUNET_SYSERR == abstract) 694 if (GNUNET_SYSERR == abstract)
633 abstract = GNUNET_NO; 695 abstract = GNUNET_NO;
634#endif 696#endif
635 if ((GNUNET_YES != abstract) 697 if ( (GNUNET_YES != abstract) &&
636 && (GNUNET_OK != 698 (GNUNET_OK !=
637 GNUNET_DISK_directory_create_for_file (unixpath))) 699 GNUNET_DISK_directory_create_for_file (unixpath)) )
638 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, 700 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
639 "mkdir", 701 "mkdir",
640 unixpath); 702 unixpath);
641 } 703 }
642 if (NULL != unixpath) 704 if (NULL != unixpath)
643 { 705 {
644 desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0); 706 desc = GNUNET_NETWORK_socket_create (AF_UNIX,
707 SOCK_STREAM,
708 0);
645 if (NULL == desc) 709 if (NULL == desc)
646 { 710 {
647 if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || 711 if ((ENOBUFS == errno) ||
712 (ENOMEM == errno) ||
713 (ENFILE == errno) ||
648 (EACCES == errno)) 714 (EACCES == errno))
649 { 715 {
650 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); 716 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
717 "socket");
651 GNUNET_free_non_null (hostname); 718 GNUNET_free_non_null (hostname);
652 GNUNET_free (unixpath); 719 GNUNET_free (unixpath);
653 return GNUNET_SYSERR; 720 return GNUNET_SYSERR;
@@ -661,7 +728,8 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
661 } 728 }
662 else 729 else
663 { 730 {
664 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); 731 GNUNET_break (GNUNET_OK ==
732 GNUNET_NETWORK_socket_close (desc));
665 desc = NULL; 733 desc = NULL;
666 } 734 }
667 } 735 }
@@ -677,9 +745,14 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
677 } 745 }
678 if (0 == port) 746 if (0 == port)
679 { 747 {
680 saddrs = GNUNET_malloc (2 * sizeof (struct sockaddr *)); 748 saddrs = GNUNET_new_array (2,
681 saddrlens = GNUNET_malloc (2 * sizeof (socklen_t)); 749 struct sockaddr *);
682 add_unixpath (saddrs, saddrlens, unixpath, abstract); 750 saddrlens = GNUNET_new_array (2,
751 socklen_t);
752 add_unixpath (saddrs,
753 saddrlens,
754 unixpath,
755 abstract);
683 GNUNET_free_non_null (unixpath); 756 GNUNET_free_non_null (unixpath);
684 GNUNET_free_non_null (hostname); 757 GNUNET_free_non_null (hostname);
685 *addrs = saddrs; 758 *addrs = saddrs;
@@ -693,11 +766,16 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
693 "Resolving `%s' since that is where `%s' will bind to.\n", 766 "Resolving `%s' since that is where `%s' will bind to.\n",
694 hostname, 767 hostname,
695 service_name); 768 service_name);
696 memset (&hints, 0, sizeof (struct addrinfo)); 769 memset (&hints,
770 0,
771 sizeof (struct addrinfo));
697 if (disablev6) 772 if (disablev6)
698 hints.ai_family = AF_INET; 773 hints.ai_family = AF_INET;
699 hints.ai_protocol = IPPROTO_TCP; 774 hints.ai_protocol = IPPROTO_TCP;
700 if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) || 775 if ((0 != (ret = getaddrinfo (hostname,
776 NULL,
777 &hints,
778 &res))) ||
701 (NULL == res)) 779 (NULL == res))
702 { 780 {
703 LOG (GNUNET_ERROR_TYPE_ERROR, 781 LOG (GNUNET_ERROR_TYPE_ERROR,
@@ -713,7 +791,8 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
713 while (NULL != (pos = next)) 791 while (NULL != (pos = next))
714 { 792 {
715 next = pos->ai_next; 793 next = pos->ai_next;
716 if ((disablev6) && (pos->ai_family == AF_INET6)) 794 if ( (disablev6) &&
795 (pos->ai_family == AF_INET6) )
717 continue; 796 continue;
718 i++; 797 i++;
719 } 798 }
@@ -731,32 +810,45 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
731 resi = i; 810 resi = i;
732 if (NULL != unixpath) 811 if (NULL != unixpath)
733 resi++; 812 resi++;
734 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *)); 813 saddrs = GNUNET_new_array (resi + 1,
735 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); 814 struct sockaddr *);
815 saddrlens = GNUNET_new_array (resi + 1,
816 socklen_t);
736 i = 0; 817 i = 0;
737 if (NULL != unixpath) 818 if (NULL != unixpath)
738 { 819 {
739 add_unixpath (saddrs, saddrlens, unixpath, abstract); 820 add_unixpath (saddrs,
821 saddrlens,
822 unixpath,
823 abstract);
740 i++; 824 i++;
741 } 825 }
742 next = res; 826 next = res;
743 while (NULL != (pos = next)) 827 while (NULL != (pos = next))
744 { 828 {
745 next = pos->ai_next; 829 next = pos->ai_next;
746 if ((disablev6) && (AF_INET6 == pos->ai_family)) 830 if ( (disablev6) &&
831 (AF_INET6 == pos->ai_family) )
747 continue; 832 continue;
748 if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol)) 833 if ( (IPPROTO_TCP != pos->ai_protocol) &&
834 (0 != pos->ai_protocol) )
749 continue; /* not TCP */ 835 continue; /* not TCP */
750 if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype)) 836 if ( (SOCK_STREAM != pos->ai_socktype) &&
837 (0 != pos->ai_socktype) )
751 continue; /* huh? */ 838 continue; /* huh? */
752 LOG (GNUNET_ERROR_TYPE_DEBUG, "Service `%s' will bind to `%s'\n", 839 LOG (GNUNET_ERROR_TYPE_DEBUG,
753 service_name, GNUNET_a2s (pos->ai_addr, pos->ai_addrlen)); 840 "Service `%s' will bind to `%s'\n",
841 service_name,
842 GNUNET_a2s (pos->ai_addr,
843 pos->ai_addrlen));
754 if (AF_INET == pos->ai_family) 844 if (AF_INET == pos->ai_family)
755 { 845 {
756 GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen); 846 GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen);
757 saddrlens[i] = pos->ai_addrlen; 847 saddrlens[i] = pos->ai_addrlen;
758 saddrs[i] = GNUNET_malloc (saddrlens[i]); 848 saddrs[i] = GNUNET_malloc (saddrlens[i]);
759 GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); 849 GNUNET_memcpy (saddrs[i],
850 pos->ai_addr,
851 saddrlens[i]);
760 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); 852 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
761 } 853 }
762 else 854 else
@@ -765,7 +857,9 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
765 GNUNET_assert (sizeof (struct sockaddr_in6) == pos->ai_addrlen); 857 GNUNET_assert (sizeof (struct sockaddr_in6) == pos->ai_addrlen);
766 saddrlens[i] = pos->ai_addrlen; 858 saddrlens[i] = pos->ai_addrlen;
767 saddrs[i] = GNUNET_malloc (saddrlens[i]); 859 saddrs[i] = GNUNET_malloc (saddrlens[i]);
768 GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); 860 GNUNET_memcpy (saddrs[i],
861 pos->ai_addr,
862 saddrlens[i]);
769 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); 863 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
770 } 864 }
771 i++; 865 i++;
@@ -784,11 +878,16 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
784 if (NULL != unixpath) 878 if (NULL != unixpath)
785 resi++; 879 resi++;
786 i = 0; 880 i = 0;
787 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *)); 881 saddrs = GNUNET_new_array (resi + 1,
788 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); 882 struct sockaddr *);
883 saddrlens = GNUNET_new_array (resi + 1,
884 socklen_t);
789 if (NULL != unixpath) 885 if (NULL != unixpath)
790 { 886 {
791 add_unixpath (saddrs, saddrlens, unixpath, abstract); 887 add_unixpath (saddrs,
888 saddrlens,
889 unixpath,
890 abstract);
792 i++; 891 i++;
793 } 892 }
794 saddrlens[i] = sizeof (struct sockaddr_in); 893 saddrlens[i] = sizeof (struct sockaddr_in);
@@ -805,12 +904,17 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
805 resi = 2; 904 resi = 2;
806 if (NULL != unixpath) 905 if (NULL != unixpath)
807 resi++; 906 resi++;
808 saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *)); 907 saddrs = GNUNET_new_array (resi + 1,
809 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); 908 struct sockaddr *);
909 saddrlens = GNUNET_new_array (resi + 1,
910 socklen_t);
810 i = 0; 911 i = 0;
811 if (NULL != unixpath) 912 if (NULL != unixpath)
812 { 913 {
813 add_unixpath (saddrs, saddrlens, unixpath, abstract); 914 add_unixpath (saddrs,
915 saddrlens,
916 unixpath,
917 abstract);
814 i++; 918 i++;
815 } 919 }
816 saddrlens[i] = sizeof (struct sockaddr_in6); 920 saddrlens[i] = sizeof (struct sockaddr_in6);
@@ -841,13 +945,14 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
841/** 945/**
842 * Read listen sockets from the parent process (ARM). 946 * Read listen sockets from the parent process (ARM).
843 * 947 *
844 * @param sctx service context to initialize 948 * @param sh service context to initialize
845 * @return #GNUNET_YES if ok, #GNUNET_NO if not ok (must bind yourself), 949 * @return NULL-terminated array of sockets on success,
846 * and #GNUNET_SYSERR on error. 950 * NULL if not ok (must bind yourself)
847 */ 951 */
848static int 952static struct GNUNET_NETWORK_Handle **
849receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx) 953receive_sockets_from_parent (struct GNUNET_SERVICE_Handle *sh)
850{ 954{
955 static struct GNUNET_NETWORK_Handle **lsocks;
851 const char *env_buf; 956 const char *env_buf;
852 int fail; 957 int fail;
853 uint64_t count; 958 uint64_t count;
@@ -855,15 +960,19 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx)
855 HANDLE lsocks_pipe; 960 HANDLE lsocks_pipe;
856 961
857 env_buf = getenv ("GNUNET_OS_READ_LSOCKS"); 962 env_buf = getenv ("GNUNET_OS_READ_LSOCKS");
858 if ((NULL == env_buf) || (strlen (env_buf) <= 0)) 963 if ( (NULL == env_buf) ||
859 return GNUNET_NO; 964 (strlen (env_buf) <= 0) )
965 return NULL;
860 /* Using W32 API directly here, because this pipe will 966 /* Using W32 API directly here, because this pipe will
861 * never be used outside of this function, and it's just too much of a bother 967 * never be used outside of this function, and it's just too much of a bother
862 * to create a GNUnet API that boxes a HANDLE (the way it is done with socks) 968 * to create a GNUnet API that boxes a HANDLE (the way it is done with socks)
863 */ 969 */
864 lsocks_pipe = (HANDLE) strtoul (env_buf, NULL, 10); 970 lsocks_pipe = (HANDLE) strtoul (env_buf,
865 if ( (0 == lsocks_pipe) || (INVALID_HANDLE_VALUE == lsocks_pipe)) 971 NULL,
866 return GNUNET_NO; 972 10);
973 if ( (0 == lsocks_pipe) ||
974 (INVALID_HANDLE_VALUE == lsocks_pipe))
975 return NULL;
867 fail = 1; 976 fail = 1;
868 do 977 do
869 { 978 {
@@ -871,11 +980,17 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx)
871 int fail2; 980 int fail2;
872 DWORD rd; 981 DWORD rd;
873 982
874 ret = ReadFile (lsocks_pipe, &count, sizeof (count), &rd, NULL); 983 ret = ReadFile (lsocks_pipe,
875 if ((0 == ret) || (sizeof (count) != rd) || (0 == count)) 984 &count,
985 sizeof (count),
986 &rd,
987 NULL);
988 if ( (0 == ret) ||
989 (sizeof (count) != rd) ||
990 (0 == count) )
876 break; 991 break;
877 sctx->lsocks = 992 lsocks = GNUNET_new_array (count + 1,
878 GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (count + 1)); 993 struct GNUNET_NETWORK_Handle *);
879 994
880 fail2 = 1; 995 fail2 = 1;
881 for (i = 0; i < count; i++) 996 for (i = 0; i < count; i++)
@@ -884,51 +999,165 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx)
884 uint64_t size; 999 uint64_t size;
885 SOCKET s; 1000 SOCKET s;
886 1001
887 ret = ReadFile (lsocks_pipe, &size, sizeof (size), &rd, NULL); 1002 ret = ReadFile (lsocks_pipe,
888 if ( (0 == ret) || (sizeof (size) != rd) || (sizeof (pi) != size) ) 1003 &size,
1004 sizeof (size),
1005 &rd,
1006 NULL);
1007 if ( (0 == ret) ||
1008 (sizeof (size) != rd) ||
1009 (sizeof (pi) != size) )
889 break; 1010 break;
890 ret = ReadFile (lsocks_pipe, &pi, sizeof (pi), &rd, NULL); 1011 ret = ReadFile (lsocks_pipe,
891 if ( (0 == ret) || (sizeof (pi) != rd)) 1012 &pi,
1013 sizeof (pi),
1014 &rd,
1015 NULL);
1016 if ( (0 == ret) ||
1017 (sizeof (pi) != rd))
892 break; 1018 break;
893 s = WSASocketA (pi.iAddressFamily, pi.iSocketType, pi.iProtocol, &pi, 0, WSA_FLAG_OVERLAPPED); 1019 s = WSASocketA (pi.iAddressFamily,
894 sctx->lsocks[i] = GNUNET_NETWORK_socket_box_native (s); 1020 pi.iSocketType,
895 if (NULL == sctx->lsocks[i]) 1021 pi.iProtocol,
1022 &pi,
1023 0,
1024 WSA_FLAG_OVERLAPPED);
1025 lsocks[i] = GNUNET_NETWORK_socket_box_native (s);
1026 if (NULL == lsocks[i])
896 break; 1027 break;
897 else if (i == count - 1) 1028 else if (i == count - 1)
898 fail2 = 0; 1029 fail2 = 0;
899 } 1030 }
900 if (fail2) 1031 if (fail2)
901 break; 1032 break;
902 sctx->lsocks[count] = NULL; 1033 lsocks[count] = NULL;
903 fail = 0; 1034 fail = 0;
904 } 1035 }
905 while (fail); 1036 while (fail);
906
907 CloseHandle (lsocks_pipe); 1037 CloseHandle (lsocks_pipe);
908 1038
909 if (fail) 1039 if (fail)
910 { 1040 {
911 LOG (GNUNET_ERROR_TYPE_ERROR, 1041 LOG (GNUNET_ERROR_TYPE_ERROR,
912 _("Could not access a pre-bound socket, will try to bind myself\n")); 1042 _("Could not access a pre-bound socket, will try to bind myself\n"));
913 for (i = 0; (i < count) && (NULL != sctx->lsocks[i]); i++) 1043 for (i = 0; (i < count) && (NULL != lsocks[i]); i++)
914 GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[i])); 1044 GNUNET_break (GNUNET_OK ==
915 GNUNET_free_non_null (sctx->lsocks); 1045 GNUNET_NETWORK_socket_close (lsocks[i]));
916 sctx->lsocks = NULL; 1046 GNUNET_free (lsocks);
917 return GNUNET_NO; 1047 return NULL;
918 } 1048 }
919 return GNUNET_YES; 1049 return lsocks;
920} 1050}
921#endif 1051#endif
922 1052
923 1053
924/** 1054/**
925 * Setup addr, addrlen, idle_timeout 1055 * Create and initialize a listen socket for the server.
926 * based on configuration! 1056 *
1057 * @param server_addr address to listen on
1058 * @param socklen length of @a server_addr
1059 * @return NULL on error, otherwise the listen socket
1060 */
1061static struct GNUNET_NETWORK_Handle *
1062open_listen_socket (const struct sockaddr *server_addr,
1063 socklen_t socklen)
1064{
1065 struct GNUNET_NETWORK_Handle *sock;
1066 uint16_t port;
1067 int eno;
1068
1069 switch (server_addr->sa_family)
1070 {
1071 case AF_INET:
1072 port = ntohs (((const struct sockaddr_in *) server_addr)->sin_port);
1073 break;
1074 case AF_INET6:
1075 port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port);
1076 break;
1077 case AF_UNIX:
1078 port = 0;
1079 break;
1080 default:
1081 GNUNET_break (0);
1082 port = 0;
1083 break;
1084 }
1085 sock = GNUNET_NETWORK_socket_create (server_addr->sa_family,
1086 SOCK_STREAM,
1087 0);
1088 if (NULL == sock)
1089 {
1090 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1091 "socket");
1092 errno = 0;
1093 return NULL;
1094 }
1095 /* bind the socket */
1096 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock,
1097 server_addr,
1098 socklen))
1099 {
1100 eno = errno;
1101 if (EADDRINUSE != errno)
1102 {
1103 /* we don't log 'EADDRINUSE' here since an IPv4 bind may
1104 * fail if we already took the port on IPv6; if both IPv4 and
1105 * IPv6 binds fail, then our caller will log using the
1106 * errno preserved in 'eno' */
1107 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1108 "bind");
1109 if (0 != port)
1110 LOG (GNUNET_ERROR_TYPE_ERROR,
1111 _("`%s' failed for port %d (%s).\n"),
1112 "bind",
1113 port,
1114 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1115 eno = 0;
1116 }
1117 else
1118 {
1119 if (0 != port)
1120 LOG (GNUNET_ERROR_TYPE_WARNING,
1121 _("`%s' failed for port %d (%s): address already in use\n"),
1122 "bind", port,
1123 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1124 else if (AF_UNIX == server_addr->sa_family)
1125 {
1126 LOG (GNUNET_ERROR_TYPE_WARNING,
1127 _("`%s' failed for `%s': address already in use\n"),
1128 "bind",
1129 GNUNET_a2s (server_addr, socklen));
1130 }
1131 }
1132 GNUNET_break (GNUNET_OK ==
1133 GNUNET_NETWORK_socket_close (sock));
1134 errno = eno;
1135 return NULL;
1136 }
1137 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock,
1138 5))
1139 {
1140 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1141 "listen");
1142 GNUNET_break (GNUNET_OK ==
1143 GNUNET_NETWORK_socket_close (sock));
1144 errno = 0;
1145 return NULL;
1146 }
1147 if (0 != port)
1148 LOG (GNUNET_ERROR_TYPE_DEBUG,
1149 "Server starts to listen on port %u.\n",
1150 port);
1151 return sock;
1152}
1153
1154
1155/**
1156 * Setup service handle
927 * 1157 *
928 * Configuration may specify: 1158 * Configuration may specify:
929 * - PORT (where to bind to for TCP) 1159 * - PORT (where to bind to for TCP)
930 * - UNIXPATH (where to bind to for UNIX domain sockets) 1160 * - UNIXPATH (where to bind to for UNIX domain sockets)
931 * - TIMEOUT (after how many ms does an inactive service timeout);
932 * - DISABLEV6 (disable support for IPv6, otherwise we use dual-stack) 1161 * - DISABLEV6 (disable support for IPv6, otherwise we use dual-stack)
933 * - BINDTO (hostname or IP address to bind to, otherwise we take everything) 1162 * - BINDTO (hostname or IP address to bind to, otherwise we take everything)
934 * - ACCEPT_FROM (only allow connections from specified IPv4 subnets) 1163 * - ACCEPT_FROM (only allow connections from specified IPv4 subnets)
@@ -936,108 +1165,170 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx)
936 * - REJECT_FROM (disallow allow connections from specified IPv4 subnets) 1165 * - REJECT_FROM (disallow allow connections from specified IPv4 subnets)
937 * - REJECT_FROM6 (disallow allow connections from specified IPv6 subnets) 1166 * - REJECT_FROM6 (disallow allow connections from specified IPv6 subnets)
938 * 1167 *
939 * @param sctx service context to initialize 1168 * @param sh service context to initialize
940 * @return #GNUNET_OK if configuration succeeded 1169 * @return #GNUNET_OK if configuration succeeded
941 */ 1170 */
942static int 1171static int
943setup_service (struct GNUNET_SERVICE_Context *sctx) 1172setup_service (struct GNUNET_SERVICE_Handle *sh)
944{ 1173{
945 struct GNUNET_TIME_Relative idleout;
946 int tolerant; 1174 int tolerant;
947 1175 struct GNUNET_NETWORK_Handle **lsocks;
948#ifndef MINGW 1176#ifndef MINGW
949 const char *nfds; 1177 const char *nfds;
950 unsigned int cnt; 1178 unsigned int cnt;
951 int flags; 1179 int flags;
952#endif 1180#endif
953 1181
954 if (GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, "TIMEOUT"))
955 {
956 if (GNUNET_OK !=
957 GNUNET_CONFIGURATION_get_value_time (sctx->cfg, sctx->service_name,
958 "TIMEOUT", &idleout))
959 {
960 LOG (GNUNET_ERROR_TYPE_ERROR,
961 _("Specified value for `%s' of service `%s' is invalid\n"),
962 "TIMEOUT", sctx->service_name);
963 return GNUNET_SYSERR;
964 }
965 sctx->timeout = idleout;
966 }
967 else
968 sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
969
970 if (GNUNET_CONFIGURATION_have_value 1182 if (GNUNET_CONFIGURATION_have_value
971 (sctx->cfg, sctx->service_name, "TOLERANT")) 1183 (sh->cfg,
1184 sh->service_name,
1185 "TOLERANT"))
972 { 1186 {
973 if (GNUNET_SYSERR == 1187 if (GNUNET_SYSERR ==
974 (tolerant = 1188 (tolerant =
975 GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name, 1189 GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1190 sh->service_name,
976 "TOLERANT"))) 1191 "TOLERANT")))
977 { 1192 {
978 LOG (GNUNET_ERROR_TYPE_ERROR, 1193 LOG (GNUNET_ERROR_TYPE_ERROR,
979 _("Specified value for `%s' of service `%s' is invalid\n"), 1194 _("Specified value for `%s' of service `%s' is invalid\n"),
980 "TOLERANT", sctx->service_name); 1195 "TOLERANT",
1196 sh->service_name);
981 return GNUNET_SYSERR; 1197 return GNUNET_SYSERR;
982 } 1198 }
983 } 1199 }
984 else 1200 else
985 tolerant = GNUNET_NO; 1201 tolerant = GNUNET_NO;
986 1202
1203 lsocks = NULL;
987#ifndef MINGW 1204#ifndef MINGW
988 errno = 0; 1205 errno = 0;
989 if ((NULL != (nfds = getenv ("LISTEN_FDS"))) && 1206 if ( (NULL != (nfds = getenv ("LISTEN_FDS"))) &&
990 (1 == SSCANF (nfds, "%u", &cnt)) && (cnt > 0) && (cnt < FD_SETSIZE) && 1207 (1 == SSCANF (nfds,
991 (cnt + 4 < FD_SETSIZE)) 1208 "%u",
1209 &cnt)) &&
1210 (cnt > 0) &&
1211 (cnt < FD_SETSIZE) &&
1212 (cnt + 4 < FD_SETSIZE) )
992 { 1213 {
993 sctx->lsocks = 1214 lsocks = GNUNET_new_array (cnt + 1,
994 GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (cnt + 1)); 1215 struct GNUNET_NETWORK_Handle *);
995 while (0 < cnt--) 1216 while (0 < cnt--)
996 { 1217 {
997 flags = fcntl (3 + cnt, F_GETFD); 1218 flags = fcntl (3 + cnt,
998 if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) || 1219 F_GETFD);
999 (NULL == 1220 if ( (flags < 0) ||
1000 (sctx->lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt)))) 1221 (0 != (flags & FD_CLOEXEC)) ||
1222 (NULL ==
1223 (lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
1001 { 1224 {
1002 LOG (GNUNET_ERROR_TYPE_ERROR, 1225 LOG (GNUNET_ERROR_TYPE_ERROR,
1003 _ 1226 _("Could not access pre-bound socket %u, will try to bind myself\n"),
1004 ("Could not access pre-bound socket %u, will try to bind myself\n"),
1005 (unsigned int) 3 + cnt); 1227 (unsigned int) 3 + cnt);
1006 cnt++; 1228 cnt++;
1007 while (sctx->lsocks[cnt] != NULL) 1229 while (NULL != lsocks[cnt])
1008 GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[cnt++])); 1230 GNUNET_break (GNUNET_OK ==
1009 GNUNET_free (sctx->lsocks); 1231 GNUNET_NETWORK_socket_close (lsocks[cnt++]));
1010 sctx->lsocks = NULL; 1232 GNUNET_free (lsocks);
1233 lsocks = NULL;
1011 break; 1234 break;
1012 } 1235 }
1013 } 1236 }
1014 unsetenv ("LISTEN_FDS"); 1237 unsetenv ("LISTEN_FDS");
1015 } 1238 }
1016#else 1239#else
1017 if (getenv ("GNUNET_OS_READ_LSOCKS") != NULL) 1240 if (NULL != getenv ("GNUNET_OS_READ_LSOCKS"))
1018 { 1241 {
1019 receive_sockets_from_parent (sctx); 1242 lsocks = receive_sockets_from_parent (sh);
1020 putenv ("GNUNET_OS_READ_LSOCKS="); 1243 putenv ("GNUNET_OS_READ_LSOCKS=");
1021 } 1244 }
1022#endif 1245#endif
1023 1246
1024 if ((NULL == sctx->lsocks) && 1247 if (NULL != lsocks)
1025 (GNUNET_SYSERR == 1248 {
1026 GNUNET_SERVICE_get_server_addresses (sctx->service_name, sctx->cfg, 1249 /* listen only on inherited sockets if we have any */
1027 &sctx->addrs, &sctx->addrlens))) 1250 struct GNUNET_NETWORK_Handle **ls;
1028 return GNUNET_SYSERR; 1251
1029 sctx->require_found = tolerant ? GNUNET_NO : GNUNET_YES; 1252 for (ls = lsocks; NULL != *ls; ls++)
1030 sctx->match_uid = 1253 {
1031 GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name, 1254 struct ServiceListenContext *slc;
1255
1256 slc = GNUNET_new (struct ServiceListenContext);
1257 slc->sh = sh;
1258 slc->listen_socket = *ls;
1259 GNUNET_CONTAINER_DLL_insert (sh->slc_head,
1260 sh->slc_tail,
1261 slc);
1262 }
1263 GNUNET_free (lsocks);
1264 }
1265 else
1266 {
1267 struct sockaddr **addrs;
1268 socklen_t *addrlens;
1269 int num;
1270
1271 num = get_server_addresses (sh->service_name,
1272 sh->cfg,
1273 &addrs,
1274 &addrlens);
1275 if (GNUNET_SYSERR == num)
1276 return GNUNET_SYSERR;
1277
1278 for (int i = 0; i < num; i++)
1279 {
1280 struct ServiceListenContext *slc;
1281
1282 slc = GNUNET_new (struct ServiceListenContext);
1283 slc->sh = sh;
1284 slc->listen_socket = open_listen_socket (addrs[i],
1285 addrlens[i]);
1286 if (NULL == slc->listen_socket)
1287 {
1288 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
1289 "bind");
1290 GNUNET_free (addrs[i++]);
1291 GNUNET_free (slc);
1292 continue;
1293 }
1294 GNUNET_free (addrs[i++]);
1295 GNUNET_CONTAINER_DLL_insert (sh->slc_head,
1296 sh->slc_tail,
1297 slc);
1298 }
1299 GNUNET_free_non_null (addrlens);
1300 GNUNET_free_non_null (addrs);
1301 if ( (0 != num) &&
1302 (NULL == sh->slc_head) )
1303 {
1304 /* All attempts to bind failed, hard failure */
1305 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1306 _("Could not bind to any of the ports I was supposed to, refusing to run!\n"));
1307 return GNUNET_SYSERR;
1308 }
1309 }
1310
1311 sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
1312 sh->match_uid
1313 = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1314 sh->service_name,
1032 "UNIX_MATCH_UID"); 1315 "UNIX_MATCH_UID");
1033 sctx->match_gid = 1316 sh->match_gid
1034 GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name, 1317 = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1318 sh->service_name,
1035 "UNIX_MATCH_GID"); 1319 "UNIX_MATCH_GID");
1036 process_acl4 (&sctx->v4_denied, sctx, "REJECT_FROM"); 1320 process_acl4 (&sh->v4_denied,
1037 process_acl4 (&sctx->v4_allowed, sctx, "ACCEPT_FROM"); 1321 sh,
1038 process_acl6 (&sctx->v6_denied, sctx, "REJECT_FROM6"); 1322 "REJECT_FROM");
1039 process_acl6 (&sctx->v6_allowed, sctx, "ACCEPT_FROM6"); 1323 process_acl4 (&sh->v4_allowed,
1040 1324 sh,
1325 "ACCEPT_FROM");
1326 process_acl6 (&sh->v6_denied,
1327 sh,
1328 "REJECT_FROM6");
1329 process_acl6 (&sh->v6_allowed,
1330 sh,
1331 "ACCEPT_FROM6");
1041 return GNUNET_OK; 1332 return GNUNET_OK;
1042} 1333}
1043 1334
@@ -1046,185 +1337,129 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
1046 * Get the name of the user that'll be used 1337 * Get the name of the user that'll be used
1047 * to provide the service. 1338 * to provide the service.
1048 * 1339 *
1049 * @param sctx service context 1340 * @param sh service context
1050 * @return value of the 'USERNAME' option 1341 * @return value of the 'USERNAME' option
1051 */ 1342 */
1052static char * 1343static char *
1053get_user_name (struct GNUNET_SERVICE_Context *sctx) 1344get_user_name (struct GNUNET_SERVICE_Handle *sh)
1054{ 1345{
1055 char *un; 1346 char *un;
1056 1347
1057 if (GNUNET_OK != 1348 if (GNUNET_OK !=
1058 GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->service_name, 1349 GNUNET_CONFIGURATION_get_value_filename (sh->cfg,
1059 "USERNAME", &un)) 1350 sh->service_name,
1351 "USERNAME",
1352 &un))
1060 return NULL; 1353 return NULL;
1061 return un; 1354 return un;
1062} 1355}
1063 1356
1064 1357
1065/** 1358/**
1066 * Write PID file. 1359 * Set user ID.
1067 * 1360 *
1068 * @param sctx service context 1361 * @param sh service context
1069 * @param pid PID to write (should be equal to 'getpid()' 1362 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1070 * @return #GNUNET_OK on success (including no work to be done)
1071 */ 1363 */
1072static int 1364static int
1073write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid) 1365set_user_id (struct GNUNET_SERVICE_Handle *sh)
1074{ 1366{
1075 FILE *pidfd;
1076 char *pif;
1077 char *user; 1367 char *user;
1078 char *rdir; 1368
1079 int len; 1369 if (NULL == (user = get_user_name (sh)))
1080 1370 return GNUNET_OK; /* keep */
1081 if (NULL == (pif = get_pid_file_name (sctx))) 1371#ifndef MINGW
1082 return GNUNET_OK; /* no file desired */ 1372 struct passwd *pws;
1083 user = get_user_name (sctx); 1373
1084 rdir = GNUNET_strdup (pif); 1374 errno = 0;
1085 len = strlen (rdir); 1375 pws = getpwnam (user);
1086 while ((len > 0) && (rdir[len] != DIR_SEPARATOR)) 1376 if (NULL == pws)
1087 len--; 1377 {
1088 rdir[len] = '\0'; 1378 LOG (GNUNET_ERROR_TYPE_ERROR,
1089 if (0 != ACCESS (rdir, F_OK)) 1379 _("Cannot obtain information about user `%s': %s\n"),
1090 { 1380 user,
1091 /* we get to create a directory -- and claim it 1381 errno == 0 ? _("No such user") : STRERROR (errno));
1092 * as ours! */ 1382 GNUNET_free (user);
1093 (void) GNUNET_DISK_directory_create (rdir);
1094 if ((NULL != user) && (0 < strlen (user)))
1095 GNUNET_DISK_file_change_owner (rdir, user);
1096 }
1097 if (0 != ACCESS (rdir, W_OK | X_OK))
1098 {
1099 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", rdir);
1100 GNUNET_free (rdir);
1101 GNUNET_free_non_null (user);
1102 GNUNET_free (pif);
1103 return GNUNET_SYSERR; 1383 return GNUNET_SYSERR;
1104 } 1384 }
1105 GNUNET_free (rdir); 1385 if ( (0 != setgid (pws->pw_gid)) ||
1106 pidfd = FOPEN (pif, "w"); 1386 (0 != setegid (pws->pw_gid)) ||
1107 if (NULL == pidfd) 1387#if HAVE_INITGROUPS
1388 (0 != initgroups (user,
1389 pws->pw_gid)) ||
1390#endif
1391 (0 != setuid (pws->pw_uid)) ||
1392 (0 != seteuid (pws->pw_uid)))
1108 { 1393 {
1109 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "fopen", pif); 1394 if ((0 != setregid (pws->pw_gid,
1110 GNUNET_free (pif); 1395 pws->pw_gid)) ||
1111 GNUNET_free_non_null (user); 1396 (0 != setreuid (pws->pw_uid,
1112 return GNUNET_SYSERR; 1397 pws->pw_uid)))
1398 {
1399 LOG (GNUNET_ERROR_TYPE_ERROR,
1400 _("Cannot change user/group to `%s': %s\n"),
1401 user,
1402 STRERROR (errno));
1403 GNUNET_free (user);
1404 return GNUNET_SYSERR;
1405 }
1113 } 1406 }
1114 if (0 > FPRINTF (pidfd, "%u", pid)) 1407#endif
1115 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fprintf", pif); 1408 GNUNET_free (user);
1116 GNUNET_break (0 == FCLOSE (pidfd));
1117 if ((NULL != user) && (0 < strlen (user)))
1118 GNUNET_DISK_file_change_owner (pif, user);
1119 GNUNET_free_non_null (user);
1120 GNUNET_free (pif);
1121 return GNUNET_OK; 1409 return GNUNET_OK;
1122} 1410}
1123 1411
1124 1412
1125/** 1413/**
1126 * Task run during shutdown. Stops the server/service. 1414 * Get the name of the file where we will
1415 * write the PID of the service.
1127 * 1416 *
1128 * @param cls the `struct GNUNET_SERVICE_Context` 1417 * @param sh service context
1418 * @return name of the file for the process ID
1129 */ 1419 */
1130static void 1420static char *
1131shutdown_task (void *cls) 1421get_pid_file_name (struct GNUNET_SERVICE_Handle *sh)
1132{ 1422{
1133 struct GNUNET_SERVICE_Context *service = cls; 1423 char *pif;
1134 struct GNUNET_SERVER_Handle *server = service->server;
1135 1424
1136 service->shutdown_task = NULL; 1425 if (GNUNET_OK !=
1137 if (0 != (service->options & GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN)) 1426 GNUNET_CONFIGURATION_get_value_filename (sh->cfg,
1138 GNUNET_SERVER_stop_listening (server); 1427 sh->service_name,
1139 else 1428 "PIDFILE",
1140 GNUNET_SERVER_destroy (server); 1429 &pif))
1430 return NULL;
1431 return pif;
1141} 1432}
1142 1433
1143 1434
1144/** 1435/**
1145 * Initial task for the service. 1436 * Delete the PID file that was created by our parent.
1146 * 1437 *
1147 * @param cls service context 1438 * @param sh service context
1148 */ 1439 */
1149static void 1440static void
1150service_task (void *cls) 1441pid_file_delete (struct GNUNET_SERVICE_Handle *sh)
1151{ 1442{
1152 struct GNUNET_SERVICE_Context *sctx = cls; 1443 char *pif = get_pid_file_name (sh);
1153 unsigned int i;
1154 1444
1155 (void) GNUNET_SPEEDUP_start_ (sctx->cfg); 1445 if (NULL == pif)
1156 GNUNET_RESOLVER_connect (sctx->cfg); 1446 return; /* no PID file */
1157 if (NULL != sctx->lsocks) 1447 if (0 != UNLINK (pif))
1158 sctx->server 1448 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING,
1159 = GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks, 1449 "unlink",
1160 sctx->timeout, sctx->require_found); 1450 pif);
1161 else 1451 GNUNET_free (pif);
1162 sctx->server
1163 = GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens,
1164 sctx->timeout, sctx->require_found);
1165 if (NULL == sctx->server)
1166 {
1167 if (NULL != sctx->addrs)
1168 for (i = 0; NULL != sctx->addrs[i]; i++)
1169 LOG (GNUNET_ERROR_TYPE_INFO,
1170 _("Failed to start `%s' at `%s'\n"),
1171 sctx->service_name, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
1172 sctx->ret = GNUNET_SYSERR;
1173 return;
1174 }
1175#ifndef WINDOWS
1176 if (NULL != sctx->addrs)
1177 for (i = 0; NULL != sctx->addrs[i]; i++)
1178 if ((AF_UNIX == sctx->addrs[i]->sa_family)
1179 && ('\0' != ((const struct sockaddr_un *)sctx->addrs[i])->sun_path[0]))
1180 GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path,
1181 sctx->match_uid,
1182 sctx->match_gid);
1183#endif
1184
1185
1186 if (0 == (sctx->options & GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN))
1187 {
1188 /* install a task that will kill the server
1189 * process if the scheduler ever gets a shutdown signal */
1190 sctx->shutdown_task = GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1191 sctx);
1192 }
1193 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
1194 GNUNET_memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
1195 i = 0;
1196 while (NULL != sctx->my_handlers[i].callback)
1197 sctx->my_handlers[i++].callback_cls = sctx;
1198 GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers);
1199 if (-1 != sctx->ready_confirm_fd)
1200 {
1201 GNUNET_break (1 == WRITE (sctx->ready_confirm_fd, ".", 1));
1202 GNUNET_break (0 == CLOSE (sctx->ready_confirm_fd));
1203 sctx->ready_confirm_fd = -1;
1204 write_pid_file (sctx, getpid ());
1205 }
1206 if (NULL != sctx->addrs)
1207 {
1208 i = 0;
1209 while (NULL != sctx->addrs[i])
1210 {
1211 LOG (GNUNET_ERROR_TYPE_INFO, _("Service `%s' runs at %s\n"),
1212 sctx->service_name, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
1213 i++;
1214 }
1215 }
1216 sctx->task (sctx->task_cls, sctx->server, sctx->cfg);
1217} 1452}
1218 1453
1219 1454
1220/** 1455/**
1221 * Detach from terminal. 1456 * Detach from terminal.
1222 * 1457 *
1223 * @param sctx service context 1458 * @param sh service context
1224 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 1459 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1225 */ 1460 */
1226static int 1461static int
1227detach_terminal (struct GNUNET_SERVICE_Context *sctx) 1462detach_terminal (struct GNUNET_SERVICE_Handle *sh)
1228{ 1463{
1229#ifndef MINGW 1464#ifndef MINGW
1230 pid_t pid; 1465 pid_t pid;
@@ -1233,13 +1468,15 @@ detach_terminal (struct GNUNET_SERVICE_Context *sctx)
1233 1468
1234 if (0 != PIPE (filedes)) 1469 if (0 != PIPE (filedes))
1235 { 1470 {
1236 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "pipe"); 1471 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1472 "pipe");
1237 return GNUNET_SYSERR; 1473 return GNUNET_SYSERR;
1238 } 1474 }
1239 pid = fork (); 1475 pid = fork ();
1240 if (pid < 0) 1476 if (pid < 0)
1241 { 1477 {
1242 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork"); 1478 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1479 "fork");
1243 return GNUNET_SYSERR; 1480 return GNUNET_SYSERR;
1244 } 1481 }
1245 if (0 != pid) 1482 if (0 != pid)
@@ -1249,15 +1486,19 @@ detach_terminal (struct GNUNET_SERVICE_Context *sctx)
1249 1486
1250 GNUNET_break (0 == CLOSE (filedes[1])); 1487 GNUNET_break (0 == CLOSE (filedes[1]));
1251 c = 'X'; 1488 c = 'X';
1252 if (1 != READ (filedes[0], &c, sizeof (char))) 1489 if (1 != READ (filedes[0],
1253 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "read"); 1490 &c,
1491 sizeof (char)))
1492 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
1493 "read");
1254 fflush (stdout); 1494 fflush (stdout);
1255 switch (c) 1495 switch (c)
1256 { 1496 {
1257 case '.': 1497 case '.':
1258 exit (0); 1498 exit (0);
1259 case 'I': 1499 case 'I':
1260 LOG (GNUNET_ERROR_TYPE_INFO, _("Service process failed to initialize\n")); 1500 LOG (GNUNET_ERROR_TYPE_INFO,
1501 _("Service process failed to initialize\n"));
1261 break; 1502 break;
1262 case 'S': 1503 case 'S':
1263 LOG (GNUNET_ERROR_TYPE_INFO, 1504 LOG (GNUNET_ERROR_TYPE_INFO,
@@ -1273,13 +1514,16 @@ detach_terminal (struct GNUNET_SERVICE_Context *sctx)
1273 GNUNET_break (0 == CLOSE (0)); 1514 GNUNET_break (0 == CLOSE (0));
1274 GNUNET_break (0 == CLOSE (1)); 1515 GNUNET_break (0 == CLOSE (1));
1275 GNUNET_break (0 == CLOSE (filedes[0])); 1516 GNUNET_break (0 == CLOSE (filedes[0]));
1276 nullfd = OPEN ("/dev/null", O_RDWR | O_APPEND); 1517 nullfd = OPEN ("/dev/null",
1518 O_RDWR | O_APPEND);
1277 if (nullfd < 0) 1519 if (nullfd < 0)
1278 return GNUNET_SYSERR; 1520 return GNUNET_SYSERR;
1279 /* set stdin/stdout to /dev/null */ 1521 /* set stdin/stdout to /dev/null */
1280 if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0)) 1522 if ( (dup2 (nullfd, 0) < 0) ||
1523 (dup2 (nullfd, 1) < 0) )
1281 { 1524 {
1282 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2"); 1525 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1526 "dup2");
1283 (void) CLOSE (nullfd); 1527 (void) CLOSE (nullfd);
1284 return GNUNET_SYSERR; 1528 return GNUNET_SYSERR;
1285 } 1529 }
@@ -1287,8 +1531,9 @@ detach_terminal (struct GNUNET_SERVICE_Context *sctx)
1287 /* Detach from controlling terminal */ 1531 /* Detach from controlling terminal */
1288 pid = setsid (); 1532 pid = setsid ();
1289 if (-1 == pid) 1533 if (-1 == pid)
1290 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "setsid"); 1534 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1291 sctx->ready_confirm_fd = filedes[1]; 1535 "setsid");
1536 sh->ready_confirm_fd = filedes[1];
1292#else 1537#else
1293 /* FIXME: we probably need to do something else 1538 /* FIXME: we probably need to do something else
1294 * elsewhere in order to fork the process itself... */ 1539 * elsewhere in order to fork the process itself... */
@@ -1299,144 +1544,228 @@ detach_terminal (struct GNUNET_SERVICE_Context *sctx)
1299 1544
1300 1545
1301/** 1546/**
1302 * Set user ID. 1547 * Tear down the service, closing the listen sockets and
1548 * freeing the ACLs.
1303 * 1549 *
1304 * @param sctx service context 1550 * @param sh handle to the service to tear down.
1305 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1306 */ 1551 */
1307static int 1552static void
1308set_user_id (struct GNUNET_SERVICE_Context *sctx) 1553teardown_service (struct GNUNET_SERVICE_Handle *sh)
1309{ 1554{
1310 char *user; 1555 struct ServiceListenContext *slc;
1311
1312 if (NULL == (user = get_user_name (sctx)))
1313 return GNUNET_OK; /* keep */
1314#ifndef MINGW
1315 struct passwd *pws;
1316 1556
1317 errno = 0; 1557 GNUNET_free_non_null (sh->v4_denied);
1318 pws = getpwnam (user); 1558 GNUNET_free_non_null (sh->v6_denied);
1319 if (NULL == pws) 1559 GNUNET_free_non_null (sh->v4_allowed);
1560 GNUNET_free_non_null (sh->v6_allowed);
1561 while (NULL != (slc = sh->slc_head))
1320 { 1562 {
1321 LOG (GNUNET_ERROR_TYPE_ERROR, 1563 GNUNET_CONTAINER_DLL_remove (sh->slc_head,
1322 _("Cannot obtain information about user `%s': %s\n"), user, 1564 sh->slc_tail,
1323 errno == 0 ? _("No such user") : STRERROR (errno)); 1565 slc);
1324 GNUNET_free (user); 1566 if (NULL != slc->listen_task)
1325 return GNUNET_SYSERR; 1567 GNUNET_SCHEDULER_cancel (slc->listen_task);
1568 GNUNET_break (GNUNET_OK ==
1569 GNUNET_NETWORK_socket_close (slc->listen_socket));
1570 GNUNET_free (slc);
1326 } 1571 }
1327 if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) || 1572}
1328#if HAVE_INITGROUPS 1573
1329 (0 != initgroups (user, pws->pw_gid)) || 1574
1330#endif 1575/**
1331 (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid))) 1576 * Low-level function to start a service if the scheduler
1577 * is already running. Should only be used directly in
1578 * special cases.
1579 *
1580 * The function will launch the service with the name @a service_name
1581 * using the @a service_options to configure its shutdown
1582 * behavior. When clients connect or disconnect, the respective
1583 * @a connect_cb or @a disconnect_cb functions will be called. For
1584 * messages received from the clients, the respective @a handlers will
1585 * be invoked; for the closure of the handlers we use the return value
1586 * from the @a connect_cb invocation of the respective client.
1587 *
1588 * Each handler MUST call #GNUNET_SERVICE_client_continue() after each
1589 * message to receive further messages from this client. If
1590 * #GNUNET_SERVICE_client_continue() is not called within a short
1591 * time, a warning will be logged. If delays are expected, services
1592 * should call #GNUNET_SERVICE_client_disable_continue_warning() to
1593 * disable the warning.
1594 *
1595 * Clients sending invalid messages (based on @a handlers) will be
1596 * dropped. Additionally, clients can be dropped at any time using
1597 * #GNUNET_SERVICE_client_drop().
1598 *
1599 * The service must be stopped using #GNUNET_SERVICE_stop().
1600 *
1601 * @param service_name name of the service to run
1602 * @param cfg configuration to use
1603 * @param connect_cb function to call whenever a client connects
1604 * @param disconnect_cb function to call whenever a client disconnects
1605 * @param cls closure argument for @a connect_cb and @a disconnect_cb
1606 * @param handlers NULL-terminated array of message handlers for the service,
1607 * the closure will be set to the value returned by
1608 * the @a connect_cb for the respective connection
1609 * @return NULL on error
1610 */
1611struct GNUNET_SERVICE_Handle *
1612GNUNET_SERVICE_start (const char *service_name,
1613 const struct GNUNET_CONFIGURATION_Handle *cfg,
1614 GNUNET_SERVICE_ConnectHandler connect_cb,
1615 GNUNET_SERVICE_DisconnectHandler disconnect_cb,
1616 void *cls,
1617 const struct GNUNET_MQ_MessageHandler *handlers)
1618{
1619 struct GNUNET_SERVICE_Handle *sh;
1620
1621 sh = GNUNET_new (struct GNUNET_SERVICE_Handle);
1622 sh->service_name = service_name;
1623 sh->cfg = cfg;
1624 sh->connect_cb = connect_cb;
1625 sh->disconnect_cb = disconnect_cb;
1626 sh->cb_cls = cls;
1627 sh->handlers = GNUNET_MQ_copy_handlers (handlers);
1628 if (GNUNET_OK != setup_service (sh))
1332 { 1629 {
1333 if ((0 != setregid (pws->pw_gid, pws->pw_gid)) || 1630 GNUNET_free_non_null (sh->handlers);
1334 (0 != setreuid (pws->pw_uid, pws->pw_uid))) 1631 GNUNET_free (sh);
1335 { 1632 return NULL;
1336 LOG (GNUNET_ERROR_TYPE_ERROR, _("Cannot change user/group to `%s': %s\n"),
1337 user, STRERROR (errno));
1338 GNUNET_free (user);
1339 return GNUNET_SYSERR;
1340 }
1341 } 1633 }
1342#endif 1634 GNUNET_SERVICE_resume (sh);
1343 GNUNET_free (user); 1635 return sh;
1344 return GNUNET_OK;
1345} 1636}
1346 1637
1347 1638
1348/** 1639/**
1349 * Delete the PID file that was created by our parent. 1640 * Stops a service that was started with #GNUNET_SERVICE_start().
1350 * 1641 *
1351 * @param sctx service context 1642 * @param srv service to stop
1352 */ 1643 */
1353static void 1644void
1354pid_file_delete (struct GNUNET_SERVICE_Context *sctx) 1645GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Handle *srv)
1355{ 1646{
1356 char *pif = get_pid_file_name (sctx); 1647 struct GNUNET_SERVICE_Client *client;
1357 1648
1358 if (NULL == pif) 1649 GNUNET_SERVICE_suspend (srv);
1359 return; /* no PID file */ 1650 while (NULL != (client = srv->clients_head))
1360 if (0 != UNLINK (pif)) 1651 GNUNET_SERVICE_client_drop (client);
1361 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", pif); 1652 teardown_service (srv);
1362 GNUNET_free (pif); 1653 GNUNET_free_non_null (srv->handlers);
1654 GNUNET_free (srv);
1363} 1655}
1364 1656
1365 1657
1366/** 1658/**
1367 * Run a standard GNUnet service startup sequence (initialize loggers 1659 * Creates the "main" function for a GNUnet service. You
1368 * and configuration, parse options). 1660 * should almost always use the #GNUNET_SERVICE_MAIN macro
1661 * instead of calling this function directly (except
1662 * for ARM, which should call this function directly).
1663 *
1664 * The function will launch the service with the name @a service_name
1665 * using the @a service_options to configure its shutdown
1666 * behavior. Once the service is ready, the @a init_cb will be called
1667 * for service-specific initialization. @a init_cb will be given the
1668 * service handler which can be used to control the service's
1669 * availability. When clients connect or disconnect, the respective
1670 * @a connect_cb or @a disconnect_cb functions will be called. For
1671 * messages received from the clients, the respective @a handlers will
1672 * be invoked; for the closure of the handlers we use the return value
1673 * from the @a connect_cb invocation of the respective client.
1369 * 1674 *
1370 * @param argc number of command line arguments 1675 * Each handler MUST call #GNUNET_SERVICE_client_continue() after each
1371 * @param argv command line arguments 1676 * message to receive further messages from this client. If
1372 * @param service_name our service name 1677 * #GNUNET_SERVICE_client_continue() is not called within a short
1373 * @param options service options 1678 * time, a warning will be logged. If delays are expected, services
1374 * @param task main task of the service 1679 * should call #GNUNET_SERVICE_client_disable_continue_warning() to
1375 * @param task_cls closure for @a task 1680 * disable the warning.
1376 * @return #GNUNET_SYSERR on error, #GNUNET_OK 1681 *
1377 * if we shutdown nicely 1682 * Clients sending invalid messages (based on @a handlers) will be
1683 * dropped. Additionally, clients can be dropped at any time using
1684 * #GNUNET_SERVICE_client_drop().
1685 *
1686 * @param argc number of command-line arguments in @a argv
1687 * @param argv array of command-line arguments
1688 * @param service_name name of the service to run
1689 * @param options options controlling shutdown of the service
1690 * @param service_init_cb function to call once the service is ready
1691 * @param connect_cb function to call whenever a client connects
1692 * @param disconnect_cb function to call whenever a client disconnects
1693 * @param cls closure argument for @a service_init_cb, @a connect_cb and @a disconnect_cb
1694 * @param handlers NULL-terminated array of message handlers for the service,
1695 * the closure will be set to the value returned by
1696 * the @a connect_cb for the respective connection
1697 * @return 0 on success, non-zero on error
1378 */ 1698 */
1379int 1699int
1380GNUNET_SERVICE_run (int argc, char *const *argv, 1700GNUNET_SERVICE_run_ (int argc,
1381 const char *service_name, 1701 char *const *argv,
1382 enum GNUNET_SERVICE_Options options, 1702 const char *service_name,
1383 GNUNET_SERVICE_Main task, 1703 enum GNUNET_SERVICE_Options options,
1384 void *task_cls) 1704 GNUNET_SERVICE_InitCallback service_init_cb,
1705 GNUNET_SERVICE_ConnectHandler connect_cb,
1706 GNUNET_SERVICE_DisconnectHandler disconnect_cb,
1707 void *cls,
1708 const struct GNUNET_MQ_MessageHandler *handlers)
1385{ 1709{
1386#define HANDLE_ERROR do { GNUNET_break (0); goto shutdown; } while (0) 1710 struct GNUNET_SERVICE_Handle sh;
1387 1711 char *cfg_filename;
1388 int err; 1712 char *opt_cfg_filename;
1389 int ret;
1390 char *cfg_fn;
1391 char *opt_cfg_fn;
1392 char *loglev; 1713 char *loglev;
1714 const char *xdg;
1393 char *logfile; 1715 char *logfile;
1394 int do_daemonize; 1716 int do_daemonize;
1395 unsigned int i;
1396 unsigned long long skew_offset; 1717 unsigned long long skew_offset;
1397 unsigned long long skew_variance; 1718 unsigned long long skew_variance;
1398 long long clock_offset; 1719 long long clock_offset;
1399 struct GNUNET_SERVICE_Context sctx;
1400 struct GNUNET_CONFIGURATION_Handle *cfg; 1720 struct GNUNET_CONFIGURATION_Handle *cfg;
1401 const char *xdg; 1721 int ret;
1722 int err;
1402 1723
1403 struct GNUNET_GETOPT_CommandLineOption service_options[] = { 1724 struct GNUNET_GETOPT_CommandLineOption service_options[] = {
1404 GNUNET_GETOPT_OPTION_CFG_FILE (&opt_cfg_fn), 1725 GNUNET_GETOPT_OPTION_CFG_FILE (&opt_cfg_filename),
1405 {'d', "daemonize", NULL, 1726 GNUNET_GETOPT_OPTION_SET_ONE ('d',
1406 gettext_noop ("do daemonize (detach from terminal)"), 0, 1727 "daemonize",
1407 GNUNET_GETOPT_set_one, &do_daemonize}, 1728 gettext_noop ("do daemonize (detach from terminal)"),
1729 &do_daemonize),
1408 GNUNET_GETOPT_OPTION_HELP (NULL), 1730 GNUNET_GETOPT_OPTION_HELP (NULL),
1409 GNUNET_GETOPT_OPTION_LOGLEVEL (&loglev), 1731 GNUNET_GETOPT_OPTION_LOGLEVEL (&loglev),
1410 GNUNET_GETOPT_OPTION_LOGFILE (&logfile), 1732 GNUNET_GETOPT_OPTION_LOGFILE (&logfile),
1411 GNUNET_GETOPT_OPTION_VERSION (PACKAGE_VERSION " " VCS_VERSION), 1733 GNUNET_GETOPT_OPTION_VERSION (PACKAGE_VERSION " " VCS_VERSION),
1412 GNUNET_GETOPT_OPTION_END 1734 GNUNET_GETOPT_OPTION_END
1413 }; 1735 };
1736
1414 err = 1; 1737 err = 1;
1415 do_daemonize = 0; 1738 memset (&sh,
1416 logfile = NULL; 1739 0,
1417 loglev = NULL; 1740 sizeof (sh));
1418 opt_cfg_fn = NULL;
1419 xdg = getenv ("XDG_CONFIG_HOME"); 1741 xdg = getenv ("XDG_CONFIG_HOME");
1420 if (NULL != xdg) 1742 if (NULL != xdg)
1421 GNUNET_asprintf (&cfg_fn, 1743 GNUNET_asprintf (&cfg_filename,
1422 "%s%s%s", 1744 "%s%s%s",
1423 xdg, 1745 xdg,
1424 DIR_SEPARATOR_STR, 1746 DIR_SEPARATOR_STR,
1425 GNUNET_OS_project_data_get ()->config_file); 1747 GNUNET_OS_project_data_get ()->config_file);
1426 else 1748 else
1427 cfg_fn = GNUNET_strdup (GNUNET_OS_project_data_get ()->user_config_file); 1749 cfg_filename = GNUNET_strdup (GNUNET_OS_project_data_get ()->user_config_file);
1428 memset (&sctx, 0, sizeof (sctx)); 1750 sh.ready_confirm_fd = -1;
1429 sctx.options = options; 1751 sh.options = options;
1430 sctx.ready_confirm_fd = -1; 1752 sh.cfg = cfg = GNUNET_CONFIGURATION_create ();
1431 sctx.ret = GNUNET_OK; 1753 sh.service_init_cb = service_init_cb;
1432 sctx.timeout = GNUNET_TIME_UNIT_FOREVER_REL; 1754 sh.connect_cb = connect_cb;
1433 sctx.task = task; 1755 sh.disconnect_cb = disconnect_cb;
1434 sctx.task_cls = task_cls; 1756 sh.cb_cls = cls;
1435 sctx.service_name = service_name; 1757 sh.handlers = GNUNET_MQ_copy_handlers (handlers);
1436 sctx.cfg = cfg = GNUNET_CONFIGURATION_create (); 1758 sh.service_name = service_name;
1437 1759
1438 /* setup subsystems */ 1760 /* setup subsystems */
1439 ret = GNUNET_GETOPT_run (service_name, service_options, argc, argv); 1761 loglev = NULL;
1762 logfile = NULL;
1763 opt_cfg_filename = NULL;
1764 do_daemonize = 0;
1765 ret = GNUNET_GETOPT_run (service_name,
1766 service_options,
1767 argc,
1768 argv);
1440 if (GNUNET_SYSERR == ret) 1769 if (GNUNET_SYSERR == ret)
1441 goto shutdown; 1770 goto shutdown;
1442 if (GNUNET_NO == ret) 1771 if (GNUNET_NO == ret)
@@ -1444,254 +1773,844 @@ GNUNET_SERVICE_run (int argc, char *const *argv,
1444 err = 0; 1773 err = 0;
1445 goto shutdown; 1774 goto shutdown;
1446 } 1775 }
1447 if (GNUNET_OK != GNUNET_log_setup (service_name, loglev, logfile)) 1776 if (GNUNET_OK != GNUNET_log_setup (service_name,
1448 HANDLE_ERROR; 1777 loglev,
1449 if (NULL == opt_cfg_fn) 1778 logfile))
1450 opt_cfg_fn = GNUNET_strdup (cfg_fn); 1779 {
1451 if (GNUNET_YES == GNUNET_DISK_file_test (opt_cfg_fn)) 1780 GNUNET_break (0);
1781 goto shutdown;
1782 }
1783 if (NULL == opt_cfg_filename)
1784 opt_cfg_filename = GNUNET_strdup (cfg_filename);
1785 if (GNUNET_YES == GNUNET_DISK_file_test (opt_cfg_filename))
1452 { 1786 {
1453 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_fn)) 1787 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg,
1788 opt_cfg_filename))
1454 { 1789 {
1455 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1790 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1456 _("Malformed configuration file `%s', exit ...\n"), 1791 _("Malformed configuration file `%s', exit ...\n"),
1457 opt_cfg_fn); 1792 opt_cfg_filename);
1458 goto shutdown; 1793 goto shutdown;
1459 } 1794 }
1460 } 1795 }
1461 else 1796 else
1462 { 1797 {
1463 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL)) 1798 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg,
1799 NULL))
1464 { 1800 {
1465 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1801 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1466 _("Malformed configuration, exit ...\n")); 1802 _("Malformed configuration, exit ...\n"));
1467 goto shutdown; 1803 goto shutdown;
1468 } 1804 }
1469 if (0 != strcmp (opt_cfg_fn, cfg_fn)) 1805 if (0 != strcmp (opt_cfg_filename,
1806 cfg_filename))
1470 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1807 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1471 _("Could not access configuration file `%s'\n"), 1808 _("Could not access configuration file `%s'\n"),
1472 opt_cfg_fn); 1809 opt_cfg_filename);
1473 } 1810 }
1474 if (GNUNET_OK != setup_service (&sctx)) 1811 if (GNUNET_OK != setup_service (&sh))
1475 goto shutdown; 1812 goto shutdown;
1476 if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sctx))) 1813 if ( (1 == do_daemonize) &&
1477 HANDLE_ERROR; 1814 (GNUNET_OK != detach_terminal (&sh)) )
1478 if (GNUNET_OK != set_user_id (&sctx)) 1815 {
1816 GNUNET_break (0);
1817 goto shutdown;
1818 }
1819 if (GNUNET_OK != set_user_id (&sh))
1479 goto shutdown; 1820 goto shutdown;
1480 LOG (GNUNET_ERROR_TYPE_DEBUG, 1821 LOG (GNUNET_ERROR_TYPE_DEBUG,
1481 "Service `%s' runs with configuration from `%s'\n", 1822 "Service `%s' runs with configuration from `%s'\n",
1482 service_name, 1823 service_name,
1483 opt_cfg_fn); 1824 opt_cfg_filename);
1484 if ((GNUNET_OK == 1825 if ((GNUNET_OK ==
1485 GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING", 1826 GNUNET_CONFIGURATION_get_value_number (sh.cfg,
1486 "SKEW_OFFSET", &skew_offset)) && 1827 "TESTING",
1828 "SKEW_OFFSET",
1829 &skew_offset)) &&
1487 (GNUNET_OK == 1830 (GNUNET_OK ==
1488 GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING", 1831 GNUNET_CONFIGURATION_get_value_number (sh.cfg,
1489 "SKEW_VARIANCE", &skew_variance))) 1832 "TESTING",
1833 "SKEW_VARIANCE",
1834 &skew_variance)))
1490 { 1835 {
1491 clock_offset = skew_offset - skew_variance; 1836 clock_offset = skew_offset - skew_variance;
1492 GNUNET_TIME_set_offset (clock_offset); 1837 GNUNET_TIME_set_offset (clock_offset);
1493 LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset); 1838 LOG (GNUNET_ERROR_TYPE_DEBUG,
1839 "Skewing clock by %dll ms\n",
1840 clock_offset);
1494 } 1841 }
1842 GNUNET_RESOLVER_connect (sh.cfg);
1843
1495 /* actually run service */ 1844 /* actually run service */
1496 err = 0; 1845 err = 0;
1497 GNUNET_SCHEDULER_run (&service_task, &sctx); 1846 GNUNET_SCHEDULER_run (&service_main,
1847 &sh);
1498 /* shutdown */ 1848 /* shutdown */
1499 if ((1 == do_daemonize) && (NULL != sctx.server)) 1849 if (1 == do_daemonize)
1500 pid_file_delete (&sctx); 1850 pid_file_delete (&sh);
1501 GNUNET_free_non_null (sctx.my_handlers);
1502 1851
1503shutdown: 1852shutdown:
1504 if (-1 != sctx.ready_confirm_fd) 1853 if (-1 != sh.ready_confirm_fd)
1505 { 1854 {
1506 if (1 != WRITE (sctx.ready_confirm_fd, err ? "I" : "S", 1)) 1855 if (1 != WRITE (sh.ready_confirm_fd,
1507 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write"); 1856 err ? "I" : "S",
1508 GNUNET_break (0 == CLOSE (sctx.ready_confirm_fd)); 1857 1))
1858 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
1859 "write");
1860 GNUNET_break (0 == CLOSE (sh.ready_confirm_fd));
1509 } 1861 }
1510#if HAVE_MALLINFO 1862#if HAVE_MALLINFO
1511 { 1863 {
1512 char *counter; 1864 char *counter;
1513 1865
1514 if ( (GNUNET_YES == 1866 if ( (GNUNET_YES ==
1515 GNUNET_CONFIGURATION_have_value (sctx.cfg, service_name, 1867 GNUNET_CONFIGURATION_have_value (sh.cfg,
1868 service_name,
1516 "GAUGER_HEAP")) && 1869 "GAUGER_HEAP")) &&
1517 (GNUNET_OK == 1870 (GNUNET_OK ==
1518 GNUNET_CONFIGURATION_get_value_string (sctx.cfg, service_name, 1871 GNUNET_CONFIGURATION_get_value_string (sh.cfg,
1872 service_name,
1519 "GAUGER_HEAP", 1873 "GAUGER_HEAP",
1520 &counter)) ) 1874 &counter)) )
1521 { 1875 {
1522 struct mallinfo mi; 1876 struct mallinfo mi;
1523 1877
1524 mi = mallinfo (); 1878 mi = mallinfo ();
1525 GAUGER (service_name, counter, mi.usmblks, "blocks"); 1879 GAUGER (service_name,
1880 counter,
1881 mi.usmblks,
1882 "blocks");
1526 GNUNET_free (counter); 1883 GNUNET_free (counter);
1527 } 1884 }
1528 } 1885 }
1529#endif 1886#endif
1887 teardown_service (&sh);
1888 GNUNET_free_non_null (sh.handlers);
1530 GNUNET_SPEEDUP_stop_ (); 1889 GNUNET_SPEEDUP_stop_ ();
1531 GNUNET_CONFIGURATION_destroy (cfg); 1890 GNUNET_CONFIGURATION_destroy (cfg);
1532 i = 0;
1533 if (NULL != sctx.addrs)
1534 while (NULL != sctx.addrs[i])
1535 GNUNET_free (sctx.addrs[i++]);
1536 GNUNET_free_non_null (sctx.addrs);
1537 GNUNET_free_non_null (sctx.addrlens);
1538 GNUNET_free_non_null (logfile); 1891 GNUNET_free_non_null (logfile);
1539 GNUNET_free_non_null (loglev); 1892 GNUNET_free_non_null (loglev);
1540 GNUNET_free (cfg_fn); 1893 GNUNET_free (cfg_filename);
1541 GNUNET_free_non_null (opt_cfg_fn); 1894 GNUNET_free_non_null (opt_cfg_filename);
1542 GNUNET_free_non_null (sctx.v4_denied); 1895
1543 GNUNET_free_non_null (sctx.v6_denied); 1896 return err ? GNUNET_SYSERR : sh.ret;
1544 GNUNET_free_non_null (sctx.v4_allowed);
1545 GNUNET_free_non_null (sctx.v6_allowed);
1546
1547 return err ? GNUNET_SYSERR : sctx.ret;
1548} 1897}
1549 1898
1550 1899
1551/** 1900/**
1552 * Run a service startup sequence within an existing 1901 * Suspend accepting connections from the listen socket temporarily.
1553 * initialized system. 1902 * Resume activity using #GNUNET_SERVICE_resume.
1554 * 1903 *
1555 * @param service_name our service name 1904 * @param sh service to stop accepting connections.
1556 * @param cfg configuration to use
1557 * @param options service options
1558 * @return NULL on error, service handle
1559 */ 1905 */
1560struct GNUNET_SERVICE_Context * 1906void
1561GNUNET_SERVICE_start (const char *service_name, 1907GNUNET_SERVICE_suspend (struct GNUNET_SERVICE_Handle *sh)
1562 const struct GNUNET_CONFIGURATION_Handle *cfg,
1563 enum GNUNET_SERVICE_Options options)
1564{ 1908{
1565 int i; 1909 struct ServiceListenContext *slc;
1566 struct GNUNET_SERVICE_Context *sctx;
1567 1910
1568 sctx = GNUNET_new (struct GNUNET_SERVICE_Context); 1911 for (slc = sh->slc_head; NULL != slc; slc = slc->next)
1569 sctx->ready_confirm_fd = -1; /* no daemonizing */ 1912 {
1570 sctx->ret = GNUNET_OK; 1913 if (NULL != slc->listen_task)
1571 sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL; 1914 {
1572 sctx->service_name = service_name; 1915 GNUNET_SCHEDULER_cancel (slc->listen_task);
1573 sctx->cfg = cfg; 1916 slc->listen_task = NULL;
1574 sctx->options = options; 1917 }
1918 }
1919}
1575 1920
1576 /* setup subsystems */ 1921
1577 if (GNUNET_OK != setup_service (sctx)) 1922/**
1923 * Task run when we are ready to transmit data to the
1924 * client.
1925 *
1926 * @param cls the `struct GNUNET_SERVICE_Client *` to send to
1927 */
1928static void
1929do_send (void *cls)
1930{
1931 struct GNUNET_SERVICE_Client *client = cls;
1932 ssize_t ret;
1933 size_t left;
1934 const char *buf;
1935
1936 client->send_task = NULL;
1937 buf = (const char *) client->msg;
1938 left = ntohs (client->msg->size) - client->msg_pos;
1939 ret = GNUNET_NETWORK_socket_send (client->sock,
1940 &buf[client->msg_pos],
1941 left);
1942 GNUNET_assert (ret <= (ssize_t) left);
1943 if (0 == ret)
1578 { 1944 {
1579 GNUNET_SERVICE_stop (sctx); 1945 GNUNET_MQ_inject_error (client->mq,
1580 return NULL; 1946 GNUNET_MQ_ERROR_WRITE);
1947 return;
1581 } 1948 }
1582 if (NULL != sctx->lsocks) 1949 if (-1 == ret)
1583 sctx->server = 1950 {
1584 GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks, 1951 if ( (EAGAIN == errno) ||
1585 sctx->timeout, sctx->require_found); 1952 (EINTR == errno) )
1586 else 1953 {
1587 sctx->server = 1954 /* ignore */
1588 GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens, 1955 ret = 0;
1589 sctx->timeout, sctx->require_found); 1956 }
1957 else
1958 {
1959 if (EPIPE != errno)
1960 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1961 "send");
1962 GNUNET_MQ_inject_error (client->mq,
1963 GNUNET_MQ_ERROR_WRITE);
1964 return;
1965 }
1966 }
1967 if (0 == client->msg_pos)
1968 {
1969 GNUNET_MQ_impl_send_in_flight (client->mq);
1970 }
1971 client->msg_pos += ret;
1972 if (left > ret)
1973 {
1974 GNUNET_assert (NULL == client->drop_task);
1975 client->send_task
1976 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1977 client->sock,
1978 &do_send,
1979 client);
1980 return;
1981 }
1982 GNUNET_MQ_impl_send_continue (client->mq);
1983}
1984
1590 1985
1591 if (NULL == sctx->server) 1986/**
1987 * Signature of functions implementing the sending functionality of a
1988 * message queue.
1989 *
1990 * @param mq the message queue
1991 * @param msg the message to send
1992 * @param impl_state our `struct GNUNET_SERVICE_Client *`
1993 */
1994static void
1995service_mq_send (struct GNUNET_MQ_Handle *mq,
1996 const struct GNUNET_MessageHeader *msg,
1997 void *impl_state)
1998{
1999 struct GNUNET_SERVICE_Client *client = impl_state;
2000
2001 if (NULL != client->drop_task)
2002 return; /* we're going down right now, do not try to send */
2003 GNUNET_assert (NULL == client->send_task);
2004 LOG (GNUNET_ERROR_TYPE_DEBUG,
2005 "Sending message of type %u and size %u to client\n",
2006 ntohs (msg->type),
2007 ntohs (msg->size));
2008 client->msg = msg;
2009 client->msg_pos = 0;
2010 client->send_task
2011 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
2012 client->sock,
2013 &do_send,
2014 client);
2015}
2016
2017
2018/**
2019 * Implementation function that cancels the currently sent message.
2020 *
2021 * @param mq message queue
2022 * @param impl_state state specific to the implementation
2023 */
2024static void
2025service_mq_cancel (struct GNUNET_MQ_Handle *mq,
2026 void *impl_state)
2027{
2028 struct GNUNET_SERVICE_Client *client = impl_state;
2029
2030 GNUNET_assert (0 == client->msg_pos);
2031 client->msg = NULL;
2032 GNUNET_SCHEDULER_cancel (client->send_task);
2033 client->send_task = NULL;
2034}
2035
2036
2037/**
2038 * Generic error handler, called with the appropriate
2039 * error code and the same closure specified at the creation of
2040 * the message queue.
2041 * Not every message queue implementation supports an error handler.
2042 *
2043 * @param cls closure with our `struct GNUNET_SERVICE_Client`
2044 * @param error error code
2045 */
2046static void
2047service_mq_error_handler (void *cls,
2048 enum GNUNET_MQ_Error error)
2049{
2050 struct GNUNET_SERVICE_Client *client = cls;
2051 struct GNUNET_SERVICE_Handle *sh = client->sh;
2052
2053 if ( (GNUNET_MQ_ERROR_NO_MATCH == error) &&
2054 (GNUNET_NO == sh->require_found) )
1592 { 2055 {
1593 GNUNET_SERVICE_stop (sctx); 2056 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1594 return NULL; 2057 "No handler for message of type %u found\n",
2058 (unsigned int) client->warn_type);
2059 GNUNET_SERVICE_client_continue (client);
2060 return; /* ignore error */
2061 }
2062 GNUNET_SERVICE_client_drop (client);
2063}
2064
2065
2066/**
2067 * Task run to warn about missing calls to #GNUNET_SERVICE_client_continue().
2068 *
2069 * @param cls our `struct GNUNET_SERVICE_Client *` to process more requests from
2070 */
2071static void
2072warn_no_client_continue (void *cls)
2073{
2074 struct GNUNET_SERVICE_Client *client = cls;
2075
2076 GNUNET_break (0 != client->warn_type); /* type should never be 0 here, as we don't use 0 */
2077 client->warn_task
2078 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
2079 &warn_no_client_continue,
2080 client);
2081 LOG (GNUNET_ERROR_TYPE_WARNING,
2082 _("Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"),
2083 (unsigned int) client->warn_type,
2084 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (client->warn_start),
2085 GNUNET_YES));
2086}
2087
2088
2089/**
2090 * Functions with this signature are called whenever a
2091 * complete message is received by the tokenizer for a client.
2092 *
2093 * Do not call #GNUNET_MST_destroy() from within
2094 * the scope of this callback.
2095 *
2096 * @param cls closure with the `struct GNUNET_SERVICE_Client *`
2097 * @param message the actual message
2098 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the client was dropped
2099 */
2100static int
2101service_client_mst_cb (void *cls,
2102 const struct GNUNET_MessageHeader *message)
2103{
2104 struct GNUNET_SERVICE_Client *client = cls;
2105
2106 LOG (GNUNET_ERROR_TYPE_DEBUG,
2107 "Received message of type %u and size %u from client\n",
2108 ntohs (message->type),
2109 ntohs (message->size));
2110 GNUNET_assert (GNUNET_NO == client->needs_continue);
2111 client->needs_continue = GNUNET_YES;
2112 client->warn_type = ntohs (message->type);
2113 client->warn_start = GNUNET_TIME_absolute_get ();
2114 GNUNET_assert (NULL == client->warn_task);
2115 client->warn_task
2116 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
2117 &warn_no_client_continue,
2118 client);
2119 GNUNET_MQ_inject_message (client->mq,
2120 message);
2121 if (NULL != client->drop_task)
2122 return GNUNET_SYSERR;
2123 return GNUNET_OK;
2124}
2125
2126
2127/**
2128 * A client sent us data. Receive and process it. If we are done,
2129 * reschedule this task.
2130 *
2131 * @param cls the `struct GNUNET_SERVICE_Client` that sent us data.
2132 */
2133static void
2134service_client_recv (void *cls)
2135{
2136 struct GNUNET_SERVICE_Client *client = cls;
2137 int ret;
2138
2139 client->recv_task = NULL;
2140 ret = GNUNET_MST_read (client->mst,
2141 client->sock,
2142 GNUNET_NO,
2143 GNUNET_YES);
2144 if (GNUNET_SYSERR == ret)
2145 {
2146 /* client closed connection (or IO error) */
2147 if (NULL == client->drop_task)
2148 {
2149 GNUNET_assert (GNUNET_NO == client->needs_continue);
2150 GNUNET_SERVICE_client_drop (client);
2151 }
2152 return;
2153 }
2154 if (GNUNET_NO == ret)
2155 return; /* more messages in buffer, wait for application
2156 to be done processing */
2157 GNUNET_assert (GNUNET_OK == ret);
2158 if (GNUNET_YES == client->needs_continue)
2159 return;
2160 if (NULL != client->recv_task)
2161 return;
2162 /* MST needs more data, re-schedule read job */
2163 client->recv_task
2164 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2165 client->sock,
2166 &service_client_recv,
2167 client);
2168}
2169
2170
2171/**
2172 * We have successfully accepted a connection from a client. Now
2173 * setup the client (with the scheduler) and tell the application.
2174 *
2175 * @param sh service that accepted the client
2176 * @param sock socket associated with the client
2177 */
2178static void
2179start_client (struct GNUNET_SERVICE_Handle *sh,
2180 struct GNUNET_NETWORK_Handle *csock)
2181{
2182 struct GNUNET_SERVICE_Client *client;
2183
2184 client = GNUNET_new (struct GNUNET_SERVICE_Client);
2185 GNUNET_CONTAINER_DLL_insert (sh->clients_head,
2186 sh->clients_tail,
2187 client);
2188 client->sh = sh;
2189 client->sock = csock;
2190 client->mq = GNUNET_MQ_queue_for_callbacks (&service_mq_send,
2191 NULL,
2192 &service_mq_cancel,
2193 client,
2194 sh->handlers,
2195 &service_mq_error_handler,
2196 client);
2197 client->mst = GNUNET_MST_create (&service_client_mst_cb,
2198 client);
2199 if (NULL != sh->connect_cb)
2200 client->user_context = sh->connect_cb (sh->cb_cls,
2201 client,
2202 client->mq);
2203 GNUNET_MQ_set_handlers_closure (client->mq,
2204 client->user_context);
2205 client->recv_task
2206 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2207 client->sock,
2208 &service_client_recv,
2209 client);
2210}
2211
2212
2213/**
2214 * Check if the given IP address is in the list of IP addresses.
2215 *
2216 * @param list a list of networks
2217 * @param add the IP to check (in network byte order)
2218 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
2219 */
2220static int
2221check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list,
2222 const struct in_addr *add)
2223{
2224 unsigned int i;
2225
2226 if (NULL == list)
2227 return GNUNET_NO;
2228 i = 0;
2229 while ( (0 != list[i].network.s_addr) ||
2230 (0 != list[i].netmask.s_addr) )
2231 {
2232 if ((add->s_addr & list[i].netmask.s_addr) ==
2233 (list[i].network.s_addr & list[i].netmask.s_addr))
2234 return GNUNET_YES;
2235 i++;
2236 }
2237 return GNUNET_NO;
2238}
2239
2240
2241/**
2242 * Check if the given IP address is in the list of IP addresses.
2243 *
2244 * @param list a list of networks
2245 * @param ip the IP to check (in network byte order)
2246 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
2247 */
2248static int
2249check_ipv6_listed (const struct GNUNET_STRINGS_IPv6NetworkPolicy *list,
2250 const struct in6_addr *ip)
2251{
2252 unsigned int i;
2253 unsigned int j;
2254 struct in6_addr zero;
2255
2256 if (NULL == list)
2257 return GNUNET_NO;
2258 memset (&zero,
2259 0,
2260 sizeof (struct in6_addr));
2261 i = 0;
2262NEXT:
2263 while (0 != memcmp (&zero,
2264 &list[i].network,
2265 sizeof (struct in6_addr)))
2266 {
2267 for (j = 0; j < sizeof (struct in6_addr) / sizeof (int); j++)
2268 if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
2269 (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
2270 {
2271 i++;
2272 goto NEXT;
2273 }
2274 return GNUNET_YES;
1595 } 2275 }
2276 return GNUNET_NO;
2277}
2278
2279
2280/**
2281 * We have a client. Accept the incoming socket(s) (and reschedule
2282 * the listen task).
2283 *
2284 * @param cls the `struct ServiceListenContext` of the ready listen socket
2285 */
2286static void
2287accept_client (void *cls)
2288{
2289 struct ServiceListenContext *slc = cls;
2290 struct GNUNET_SERVICE_Handle *sh = slc->sh;
2291
2292 slc->listen_task = NULL;
2293 while (1)
2294 {
2295 struct GNUNET_NETWORK_Handle *sock;
2296 const struct sockaddr_in *v4;
2297 const struct sockaddr_in6 *v6;
2298 struct sockaddr_storage sa;
2299 socklen_t addrlen;
2300 int ok;
2301
2302 addrlen = sizeof (sa);
2303 sock = GNUNET_NETWORK_socket_accept (slc->listen_socket,
2304 (struct sockaddr *) &sa,
2305 &addrlen);
2306 if (NULL == sock)
2307 break;
2308 switch (sa.ss_family)
2309 {
2310 case AF_INET:
2311 GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
2312 v4 = (const struct sockaddr_in *) &sa;
2313 ok = ( ( (NULL == sh->v4_allowed) ||
2314 (check_ipv4_listed (sh->v4_allowed,
2315 &v4->sin_addr))) &&
2316 ( (NULL == sh->v4_denied) ||
2317 (! check_ipv4_listed (sh->v4_denied,
2318 &v4->sin_addr)) ) );
2319 break;
2320 case AF_INET6:
2321 GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
2322 v6 = (const struct sockaddr_in6 *) &sa;
2323 ok = ( ( (NULL == sh->v6_allowed) ||
2324 (check_ipv6_listed (sh->v6_allowed,
2325 &v6->sin6_addr))) &&
2326 ( (NULL == sh->v6_denied) ||
2327 (! check_ipv6_listed (sh->v6_denied,
2328 &v6->sin6_addr)) ) );
2329 break;
1596#ifndef WINDOWS 2330#ifndef WINDOWS
1597 if (NULL != sctx->addrs) 2331 case AF_UNIX:
1598 for (i = 0; NULL != sctx->addrs[i]; i++) 2332 ok = GNUNET_OK; /* controlled using file-system ACL now */
1599 if ((AF_UNIX == sctx->addrs[i]->sa_family) 2333 break;
1600 && ('\0' != ((const struct sockaddr_un *)sctx->addrs[i])->sun_path[0]))
1601 GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path,
1602 sctx->match_uid,
1603 sctx->match_gid);
1604#endif 2334#endif
1605 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers)); 2335 default:
1606 GNUNET_memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers)); 2336 LOG (GNUNET_ERROR_TYPE_WARNING,
1607 i = 0; 2337 _("Unknown address family %d\n"),
1608 while ((sctx->my_handlers[i].callback != NULL)) 2338 sa.ss_family);
1609 sctx->my_handlers[i++].callback_cls = sctx; 2339 return;
1610 GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers); 2340 }
1611 return sctx; 2341 if (! ok)
2342 {
2343 LOG (GNUNET_ERROR_TYPE_DEBUG,
2344 "Service rejected incoming connection from %s due to policy.\n",
2345 GNUNET_a2s ((const struct sockaddr *) &sa,
2346 addrlen));
2347 GNUNET_break (GNUNET_OK ==
2348 GNUNET_NETWORK_socket_close (sock));
2349 continue;
2350 }
2351 LOG (GNUNET_ERROR_TYPE_DEBUG,
2352 "Service accepted incoming connection from %s.\n",
2353 GNUNET_a2s ((const struct sockaddr *) &sa,
2354 addrlen));
2355 start_client (slc->sh,
2356 sock);
2357 }
2358 slc->listen_task
2359 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2360 slc->listen_socket,
2361 &accept_client,
2362 slc);
2363}
2364
2365
2366/**
2367 * Resume accepting connections from the listen socket.
2368 *
2369 * @param sh service to resume accepting connections.
2370 */
2371void
2372GNUNET_SERVICE_resume (struct GNUNET_SERVICE_Handle *sh)
2373{
2374 struct ServiceListenContext *slc;
2375
2376 for (slc = sh->slc_head; NULL != slc; slc = slc->next)
2377 {
2378 GNUNET_assert (NULL == slc->listen_task);
2379 slc->listen_task
2380 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2381 slc->listen_socket,
2382 &accept_client,
2383 slc);
2384 }
1612} 2385}
1613 2386
1614 2387
1615/** 2388/**
1616 * Obtain the server used by a service. Note that the server must NOT 2389 * Task run to resume receiving data from the client after
1617 * be destroyed by the caller. 2390 * the client called #GNUNET_SERVICE_client_continue().
1618 * 2391 *
1619 * @param ctx the service context returned from the start function 2392 * @param cls our `struct GNUNET_SERVICE_Client`
1620 * @return handle to the server for this service, NULL if there is none
1621 */ 2393 */
1622struct GNUNET_SERVER_Handle * 2394static void
1623GNUNET_SERVICE_get_server (struct GNUNET_SERVICE_Context *ctx) 2395resume_client_receive (void *cls)
1624{ 2396{
1625 return ctx->server; 2397 struct GNUNET_SERVICE_Client *c = cls;
2398 int ret;
2399
2400 c->recv_task = NULL;
2401 /* first, check if there is still something in the buffer */
2402 ret = GNUNET_MST_next (c->mst,
2403 GNUNET_YES);
2404 if (GNUNET_SYSERR == ret)
2405 {
2406 if (NULL != c->drop_task)
2407 GNUNET_SERVICE_client_drop (c);
2408 return;
2409 }
2410 if (GNUNET_NO == ret)
2411 return; /* done processing, wait for more later */
2412 GNUNET_assert (GNUNET_OK == ret);
2413 if (GNUNET_YES == c->needs_continue)
2414 return; /* #GNUNET_MST_next() did give a message to the client */
2415 /* need to receive more data from the network first */
2416 if (NULL != c->recv_task)
2417 return;
2418 c->recv_task
2419 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2420 c->sock,
2421 &service_client_recv,
2422 c);
1626} 2423}
1627 2424
1628 2425
1629/** 2426/**
1630 * Get the NULL-terminated array of listen sockets for this service. 2427 * Continue receiving further messages from the given client.
2428 * Must be called after each message received.
1631 * 2429 *
1632 * @param ctx service context to query 2430 * @param c the client to continue receiving from
1633 * @return NULL if there are no listen sockets, otherwise NULL-terminated
1634 * array of listen sockets.
1635 */ 2431 */
1636struct GNUNET_NETWORK_Handle *const* 2432void
1637GNUNET_SERVICE_get_listen_sockets (struct GNUNET_SERVICE_Context *ctx) 2433GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c)
1638{ 2434{
1639 return ctx->lsocks; 2435 GNUNET_assert (GNUNET_YES == c->needs_continue);
2436 GNUNET_assert (NULL == c->recv_task);
2437 c->needs_continue = GNUNET_NO;
2438 if (NULL != c->warn_task)
2439 {
2440 GNUNET_SCHEDULER_cancel (c->warn_task);
2441 c->warn_task = NULL;
2442 }
2443 c->recv_task
2444 = GNUNET_SCHEDULER_add_now (&resume_client_receive,
2445 c);
1640} 2446}
1641 2447
1642 2448
1643/** 2449/**
1644 * Stop a service that was started with "GNUNET_SERVICE_start". 2450 * Disable the warning the server issues if a message is not
2451 * acknowledged in a timely fashion. Use this call if a client is
2452 * intentionally delayed for a while. Only applies to the current
2453 * message.
1645 * 2454 *
1646 * @param sctx the service context returned from the start function 2455 * @param c client for which to disable the warning
1647 */ 2456 */
1648void 2457void
1649GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Context *sctx) 2458GNUNET_SERVICE_client_disable_continue_warning (struct GNUNET_SERVICE_Client *c)
1650{ 2459{
1651 unsigned int i; 2460 GNUNET_break (NULL != c->warn_task);
2461 if (NULL != c->warn_task)
2462 {
2463 GNUNET_SCHEDULER_cancel (c->warn_task);
2464 c->warn_task = NULL;
2465 }
2466}
1652 2467
1653#if HAVE_MALLINFO 2468
2469/**
2470 * Asynchronously finish dropping the client.
2471 *
2472 * @param cls the `struct GNUNET_SERVICE_Client`.
2473 */
2474static void
2475finish_client_drop (void *cls)
2476{
2477 struct GNUNET_SERVICE_Client *c = cls;
2478 struct GNUNET_SERVICE_Handle *sh = c->sh;
2479
2480 c->drop_task = NULL;
2481 GNUNET_assert (NULL == c->send_task);
2482 GNUNET_assert (NULL == c->recv_task);
2483 GNUNET_assert (NULL == c->warn_task);
2484 GNUNET_MST_destroy (c->mst);
2485 GNUNET_MQ_destroy (c->mq);
2486 if (GNUNET_NO == c->persist)
1654 { 2487 {
1655 char *counter; 2488 GNUNET_break (GNUNET_OK ==
2489 GNUNET_NETWORK_socket_close (c->sock));
2490 }
2491 else
2492 {
2493 GNUNET_NETWORK_socket_free_memory_only_ (c->sock);
2494 }
2495 GNUNET_free (c);
2496 if ( (GNUNET_YES == sh->got_shutdown) &&
2497 (GNUNET_NO == have_non_monitor_clients (sh)) )
2498 GNUNET_SERVICE_shutdown (sh);
2499}
1656 2500
1657 if ( (GNUNET_YES ==
1658 GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name,
1659 "GAUGER_HEAP")) &&
1660 (GNUNET_OK ==
1661 GNUNET_CONFIGURATION_get_value_string (sctx->cfg, sctx->service_name,
1662 "GAUGER_HEAP",
1663 &counter)) )
1664 {
1665 struct mallinfo mi;
1666 2501
1667 mi = mallinfo (); 2502/**
1668 GAUGER (sctx->service_name, counter, mi.usmblks, "blocks"); 2503 * Ask the server to disconnect from the given client. This is the
1669 GNUNET_free (counter); 2504 * same as returning #GNUNET_SYSERR within the check procedure when
1670 } 2505 * handling a message, wexcept that it allows dropping of a client even
2506 * when not handling a message from that client. The `disconnect_cb`
2507 * will be called on @a c even if the application closes the connection
2508 * using this function.
2509 *
2510 * @param c client to disconnect now
2511 */
2512void
2513GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c)
2514{
2515 struct GNUNET_SERVICE_Handle *sh = c->sh;
2516
2517 if (NULL != c->drop_task)
2518 {
2519 /* asked to drop twice! */
2520 GNUNET_assert (0);
2521 return;
1671 } 2522 }
1672#endif 2523 GNUNET_CONTAINER_DLL_remove (sh->clients_head,
1673 if (NULL != sctx->shutdown_task) 2524 sh->clients_tail,
2525 c);
2526 if (NULL != sh->disconnect_cb)
2527 sh->disconnect_cb (sh->cb_cls,
2528 c,
2529 c->user_context);
2530 if (NULL != c->warn_task)
1674 { 2531 {
1675 GNUNET_SCHEDULER_cancel (sctx->shutdown_task); 2532 GNUNET_SCHEDULER_cancel (c->warn_task);
1676 sctx->shutdown_task = NULL; 2533 c->warn_task = NULL;
1677 } 2534 }
1678 if (NULL != sctx->server) 2535 if (NULL != c->recv_task)
1679 GNUNET_SERVER_destroy (sctx->server);
1680 GNUNET_free_non_null (sctx->my_handlers);
1681 if (NULL != sctx->addrs)
1682 { 2536 {
1683 i = 0; 2537 GNUNET_SCHEDULER_cancel (c->recv_task);
1684 while (NULL != sctx->addrs[i]) 2538 c->recv_task = NULL;
1685 GNUNET_free (sctx->addrs[i++]); 2539 }
1686 GNUNET_free (sctx->addrs); 2540 if (NULL != c->send_task)
1687 } 2541 {
1688 GNUNET_free_non_null (sctx->addrlens); 2542 GNUNET_SCHEDULER_cancel (c->send_task);
1689 GNUNET_free_non_null (sctx->v4_denied); 2543 c->send_task = NULL;
1690 GNUNET_free_non_null (sctx->v6_denied); 2544 }
1691 GNUNET_free_non_null (sctx->v4_allowed); 2545 c->drop_task = GNUNET_SCHEDULER_add_now (&finish_client_drop,
1692 GNUNET_free_non_null (sctx->v6_allowed); 2546 c);
1693 GNUNET_free (sctx); 2547}
2548
2549
2550/**
2551 * Explicitly stops the service.
2552 *
2553 * @param sh server to shutdown
2554 */
2555void
2556GNUNET_SERVICE_shutdown (struct GNUNET_SERVICE_Handle *sh)
2557{
2558 struct GNUNET_SERVICE_Client *client;
2559
2560 GNUNET_SERVICE_suspend (sh);
2561 sh->got_shutdown = GNUNET_NO;
2562 while (NULL != (client = sh->clients_head))
2563 GNUNET_SERVICE_client_drop (client);
2564}
2565
2566
2567/**
2568 * Set the 'monitor' flag on this client. Clients which have been
2569 * marked as 'monitors' won't prevent the server from shutting down
2570 * once #GNUNET_SERVICE_stop_listening() has been invoked. The idea is
2571 * that for "normal" clients we likely want to allow them to process
2572 * their requests; however, monitor-clients are likely to 'never'
2573 * disconnect during shutdown and thus will not be considered when
2574 * determining if the server should continue to exist after
2575 * shutdown has been triggered.
2576 *
2577 * @param c client to mark as a monitor
2578 */
2579void
2580GNUNET_SERVICE_client_mark_monitor (struct GNUNET_SERVICE_Client *c)
2581{
2582 c->is_monitor = GNUNET_YES;
2583 if ( (GNUNET_YES == c->sh->got_shutdown) &&
2584 (GNUNET_NO == have_non_monitor_clients (c->sh)) )
2585 GNUNET_SERVICE_shutdown (c->sh);
2586}
2587
2588
2589/**
2590 * Set the persist option on this client. Indicates that the
2591 * underlying socket or fd should never really be closed. Used for
2592 * indicating process death.
2593 *
2594 * @param c client to persist the socket (never to be closed)
2595 */
2596void
2597GNUNET_SERVICE_client_persist (struct GNUNET_SERVICE_Client *c)
2598{
2599 c->persist = GNUNET_YES;
2600}
2601
2602
2603/**
2604 * Obtain the message queue of @a c. Convenience function.
2605 *
2606 * @param c the client to continue receiving from
2607 * @return the message queue of @a c
2608 */
2609struct GNUNET_MQ_Handle *
2610GNUNET_SERVICE_client_get_mq (struct GNUNET_SERVICE_Client *c)
2611{
2612 return c->mq;
1694} 2613}
1695 2614
1696 2615
1697/* end of service.c */ 2616/* end of service_new.c */
diff --git a/src/util/service_new.c b/src/util/service_new.c
deleted file mode 100644
index 9c0ee539b..000000000
--- a/src/util/service_new.c
+++ /dev/null
@@ -1,2615 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2016 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file util/service_new.c
23 * @brief functions related to starting services (redesign)
24 * @author Christian Grothoff
25 * @author Florian Dold
26 */
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_protocols.h"
30#include "gnunet_constants.h"
31#include "gnunet_resolver_service.h"
32#include "speedup.h"
33
34#if HAVE_MALLINFO
35#include <malloc.h>
36#include "gauger.h"
37#endif
38
39
40#define LOG(kind,...) GNUNET_log_from (kind, "util-service", __VA_ARGS__)
41
42#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-service", syscall)
43
44#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-service", syscall, filename)
45
46
47/**
48 * Information the service tracks per listen operation.
49 */
50struct ServiceListenContext
51{
52
53 /**
54 * Kept in a DLL.
55 */
56 struct ServiceListenContext *next;
57
58 /**
59 * Kept in a DLL.
60 */
61 struct ServiceListenContext *prev;
62
63 /**
64 * Service this listen context belongs to.
65 */
66 struct GNUNET_SERVICE_Handle *sh;
67
68 /**
69 * Socket we are listening on.
70 */
71 struct GNUNET_NETWORK_Handle *listen_socket;
72
73 /**
74 * Task scheduled to do the listening.
75 */
76 struct GNUNET_SCHEDULER_Task *listen_task;
77
78};
79
80
81/**
82 * Handle to a service.
83 */
84struct GNUNET_SERVICE_Handle
85{
86 /**
87 * Our configuration.
88 */
89 const struct GNUNET_CONFIGURATION_Handle *cfg;
90
91 /**
92 * Name of our service.
93 */
94 const char *service_name;
95
96 /**
97 * Main service-specific task to run.
98 */
99 GNUNET_SERVICE_InitCallback service_init_cb;
100
101 /**
102 * Function to call when clients connect.
103 */
104 GNUNET_SERVICE_ConnectHandler connect_cb;
105
106 /**
107 * Function to call when clients disconnect / are disconnected.
108 */
109 GNUNET_SERVICE_DisconnectHandler disconnect_cb;
110
111 /**
112 * Closure for @e service_init_cb, @e connect_cb, @e disconnect_cb.
113 */
114 void *cb_cls;
115
116 /**
117 * DLL of listen sockets used to accept new connections.
118 */
119 struct ServiceListenContext *slc_head;
120
121 /**
122 * DLL of listen sockets used to accept new connections.
123 */
124 struct ServiceListenContext *slc_tail;
125
126 /**
127 * Our clients, kept in a DLL.
128 */
129 struct GNUNET_SERVICE_Client *clients_head;
130
131 /**
132 * Our clients, kept in a DLL.
133 */
134 struct GNUNET_SERVICE_Client *clients_tail;
135
136 /**
137 * Message handlers to use for all clients.
138 */
139 struct GNUNET_MQ_MessageHandler *handlers;
140
141 /**
142 * Closure for @e task.
143 */
144 void *task_cls;
145
146 /**
147 * IPv4 addresses that are not allowed to connect.
148 */
149 struct GNUNET_STRINGS_IPv4NetworkPolicy *v4_denied;
150
151 /**
152 * IPv6 addresses that are not allowed to connect.
153 */
154 struct GNUNET_STRINGS_IPv6NetworkPolicy *v6_denied;
155
156 /**
157 * IPv4 addresses that are allowed to connect (if not
158 * set, all are allowed).
159 */
160 struct GNUNET_STRINGS_IPv4NetworkPolicy *v4_allowed;
161
162 /**
163 * IPv6 addresses that are allowed to connect (if not
164 * set, all are allowed).
165 */
166 struct GNUNET_STRINGS_IPv6NetworkPolicy *v6_allowed;
167
168 /**
169 * Do we require a matching UID for UNIX domain socket connections?
170 * #GNUNET_NO means that the UID does not have to match (however,
171 * @e match_gid may still impose other access control checks).
172 */
173 int match_uid;
174
175 /**
176 * Do we require a matching GID for UNIX domain socket connections?
177 * Ignored if @e match_uid is #GNUNET_YES. Note that this is about
178 * checking that the client's UID is in our group OR that the
179 * client's GID is our GID. If both "match_gid" and @e match_uid are
180 * #GNUNET_NO, all users on the local system have access.
181 */
182 int match_gid;
183
184 /**
185 * Set to #GNUNET_YES if we got a shutdown signal and terminate
186 * the service if #have_non_monitor_clients() returns #GNUNET_YES.
187 */
188 int got_shutdown;
189
190 /**
191 * Our options.
192 */
193 enum GNUNET_SERVICE_Options options;
194
195 /**
196 * If we are daemonizing, this FD is set to the
197 * pipe to the parent. Send '.' if we started
198 * ok, '!' if not. -1 if we are not daemonizing.
199 */
200 int ready_confirm_fd;
201
202 /**
203 * Overall success/failure of the service start.
204 */
205 int ret;
206
207 /**
208 * If #GNUNET_YES, consider unknown message types an error where the
209 * client is disconnected.
210 */
211 int require_found;
212};
213
214
215/**
216 * Handle to a client that is connected to a service.
217 */
218struct GNUNET_SERVICE_Client
219{
220
221 /**
222 * Kept in a DLL.
223 */
224 struct GNUNET_SERVICE_Client *next;
225
226 /**
227 * Kept in a DLL.
228 */
229 struct GNUNET_SERVICE_Client *prev;
230
231 /**
232 * Service that this client belongs to.
233 */
234 struct GNUNET_SERVICE_Handle *sh;
235
236 /**
237 * Socket of this client.
238 */
239 struct GNUNET_NETWORK_Handle *sock;
240
241 /**
242 * Message queue for the client.
243 */
244 struct GNUNET_MQ_Handle *mq;
245
246 /**
247 * Tokenizer we use for processing incoming data.
248 */
249 struct GNUNET_MessageStreamTokenizer *mst;
250
251 /**
252 * Task that warns about missing calls to
253 * #GNUNET_SERVICE_client_continue().
254 */
255 struct GNUNET_SCHEDULER_Task *warn_task;
256
257 /**
258 * Task run to finish dropping the client after the stack has
259 * properly unwound.
260 */
261 struct GNUNET_SCHEDULER_Task *drop_task;
262
263 /**
264 * Task that receives data from the client to
265 * pass it to the handlers.
266 */
267 struct GNUNET_SCHEDULER_Task *recv_task;
268
269 /**
270 * Task that transmit data to the client.
271 */
272 struct GNUNET_SCHEDULER_Task *send_task;
273
274 /**
275 * Pointer to the message to be transmitted by @e send_task.
276 */
277 const struct GNUNET_MessageHeader *msg;
278
279 /**
280 * User context value, value returned from
281 * the connect callback.
282 */
283 void *user_context;
284
285 /**
286 * Time when we last gave a message from this client
287 * to the application.
288 */
289 struct GNUNET_TIME_Absolute warn_start;
290
291 /**
292 * Current position in @e msg at which we are transmitting.
293 */
294 size_t msg_pos;
295
296 /**
297 * Persist the file handle for this client no matter what happens,
298 * force the OS to close once the process actually dies. Should only
299 * be used in special cases!
300 */
301 int persist;
302
303 /**
304 * Is this client a 'monitor' client that should not be counted
305 * when deciding on destroying the server during soft shutdown?
306 * (see also #GNUNET_SERVICE_start)
307 */
308 int is_monitor;
309
310 /**
311 * Are we waiting for the application to call #GNUNET_SERVICE_client_continue()?
312 */
313 int needs_continue;
314
315 /**
316 * Type of last message processed (for warn_no_receive_done).
317 */
318 uint16_t warn_type;
319};
320
321
322/**
323 * Check if any of the clients we have left are unrelated to
324 * monitoring.
325 *
326 * @param sh service to check clients for
327 * @return #GNUNET_YES if we have non-monitoring clients left
328 */
329static int
330have_non_monitor_clients (struct GNUNET_SERVICE_Handle *sh)
331{
332 struct GNUNET_SERVICE_Client *client;
333
334 for (client = sh->clients_head;NULL != client; client = client->next)
335 {
336 if (client->is_monitor)
337 continue;
338 return GNUNET_YES;
339 }
340 return GNUNET_NO;
341}
342
343
344/**
345 * Shutdown task triggered when a service should be terminated.
346 * This considers active clients and the service options to see
347 * how this specific service is to be terminated, and depending
348 * on this proceeds with the shutdown logic.
349 *
350 * @param cls our `struct GNUNET_SERVICE_Handle`
351 */
352static void
353service_shutdown (void *cls)
354{
355 struct GNUNET_SERVICE_Handle *sh = cls;
356
357 switch (sh->options)
358 {
359 case GNUNET_SERVICE_OPTION_NONE:
360 GNUNET_SERVICE_shutdown (sh);
361 break;
362 case GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN:
363 /* This task should never be run if we are using
364 the manual shutdown. */
365 GNUNET_assert (0);
366 break;
367 case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN:
368 sh->got_shutdown = GNUNET_YES;
369 GNUNET_SERVICE_suspend (sh);
370 if (GNUNET_NO == have_non_monitor_clients (sh))
371 GNUNET_SERVICE_shutdown (sh);
372 break;
373 }
374}
375
376
377/**
378 * First task run by any service. Initializes our shutdown task,
379 * starts the listening operation on our listen sockets and launches
380 * the custom logic of the application service.
381 *
382 * @param cls our `struct GNUNET_SERVICE_Handle`
383 */
384static void
385service_main (void *cls)
386{
387 struct GNUNET_SERVICE_Handle *sh = cls;
388
389 if (GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN != sh->options)
390 GNUNET_SCHEDULER_add_shutdown (&service_shutdown,
391 sh);
392 GNUNET_SERVICE_resume (sh);
393
394 if (-1 != sh->ready_confirm_fd)
395 {
396 GNUNET_break (1 == WRITE (sh->ready_confirm_fd, ".", 1));
397 GNUNET_break (0 == CLOSE (sh->ready_confirm_fd));
398 sh->ready_confirm_fd = -1;
399 }
400
401 if (NULL != sh->service_init_cb)
402 sh->service_init_cb (sh->cb_cls,
403 sh->cfg,
404 sh);
405}
406
407
408/**
409 * Parse an IPv4 access control list.
410 *
411 * @param ret location where to write the ACL (set)
412 * @param sh service context to use to get the configuration
413 * @param option name of the ACL option to parse
414 * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
415 * no ACL configured)
416 */
417static int
418process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret,
419 struct GNUNET_SERVICE_Handle *sh,
420 const char *option)
421{
422 char *opt;
423
424 if (! GNUNET_CONFIGURATION_have_value (sh->cfg,
425 sh->service_name,
426 option))
427 {
428 *ret = NULL;
429 return GNUNET_OK;
430 }
431 GNUNET_break (GNUNET_OK ==
432 GNUNET_CONFIGURATION_get_value_string (sh->cfg,
433 sh->service_name,
434 option,
435 &opt));
436 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt)))
437 {
438 LOG (GNUNET_ERROR_TYPE_WARNING,
439 _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
440 opt,
441 sh->service_name,
442 option);
443 GNUNET_free (opt);
444 return GNUNET_SYSERR;
445 }
446 GNUNET_free (opt);
447 return GNUNET_OK;
448}
449
450
451/**
452 * Parse an IPv6 access control list.
453 *
454 * @param ret location where to write the ACL (set)
455 * @param sh service context to use to get the configuration
456 * @param option name of the ACL option to parse
457 * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
458 * no ACL configured)
459 */
460static int
461process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret,
462 struct GNUNET_SERVICE_Handle *sh,
463 const char *option)
464{
465 char *opt;
466
467 if (! GNUNET_CONFIGURATION_have_value (sh->cfg,
468 sh->service_name,
469 option))
470 {
471 *ret = NULL;
472 return GNUNET_OK;
473 }
474 GNUNET_break (GNUNET_OK ==
475 GNUNET_CONFIGURATION_get_value_string (sh->cfg,
476 sh->service_name,
477 option,
478 &opt));
479 if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt)))
480 {
481 LOG (GNUNET_ERROR_TYPE_WARNING,
482 _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
483 opt,
484 sh->service_name,
485 option);
486 GNUNET_free (opt);
487 return GNUNET_SYSERR;
488 }
489 GNUNET_free (opt);
490 return GNUNET_OK;
491}
492
493
494/**
495 * Add the given UNIX domain path as an address to the
496 * list (as the first entry).
497 *
498 * @param saddrs array to update
499 * @param saddrlens where to store the address length
500 * @param unixpath path to add
501 * @param abstract #GNUNET_YES to add an abstract UNIX domain socket. This
502 * parameter is ignore on systems other than LINUX
503 */
504static void
505add_unixpath (struct sockaddr **saddrs,
506 socklen_t *saddrlens,
507 const char *unixpath,
508 int abstract)
509{
510#ifdef AF_UNIX
511 struct sockaddr_un *un;
512
513 un = GNUNET_new (struct sockaddr_un);
514 un->sun_family = AF_UNIX;
515 strncpy (un->sun_path,
516 unixpath,
517 sizeof (un->sun_path) - 1);
518#ifdef LINUX
519 if (GNUNET_YES == abstract)
520 un->sun_path[0] = '\0';
521#endif
522#if HAVE_SOCKADDR_UN_SUN_LEN
523 un->sun_len = (u_char) sizeof (struct sockaddr_un);
524#endif
525 *saddrs = (struct sockaddr *) un;
526 *saddrlens = sizeof (struct sockaddr_un);
527#else
528 /* this function should never be called
529 * unless AF_UNIX is defined! */
530 GNUNET_assert (0);
531#endif
532}
533
534
535/**
536 * Get the list of addresses that a server for the given service
537 * should bind to.
538 *
539 * @param service_name name of the service
540 * @param cfg configuration (which specifies the addresses)
541 * @param addrs set (call by reference) to an array of pointers to the
542 * addresses the server should bind to and listen on; the
543 * array will be NULL-terminated (on success)
544 * @param addr_lens set (call by reference) to an array of the lengths
545 * of the respective `struct sockaddr` struct in the @a addrs
546 * array (on success)
547 * @return number of addresses found on success,
548 * #GNUNET_SYSERR if the configuration
549 * did not specify reasonable finding information or
550 * if it specified a hostname that could not be resolved;
551 * #GNUNET_NO if the number of addresses configured is
552 * zero (in this case, `*addrs` and `*addr_lens` will be
553 * set to NULL).
554 */
555static int
556get_server_addresses (const char *service_name,
557 const struct GNUNET_CONFIGURATION_Handle *cfg,
558 struct sockaddr ***addrs,
559 socklen_t **addr_lens)
560{
561 int disablev6;
562 struct GNUNET_NETWORK_Handle *desc;
563 unsigned long long port;
564 char *unixpath;
565 struct addrinfo hints;
566 struct addrinfo *res;
567 struct addrinfo *pos;
568 struct addrinfo *next;
569 unsigned int i;
570 int resi;
571 int ret;
572 int abstract;
573 struct sockaddr **saddrs;
574 socklen_t *saddrlens;
575 char *hostname;
576
577 *addrs = NULL;
578 *addr_lens = NULL;
579 desc = NULL;
580 if (GNUNET_CONFIGURATION_have_value (cfg,
581 service_name,
582 "DISABLEV6"))
583 {
584 if (GNUNET_SYSERR ==
585 (disablev6 =
586 GNUNET_CONFIGURATION_get_value_yesno (cfg,
587 service_name,
588 "DISABLEV6")))
589 return GNUNET_SYSERR;
590 }
591 else
592 disablev6 = GNUNET_NO;
593
594 if (! disablev6)
595 {
596 /* probe IPv6 support */
597 desc = GNUNET_NETWORK_socket_create (PF_INET6,
598 SOCK_STREAM,
599 0);
600 if (NULL == desc)
601 {
602 if ( (ENOBUFS == errno) ||
603 (ENOMEM == errno) ||
604 (ENFILE == errno) ||
605 (EACCES == errno) )
606 {
607 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
608 "socket");
609 return GNUNET_SYSERR;
610 }
611 LOG (GNUNET_ERROR_TYPE_INFO,
612 _("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
613 service_name,
614 STRERROR (errno));
615 disablev6 = GNUNET_YES;
616 }
617 else
618 {
619 GNUNET_break (GNUNET_OK ==
620 GNUNET_NETWORK_socket_close (desc));
621 desc = NULL;
622 }
623 }
624
625 port = 0;
626 if (GNUNET_CONFIGURATION_have_value (cfg,
627 service_name,
628 "PORT"))
629 {
630 if (GNUNET_OK !=
631 GNUNET_CONFIGURATION_get_value_number (cfg,
632 service_name,
633 "PORT",
634 &port))
635 {
636 LOG (GNUNET_ERROR_TYPE_ERROR,
637 _("Require valid port number for service `%s' in configuration!\n"),
638 service_name);
639 }
640 if (port > 65535)
641 {
642 LOG (GNUNET_ERROR_TYPE_ERROR,
643 _("Require valid port number for service `%s' in configuration!\n"),
644 service_name);
645 return GNUNET_SYSERR;
646 }
647 }
648
649 if (GNUNET_CONFIGURATION_have_value (cfg,
650 service_name,
651 "BINDTO"))
652 {
653 GNUNET_break (GNUNET_OK ==
654 GNUNET_CONFIGURATION_get_value_string (cfg,
655 service_name,
656 "BINDTO",
657 &hostname));
658 }
659 else
660 hostname = NULL;
661
662 unixpath = NULL;
663 abstract = GNUNET_NO;
664#ifdef AF_UNIX
665 if ((GNUNET_YES ==
666 GNUNET_CONFIGURATION_have_value (cfg,
667 service_name,
668 "UNIXPATH")) &&
669 (GNUNET_OK ==
670 GNUNET_CONFIGURATION_get_value_filename (cfg,
671 service_name,
672 "UNIXPATH",
673 &unixpath)) &&
674 (0 < strlen (unixpath)))
675 {
676 /* probe UNIX support */
677 struct sockaddr_un s_un;
678
679 if (strlen (unixpath) >= sizeof (s_un.sun_path))
680 {
681 LOG (GNUNET_ERROR_TYPE_WARNING,
682 _("UNIXPATH `%s' too long, maximum length is %llu\n"),
683 unixpath,
684 (unsigned long long) sizeof (s_un.sun_path));
685 unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
686 LOG (GNUNET_ERROR_TYPE_INFO,
687 _("Using `%s' instead\n"),
688 unixpath);
689 }
690#ifdef LINUX
691 abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
692 "TESTING",
693 "USE_ABSTRACT_SOCKETS");
694 if (GNUNET_SYSERR == abstract)
695 abstract = GNUNET_NO;
696#endif
697 if ( (GNUNET_YES != abstract) &&
698 (GNUNET_OK !=
699 GNUNET_DISK_directory_create_for_file (unixpath)) )
700 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
701 "mkdir",
702 unixpath);
703 }
704 if (NULL != unixpath)
705 {
706 desc = GNUNET_NETWORK_socket_create (AF_UNIX,
707 SOCK_STREAM,
708 0);
709 if (NULL == desc)
710 {
711 if ((ENOBUFS == errno) ||
712 (ENOMEM == errno) ||
713 (ENFILE == errno) ||
714 (EACCES == errno))
715 {
716 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
717 "socket");
718 GNUNET_free_non_null (hostname);
719 GNUNET_free (unixpath);
720 return GNUNET_SYSERR;
721 }
722 LOG (GNUNET_ERROR_TYPE_INFO,
723 _("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
724 service_name,
725 STRERROR (errno));
726 GNUNET_free (unixpath);
727 unixpath = NULL;
728 }
729 else
730 {
731 GNUNET_break (GNUNET_OK ==
732 GNUNET_NETWORK_socket_close (desc));
733 desc = NULL;
734 }
735 }
736#endif
737
738 if ((0 == port) && (NULL == unixpath))
739 {
740 LOG (GNUNET_ERROR_TYPE_ERROR,
741 _("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
742 service_name);
743 GNUNET_free_non_null (hostname);
744 return GNUNET_SYSERR;
745 }
746 if (0 == port)
747 {
748 saddrs = GNUNET_new_array (2,
749 struct sockaddr *);
750 saddrlens = GNUNET_new_array (2,
751 socklen_t);
752 add_unixpath (saddrs,
753 saddrlens,
754 unixpath,
755 abstract);
756 GNUNET_free_non_null (unixpath);
757 GNUNET_free_non_null (hostname);
758 *addrs = saddrs;
759 *addr_lens = saddrlens;
760 return 1;
761 }
762
763 if (NULL != hostname)
764 {
765 LOG (GNUNET_ERROR_TYPE_DEBUG,
766 "Resolving `%s' since that is where `%s' will bind to.\n",
767 hostname,
768 service_name);
769 memset (&hints,
770 0,
771 sizeof (struct addrinfo));
772 if (disablev6)
773 hints.ai_family = AF_INET;
774 hints.ai_protocol = IPPROTO_TCP;
775 if ((0 != (ret = getaddrinfo (hostname,
776 NULL,
777 &hints,
778 &res))) ||
779 (NULL == res))
780 {
781 LOG (GNUNET_ERROR_TYPE_ERROR,
782 _("Failed to resolve `%s': %s\n"),
783 hostname,
784 gai_strerror (ret));
785 GNUNET_free (hostname);
786 GNUNET_free_non_null (unixpath);
787 return GNUNET_SYSERR;
788 }
789 next = res;
790 i = 0;
791 while (NULL != (pos = next))
792 {
793 next = pos->ai_next;
794 if ( (disablev6) &&
795 (pos->ai_family == AF_INET6) )
796 continue;
797 i++;
798 }
799 if (0 == i)
800 {
801 LOG (GNUNET_ERROR_TYPE_ERROR,
802 _("Failed to find %saddress for `%s'.\n"),
803 disablev6 ? "IPv4 " : "",
804 hostname);
805 freeaddrinfo (res);
806 GNUNET_free (hostname);
807 GNUNET_free_non_null (unixpath);
808 return GNUNET_SYSERR;
809 }
810 resi = i;
811 if (NULL != unixpath)
812 resi++;
813 saddrs = GNUNET_new_array (resi + 1,
814 struct sockaddr *);
815 saddrlens = GNUNET_new_array (resi + 1,
816 socklen_t);
817 i = 0;
818 if (NULL != unixpath)
819 {
820 add_unixpath (saddrs,
821 saddrlens,
822 unixpath,
823 abstract);
824 i++;
825 }
826 next = res;
827 while (NULL != (pos = next))
828 {
829 next = pos->ai_next;
830 if ( (disablev6) &&
831 (AF_INET6 == pos->ai_family) )
832 continue;
833 if ( (IPPROTO_TCP != pos->ai_protocol) &&
834 (0 != pos->ai_protocol) )
835 continue; /* not TCP */
836 if ( (SOCK_STREAM != pos->ai_socktype) &&
837 (0 != pos->ai_socktype) )
838 continue; /* huh? */
839 LOG (GNUNET_ERROR_TYPE_DEBUG,
840 "Service `%s' will bind to `%s'\n",
841 service_name,
842 GNUNET_a2s (pos->ai_addr,
843 pos->ai_addrlen));
844 if (AF_INET == pos->ai_family)
845 {
846 GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen);
847 saddrlens[i] = pos->ai_addrlen;
848 saddrs[i] = GNUNET_malloc (saddrlens[i]);
849 GNUNET_memcpy (saddrs[i],
850 pos->ai_addr,
851 saddrlens[i]);
852 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
853 }
854 else
855 {
856 GNUNET_assert (AF_INET6 == pos->ai_family);
857 GNUNET_assert (sizeof (struct sockaddr_in6) == pos->ai_addrlen);
858 saddrlens[i] = pos->ai_addrlen;
859 saddrs[i] = GNUNET_malloc (saddrlens[i]);
860 GNUNET_memcpy (saddrs[i],
861 pos->ai_addr,
862 saddrlens[i]);
863 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
864 }
865 i++;
866 }
867 GNUNET_free (hostname);
868 freeaddrinfo (res);
869 resi = i;
870 }
871 else
872 {
873 /* will bind against everything, just set port */
874 if (disablev6)
875 {
876 /* V4-only */
877 resi = 1;
878 if (NULL != unixpath)
879 resi++;
880 i = 0;
881 saddrs = GNUNET_new_array (resi + 1,
882 struct sockaddr *);
883 saddrlens = GNUNET_new_array (resi + 1,
884 socklen_t);
885 if (NULL != unixpath)
886 {
887 add_unixpath (saddrs,
888 saddrlens,
889 unixpath,
890 abstract);
891 i++;
892 }
893 saddrlens[i] = sizeof (struct sockaddr_in);
894 saddrs[i] = GNUNET_malloc (saddrlens[i]);
895#if HAVE_SOCKADDR_IN_SIN_LEN
896 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
897#endif
898 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
899 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
900 }
901 else
902 {
903 /* dual stack */
904 resi = 2;
905 if (NULL != unixpath)
906 resi++;
907 saddrs = GNUNET_new_array (resi + 1,
908 struct sockaddr *);
909 saddrlens = GNUNET_new_array (resi + 1,
910 socklen_t);
911 i = 0;
912 if (NULL != unixpath)
913 {
914 add_unixpath (saddrs,
915 saddrlens,
916 unixpath,
917 abstract);
918 i++;
919 }
920 saddrlens[i] = sizeof (struct sockaddr_in6);
921 saddrs[i] = GNUNET_malloc (saddrlens[i]);
922#if HAVE_SOCKADDR_IN_SIN_LEN
923 ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
924#endif
925 ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
926 ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
927 i++;
928 saddrlens[i] = sizeof (struct sockaddr_in);
929 saddrs[i] = GNUNET_malloc (saddrlens[i]);
930#if HAVE_SOCKADDR_IN_SIN_LEN
931 ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
932#endif
933 ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
934 ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
935 }
936 }
937 GNUNET_free_non_null (unixpath);
938 *addrs = saddrs;
939 *addr_lens = saddrlens;
940 return resi;
941}
942
943
944#ifdef MINGW
945/**
946 * Read listen sockets from the parent process (ARM).
947 *
948 * @param sh service context to initialize
949 * @return NULL-terminated array of sockets on success,
950 * NULL if not ok (must bind yourself)
951 */
952static struct GNUNET_NETWORK_Handle **
953receive_sockets_from_parent (struct GNUNET_SERVICE_Handle *sh)
954{
955 static struct GNUNET_NETWORK_Handle **lsocks;
956 const char *env_buf;
957 int fail;
958 uint64_t count;
959 uint64_t i;
960 HANDLE lsocks_pipe;
961
962 env_buf = getenv ("GNUNET_OS_READ_LSOCKS");
963 if ( (NULL == env_buf) ||
964 (strlen (env_buf) <= 0) )
965 return NULL;
966 /* Using W32 API directly here, because this pipe will
967 * never be used outside of this function, and it's just too much of a bother
968 * to create a GNUnet API that boxes a HANDLE (the way it is done with socks)
969 */
970 lsocks_pipe = (HANDLE) strtoul (env_buf,
971 NULL,
972 10);
973 if ( (0 == lsocks_pipe) ||
974 (INVALID_HANDLE_VALUE == lsocks_pipe))
975 return NULL;
976 fail = 1;
977 do
978 {
979 int ret;
980 int fail2;
981 DWORD rd;
982
983 ret = ReadFile (lsocks_pipe,
984 &count,
985 sizeof (count),
986 &rd,
987 NULL);
988 if ( (0 == ret) ||
989 (sizeof (count) != rd) ||
990 (0 == count) )
991 break;
992 lsocks = GNUNET_new_array (count + 1,
993 struct GNUNET_NETWORK_Handle *);
994
995 fail2 = 1;
996 for (i = 0; i < count; i++)
997 {
998 WSAPROTOCOL_INFOA pi;
999 uint64_t size;
1000 SOCKET s;
1001
1002 ret = ReadFile (lsocks_pipe,
1003 &size,
1004 sizeof (size),
1005 &rd,
1006 NULL);
1007 if ( (0 == ret) ||
1008 (sizeof (size) != rd) ||
1009 (sizeof (pi) != size) )
1010 break;
1011 ret = ReadFile (lsocks_pipe,
1012 &pi,
1013 sizeof (pi),
1014 &rd,
1015 NULL);
1016 if ( (0 == ret) ||
1017 (sizeof (pi) != rd))
1018 break;
1019 s = WSASocketA (pi.iAddressFamily,
1020 pi.iSocketType,
1021 pi.iProtocol,
1022 &pi,
1023 0,
1024 WSA_FLAG_OVERLAPPED);
1025 lsocks[i] = GNUNET_NETWORK_socket_box_native (s);
1026 if (NULL == lsocks[i])
1027 break;
1028 else if (i == count - 1)
1029 fail2 = 0;
1030 }
1031 if (fail2)
1032 break;
1033 lsocks[count] = NULL;
1034 fail = 0;
1035 }
1036 while (fail);
1037 CloseHandle (lsocks_pipe);
1038
1039 if (fail)
1040 {
1041 LOG (GNUNET_ERROR_TYPE_ERROR,
1042 _("Could not access a pre-bound socket, will try to bind myself\n"));
1043 for (i = 0; (i < count) && (NULL != lsocks[i]); i++)
1044 GNUNET_break (GNUNET_OK ==
1045 GNUNET_NETWORK_socket_close (lsocks[i]));
1046 GNUNET_free (lsocks);
1047 return NULL;
1048 }
1049 return lsocks;
1050}
1051#endif
1052
1053
1054/**
1055 * Create and initialize a listen socket for the server.
1056 *
1057 * @param server_addr address to listen on
1058 * @param socklen length of @a server_addr
1059 * @return NULL on error, otherwise the listen socket
1060 */
1061static struct GNUNET_NETWORK_Handle *
1062open_listen_socket (const struct sockaddr *server_addr,
1063 socklen_t socklen)
1064{
1065 struct GNUNET_NETWORK_Handle *sock;
1066 uint16_t port;
1067 int eno;
1068
1069 switch (server_addr->sa_family)
1070 {
1071 case AF_INET:
1072 port = ntohs (((const struct sockaddr_in *) server_addr)->sin_port);
1073 break;
1074 case AF_INET6:
1075 port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port);
1076 break;
1077 case AF_UNIX:
1078 port = 0;
1079 break;
1080 default:
1081 GNUNET_break (0);
1082 port = 0;
1083 break;
1084 }
1085 sock = GNUNET_NETWORK_socket_create (server_addr->sa_family,
1086 SOCK_STREAM,
1087 0);
1088 if (NULL == sock)
1089 {
1090 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1091 "socket");
1092 errno = 0;
1093 return NULL;
1094 }
1095 /* bind the socket */
1096 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock,
1097 server_addr,
1098 socklen))
1099 {
1100 eno = errno;
1101 if (EADDRINUSE != errno)
1102 {
1103 /* we don't log 'EADDRINUSE' here since an IPv4 bind may
1104 * fail if we already took the port on IPv6; if both IPv4 and
1105 * IPv6 binds fail, then our caller will log using the
1106 * errno preserved in 'eno' */
1107 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1108 "bind");
1109 if (0 != port)
1110 LOG (GNUNET_ERROR_TYPE_ERROR,
1111 _("`%s' failed for port %d (%s).\n"),
1112 "bind",
1113 port,
1114 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1115 eno = 0;
1116 }
1117 else
1118 {
1119 if (0 != port)
1120 LOG (GNUNET_ERROR_TYPE_WARNING,
1121 _("`%s' failed for port %d (%s): address already in use\n"),
1122 "bind", port,
1123 (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
1124 else if (AF_UNIX == server_addr->sa_family)
1125 {
1126 LOG (GNUNET_ERROR_TYPE_WARNING,
1127 _("`%s' failed for `%s': address already in use\n"),
1128 "bind",
1129 GNUNET_a2s (server_addr, socklen));
1130 }
1131 }
1132 GNUNET_break (GNUNET_OK ==
1133 GNUNET_NETWORK_socket_close (sock));
1134 errno = eno;
1135 return NULL;
1136 }
1137 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock,
1138 5))
1139 {
1140 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1141 "listen");
1142 GNUNET_break (GNUNET_OK ==
1143 GNUNET_NETWORK_socket_close (sock));
1144 errno = 0;
1145 return NULL;
1146 }
1147 if (0 != port)
1148 LOG (GNUNET_ERROR_TYPE_DEBUG,
1149 "Server starts to listen on port %u.\n",
1150 port);
1151 return sock;
1152}
1153
1154
1155/**
1156 * Setup service handle
1157 *
1158 * Configuration may specify:
1159 * - PORT (where to bind to for TCP)
1160 * - UNIXPATH (where to bind to for UNIX domain sockets)
1161 * - DISABLEV6 (disable support for IPv6, otherwise we use dual-stack)
1162 * - BINDTO (hostname or IP address to bind to, otherwise we take everything)
1163 * - ACCEPT_FROM (only allow connections from specified IPv4 subnets)
1164 * - ACCEPT_FROM6 (only allow connections from specified IPv6 subnets)
1165 * - REJECT_FROM (disallow allow connections from specified IPv4 subnets)
1166 * - REJECT_FROM6 (disallow allow connections from specified IPv6 subnets)
1167 *
1168 * @param sh service context to initialize
1169 * @return #GNUNET_OK if configuration succeeded
1170 */
1171static int
1172setup_service (struct GNUNET_SERVICE_Handle *sh)
1173{
1174 int tolerant;
1175 struct GNUNET_NETWORK_Handle **lsocks;
1176#ifndef MINGW
1177 const char *nfds;
1178 unsigned int cnt;
1179 int flags;
1180#endif
1181
1182 if (GNUNET_CONFIGURATION_have_value
1183 (sh->cfg,
1184 sh->service_name,
1185 "TOLERANT"))
1186 {
1187 if (GNUNET_SYSERR ==
1188 (tolerant =
1189 GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1190 sh->service_name,
1191 "TOLERANT")))
1192 {
1193 LOG (GNUNET_ERROR_TYPE_ERROR,
1194 _("Specified value for `%s' of service `%s' is invalid\n"),
1195 "TOLERANT",
1196 sh->service_name);
1197 return GNUNET_SYSERR;
1198 }
1199 }
1200 else
1201 tolerant = GNUNET_NO;
1202
1203 lsocks = NULL;
1204#ifndef MINGW
1205 errno = 0;
1206 if ( (NULL != (nfds = getenv ("LISTEN_FDS"))) &&
1207 (1 == SSCANF (nfds,
1208 "%u",
1209 &cnt)) &&
1210 (cnt > 0) &&
1211 (cnt < FD_SETSIZE) &&
1212 (cnt + 4 < FD_SETSIZE) )
1213 {
1214 lsocks = GNUNET_new_array (cnt + 1,
1215 struct GNUNET_NETWORK_Handle *);
1216 while (0 < cnt--)
1217 {
1218 flags = fcntl (3 + cnt,
1219 F_GETFD);
1220 if ( (flags < 0) ||
1221 (0 != (flags & FD_CLOEXEC)) ||
1222 (NULL ==
1223 (lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
1224 {
1225 LOG (GNUNET_ERROR_TYPE_ERROR,
1226 _("Could not access pre-bound socket %u, will try to bind myself\n"),
1227 (unsigned int) 3 + cnt);
1228 cnt++;
1229 while (NULL != lsocks[cnt])
1230 GNUNET_break (GNUNET_OK ==
1231 GNUNET_NETWORK_socket_close (lsocks[cnt++]));
1232 GNUNET_free (lsocks);
1233 lsocks = NULL;
1234 break;
1235 }
1236 }
1237 unsetenv ("LISTEN_FDS");
1238 }
1239#else
1240 if (NULL != getenv ("GNUNET_OS_READ_LSOCKS"))
1241 {
1242 lsocks = receive_sockets_from_parent (sh);
1243 putenv ("GNUNET_OS_READ_LSOCKS=");
1244 }
1245#endif
1246
1247 if (NULL != lsocks)
1248 {
1249 /* listen only on inherited sockets if we have any */
1250 struct GNUNET_NETWORK_Handle **ls;
1251
1252 for (ls = lsocks; NULL != *ls; ls++)
1253 {
1254 struct ServiceListenContext *slc;
1255
1256 slc = GNUNET_new (struct ServiceListenContext);
1257 slc->sh = sh;
1258 slc->listen_socket = *ls;
1259 GNUNET_CONTAINER_DLL_insert (sh->slc_head,
1260 sh->slc_tail,
1261 slc);
1262 }
1263 GNUNET_free (lsocks);
1264 }
1265 else
1266 {
1267 struct sockaddr **addrs;
1268 socklen_t *addrlens;
1269 int num;
1270
1271 num = get_server_addresses (sh->service_name,
1272 sh->cfg,
1273 &addrs,
1274 &addrlens);
1275 if (GNUNET_SYSERR == num)
1276 return GNUNET_SYSERR;
1277
1278 for (int i = 0; i < num; i++)
1279 {
1280 struct ServiceListenContext *slc;
1281
1282 slc = GNUNET_new (struct ServiceListenContext);
1283 slc->sh = sh;
1284 slc->listen_socket = open_listen_socket (addrs[i],
1285 addrlens[i]);
1286 if (NULL == slc->listen_socket)
1287 {
1288 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
1289 "bind");
1290 GNUNET_free (addrs[i++]);
1291 GNUNET_free (slc);
1292 continue;
1293 }
1294 GNUNET_free (addrs[i++]);
1295 GNUNET_CONTAINER_DLL_insert (sh->slc_head,
1296 sh->slc_tail,
1297 slc);
1298 }
1299 GNUNET_free_non_null (addrlens);
1300 GNUNET_free_non_null (addrs);
1301 if ( (0 != num) &&
1302 (NULL == sh->slc_head) )
1303 {
1304 /* All attempts to bind failed, hard failure */
1305 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1306 _("Could not bind to any of the ports I was supposed to, refusing to run!\n"));
1307 return GNUNET_SYSERR;
1308 }
1309 }
1310
1311 sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
1312 sh->match_uid
1313 = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1314 sh->service_name,
1315 "UNIX_MATCH_UID");
1316 sh->match_gid
1317 = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg,
1318 sh->service_name,
1319 "UNIX_MATCH_GID");
1320 process_acl4 (&sh->v4_denied,
1321 sh,
1322 "REJECT_FROM");
1323 process_acl4 (&sh->v4_allowed,
1324 sh,
1325 "ACCEPT_FROM");
1326 process_acl6 (&sh->v6_denied,
1327 sh,
1328 "REJECT_FROM6");
1329 process_acl6 (&sh->v6_allowed,
1330 sh,
1331 "ACCEPT_FROM6");
1332 return GNUNET_OK;
1333}
1334
1335
1336/**
1337 * Get the name of the user that'll be used
1338 * to provide the service.
1339 *
1340 * @param sh service context
1341 * @return value of the 'USERNAME' option
1342 */
1343static char *
1344get_user_name (struct GNUNET_SERVICE_Handle *sh)
1345{
1346 char *un;
1347
1348 if (GNUNET_OK !=
1349 GNUNET_CONFIGURATION_get_value_filename (sh->cfg,
1350 sh->service_name,
1351 "USERNAME",
1352 &un))
1353 return NULL;
1354 return un;
1355}
1356
1357
1358/**
1359 * Set user ID.
1360 *
1361 * @param sh service context
1362 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1363 */
1364static int
1365set_user_id (struct GNUNET_SERVICE_Handle *sh)
1366{
1367 char *user;
1368
1369 if (NULL == (user = get_user_name (sh)))
1370 return GNUNET_OK; /* keep */
1371#ifndef MINGW
1372 struct passwd *pws;
1373
1374 errno = 0;
1375 pws = getpwnam (user);
1376 if (NULL == pws)
1377 {
1378 LOG (GNUNET_ERROR_TYPE_ERROR,
1379 _("Cannot obtain information about user `%s': %s\n"),
1380 user,
1381 errno == 0 ? _("No such user") : STRERROR (errno));
1382 GNUNET_free (user);
1383 return GNUNET_SYSERR;
1384 }
1385 if ( (0 != setgid (pws->pw_gid)) ||
1386 (0 != setegid (pws->pw_gid)) ||
1387#if HAVE_INITGROUPS
1388 (0 != initgroups (user,
1389 pws->pw_gid)) ||
1390#endif
1391 (0 != setuid (pws->pw_uid)) ||
1392 (0 != seteuid (pws->pw_uid)))
1393 {
1394 if ((0 != setregid (pws->pw_gid,
1395 pws->pw_gid)) ||
1396 (0 != setreuid (pws->pw_uid,
1397 pws->pw_uid)))
1398 {
1399 LOG (GNUNET_ERROR_TYPE_ERROR,
1400 _("Cannot change user/group to `%s': %s\n"),
1401 user,
1402 STRERROR (errno));
1403 GNUNET_free (user);
1404 return GNUNET_SYSERR;
1405 }
1406 }
1407#endif
1408 GNUNET_free (user);
1409 return GNUNET_OK;
1410}
1411
1412
1413/**
1414 * Get the name of the file where we will
1415 * write the PID of the service.
1416 *
1417 * @param sh service context
1418 * @return name of the file for the process ID
1419 */
1420static char *
1421get_pid_file_name (struct GNUNET_SERVICE_Handle *sh)
1422{
1423 char *pif;
1424
1425 if (GNUNET_OK !=
1426 GNUNET_CONFIGURATION_get_value_filename (sh->cfg,
1427 sh->service_name,
1428 "PIDFILE",
1429 &pif))
1430 return NULL;
1431 return pif;
1432}
1433
1434
1435/**
1436 * Delete the PID file that was created by our parent.
1437 *
1438 * @param sh service context
1439 */
1440static void
1441pid_file_delete (struct GNUNET_SERVICE_Handle *sh)
1442{
1443 char *pif = get_pid_file_name (sh);
1444
1445 if (NULL == pif)
1446 return; /* no PID file */
1447 if (0 != UNLINK (pif))
1448 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING,
1449 "unlink",
1450 pif);
1451 GNUNET_free (pif);
1452}
1453
1454
1455/**
1456 * Detach from terminal.
1457 *
1458 * @param sh service context
1459 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1460 */
1461static int
1462detach_terminal (struct GNUNET_SERVICE_Handle *sh)
1463{
1464#ifndef MINGW
1465 pid_t pid;
1466 int nullfd;
1467 int filedes[2];
1468
1469 if (0 != PIPE (filedes))
1470 {
1471 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1472 "pipe");
1473 return GNUNET_SYSERR;
1474 }
1475 pid = fork ();
1476 if (pid < 0)
1477 {
1478 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1479 "fork");
1480 return GNUNET_SYSERR;
1481 }
1482 if (0 != pid)
1483 {
1484 /* Parent */
1485 char c;
1486
1487 GNUNET_break (0 == CLOSE (filedes[1]));
1488 c = 'X';
1489 if (1 != READ (filedes[0],
1490 &c,
1491 sizeof (char)))
1492 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
1493 "read");
1494 fflush (stdout);
1495 switch (c)
1496 {
1497 case '.':
1498 exit (0);
1499 case 'I':
1500 LOG (GNUNET_ERROR_TYPE_INFO,
1501 _("Service process failed to initialize\n"));
1502 break;
1503 case 'S':
1504 LOG (GNUNET_ERROR_TYPE_INFO,
1505 _("Service process could not initialize server function\n"));
1506 break;
1507 case 'X':
1508 LOG (GNUNET_ERROR_TYPE_INFO,
1509 _("Service process failed to report status\n"));
1510 break;
1511 }
1512 exit (1); /* child reported error */
1513 }
1514 GNUNET_break (0 == CLOSE (0));
1515 GNUNET_break (0 == CLOSE (1));
1516 GNUNET_break (0 == CLOSE (filedes[0]));
1517 nullfd = OPEN ("/dev/null",
1518 O_RDWR | O_APPEND);
1519 if (nullfd < 0)
1520 return GNUNET_SYSERR;
1521 /* set stdin/stdout to /dev/null */
1522 if ( (dup2 (nullfd, 0) < 0) ||
1523 (dup2 (nullfd, 1) < 0) )
1524 {
1525 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1526 "dup2");
1527 (void) CLOSE (nullfd);
1528 return GNUNET_SYSERR;
1529 }
1530 (void) CLOSE (nullfd);
1531 /* Detach from controlling terminal */
1532 pid = setsid ();
1533 if (-1 == pid)
1534 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
1535 "setsid");
1536 sh->ready_confirm_fd = filedes[1];
1537#else
1538 /* FIXME: we probably need to do something else
1539 * elsewhere in order to fork the process itself... */
1540 FreeConsole ();
1541#endif
1542 return GNUNET_OK;
1543}
1544
1545
1546/**
1547 * Tear down the service, closing the listen sockets and
1548 * freeing the ACLs.
1549 *
1550 * @param sh handle to the service to tear down.
1551 */
1552static void
1553teardown_service (struct GNUNET_SERVICE_Handle *sh)
1554{
1555 struct ServiceListenContext *slc;
1556
1557 GNUNET_free_non_null (sh->v4_denied);
1558 GNUNET_free_non_null (sh->v6_denied);
1559 GNUNET_free_non_null (sh->v4_allowed);
1560 GNUNET_free_non_null (sh->v6_allowed);
1561 while (NULL != (slc = sh->slc_head))
1562 {
1563 GNUNET_CONTAINER_DLL_remove (sh->slc_head,
1564 sh->slc_tail,
1565 slc);
1566 if (NULL != slc->listen_task)
1567 GNUNET_SCHEDULER_cancel (slc->listen_task);
1568 GNUNET_break (GNUNET_OK ==
1569 GNUNET_NETWORK_socket_close (slc->listen_socket));
1570 GNUNET_free (slc);
1571 }
1572}
1573
1574
1575/**
1576 * Low-level function to start a service if the scheduler
1577 * is already running. Should only be used directly in
1578 * special cases.
1579 *
1580 * The function will launch the service with the name @a service_name
1581 * using the @a service_options to configure its shutdown
1582 * behavior. When clients connect or disconnect, the respective
1583 * @a connect_cb or @a disconnect_cb functions will be called. For
1584 * messages received from the clients, the respective @a handlers will
1585 * be invoked; for the closure of the handlers we use the return value
1586 * from the @a connect_cb invocation of the respective client.
1587 *
1588 * Each handler MUST call #GNUNET_SERVICE_client_continue() after each
1589 * message to receive further messages from this client. If
1590 * #GNUNET_SERVICE_client_continue() is not called within a short
1591 * time, a warning will be logged. If delays are expected, services
1592 * should call #GNUNET_SERVICE_client_disable_continue_warning() to
1593 * disable the warning.
1594 *
1595 * Clients sending invalid messages (based on @a handlers) will be
1596 * dropped. Additionally, clients can be dropped at any time using
1597 * #GNUNET_SERVICE_client_drop().
1598 *
1599 * The service must be stopped using #GNUNET_SERVICE_stoP().
1600 *
1601 * @param service_name name of the service to run
1602 * @param cfg configuration to use
1603 * @param connect_cb function to call whenever a client connects
1604 * @param disconnect_cb function to call whenever a client disconnects
1605 * @param cls closure argument for @a connect_cb and @a disconnect_cb
1606 * @param handlers NULL-terminated array of message handlers for the service,
1607 * the closure will be set to the value returned by
1608 * the @a connect_cb for the respective connection
1609 * @return NULL on error
1610 */
1611struct GNUNET_SERVICE_Handle *
1612GNUNET_SERVICE_starT (const char *service_name,
1613 const struct GNUNET_CONFIGURATION_Handle *cfg,
1614 GNUNET_SERVICE_ConnectHandler connect_cb,
1615 GNUNET_SERVICE_DisconnectHandler disconnect_cb,
1616 void *cls,
1617 const struct GNUNET_MQ_MessageHandler *handlers)
1618{
1619 struct GNUNET_SERVICE_Handle *sh;
1620
1621 sh = GNUNET_new (struct GNUNET_SERVICE_Handle);
1622 sh->service_name = service_name;
1623 sh->cfg = cfg;
1624 sh->connect_cb = connect_cb;
1625 sh->disconnect_cb = disconnect_cb;
1626 sh->cb_cls = cls;
1627 sh->handlers = GNUNET_MQ_copy_handlers (handlers);
1628 if (GNUNET_OK != setup_service (sh))
1629 {
1630 GNUNET_free_non_null (sh->handlers);
1631 GNUNET_free (sh);
1632 return NULL;
1633 }
1634 GNUNET_SERVICE_resume (sh);
1635 return sh;
1636}
1637
1638
1639/**
1640 * Stops a service that was started with #GNUNET_SERVICE_starT().
1641 *
1642 * @param srv service to stop
1643 */
1644void
1645GNUNET_SERVICE_stoP (struct GNUNET_SERVICE_Handle *srv)
1646{
1647 struct GNUNET_SERVICE_Client *client;
1648
1649 GNUNET_SERVICE_suspend (srv);
1650 while (NULL != (client = srv->clients_head))
1651 GNUNET_SERVICE_client_drop (client);
1652 teardown_service (srv);
1653 GNUNET_free_non_null (srv->handlers);
1654 GNUNET_free (srv);
1655}
1656
1657
1658/**
1659 * Creates the "main" function for a GNUnet service. You
1660 * should almost always use the #GNUNET_SERVICE_MAIN macro
1661 * instead of calling this function directly (except
1662 * for ARM, which should call this function directly).
1663 *
1664 * The function will launch the service with the name @a service_name
1665 * using the @a service_options to configure its shutdown
1666 * behavior. Once the service is ready, the @a init_cb will be called
1667 * for service-specific initialization. @a init_cb will be given the
1668 * service handler which can be used to control the service's
1669 * availability. When clients connect or disconnect, the respective
1670 * @a connect_cb or @a disconnect_cb functions will be called. For
1671 * messages received from the clients, the respective @a handlers will
1672 * be invoked; for the closure of the handlers we use the return value
1673 * from the @a connect_cb invocation of the respective client.
1674 *
1675 * Each handler MUST call #GNUNET_SERVICE_client_continue() after each
1676 * message to receive further messages from this client. If
1677 * #GNUNET_SERVICE_client_continue() is not called within a short
1678 * time, a warning will be logged. If delays are expected, services
1679 * should call #GNUNET_SERVICE_client_disable_continue_warning() to
1680 * disable the warning.
1681 *
1682 * Clients sending invalid messages (based on @a handlers) will be
1683 * dropped. Additionally, clients can be dropped at any time using
1684 * #GNUNET_SERVICE_client_drop().
1685 *
1686 * @param argc number of command-line arguments in @a argv
1687 * @param argv array of command-line arguments
1688 * @param service_name name of the service to run
1689 * @param options options controlling shutdown of the service
1690 * @param service_init_cb function to call once the service is ready
1691 * @param connect_cb function to call whenever a client connects
1692 * @param disconnect_cb function to call whenever a client disconnects
1693 * @param cls closure argument for @a service_init_cb, @a connect_cb and @a disconnect_cb
1694 * @param handlers NULL-terminated array of message handlers for the service,
1695 * the closure will be set to the value returned by
1696 * the @a connect_cb for the respective connection
1697 * @return 0 on success, non-zero on error
1698 */
1699int
1700GNUNET_SERVICE_ruN_ (int argc,
1701 char *const *argv,
1702 const char *service_name,
1703 enum GNUNET_SERVICE_Options options,
1704 GNUNET_SERVICE_InitCallback service_init_cb,
1705 GNUNET_SERVICE_ConnectHandler connect_cb,
1706 GNUNET_SERVICE_DisconnectHandler disconnect_cb,
1707 void *cls,
1708 const struct GNUNET_MQ_MessageHandler *handlers)
1709{
1710 struct GNUNET_SERVICE_Handle sh;
1711 char *cfg_filename;
1712 char *opt_cfg_filename;
1713 char *loglev;
1714 const char *xdg;
1715 char *logfile;
1716 int do_daemonize;
1717 unsigned long long skew_offset;
1718 unsigned long long skew_variance;
1719 long long clock_offset;
1720 struct GNUNET_CONFIGURATION_Handle *cfg;
1721 int ret;
1722 int err;
1723
1724 struct GNUNET_GETOPT_CommandLineOption service_options[] = {
1725 GNUNET_GETOPT_OPTION_CFG_FILE (&opt_cfg_filename),
1726 {'d', "daemonize", NULL,
1727 gettext_noop ("do daemonize (detach from terminal)"), 0,
1728 GNUNET_GETOPT_set_one, &do_daemonize},
1729 GNUNET_GETOPT_OPTION_HELP (NULL),
1730 GNUNET_GETOPT_OPTION_LOGLEVEL (&loglev),
1731 GNUNET_GETOPT_OPTION_LOGFILE (&logfile),
1732 GNUNET_GETOPT_OPTION_VERSION (PACKAGE_VERSION " " VCS_VERSION),
1733 GNUNET_GETOPT_OPTION_END
1734 };
1735
1736 err = 1;
1737 memset (&sh,
1738 0,
1739 sizeof (sh));
1740 xdg = getenv ("XDG_CONFIG_HOME");
1741 if (NULL != xdg)
1742 GNUNET_asprintf (&cfg_filename,
1743 "%s%s%s",
1744 xdg,
1745 DIR_SEPARATOR_STR,
1746 GNUNET_OS_project_data_get ()->config_file);
1747 else
1748 cfg_filename = GNUNET_strdup (GNUNET_OS_project_data_get ()->user_config_file);
1749 sh.ready_confirm_fd = -1;
1750 sh.options = options;
1751 sh.cfg = cfg = GNUNET_CONFIGURATION_create ();
1752 sh.service_init_cb = service_init_cb;
1753 sh.connect_cb = connect_cb;
1754 sh.disconnect_cb = disconnect_cb;
1755 sh.cb_cls = cls;
1756 sh.handlers = GNUNET_MQ_copy_handlers (handlers);
1757 sh.service_name = service_name;
1758
1759 /* setup subsystems */
1760 loglev = NULL;
1761 logfile = NULL;
1762 opt_cfg_filename = NULL;
1763 do_daemonize = 0;
1764 ret = GNUNET_GETOPT_run (service_name,
1765 service_options,
1766 argc,
1767 argv);
1768 if (GNUNET_SYSERR == ret)
1769 goto shutdown;
1770 if (GNUNET_NO == ret)
1771 {
1772 err = 0;
1773 goto shutdown;
1774 }
1775 if (GNUNET_OK != GNUNET_log_setup (service_name,
1776 loglev,
1777 logfile))
1778 {
1779 GNUNET_break (0);
1780 goto shutdown;
1781 }
1782 if (NULL == opt_cfg_filename)
1783 opt_cfg_filename = GNUNET_strdup (cfg_filename);
1784 if (GNUNET_YES == GNUNET_DISK_file_test (opt_cfg_filename))
1785 {
1786 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg,
1787 opt_cfg_filename))
1788 {
1789 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1790 _("Malformed configuration file `%s', exit ...\n"),
1791 opt_cfg_filename);
1792 goto shutdown;
1793 }
1794 }
1795 else
1796 {
1797 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg,
1798 NULL))
1799 {
1800 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1801 _("Malformed configuration, exit ...\n"));
1802 goto shutdown;
1803 }
1804 if (0 != strcmp (opt_cfg_filename,
1805 cfg_filename))
1806 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1807 _("Could not access configuration file `%s'\n"),
1808 opt_cfg_filename);
1809 }
1810 if (GNUNET_OK != setup_service (&sh))
1811 goto shutdown;
1812 if ( (1 == do_daemonize) &&
1813 (GNUNET_OK != detach_terminal (&sh)) )
1814 {
1815 GNUNET_break (0);
1816 goto shutdown;
1817 }
1818 if (GNUNET_OK != set_user_id (&sh))
1819 goto shutdown;
1820 LOG (GNUNET_ERROR_TYPE_DEBUG,
1821 "Service `%s' runs with configuration from `%s'\n",
1822 service_name,
1823 opt_cfg_filename);
1824 if ((GNUNET_OK ==
1825 GNUNET_CONFIGURATION_get_value_number (sh.cfg,
1826 "TESTING",
1827 "SKEW_OFFSET",
1828 &skew_offset)) &&
1829 (GNUNET_OK ==
1830 GNUNET_CONFIGURATION_get_value_number (sh.cfg,
1831 "TESTING",
1832 "SKEW_VARIANCE",
1833 &skew_variance)))
1834 {
1835 clock_offset = skew_offset - skew_variance;
1836 GNUNET_TIME_set_offset (clock_offset);
1837 LOG (GNUNET_ERROR_TYPE_DEBUG,
1838 "Skewing clock by %dll ms\n",
1839 clock_offset);
1840 }
1841 GNUNET_RESOLVER_connect (sh.cfg);
1842
1843 /* actually run service */
1844 err = 0;
1845 GNUNET_SCHEDULER_run (&service_main,
1846 &sh);
1847 /* shutdown */
1848 if (1 == do_daemonize)
1849 pid_file_delete (&sh);
1850
1851shutdown:
1852 if (-1 != sh.ready_confirm_fd)
1853 {
1854 if (1 != WRITE (sh.ready_confirm_fd,
1855 err ? "I" : "S",
1856 1))
1857 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
1858 "write");
1859 GNUNET_break (0 == CLOSE (sh.ready_confirm_fd));
1860 }
1861#if HAVE_MALLINFO
1862 {
1863 char *counter;
1864
1865 if ( (GNUNET_YES ==
1866 GNUNET_CONFIGURATION_have_value (sh.cfg,
1867 service_name,
1868 "GAUGER_HEAP")) &&
1869 (GNUNET_OK ==
1870 GNUNET_CONFIGURATION_get_value_string (sh.cfg,
1871 service_name,
1872 "GAUGER_HEAP",
1873 &counter)) )
1874 {
1875 struct mallinfo mi;
1876
1877 mi = mallinfo ();
1878 GAUGER (service_name,
1879 counter,
1880 mi.usmblks,
1881 "blocks");
1882 GNUNET_free (counter);
1883 }
1884 }
1885#endif
1886 teardown_service (&sh);
1887 GNUNET_free_non_null (sh.handlers);
1888 GNUNET_SPEEDUP_stop_ ();
1889 GNUNET_CONFIGURATION_destroy (cfg);
1890 GNUNET_free_non_null (logfile);
1891 GNUNET_free_non_null (loglev);
1892 GNUNET_free (cfg_filename);
1893 GNUNET_free_non_null (opt_cfg_filename);
1894
1895 return err ? GNUNET_SYSERR : sh.ret;
1896}
1897
1898
1899/**
1900 * Suspend accepting connections from the listen socket temporarily.
1901 * Resume activity using #GNUNET_SERVICE_resume.
1902 *
1903 * @param sh service to stop accepting connections.
1904 */
1905void
1906GNUNET_SERVICE_suspend (struct GNUNET_SERVICE_Handle *sh)
1907{
1908 struct ServiceListenContext *slc;
1909
1910 for (slc = sh->slc_head; NULL != slc; slc = slc->next)
1911 {
1912 if (NULL != slc->listen_task)
1913 {
1914 GNUNET_SCHEDULER_cancel (slc->listen_task);
1915 slc->listen_task = NULL;
1916 }
1917 }
1918}
1919
1920
1921/**
1922 * Task run when we are ready to transmit data to the
1923 * client.
1924 *
1925 * @param cls the `struct GNUNET_SERVICE_Client *` to send to
1926 */
1927static void
1928do_send (void *cls)
1929{
1930 struct GNUNET_SERVICE_Client *client = cls;
1931 ssize_t ret;
1932 size_t left;
1933 const char *buf;
1934
1935 client->send_task = NULL;
1936 buf = (const char *) client->msg;
1937 left = ntohs (client->msg->size) - client->msg_pos;
1938 ret = GNUNET_NETWORK_socket_send (client->sock,
1939 &buf[client->msg_pos],
1940 left);
1941 GNUNET_assert (ret <= (ssize_t) left);
1942 if (0 == ret)
1943 {
1944 GNUNET_MQ_inject_error (client->mq,
1945 GNUNET_MQ_ERROR_WRITE);
1946 return;
1947 }
1948 if (-1 == ret)
1949 {
1950 if ( (EAGAIN == errno) ||
1951 (EINTR == errno) )
1952 {
1953 /* ignore */
1954 ret = 0;
1955 }
1956 else
1957 {
1958 if (EPIPE != errno)
1959 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1960 "send");
1961 GNUNET_MQ_inject_error (client->mq,
1962 GNUNET_MQ_ERROR_WRITE);
1963 return;
1964 }
1965 }
1966 if (0 == client->msg_pos)
1967 {
1968 GNUNET_MQ_impl_send_in_flight (client->mq);
1969 }
1970 client->msg_pos += ret;
1971 if (left > ret)
1972 {
1973 GNUNET_assert (NULL == client->drop_task);
1974 client->send_task
1975 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1976 client->sock,
1977 &do_send,
1978 client);
1979 return;
1980 }
1981 GNUNET_MQ_impl_send_continue (client->mq);
1982}
1983
1984
1985/**
1986 * Signature of functions implementing the sending functionality of a
1987 * message queue.
1988 *
1989 * @param mq the message queue
1990 * @param msg the message to send
1991 * @param impl_state our `struct GNUNET_SERVICE_Client *`
1992 */
1993static void
1994service_mq_send (struct GNUNET_MQ_Handle *mq,
1995 const struct GNUNET_MessageHeader *msg,
1996 void *impl_state)
1997{
1998 struct GNUNET_SERVICE_Client *client = impl_state;
1999
2000 if (NULL != client->drop_task)
2001 return; /* we're going down right now, do not try to send */
2002 GNUNET_assert (NULL == client->send_task);
2003 LOG (GNUNET_ERROR_TYPE_DEBUG,
2004 "Sending message of type %u and size %u to client\n",
2005 ntohs (msg->type),
2006 ntohs (msg->size));
2007 client->msg = msg;
2008 client->msg_pos = 0;
2009 client->send_task
2010 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
2011 client->sock,
2012 &do_send,
2013 client);
2014}
2015
2016
2017/**
2018 * Implementation function that cancels the currently sent message.
2019 *
2020 * @param mq message queue
2021 * @param impl_state state specific to the implementation
2022 */
2023static void
2024service_mq_cancel (struct GNUNET_MQ_Handle *mq,
2025 void *impl_state)
2026{
2027 struct GNUNET_SERVICE_Client *client = impl_state;
2028
2029 GNUNET_assert (0 == client->msg_pos);
2030 client->msg = NULL;
2031 GNUNET_SCHEDULER_cancel (client->send_task);
2032 client->send_task = NULL;
2033}
2034
2035
2036/**
2037 * Generic error handler, called with the appropriate
2038 * error code and the same closure specified at the creation of
2039 * the message queue.
2040 * Not every message queue implementation supports an error handler.
2041 *
2042 * @param cls closure with our `struct GNUNET_SERVICE_Client`
2043 * @param error error code
2044 */
2045static void
2046service_mq_error_handler (void *cls,
2047 enum GNUNET_MQ_Error error)
2048{
2049 struct GNUNET_SERVICE_Client *client = cls;
2050 struct GNUNET_SERVICE_Handle *sh = client->sh;
2051
2052 if ( (GNUNET_MQ_ERROR_NO_MATCH == error) &&
2053 (GNUNET_NO == sh->require_found) )
2054 {
2055 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2056 "No handler for message of type %u found\n",
2057 (unsigned int) client->warn_type);
2058 GNUNET_SERVICE_client_continue (client);
2059 return; /* ignore error */
2060 }
2061 GNUNET_SERVICE_client_drop (client);
2062}
2063
2064
2065/**
2066 * Task run to warn about missing calls to #GNUNET_SERVICE_client_continue().
2067 *
2068 * @param cls our `struct GNUNET_SERVICE_Client *` to process more requests from
2069 */
2070static void
2071warn_no_client_continue (void *cls)
2072{
2073 struct GNUNET_SERVICE_Client *client = cls;
2074
2075 GNUNET_break (0 != client->warn_type); /* type should never be 0 here, as we don't use 0 */
2076 client->warn_task
2077 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
2078 &warn_no_client_continue,
2079 client);
2080 LOG (GNUNET_ERROR_TYPE_WARNING,
2081 _("Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"),
2082 (unsigned int) client->warn_type,
2083 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (client->warn_start),
2084 GNUNET_YES));
2085}
2086
2087
2088/**
2089 * Functions with this signature are called whenever a
2090 * complete message is received by the tokenizer for a client.
2091 *
2092 * Do not call #GNUNET_MST_destroy() from within
2093 * the scope of this callback.
2094 *
2095 * @param cls closure with the `struct GNUNET_SERVICE_Client *`
2096 * @param message the actual message
2097 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the client was dropped
2098 */
2099static int
2100service_client_mst_cb (void *cls,
2101 const struct GNUNET_MessageHeader *message)
2102{
2103 struct GNUNET_SERVICE_Client *client = cls;
2104
2105 LOG (GNUNET_ERROR_TYPE_DEBUG,
2106 "Received message of type %u and size %u from client\n",
2107 ntohs (message->type),
2108 ntohs (message->size));
2109 GNUNET_assert (GNUNET_NO == client->needs_continue);
2110 client->needs_continue = GNUNET_YES;
2111 client->warn_type = ntohs (message->type);
2112 client->warn_start = GNUNET_TIME_absolute_get ();
2113 GNUNET_assert (NULL == client->warn_task);
2114 client->warn_task
2115 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
2116 &warn_no_client_continue,
2117 client);
2118 GNUNET_MQ_inject_message (client->mq,
2119 message);
2120 if (NULL != client->drop_task)
2121 return GNUNET_SYSERR;
2122 return GNUNET_OK;
2123}
2124
2125
2126/**
2127 * A client sent us data. Receive and process it. If we are done,
2128 * reschedule this task.
2129 *
2130 * @param cls the `struct GNUNET_SERVICE_Client` that sent us data.
2131 */
2132static void
2133service_client_recv (void *cls)
2134{
2135 struct GNUNET_SERVICE_Client *client = cls;
2136 int ret;
2137
2138 client->recv_task = NULL;
2139 ret = GNUNET_MST_read (client->mst,
2140 client->sock,
2141 GNUNET_NO,
2142 GNUNET_YES);
2143 if (GNUNET_SYSERR == ret)
2144 {
2145 /* client closed connection (or IO error) */
2146 if (NULL == client->drop_task)
2147 {
2148 GNUNET_assert (GNUNET_NO == client->needs_continue);
2149 GNUNET_SERVICE_client_drop (client);
2150 }
2151 return;
2152 }
2153 if (GNUNET_NO == ret)
2154 return; /* more messages in buffer, wait for application
2155 to be done processing */
2156 GNUNET_assert (GNUNET_OK == ret);
2157 if (GNUNET_YES == client->needs_continue)
2158 return;
2159 if (NULL != client->recv_task)
2160 return;
2161 /* MST needs more data, re-schedule read job */
2162 client->recv_task
2163 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2164 client->sock,
2165 &service_client_recv,
2166 client);
2167}
2168
2169
2170/**
2171 * We have successfully accepted a connection from a client. Now
2172 * setup the client (with the scheduler) and tell the application.
2173 *
2174 * @param sh service that accepted the client
2175 * @param sock socket associated with the client
2176 */
2177static void
2178start_client (struct GNUNET_SERVICE_Handle *sh,
2179 struct GNUNET_NETWORK_Handle *csock)
2180{
2181 struct GNUNET_SERVICE_Client *client;
2182
2183 client = GNUNET_new (struct GNUNET_SERVICE_Client);
2184 GNUNET_CONTAINER_DLL_insert (sh->clients_head,
2185 sh->clients_tail,
2186 client);
2187 client->sh = sh;
2188 client->sock = csock;
2189 client->mq = GNUNET_MQ_queue_for_callbacks (&service_mq_send,
2190 NULL,
2191 &service_mq_cancel,
2192 client,
2193 sh->handlers,
2194 &service_mq_error_handler,
2195 client);
2196 client->mst = GNUNET_MST_create (&service_client_mst_cb,
2197 client);
2198 if (NULL != sh->connect_cb)
2199 client->user_context = sh->connect_cb (sh->cb_cls,
2200 client,
2201 client->mq);
2202 GNUNET_MQ_set_handlers_closure (client->mq,
2203 client->user_context);
2204 client->recv_task
2205 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2206 client->sock,
2207 &service_client_recv,
2208 client);
2209}
2210
2211
2212/**
2213 * Check if the given IP address is in the list of IP addresses.
2214 *
2215 * @param list a list of networks
2216 * @param add the IP to check (in network byte order)
2217 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
2218 */
2219static int
2220check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list,
2221 const struct in_addr *add)
2222{
2223 unsigned int i;
2224
2225 if (NULL == list)
2226 return GNUNET_NO;
2227 i = 0;
2228 while ( (0 != list[i].network.s_addr) ||
2229 (0 != list[i].netmask.s_addr) )
2230 {
2231 if ((add->s_addr & list[i].netmask.s_addr) ==
2232 (list[i].network.s_addr & list[i].netmask.s_addr))
2233 return GNUNET_YES;
2234 i++;
2235 }
2236 return GNUNET_NO;
2237}
2238
2239
2240/**
2241 * Check if the given IP address is in the list of IP addresses.
2242 *
2243 * @param list a list of networks
2244 * @param ip the IP to check (in network byte order)
2245 * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
2246 */
2247static int
2248check_ipv6_listed (const struct GNUNET_STRINGS_IPv6NetworkPolicy *list,
2249 const struct in6_addr *ip)
2250{
2251 unsigned int i;
2252 unsigned int j;
2253 struct in6_addr zero;
2254
2255 if (NULL == list)
2256 return GNUNET_NO;
2257 memset (&zero,
2258 0,
2259 sizeof (struct in6_addr));
2260 i = 0;
2261NEXT:
2262 while (0 != memcmp (&zero,
2263 &list[i].network,
2264 sizeof (struct in6_addr)))
2265 {
2266 for (j = 0; j < sizeof (struct in6_addr) / sizeof (int); j++)
2267 if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
2268 (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
2269 {
2270 i++;
2271 goto NEXT;
2272 }
2273 return GNUNET_YES;
2274 }
2275 return GNUNET_NO;
2276}
2277
2278
2279/**
2280 * We have a client. Accept the incoming socket(s) (and reschedule
2281 * the listen task).
2282 *
2283 * @param cls the `struct ServiceListenContext` of the ready listen socket
2284 */
2285static void
2286accept_client (void *cls)
2287{
2288 struct ServiceListenContext *slc = cls;
2289 struct GNUNET_SERVICE_Handle *sh = slc->sh;
2290
2291 slc->listen_task = NULL;
2292 while (1)
2293 {
2294 struct GNUNET_NETWORK_Handle *sock;
2295 const struct sockaddr_in *v4;
2296 const struct sockaddr_in6 *v6;
2297 struct sockaddr_storage sa;
2298 socklen_t addrlen;
2299 int ok;
2300
2301 addrlen = sizeof (sa);
2302 sock = GNUNET_NETWORK_socket_accept (slc->listen_socket,
2303 (struct sockaddr *) &sa,
2304 &addrlen);
2305 if (NULL == sock)
2306 break;
2307 switch (sa.ss_family)
2308 {
2309 case AF_INET:
2310 GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
2311 v4 = (const struct sockaddr_in *) &sa;
2312 ok = ( ( (NULL == sh->v4_allowed) ||
2313 (check_ipv4_listed (sh->v4_allowed,
2314 &v4->sin_addr))) &&
2315 ( (NULL == sh->v4_denied) ||
2316 (! check_ipv4_listed (sh->v4_denied,
2317 &v4->sin_addr)) ) );
2318 break;
2319 case AF_INET6:
2320 GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
2321 v6 = (const struct sockaddr_in6 *) &sa;
2322 ok = ( ( (NULL == sh->v6_allowed) ||
2323 (check_ipv6_listed (sh->v6_allowed,
2324 &v6->sin6_addr))) &&
2325 ( (NULL == sh->v6_denied) ||
2326 (! check_ipv6_listed (sh->v6_denied,
2327 &v6->sin6_addr)) ) );
2328 break;
2329#ifndef WINDOWS
2330 case AF_UNIX:
2331 ok = GNUNET_OK; /* controlled using file-system ACL now */
2332 break;
2333#endif
2334 default:
2335 LOG (GNUNET_ERROR_TYPE_WARNING,
2336 _("Unknown address family %d\n"),
2337 sa.ss_family);
2338 return;
2339 }
2340 if (! ok)
2341 {
2342 LOG (GNUNET_ERROR_TYPE_DEBUG,
2343 "Service rejected incoming connection from %s due to policy.\n",
2344 GNUNET_a2s ((const struct sockaddr *) &sa,
2345 addrlen));
2346 GNUNET_break (GNUNET_OK ==
2347 GNUNET_NETWORK_socket_close (sock));
2348 continue;
2349 }
2350 LOG (GNUNET_ERROR_TYPE_DEBUG,
2351 "Service accepted incoming connection from %s.\n",
2352 GNUNET_a2s ((const struct sockaddr *) &sa,
2353 addrlen));
2354 start_client (slc->sh,
2355 sock);
2356 }
2357 slc->listen_task
2358 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2359 slc->listen_socket,
2360 &accept_client,
2361 slc);
2362}
2363
2364
2365/**
2366 * Resume accepting connections from the listen socket.
2367 *
2368 * @param sh service to resume accepting connections.
2369 */
2370void
2371GNUNET_SERVICE_resume (struct GNUNET_SERVICE_Handle *sh)
2372{
2373 struct ServiceListenContext *slc;
2374
2375 for (slc = sh->slc_head; NULL != slc; slc = slc->next)
2376 {
2377 GNUNET_assert (NULL == slc->listen_task);
2378 slc->listen_task
2379 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2380 slc->listen_socket,
2381 &accept_client,
2382 slc);
2383 }
2384}
2385
2386
2387/**
2388 * Task run to resume receiving data from the client after
2389 * the client called #GNUNET_SERVICE_client_continue().
2390 *
2391 * @param cls our `struct GNUNET_SERVICE_Client`
2392 */
2393static void
2394resume_client_receive (void *cls)
2395{
2396 struct GNUNET_SERVICE_Client *c = cls;
2397 int ret;
2398
2399 c->recv_task = NULL;
2400 /* first, check if there is still something in the buffer */
2401 ret = GNUNET_MST_next (c->mst,
2402 GNUNET_YES);
2403 if (GNUNET_SYSERR == ret)
2404 {
2405 if (NULL != c->drop_task)
2406 GNUNET_SERVICE_client_drop (c);
2407 return;
2408 }
2409 if (GNUNET_NO == ret)
2410 return; /* done processing, wait for more later */
2411 GNUNET_assert (GNUNET_OK == ret);
2412 if (GNUNET_YES == c->needs_continue)
2413 return; /* #GNUNET_MST_next() did give a message to the client */
2414 /* need to receive more data from the network first */
2415 if (NULL != c->recv_task)
2416 return;
2417 c->recv_task
2418 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2419 c->sock,
2420 &service_client_recv,
2421 c);
2422}
2423
2424
2425/**
2426 * Continue receiving further messages from the given client.
2427 * Must be called after each message received.
2428 *
2429 * @param c the client to continue receiving from
2430 */
2431void
2432GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c)
2433{
2434 GNUNET_assert (GNUNET_YES == c->needs_continue);
2435 GNUNET_assert (NULL == c->recv_task);
2436 c->needs_continue = GNUNET_NO;
2437 if (NULL != c->warn_task)
2438 {
2439 GNUNET_SCHEDULER_cancel (c->warn_task);
2440 c->warn_task = NULL;
2441 }
2442 c->recv_task
2443 = GNUNET_SCHEDULER_add_now (&resume_client_receive,
2444 c);
2445}
2446
2447
2448/**
2449 * Disable the warning the server issues if a message is not
2450 * acknowledged in a timely fashion. Use this call if a client is
2451 * intentionally delayed for a while. Only applies to the current
2452 * message.
2453 *
2454 * @param c client for which to disable the warning
2455 */
2456void
2457GNUNET_SERVICE_client_disable_continue_warning (struct GNUNET_SERVICE_Client *c)
2458{
2459 GNUNET_break (NULL != c->warn_task);
2460 if (NULL != c->warn_task)
2461 {
2462 GNUNET_SCHEDULER_cancel (c->warn_task);
2463 c->warn_task = NULL;
2464 }
2465}
2466
2467
2468/**
2469 * Asynchronously finish dropping the client.
2470 *
2471 * @param cls the `struct GNUNET_SERVICE_Client`.
2472 */
2473static void
2474finish_client_drop (void *cls)
2475{
2476 struct GNUNET_SERVICE_Client *c = cls;
2477 struct GNUNET_SERVICE_Handle *sh = c->sh;
2478
2479 c->drop_task = NULL;
2480 GNUNET_assert (NULL == c->send_task);
2481 GNUNET_assert (NULL == c->recv_task);
2482 GNUNET_assert (NULL == c->warn_task);
2483 GNUNET_MST_destroy (c->mst);
2484 GNUNET_MQ_destroy (c->mq);
2485 if (GNUNET_NO == c->persist)
2486 {
2487 GNUNET_break (GNUNET_OK ==
2488 GNUNET_NETWORK_socket_close (c->sock));
2489 }
2490 else
2491 {
2492 GNUNET_NETWORK_socket_free_memory_only_ (c->sock);
2493 }
2494 GNUNET_free (c);
2495 if ( (GNUNET_YES == sh->got_shutdown) &&
2496 (GNUNET_NO == have_non_monitor_clients (sh)) )
2497 GNUNET_SERVICE_shutdown (sh);
2498}
2499
2500
2501/**
2502 * Ask the server to disconnect from the given client. This is the
2503 * same as returning #GNUNET_SYSERR within the check procedure when
2504 * handling a message, wexcept that it allows dropping of a client even
2505 * when not handling a message from that client. The `disconnect_cb`
2506 * will be called on @a c even if the application closes the connection
2507 * using this function.
2508 *
2509 * @param c client to disconnect now
2510 */
2511void
2512GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c)
2513{
2514 struct GNUNET_SERVICE_Handle *sh = c->sh;
2515
2516 if (NULL != c->drop_task)
2517 {
2518 /* asked to drop twice! */
2519 GNUNET_assert (0);
2520 return;
2521 }
2522 GNUNET_CONTAINER_DLL_remove (sh->clients_head,
2523 sh->clients_tail,
2524 c);
2525 if (NULL != sh->disconnect_cb)
2526 sh->disconnect_cb (sh->cb_cls,
2527 c,
2528 c->user_context);
2529 if (NULL != c->warn_task)
2530 {
2531 GNUNET_SCHEDULER_cancel (c->warn_task);
2532 c->warn_task = NULL;
2533 }
2534 if (NULL != c->recv_task)
2535 {
2536 GNUNET_SCHEDULER_cancel (c->recv_task);
2537 c->recv_task = NULL;
2538 }
2539 if (NULL != c->send_task)
2540 {
2541 GNUNET_SCHEDULER_cancel (c->send_task);
2542 c->send_task = NULL;
2543 }
2544 c->drop_task = GNUNET_SCHEDULER_add_now (&finish_client_drop,
2545 c);
2546}
2547
2548
2549/**
2550 * Explicitly stops the service.
2551 *
2552 * @param sh server to shutdown
2553 */
2554void
2555GNUNET_SERVICE_shutdown (struct GNUNET_SERVICE_Handle *sh)
2556{
2557 struct GNUNET_SERVICE_Client *client;
2558
2559 GNUNET_SERVICE_suspend (sh);
2560 sh->got_shutdown = GNUNET_NO;
2561 while (NULL != (client = sh->clients_head))
2562 GNUNET_SERVICE_client_drop (client);
2563}
2564
2565
2566/**
2567 * Set the 'monitor' flag on this client. Clients which have been
2568 * marked as 'monitors' won't prevent the server from shutting down
2569 * once #GNUNET_SERVICE_stop_listening() has been invoked. The idea is
2570 * that for "normal" clients we likely want to allow them to process
2571 * their requests; however, monitor-clients are likely to 'never'
2572 * disconnect during shutdown and thus will not be considered when
2573 * determining if the server should continue to exist after
2574 * shutdown has been triggered.
2575 *
2576 * @param c client to mark as a monitor
2577 */
2578void
2579GNUNET_SERVICE_client_mark_monitor (struct GNUNET_SERVICE_Client *c)
2580{
2581 c->is_monitor = GNUNET_YES;
2582 if ( (GNUNET_YES == c->sh->got_shutdown) &&
2583 (GNUNET_NO == have_non_monitor_clients (c->sh)) )
2584 GNUNET_SERVICE_shutdown (c->sh);
2585}
2586
2587
2588/**
2589 * Set the persist option on this client. Indicates that the
2590 * underlying socket or fd should never really be closed. Used for
2591 * indicating process death.
2592 *
2593 * @param c client to persist the socket (never to be closed)
2594 */
2595void
2596GNUNET_SERVICE_client_persist (struct GNUNET_SERVICE_Client *c)
2597{
2598 c->persist = GNUNET_YES;
2599}
2600
2601
2602/**
2603 * Obtain the message queue of @a c. Convenience function.
2604 *
2605 * @param c the client to continue receiving from
2606 * @return the message queue of @a c
2607 */
2608struct GNUNET_MQ_Handle *
2609GNUNET_SERVICE_client_get_mq (struct GNUNET_SERVICE_Client *c)
2610{
2611 return c->mq;
2612}
2613
2614
2615/* end of service_new.c */
diff --git a/src/util/test_client.c b/src/util/test_client.c
index f60e5b7f7..527b400b0 100644
--- a/src/util/test_client.c
+++ b/src/util/test_client.c
@@ -179,7 +179,7 @@ main (int argc,
179 test_argv[2] = "test_client_unix.conf"; 179 test_argv[2] = "test_client_unix.conf";
180 global_ret = 1; 180 global_ret = 1;
181 if (0 != 181 if (0 !=
182 GNUNET_SERVICE_ruN_ (3, 182 GNUNET_SERVICE_run_ (3,
183 test_argv, 183 test_argv,
184 "test_client", 184 "test_client",
185 GNUNET_SERVICE_OPTION_NONE, 185 GNUNET_SERVICE_OPTION_NONE,
diff --git a/src/util/test_connection.c b/src/util/test_connection.c
deleted file mode 100644
index eaca75c2e..000000000
--- a/src/util/test_connection.c
+++ /dev/null
@@ -1,167 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file util/test_connection.c
22 * @brief tests for connection.c
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26
27#define PORT 12435
28
29
30static struct GNUNET_CONNECTION_Handle *csock;
31
32static struct GNUNET_CONNECTION_Handle *asock;
33
34static struct GNUNET_CONNECTION_Handle *lsock;
35
36static size_t sofar;
37
38static struct GNUNET_NETWORK_Handle *ls;
39
40static struct GNUNET_CONFIGURATION_Handle *cfg;
41
42/**
43 * Create and initialize a listen socket for the server.
44 *
45 * @return -1 on error, otherwise the listen socket
46 */
47static struct GNUNET_NETWORK_Handle *
48open_listen_socket ()
49{
50 const static int on = 1;
51 struct sockaddr_in sa;
52 struct GNUNET_NETWORK_Handle *desc;
53
54 memset (&sa, 0, sizeof (sa));
55#if HAVE_SOCKADDR_IN_SIN_LEN
56 sa.sin_len = sizeof (sa);
57#endif
58 sa.sin_port = htons (PORT);
59 sa.sin_family = AF_INET;
60 desc = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
61 GNUNET_assert (desc != NULL);
62 if (GNUNET_NETWORK_socket_setsockopt
63 (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
64 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "setsockopt");
65 GNUNET_assert (GNUNET_OK ==
66 GNUNET_NETWORK_socket_bind (desc, (const struct sockaddr *) &sa,
67 sizeof (sa)));
68 GNUNET_NETWORK_socket_listen (desc, 5);
69 return desc;
70}
71
72static void
73receive_check (void *cls, const void *buf, size_t available,
74 const struct sockaddr *addr, socklen_t addrlen, int errCode)
75{
76 int *ok = cls;
77
78 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receive validates incoming data\n");
79 GNUNET_assert (buf != NULL); /* no timeout */
80 if (0 == memcmp (&"Hello World"[sofar], buf, available))
81 sofar += available;
82 if (sofar < 12)
83 {
84 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receive needs more data\n");
85 GNUNET_CONNECTION_receive (asock, 1024,
86 GNUNET_TIME_relative_multiply
87 (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check,
88 cls);
89 }
90 else
91 {
92 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receive closes accepted socket\n");
93 *ok = 0;
94 GNUNET_CONNECTION_destroy (asock);
95 GNUNET_CONNECTION_destroy (csock);
96 }
97}
98
99
100static void
101run_accept (void *cls)
102{
103 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test accepts connection\n");
104 asock = GNUNET_CONNECTION_create_from_accept (NULL, NULL, ls);
105 GNUNET_assert (asock != NULL);
106 GNUNET_assert (GNUNET_YES == GNUNET_CONNECTION_check (asock));
107 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test destroys listen socket\n");
108 GNUNET_CONNECTION_destroy (lsock);
109 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
110 "Test asks to receive on accepted socket\n");
111 GNUNET_CONNECTION_receive (asock, 1024,
112 GNUNET_TIME_relative_multiply
113 (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check,
114 cls);
115}
116
117
118static size_t
119make_hello (void *cls, size_t size, void *buf)
120{
121 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
122 "Test prepares to transmit on connect socket\n");
123 GNUNET_assert (size >= 12);
124 strcpy ((char *) buf, "Hello World");
125 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test destroys client socket\n");
126 return 12;
127}
128
129
130static void
131task (void *cls)
132{
133 ls = open_listen_socket ();
134 lsock = GNUNET_CONNECTION_create_from_existing (ls);
135 GNUNET_assert (lsock != NULL);
136 csock = GNUNET_CONNECTION_create_from_connect (cfg, "localhost", PORT);
137 GNUNET_assert (csock != NULL);
138 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test asks for write notification\n");
139 GNUNET_assert (NULL !=
140 GNUNET_CONNECTION_notify_transmit_ready (csock, 12,
141 GNUNET_TIME_UNIT_SECONDS,
142 &make_hello, NULL));
143 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test prepares to accept\n");
144 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, ls, &run_accept,
145 cls);
146}
147
148
149int
150main (int argc, char *argv[])
151{
152 int ok;
153
154 GNUNET_log_setup ("test_connection",
155 "WARNING",
156 NULL);
157
158 ok = 1;
159 cfg = GNUNET_CONFIGURATION_create ();
160 GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME",
161 "localhost");
162 GNUNET_SCHEDULER_run (&task, &ok);
163 GNUNET_CONFIGURATION_destroy (cfg);
164 return ok;
165}
166
167/* end of test_connection.c */
diff --git a/src/util/test_connection_addressing.c b/src/util/test_connection_addressing.c
deleted file mode 100644
index a6345b10a..000000000
--- a/src/util/test_connection_addressing.c
+++ /dev/null
@@ -1,186 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file util/test_connection_addressing.c
22 * @brief tests for connection.c
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26
27
28#define PORT 12435
29
30
31static struct GNUNET_CONNECTION_Handle *csock;
32
33static struct GNUNET_CONNECTION_Handle *asock;
34
35static struct GNUNET_CONNECTION_Handle *lsock;
36
37static size_t sofar;
38
39static struct GNUNET_NETWORK_Handle *ls;
40
41
42
43/**
44 * Create and initialize a listen socket for the server.
45 *
46 * @return NULL on error, otherwise the listen socket
47 */
48static struct GNUNET_NETWORK_Handle *
49open_listen_socket ()
50{
51 const static int on = 1;
52 struct sockaddr_in sa;
53 struct GNUNET_NETWORK_Handle *desc;
54
55 memset (&sa, 0, sizeof (sa));
56#if HAVE_SOCKADDR_IN_SIN_LEN
57 sa.sin_len = sizeof (sa);
58#endif
59 sa.sin_family = AF_INET;
60 sa.sin_port = htons (PORT);
61 desc = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
62 GNUNET_assert (desc != 0);
63 if (GNUNET_NETWORK_socket_setsockopt
64 (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
65 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "setsockopt");
66 if (GNUNET_OK !=
67 GNUNET_NETWORK_socket_bind (desc, (const struct sockaddr *) &sa,
68 sizeof (sa)))
69 {
70 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
71 "bind");
72 GNUNET_assert (0);
73 }
74 GNUNET_NETWORK_socket_listen (desc, 5);
75 return desc;
76}
77
78
79static void
80receive_check (void *cls, const void *buf, size_t available,
81 const struct sockaddr *addr, socklen_t addrlen, int errCode)
82{
83 int *ok = cls;
84
85 GNUNET_assert (buf != NULL); /* no timeout */
86 if (0 == memcmp (&"Hello World"[sofar], buf, available))
87 sofar += available;
88 if (sofar < 12)
89 {
90 GNUNET_CONNECTION_receive (asock, 1024,
91 GNUNET_TIME_relative_multiply
92 (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check,
93 cls);
94 }
95 else
96 {
97 *ok = 0;
98 GNUNET_CONNECTION_destroy (csock);
99 GNUNET_CONNECTION_destroy (asock);
100 }
101}
102
103
104static void
105run_accept (void *cls)
106{
107 void *addr;
108 size_t alen;
109 struct sockaddr_in *v4;
110 struct sockaddr_in expect;
111
112 asock = GNUNET_CONNECTION_create_from_accept (NULL, NULL, ls);
113 GNUNET_assert (asock != NULL);
114 GNUNET_assert (GNUNET_YES == GNUNET_CONNECTION_check (asock));
115 GNUNET_assert (GNUNET_OK ==
116 GNUNET_CONNECTION_get_address (asock, &addr, &alen));
117 GNUNET_assert (alen == sizeof (struct sockaddr_in));
118 v4 = addr;
119 memset (&expect, 0, sizeof (expect));
120#if HAVE_SOCKADDR_IN_SIN_LEN
121 expect.sin_len = sizeof (expect);
122#endif
123 expect.sin_family = AF_INET;
124 expect.sin_port = v4->sin_port;
125 expect.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
126 GNUNET_assert (0 == memcmp (&expect, v4, alen));
127 GNUNET_free (addr);
128 GNUNET_CONNECTION_destroy (lsock);
129 GNUNET_CONNECTION_receive (asock, 1024,
130 GNUNET_TIME_relative_multiply
131 (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check,
132 cls);
133}
134
135static size_t
136make_hello (void *cls, size_t size, void *buf)
137{
138 GNUNET_assert (size >= 12);
139 strcpy ((char *) buf, "Hello World");
140 return 12;
141}
142
143
144static void
145task (void *cls)
146{
147 struct sockaddr_in v4;
148
149 ls = open_listen_socket ();
150 lsock = GNUNET_CONNECTION_create_from_existing (ls);
151 GNUNET_assert (lsock != NULL);
152
153#if HAVE_SOCKADDR_IN_SIN_LEN
154 v4.sin_len = sizeof (v4);
155#endif
156 v4.sin_family = AF_INET;
157 v4.sin_port = htons (PORT);
158 v4.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
159 csock =
160 GNUNET_CONNECTION_create_from_sockaddr (AF_INET,
161 (const struct sockaddr *) &v4,
162 sizeof (v4));
163 GNUNET_assert (csock != NULL);
164 GNUNET_assert (NULL !=
165 GNUNET_CONNECTION_notify_transmit_ready (csock, 12,
166 GNUNET_TIME_UNIT_SECONDS,
167 &make_hello, NULL));
168 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, ls, &run_accept,
169 cls);
170}
171
172
173int
174main (int argc, char *argv[])
175{
176 int ok;
177
178 GNUNET_log_setup ("test_connection_addressing",
179 "WARNING",
180 NULL);
181 ok = 1;
182 GNUNET_SCHEDULER_run (&task, &ok);
183 return ok;
184}
185
186/* end of test_connection_addressing.c */
diff --git a/src/util/test_connection_receive_cancel.c b/src/util/test_connection_receive_cancel.c
deleted file mode 100644
index 9c0ab699e..000000000
--- a/src/util/test_connection_receive_cancel.c
+++ /dev/null
@@ -1,160 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file util/test_connection_receive_cancel.c
22 * @brief tests for connection.c
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26
27#define PORT 12435
28
29
30static struct GNUNET_CONNECTION_Handle *csock;
31
32static struct GNUNET_CONNECTION_Handle *asock;
33
34static struct GNUNET_CONNECTION_Handle *lsock;
35
36static struct GNUNET_NETWORK_Handle *ls;
37
38static struct GNUNET_CONFIGURATION_Handle *cfg;
39
40
41/**
42 * Create and initialize a listen socket for the server.
43 *
44 * @return NULL on error, otherwise the listen socket
45 */
46static struct GNUNET_NETWORK_Handle *
47open_listen_socket ()
48{
49 const static int on = 1;
50 struct sockaddr_in sa;
51 struct GNUNET_NETWORK_Handle *desc;
52
53 memset (&sa, 0, sizeof (sa));
54#if HAVE_SOCKADDR_IN_SIN_LEN
55 sa.sin_len = sizeof (sa);
56#endif
57 sa.sin_family = AF_INET;
58 sa.sin_port = htons (PORT);
59 desc = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
60 GNUNET_assert (desc != NULL);
61 if (GNUNET_NETWORK_socket_setsockopt
62 (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
63 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
64 "setsockopt");
65 GNUNET_assert (GNUNET_OK ==
66 GNUNET_NETWORK_socket_bind (desc, (const struct sockaddr *) &sa,
67 sizeof (sa)));
68 GNUNET_NETWORK_socket_listen (desc, 5);
69 return desc;
70}
71
72
73static void
74dead_receive (void *cls,
75 const void *buf,
76 size_t available,
77 const struct sockaddr *addr,
78 socklen_t addrlen,
79 int errCode)
80{
81 GNUNET_assert (0);
82}
83
84
85static void
86run_accept_cancel (void *cls)
87{
88 asock = GNUNET_CONNECTION_create_from_accept (NULL, NULL, ls);
89 GNUNET_assert (asock != NULL);
90 GNUNET_assert (GNUNET_YES == GNUNET_CONNECTION_check (asock));
91 GNUNET_CONNECTION_destroy (lsock);
92 GNUNET_CONNECTION_receive (asock, 1024,
93 GNUNET_TIME_relative_multiply
94 (GNUNET_TIME_UNIT_SECONDS, 5),
95 &dead_receive, cls);
96}
97
98
99static void
100receive_cancel_task (void *cls)
101{
102 int *ok = cls;
103
104 GNUNET_CONNECTION_receive_cancel (asock);
105 GNUNET_CONNECTION_destroy (csock);
106 GNUNET_CONNECTION_destroy (asock);
107 *ok = 0;
108}
109
110
111static void
112task_receive_cancel (void *cls)
113{
114 ls = open_listen_socket ();
115 lsock = GNUNET_CONNECTION_create_from_existing (ls);
116 GNUNET_assert (lsock != NULL);
117 csock = GNUNET_CONNECTION_create_from_connect (cfg, "localhost", PORT);
118 GNUNET_assert (csock != NULL);
119 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
120 ls,
121 &run_accept_cancel,
122 cls);
123 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
124 &receive_cancel_task,
125 cls);
126}
127
128
129/**
130 * Main method, starts scheduler with task_timeout.
131 */
132static int
133check_receive_cancel ()
134{
135 int ok;
136
137 ok = 1;
138 cfg = GNUNET_CONFIGURATION_create ();
139 GNUNET_CONFIGURATION_set_value_string (cfg,
140 "resolver",
141 "HOSTNAME",
142 "localhost");
143 GNUNET_SCHEDULER_run (&task_receive_cancel, &ok);
144 GNUNET_CONFIGURATION_destroy (cfg);
145 return ok;
146}
147
148
149int
150main (int argc, char *argv[])
151{
152 int ret = 0;
153
154 GNUNET_log_setup ("test_connection_receive_cancel", "WARNING", NULL);
155 ret += check_receive_cancel ();
156
157 return ret;
158}
159
160/* end of test_connection_receive_cancel.c */
diff --git a/src/util/test_connection_timeout.c b/src/util/test_connection_timeout.c
deleted file mode 100644
index e78cec669..000000000
--- a/src/util/test_connection_timeout.c
+++ /dev/null
@@ -1,129 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file util/test_connection_timeout.c
22 * @brief tests for connection.c
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26
27#define PORT 12435
28
29static struct GNUNET_CONNECTION_Handle *csock;
30
31static struct GNUNET_CONNECTION_Handle *lsock;
32
33static struct GNUNET_NETWORK_Handle *ls;
34
35static struct GNUNET_CONFIGURATION_Handle *cfg;
36
37
38/**
39 * Create and initialize a listen socket for the server.
40 *
41 * @return NULL on error, otherwise the listen socket
42 */
43static struct GNUNET_NETWORK_Handle *
44open_listen_socket ()
45{
46 const static int on = 1;
47 struct sockaddr_in sa;
48 struct GNUNET_NETWORK_Handle *desc;
49
50 memset (&sa, 0, sizeof (sa));
51#if HAVE_SOCKADDR_IN_SIN_LEN
52 sa.sin_len = sizeof (sa);
53#endif
54 sa.sin_family = AF_INET;
55 sa.sin_port = htons (PORT);
56 desc = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
57 GNUNET_assert (desc != NULL);
58 if (GNUNET_NETWORK_socket_setsockopt
59 (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
60 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "setsockopt");
61 GNUNET_assert (GNUNET_OK ==
62 GNUNET_NETWORK_socket_bind (desc, (const struct sockaddr *) &sa,
63 sizeof (sa)));
64 GNUNET_NETWORK_socket_listen (desc, 5);
65 return desc;
66}
67
68
69static size_t
70send_kilo (void *cls, size_t size, void *buf)
71{
72 int *ok = cls;
73
74 if (size == 0)
75 {
76 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got the desired timeout!\n");
77 GNUNET_assert (buf == NULL);
78 *ok = 0;
79 GNUNET_CONNECTION_destroy (lsock);
80 GNUNET_CONNECTION_destroy (csock);
81 return 0;
82 }
83 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending kilo to fill buffer.\n");
84 GNUNET_assert (size >= 1024);
85 memset (buf, 42, 1024);
86
87 GNUNET_assert (NULL !=
88 GNUNET_CONNECTION_notify_transmit_ready (csock, 1024,
89 GNUNET_TIME_UNIT_SECONDS,
90 &send_kilo, cls));
91 return 1024;
92}
93
94
95static void
96task_timeout (void *cls)
97{
98
99 ls = open_listen_socket ();
100 lsock = GNUNET_CONNECTION_create_from_existing (ls);
101 GNUNET_assert (lsock != NULL);
102 csock = GNUNET_CONNECTION_create_from_connect (cfg, "localhost", PORT);
103 GNUNET_assert (csock != NULL);
104 GNUNET_assert (NULL !=
105 GNUNET_CONNECTION_notify_transmit_ready (csock, 1024,
106 GNUNET_TIME_UNIT_SECONDS,
107 &send_kilo, cls));
108}
109
110
111int
112main (int argc, char *argv[])
113{
114 int ok;
115
116 GNUNET_log_setup ("test_connection_timeout",
117 "WARNING",
118 NULL);
119
120 ok = 1;
121 cfg = GNUNET_CONFIGURATION_create ();
122 GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME",
123 "localhost");
124 GNUNET_SCHEDULER_run (&task_timeout, &ok);
125 GNUNET_CONFIGURATION_destroy (cfg);
126 return ok;
127}
128
129/* end of test_connection_timeout.c */
diff --git a/src/util/test_connection_timeout_no_connect.c b/src/util/test_connection_timeout_no_connect.c
deleted file mode 100644
index ebcd4b71e..000000000
--- a/src/util/test_connection_timeout_no_connect.c
+++ /dev/null
@@ -1,76 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file util/test_connection_timeout_no_connect.c
22 * @brief tests for connection.c, doing timeout which connect failure
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26
27#define PORT 13425
28
29static struct GNUNET_CONNECTION_Handle *csock;
30
31static struct GNUNET_CONFIGURATION_Handle *cfg;
32
33static size_t
34handle_timeout (void *cls, size_t size, void *buf)
35{
36 int *ok = cls;
37
38 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received timeout signal.\n");
39 GNUNET_assert (size == 0);
40 GNUNET_assert (buf == NULL);
41 *ok = 0;
42 return 0;
43}
44
45
46static void
47task_timeout (void *cls)
48{
49 csock = GNUNET_CONNECTION_create_from_connect (cfg, "localhost", PORT);
50 GNUNET_assert (csock != NULL);
51 GNUNET_assert (NULL !=
52 GNUNET_CONNECTION_notify_transmit_ready (csock, 1024,
53 GNUNET_TIME_UNIT_SECONDS,
54 &handle_timeout,
55 cls));
56}
57
58
59int
60main (int argc, char *argv[])
61{
62 int ok;
63
64 GNUNET_log_setup ("test_connection_timeout_no_connect",
65 "WARNING",
66 NULL);
67 ok = 1;
68 cfg = GNUNET_CONFIGURATION_create ();
69 GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME",
70 "localhost");
71 GNUNET_SCHEDULER_run (&task_timeout, &ok);
72 GNUNET_CONFIGURATION_destroy (cfg);
73 return ok;
74}
75
76/* end of test_connection_timeout_no_connect.c */
diff --git a/src/util/test_connection_transmit_cancel.c b/src/util/test_connection_transmit_cancel.c
deleted file mode 100644
index 9ef0720ed..000000000
--- a/src/util/test_connection_transmit_cancel.c
+++ /dev/null
@@ -1,76 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file util/test_connection_transmit_cancel.c
22 * @brief tests for connection.c
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26
27#define PORT 12435
28
29static struct GNUNET_CONFIGURATION_Handle *cfg;
30
31
32static size_t
33not_run (void *cls, size_t size, void *buf)
34{
35 GNUNET_assert (0);
36 return 0;
37}
38
39
40static void
41task_transmit_cancel (void *cls)
42{
43 int *ok = cls;
44 struct GNUNET_CONNECTION_TransmitHandle *th;
45 struct GNUNET_CONNECTION_Handle *csock;
46
47 csock = GNUNET_CONNECTION_create_from_connect (cfg, "localhost", PORT);
48 GNUNET_assert (csock != NULL);
49 th = GNUNET_CONNECTION_notify_transmit_ready (csock, 12,
50 GNUNET_TIME_UNIT_MINUTES,
51 &not_run, cls);
52 GNUNET_assert (NULL != th);
53 GNUNET_CONNECTION_notify_transmit_ready_cancel (th);
54 GNUNET_CONNECTION_destroy (csock);
55 *ok = 0;
56}
57
58
59int
60main (int argc, char *argv[])
61{
62 int ok;
63
64 GNUNET_log_setup ("test_connection_transmit_cancel",
65 "WARNING",
66 NULL);
67 ok = 1;
68 cfg = GNUNET_CONFIGURATION_create ();
69 GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME",
70 "localhost");
71 GNUNET_SCHEDULER_run (&task_transmit_cancel, &ok);
72 GNUNET_CONFIGURATION_destroy (cfg);
73 return ok;
74}
75
76/* end of test_connection_transmit_cancel.c */
diff --git a/src/util/test_getopt.c b/src/util/test_getopt.c
index 8e578640d..13cedd7f5 100644
--- a/src/util/test_getopt.c
+++ b/src/util/test_getopt.c
@@ -136,13 +136,16 @@ testLogOpts ()
136 GNUNET_GETOPT_OPTION_END 136 GNUNET_GETOPT_OPTION_END
137 }; 137 };
138 138
139 if (5 != GNUNET_GETOPT_run ("test_getopt", logoptionlist, 5, myargv)) 139 if (5 != GNUNET_GETOPT_run ("test_getopt",
140 logoptionlist,
141 5, myargv))
140 { 142 {
141 GNUNET_break (0); 143 GNUNET_break (0);
142 return 1; 144 return 1;
143 } 145 }
144 GNUNET_assert (fn != NULL); 146 GNUNET_assert (NULL != fn);
145 if ((0 != strcmp (level, "WARNING")) || (0 != strcmp (fn, "filename"))) 147 if ( (0 != strcmp (level, "WARNING")) ||
148 (NULL == strstr (fn, "/filename")) )
146 { 149 {
147 GNUNET_break (0); 150 GNUNET_break (0);
148 GNUNET_free (level); 151 GNUNET_free (level);
@@ -170,21 +173,35 @@ testFlagNum ()
170 unsigned long long lnum = 0; 173 unsigned long long lnum = 0;
171 174
172 const struct GNUNET_GETOPT_CommandLineOption logoptionlist[] = { 175 const struct GNUNET_GETOPT_CommandLineOption logoptionlist[] = {
173 {'f', "--flag", NULL, "helptext", 0, &GNUNET_GETOPT_set_one, 176 GNUNET_GETOPT_OPTION_SET_ONE ('f',
174 (void *) &flag}, 177 "--flag",
175 {'n', "--num", "ARG", "helptext", 1, &GNUNET_GETOPT_set_uint, 178 "helptext",
176 (void *) &num}, 179 &flag),
177 {'N', "--lnum", "ARG", "helptext", 1, &GNUNET_GETOPT_set_ulong, 180 GNUNET_GETOPT_OPTION_SET_UINT ('n',
178 (void *) &lnum}, 181 "--num",
182 "ARG",
183 "helptext",
184 &num),
185 GNUNET_GETOPT_OPTION_SET_ULONG ('N',
186 "--lnum",
187 "ARG",
188 "helptext",
189 &lnum),
179 GNUNET_GETOPT_OPTION_END 190 GNUNET_GETOPT_OPTION_END
180 }; 191 };
181 192
182 if (6 != GNUNET_GETOPT_run ("test_getopt", logoptionlist, 6, myargv)) 193 if (6 !=
194 GNUNET_GETOPT_run ("test_getopt",
195 logoptionlist,
196 6,
197 myargv))
183 { 198 {
184 GNUNET_break (0); 199 GNUNET_break (0);
185 return 1; 200 return 1;
186 } 201 }
187 if ((1 != flag) || (42 != num) || (42 != lnum)) 202 if ( (1 != flag) ||
203 (42 != num) ||
204 (42 != lnum))
188 { 205 {
189 GNUNET_break (0); 206 GNUNET_break (0);
190 return 1; 207 return 1;
@@ -198,7 +215,9 @@ main (int argc, char *argv[])
198{ 215{
199 int errCnt = 0; 216 int errCnt = 0;
200 217
201 GNUNET_log_setup ("test_getopt", "WARNING", NULL); 218 GNUNET_log_setup ("test_getopt",
219 "WARNING",
220 NULL);
202 /* suppress output from -h, -v options */ 221 /* suppress output from -h, -v options */
203#ifndef MINGW 222#ifndef MINGW
204 GNUNET_break (0 == CLOSE (1)); 223 GNUNET_break (0 == CLOSE (1));
diff --git a/src/util/test_program.c b/src/util/test_program.c
index 669cee7bd..d206952af 100644
--- a/src/util/test_program.c
+++ b/src/util/test_program.c
@@ -24,37 +24,19 @@
24#include "platform.h" 24#include "platform.h"
25#include "gnunet_util_lib.h" 25#include "gnunet_util_lib.h"
26 26
27static int setme1, setme2; 27
28 28static int setme1;
29static struct GNUNET_GETOPT_CommandLineOption options1[] = { 29
30 {'n', "name", NULL, "description", 0, &GNUNET_GETOPT_set_one, &setme1}, 30static int setme2;
31 GNUNET_GETOPT_OPTION_END 31
32};
33
34static struct GNUNET_GETOPT_CommandLineOption options2[] = {
35 {'n', "name", NULL, "description", 0, &GNUNET_GETOPT_set_one, &setme1},
36 {'N', "number", NULL, "description", 0, &GNUNET_GETOPT_set_one, &setme2},
37 GNUNET_GETOPT_OPTION_END
38};
39
40static struct GNUNET_GETOPT_CommandLineOption options3[] = {
41 {'N', "number", NULL, "description", 0, &GNUNET_GETOPT_set_one, &setme1},
42 {'n', "name", NULL, "description", 0, &GNUNET_GETOPT_set_one, &setme2},
43 GNUNET_GETOPT_OPTION_END
44};
45
46static struct GNUNET_GETOPT_CommandLineOption options4[] = {
47 {'n', "name", NULL, "description", 0, &GNUNET_GETOPT_set_one, &setme1},
48 {'n', "number", NULL, "description", 0, &GNUNET_GETOPT_set_one, &setme2},
49 GNUNET_GETOPT_OPTION_END
50};
51 32
52/** 33/**
53 * Main function that will be run. 34 * Main function that will be run.
54 */ 35 */
55
56static void 36static void
57runner (void *cls, char *const *args, const char *cfgfile, 37runner (void *cls,
38 char *const *args,
39 const char *cfgfile,
58 const struct GNUNET_CONFIGURATION_Handle *cfg) 40 const struct GNUNET_CONFIGURATION_Handle *cfg)
59{ 41{
60 int *ok = cls; 42 int *ok = cls;
@@ -62,21 +44,16 @@ runner (void *cls, char *const *args, const char *cfgfile,
62 GNUNET_assert (setme1 == 1); 44 GNUNET_assert (setme1 == 1);
63 GNUNET_assert (0 == strcmp (args[0], "extra")); 45 GNUNET_assert (0 == strcmp (args[0], "extra"));
64 GNUNET_assert (args[1] == NULL); 46 GNUNET_assert (args[1] == NULL);
65 GNUNET_assert (0 == strcmp (cfgfile, "test_program_data.conf")); 47 GNUNET_assert (NULL != strstr (cfgfile, "/test_program_data.conf"));
66
67 *ok = 0; 48 *ok = 0;
68} 49}
69 50
70/** 51
71 * Main method, starts scheduler with task1, 52int
72 * checks that "ok" is correct at the end. 53main (int argc, char *argv[])
73 */
74static int
75check ()
76{ 54{
77 int ok = 1; 55 int ok = 1;
78 56 char *const argvx[] = {
79 char *const argv[] = {
80 "test_program", 57 "test_program",
81 "-c", 58 "-c",
82 "test_program_data.conf", 59 "test_program_data.conf",
@@ -86,33 +63,75 @@ check ()
86 "extra", 63 "extra",
87 NULL 64 NULL
88 }; 65 };
66 struct GNUNET_GETOPT_CommandLineOption options1[] = {
67 GNUNET_GETOPT_OPTION_SET_ONE ('n',
68 "name",
69 "description",
70 &setme1),
71 GNUNET_GETOPT_OPTION_END
72 };
73 struct GNUNET_GETOPT_CommandLineOption options2[] = {
74 GNUNET_GETOPT_OPTION_SET_ONE ('n',
75 "name",
76 "description",
77 &setme1),
78 GNUNET_GETOPT_OPTION_SET_ONE ('N',
79 "number",
80 "description",
81 &setme2),
82 GNUNET_GETOPT_OPTION_END
83 };
84 struct GNUNET_GETOPT_CommandLineOption options3[] = {
85 GNUNET_GETOPT_OPTION_SET_ONE ('N',
86 "number",
87 "description",
88 &setme1),
89 GNUNET_GETOPT_OPTION_SET_ONE ('n',
90 "name",
91 "description",
92 &setme2),
93 GNUNET_GETOPT_OPTION_END
94 };
95 struct GNUNET_GETOPT_CommandLineOption options4[] = {
96 GNUNET_GETOPT_OPTION_SET_ONE ('n',
97 "name",
98 "description",
99 &setme1),
100 GNUNET_GETOPT_OPTION_SET_ONE ('n',
101 "name",
102 "description",
103 &setme2),
104 GNUNET_GETOPT_OPTION_END
105 };
89 106
107
108 GNUNET_log_setup ("test_program",
109 "WARNING",
110 NULL);
90 GNUNET_assert (GNUNET_OK == 111 GNUNET_assert (GNUNET_OK ==
91 GNUNET_PROGRAM_run (7, argv, "test_program", "A test", 112 GNUNET_PROGRAM_run (7, argvx,
92 options1, &runner, &ok)); 113 "test_program",
114 "A test",
115 options1,
116 &runner, &ok));
93 117
94 GNUNET_assert (GNUNET_OK == 118 GNUNET_assert (GNUNET_OK ==
95 GNUNET_PROGRAM_run (7, argv, "test_program", "A test", 119 GNUNET_PROGRAM_run (7, argvx,
96 options2, &runner, &ok)); 120 "test_program", "A test",
121 options2,
122 &runner, &ok));
97 GNUNET_assert (GNUNET_OK == 123 GNUNET_assert (GNUNET_OK ==
98 GNUNET_PROGRAM_run (7, argv, "test_program", "A test", 124 GNUNET_PROGRAM_run (7, argvx,
99 options3, &runner, &ok)); 125 "test_program", "A test",
126 options3,
127 &runner, &ok));
100 GNUNET_assert (GNUNET_OK == 128 GNUNET_assert (GNUNET_OK ==
101 GNUNET_PROGRAM_run (7, argv, "test_program", "A test", 129 GNUNET_PROGRAM_run (7, argvx,
102 options4, &runner, &ok)); 130 "test_program", "A test",
131 options4,
132 &runner, &ok));
103 133
104 return ok; 134 return ok;
105} 135}
106 136
107int
108main (int argc, char *argv[])
109{
110 int ret = 0;
111
112 GNUNET_log_setup ("test_program", "WARNING", NULL);
113 ret += check ();
114
115 return ret;
116}
117
118/* end of test_program.c */ 137/* end of test_program.c */
diff --git a/src/util/test_server.c b/src/util/test_server.c
deleted file mode 100644
index 8003adbf4..000000000
--- a/src/util/test_server.c
+++ /dev/null
@@ -1,302 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2014, 2016 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file util/test_server.c
22 * @brief tests for server.c
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26
27/**
28 * TCP port to use for the server.
29 */
30#define PORT 12435
31
32/**
33 * Timeout to use for operations.
34 */
35#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2)
36
37/**
38 * Test message type.
39 */
40#define MY_TYPE 128
41
42/**
43 * Test message type.
44 */
45#define MY_TYPE2 129
46
47/**
48 * Handle for the server.
49 */
50static struct GNUNET_SERVER_Handle *server;
51
52/**
53 * Handle for the client.
54 */
55static struct GNUNET_MQ_Handle *mq;
56
57/**
58 * Handle of the server for the client.
59 */
60static struct GNUNET_SERVER_Client *argclient;
61
62/**
63 * Our configuration.
64 */
65static struct GNUNET_CONFIGURATION_Handle *cfg;
66
67/**
68 * Number indiciating in which phase of the test we are.
69 */
70static int ok;
71
72
73/**
74 * Final task invoked to clean up.
75 *
76 * @param cls NULL
77 */
78static void
79finish_up (void *cls)
80{
81 GNUNET_assert (7 == ok);
82 ok = 0;
83 GNUNET_SERVER_destroy (server);
84 GNUNET_MQ_destroy (mq);
85 GNUNET_CONFIGURATION_destroy (cfg);
86}
87
88
89/**
90 * The server has received the second message, initiate clean up.
91 *
92 * @param cls NULL
93 * @param client client we got the message from
94 * @param message the message
95 */
96static void
97recv_fin_cb (void *cls,
98 struct GNUNET_SERVER_Client *client,
99 const struct GNUNET_MessageHeader *message)
100{
101 GNUNET_assert (6 == ok);
102 ok = 7;
103 GNUNET_SERVER_receive_done (client, GNUNET_OK);
104 GNUNET_SCHEDULER_add_now (&finish_up, NULL);
105}
106
107
108/**
109 * We have received the reply from the server, check that we are at
110 * the right stage and queue the next message to the server. Cleans
111 * up #argclient.
112 *
113 * @param cls NULL
114 * @param msg message we got from the server
115 */
116static void
117handle_reply (void *cls,
118 const struct GNUNET_MessageHeader *msg)
119{
120 struct GNUNET_MQ_Envelope *env;
121 struct GNUNET_MessageHeader *m;
122
123 GNUNET_assert (4 == ok);
124 ok = 6;
125 env = GNUNET_MQ_msg (m,
126 MY_TYPE2);
127 GNUNET_MQ_send (mq,
128 env);
129}
130
131
132/**
133 * Send a reply of type #MY_TYPE from the server to the client.
134 * Checks that we are in the right phase and transmits the
135 * reply. Cleans up #argclient state.
136 *
137 * @param cls NULL
138 * @param size number of bytes we are allowed to send
139 * @param buf where to copy the reply
140 * @return number of bytes written to @a buf
141 */
142static size_t
143reply_msg (void *cls,
144 size_t size,
145 void *buf)
146{
147 struct GNUNET_MessageHeader msg;
148
149 GNUNET_assert (3 == ok);
150 ok = 4;
151 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
152 msg.type = htons (MY_TYPE);
153 msg.size = htons (sizeof (struct GNUNET_MessageHeader));
154 GNUNET_memcpy (buf, &msg, sizeof (struct GNUNET_MessageHeader));
155 GNUNET_assert (NULL != argclient);
156 GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
157 GNUNET_SERVER_client_drop (argclient);
158 argclient = NULL;
159 return sizeof (struct GNUNET_MessageHeader);
160}
161
162
163/**
164 * Function called whenever the server receives a message of
165 * type #MY_TYPE. Checks that we are at the stage where
166 * we expect the first message, then sends a reply. Stores
167 * the handle to the client in #argclient.
168 *
169 * @param cls NULL
170 * @param client client that sent the message
171 * @param message the message we received
172 */
173static void
174recv_cb (void *cls,
175 struct GNUNET_SERVER_Client *client,
176 const struct GNUNET_MessageHeader *message)
177{
178 GNUNET_assert (2 == ok);
179 ok = 3;
180 argclient = client;
181 GNUNET_SERVER_client_keep (argclient);
182 GNUNET_assert (sizeof (struct GNUNET_MessageHeader) == ntohs (message->size));
183 GNUNET_assert (MY_TYPE == ntohs (message->type));
184 GNUNET_assert (NULL !=
185 GNUNET_SERVER_notify_transmit_ready (client,
186 ntohs (message->size),
187 TIMEOUT,
188 &reply_msg,
189 NULL));
190}
191
192
193/**
194 * Message handlers for the server.
195 */
196static struct GNUNET_SERVER_MessageHandler handlers[] = {
197 {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)},
198 {&recv_fin_cb, NULL, MY_TYPE2, sizeof (struct GNUNET_MessageHeader)},
199 {NULL, NULL, 0, 0}
200};
201
202
203/**
204 * Generic error handler, called with the appropriate error code and
205 * the same closure specified at the creation of the message queue.
206 * Not every message queue implementation supports an error handler.
207 *
208 * @param cls closure with the `struct GNUNET_STATISTICS_Handle *`
209 * @param error error code
210 */
211static void
212mq_error_handler (void *cls,
213 enum GNUNET_MQ_Error error)
214{
215 GNUNET_assert (0); /* should never happen */
216}
217
218
219/**
220 * First task run by the scheduler. Initializes the server and
221 * a client and asks for a transmission from the client to the
222 * server.
223 *
224 * @param cls NULL
225 */
226static void
227task (void *cls)
228{
229 struct sockaddr_in sa;
230 struct sockaddr *sap[2];
231 socklen_t slens[2];
232 struct GNUNET_MQ_Envelope *env;
233 struct GNUNET_MessageHeader *msg;
234 struct GNUNET_MQ_MessageHandler chandlers[] = {
235 GNUNET_MQ_hd_fixed_size (reply,
236 MY_TYPE,
237 struct GNUNET_MessageHeader,
238 cls),
239 GNUNET_MQ_handler_end ()
240 };
241
242 sap[0] = (struct sockaddr *) &sa;
243 slens[0] = sizeof (sa);
244 sap[1] = NULL;
245 slens[1] = 0;
246 memset (&sa, 0, sizeof (sa));
247#if HAVE_SOCKADDR_IN_SIN_LEN
248 sa.sin_len = sizeof (sa);
249#endif
250 sa.sin_family = AF_INET;
251 sa.sin_port = htons (PORT);
252 server = GNUNET_SERVER_create (NULL, NULL,
253 sap, slens,
254 TIMEOUT, GNUNET_NO);
255 GNUNET_assert (server != NULL);
256 GNUNET_SERVER_add_handlers (server, handlers);
257 cfg = GNUNET_CONFIGURATION_create ();
258 GNUNET_CONFIGURATION_set_value_number (cfg,
259 "test-server",
260 "PORT",
261 PORT);
262 GNUNET_CONFIGURATION_set_value_string (cfg,
263 "test-server",
264 "HOSTNAME",
265 "localhost");
266 GNUNET_CONFIGURATION_set_value_string (cfg,
267 "resolver",
268 "HOSTNAME",
269 "localhost");
270 mq = GNUNET_CLIENT_connect (cfg,
271 "test-server",
272 chandlers,
273 &mq_error_handler,
274 NULL);
275 GNUNET_assert (NULL != mq);
276 ok = 2;
277 env = GNUNET_MQ_msg (msg,
278 MY_TYPE);
279 GNUNET_MQ_send (mq,
280 env);
281}
282
283
284/**
285 * Runs the test.
286 *
287 * @param argc length of @a argv
288 * @param argv command line arguments (ignored)
289 * @return 0 on success, otherwise phase of failure
290 */
291int
292main (int argc, char *argv[])
293{
294 GNUNET_log_setup ("test_server",
295 "WARNING",
296 NULL);
297 ok = 1;
298 GNUNET_SCHEDULER_run (&task, &ok);
299 return ok;
300}
301
302/* end of test_server.c */
diff --git a/src/util/test_server_disconnect.c b/src/util/test_server_disconnect.c
deleted file mode 100644
index c3d003e90..000000000
--- a/src/util/test_server_disconnect.c
+++ /dev/null
@@ -1,166 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2016 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file util/test_server_disconnect.c
22 * @brief tests for server.c, specifically GNUNET_SERVER_client_disconnect
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26
27
28#define PORT 12435
29
30#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 250)
31
32#define MY_TYPE 128
33
34static struct GNUNET_SERVER_Handle *server;
35
36static struct GNUNET_MQ_Handle *mq;
37
38static struct GNUNET_CONFIGURATION_Handle *cfg;
39
40static int ok;
41
42
43static void
44finish_up (void *cls)
45{
46 GNUNET_assert (ok == 5);
47 ok = 0;
48 GNUNET_SERVER_destroy (server);
49 GNUNET_MQ_destroy (mq);
50 GNUNET_CONFIGURATION_destroy (cfg);
51}
52
53
54static void
55notify_disconnect (void *cls,
56 struct GNUNET_SERVER_Client *clientarg)
57{
58 if (NULL == clientarg)
59 return;
60 GNUNET_assert (ok == 4);
61 ok = 5;
62 GNUNET_SCHEDULER_add_now (&finish_up, NULL);
63}
64
65
66static void
67server_disconnect (void *cls)
68{
69 struct GNUNET_SERVER_Client *argclient = cls;
70
71 GNUNET_assert (ok == 3);
72 ok = 4;
73 GNUNET_SERVER_client_disconnect (argclient);
74 GNUNET_SERVER_client_drop (argclient);
75}
76
77
78static void
79recv_cb (void *cls,
80 struct GNUNET_SERVER_Client *client,
81 const struct GNUNET_MessageHeader *message)
82{
83 GNUNET_assert (ok == 2);
84 ok = 3;
85 GNUNET_SERVER_client_keep (client);
86 GNUNET_SCHEDULER_add_now (&server_disconnect, client);
87 GNUNET_assert (sizeof (struct GNUNET_MessageHeader) == ntohs (message->size));
88 GNUNET_assert (MY_TYPE == ntohs (message->type));
89 GNUNET_SERVER_receive_done (client, GNUNET_OK);
90}
91
92
93static struct GNUNET_SERVER_MessageHandler handlers[] = {
94 {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)},
95 {NULL, NULL, 0, 0}
96};
97
98
99static void
100task (void *cls)
101{
102 struct sockaddr_in sa;
103 struct sockaddr *sap[2];
104 socklen_t slens[2];
105 struct GNUNET_MQ_Envelope *env;
106 struct GNUNET_MessageHeader *msg;
107
108 sap[0] = (struct sockaddr *) &sa;
109 slens[0] = sizeof (sa);
110 sap[1] = NULL;
111 slens[1] = 0;
112 memset (&sa, 0, sizeof (sa));
113#if HAVE_SOCKADDR_IN_SIN_LEN
114 sa.sin_len = sizeof (sa);
115#endif
116 sa.sin_family = AF_INET;
117 sa.sin_port = htons (PORT);
118 server = GNUNET_SERVER_create (NULL, NULL, sap, slens, TIMEOUT, GNUNET_NO);
119 GNUNET_assert (server != NULL);
120 GNUNET_SERVER_add_handlers (server, handlers);
121 GNUNET_SERVER_disconnect_notify (server, &notify_disconnect, NULL);
122 cfg = GNUNET_CONFIGURATION_create ();
123 GNUNET_CONFIGURATION_set_value_number (cfg, "test-server", "PORT", PORT);
124 GNUNET_CONFIGURATION_set_value_string (cfg, "test-server", "HOSTNAME",
125 "localhost");
126 GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME",
127 "localhost");
128 mq = GNUNET_CLIENT_connect (cfg,
129 "test-server",
130 NULL,
131 NULL,
132 NULL);
133 GNUNET_assert (NULL != mq);
134 ok = 2;
135 env = GNUNET_MQ_msg (msg,
136 MY_TYPE);
137 GNUNET_MQ_send (mq,
138 env);
139}
140
141
142/**
143 * Main method, starts scheduler with task1,
144 * checks that "ok" is correct at the end.
145 */
146static int
147check ()
148{
149 ok = 1;
150 GNUNET_SCHEDULER_run (&task, &ok);
151 return ok;
152}
153
154
155int
156main (int argc, char *argv[])
157{
158 int ret = 0;
159
160 GNUNET_log_setup ("test_server_disconnect", "WARNING", NULL);
161 ret += check ();
162
163 return ret;
164}
165
166/* end of test_server_disconnect.c */
diff --git a/src/util/test_server_mst_interrupt.c b/src/util/test_server_mst_interrupt.c
deleted file mode 100644
index 3141a75bd..000000000
--- a/src/util/test_server_mst_interrupt.c
+++ /dev/null
@@ -1,60 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file util/test_server_mst_interrupt.c
22 * @brief test for interrupt message processing in server_mst.c
23 */
24#include "platform.h"
25#include "gnunet_protocols.h"
26#include "gnunet_util_lib.h"
27
28static struct GNUNET_SERVER_MessageStreamTokenizer * mst;
29
30
31/* Callback destroying mst with data in buffer */
32static int
33mst_cb (void *cls, void *client,
34 const struct GNUNET_MessageHeader * message)
35{
36 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MST gave me message, destroying\n");
37 GNUNET_SERVER_mst_destroy (mst);
38 return GNUNET_SYSERR;
39}
40
41
42int
43main (int argc, char *argv[])
44{
45 struct GNUNET_PeerIdentity id;
46 struct GNUNET_MessageHeader msg[2];
47
48 GNUNET_log_setup ("test_server_mst_interrupt", "WARNING", NULL);
49 memset (&id, 0, sizeof (id));
50 msg[0].size = htons (sizeof (msg));
51 msg[0].type = htons (sizeof (GNUNET_MESSAGE_TYPE_DUMMY));
52 mst = GNUNET_SERVER_mst_create(mst_cb, NULL);
53 GNUNET_SERVER_mst_receive (mst, &id,
54 (const char *) &msg, 2 * sizeof (msg),
55 GNUNET_NO, GNUNET_NO);
56 /* If we reach this line, it did not crash */
57 return 0;
58}
59
60/* end of test_server_mst_interrupt.c */
diff --git a/src/util/test_server_with_client.c b/src/util/test_server_with_client.c
deleted file mode 100644
index 63bfda00c..000000000
--- a/src/util/test_server_with_client.c
+++ /dev/null
@@ -1,198 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2016 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file util/test_server_with_client.c
22 * @brief tests for server.c and client.c,
23 * specifically disconnect_notify,
24 * client_get_address and receive_done (resume processing)
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28
29#define PORT 22335
30
31#define MY_TYPE 128
32
33
34static struct GNUNET_SERVER_Handle *server;
35
36static struct GNUNET_MQ_Handle *mq;
37
38static struct GNUNET_CONFIGURATION_Handle *cfg;
39
40static int ok;
41
42
43static void
44send_done (void *cls)
45{
46 struct GNUNET_SERVER_Client *argclient = cls;
47
48 GNUNET_assert (ok == 3);
49 ok++;
50 GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
51}
52
53
54static void
55recv_cb (void *cls,
56 struct GNUNET_SERVER_Client *argclient,
57 const struct GNUNET_MessageHeader *message)
58{
59 void *addr;
60 size_t addrlen;
61 struct sockaddr_in sa;
62 struct sockaddr_in *have;
63
64 GNUNET_assert (GNUNET_OK ==
65 GNUNET_SERVER_client_get_address (argclient,
66 &addr,
67 &addrlen));
68
69 GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
70 have = addr;
71 memset (&sa, 0, sizeof (sa));
72#if HAVE_SOCKADDR_IN_SIN_LEN
73 sa.sin_len = sizeof (sa);
74#endif
75 sa.sin_family = AF_INET;
76 sa.sin_port = have->sin_port;
77 sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
78 GNUNET_assert (0 == memcmp (&sa, addr, addrlen));
79 GNUNET_free (addr);
80 switch (ok)
81 {
82 case 2:
83 ok++;
84 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
85 (GNUNET_TIME_UNIT_MILLISECONDS, 50),
86 &send_done,
87 argclient);
88 break;
89 case 4:
90 ok++;
91 GNUNET_MQ_destroy (mq);
92 GNUNET_SERVER_receive_done (argclient,
93 GNUNET_OK);
94 break;
95 default:
96 GNUNET_assert (0);
97 }
98
99}
100
101
102static void
103clean_up (void *cls)
104{
105 GNUNET_SERVER_destroy (server);
106 server = NULL;
107 GNUNET_CONFIGURATION_destroy (cfg);
108 cfg = NULL;
109}
110
111
112/**
113 * Functions with this signature are called whenever a client
114 * is disconnected on the network level.
115 *
116 * @param cls closure
117 * @param client identification of the client
118 */
119static void
120notify_disconnect (void *cls,
121 struct GNUNET_SERVER_Client *client)
122{
123 if (client == NULL)
124 return;
125 GNUNET_assert (ok == 5);
126 ok = 0;
127 GNUNET_SCHEDULER_add_now (&clean_up, NULL);
128}
129
130
131static struct GNUNET_SERVER_MessageHandler handlers[] = {
132 {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)},
133 {NULL, NULL, 0, 0}
134};
135
136
137static void
138task (void *cls)
139{
140 struct sockaddr_in sa;
141 struct sockaddr *sap[2];
142 socklen_t slens[2];
143 struct GNUNET_MQ_Envelope *env;
144 struct GNUNET_MessageHeader *msg;
145
146 sap[0] = (struct sockaddr *) &sa;
147 slens[0] = sizeof (sa);
148 sap[1] = NULL;
149 slens[1] = 0;
150 memset (&sa, 0, sizeof (sa));
151#if HAVE_SOCKADDR_IN_SIN_LEN
152 sa.sin_len = sizeof (sa);
153#endif
154 sa.sin_family = AF_INET;
155 sa.sin_port = htons (PORT);
156 server =
157 GNUNET_SERVER_create (NULL, NULL, sap, slens,
158 GNUNET_TIME_relative_multiply
159 (GNUNET_TIME_UNIT_MILLISECONDS, 250), GNUNET_NO);
160 GNUNET_assert (server != NULL);
161 handlers[0].callback_cls = cls;
162 GNUNET_SERVER_add_handlers (server, handlers);
163 GNUNET_SERVER_disconnect_notify (server, &notify_disconnect, cls);
164 cfg = GNUNET_CONFIGURATION_create ();
165 GNUNET_CONFIGURATION_set_value_number (cfg, "test", "PORT", PORT);
166 GNUNET_CONFIGURATION_set_value_string (cfg, "test", "HOSTNAME", "localhost");
167 GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME",
168 "localhost");
169 mq = GNUNET_CLIENT_connect (cfg,
170 "test",
171 NULL,
172 NULL,
173 NULL);
174 GNUNET_assert (NULL != mq);
175 ok = 2;
176 env = GNUNET_MQ_msg (msg,
177 MY_TYPE);
178 GNUNET_MQ_send (mq,
179 env);
180 env = GNUNET_MQ_msg (msg,
181 MY_TYPE);
182 GNUNET_MQ_send (mq,
183 env);
184}
185
186
187int
188main (int argc, char *argv[])
189{
190 GNUNET_log_setup ("test_server_with_client",
191 "WARNING",
192 NULL);
193 ok = 1;
194 GNUNET_SCHEDULER_run (&task, NULL);
195 return ok;
196}
197
198/* end of test_server_with_client.c */
diff --git a/src/util/test_server_with_client_unix.c b/src/util/test_server_with_client_unix.c
deleted file mode 100644
index 8fabbe210..000000000
--- a/src/util/test_server_with_client_unix.c
+++ /dev/null
@@ -1,176 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2016 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file util/test_server_with_client_unix.c
22 * @brief tests for server.c and client.c,
23 * specifically disconnect_notify,
24 * client_get_address and receive_done (resume processing)
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28
29#define MY_TYPE 128
30
31
32static struct GNUNET_SERVER_Handle *server;
33
34static struct GNUNET_MQ_Handle *mq;
35
36static struct GNUNET_CONFIGURATION_Handle *cfg;
37
38static int ok;
39
40
41static void
42send_done (void *cls)
43{
44 struct GNUNET_SERVER_Client *argclient = cls;
45
46 GNUNET_assert (ok == 3);
47 ok++;
48 GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
49}
50
51
52static void
53recv_cb (void *cls,
54 struct GNUNET_SERVER_Client *argclient,
55 const struct GNUNET_MessageHeader *message)
56{
57 switch (ok)
58 {
59 case 2:
60 ok++;
61 (void) GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
62 (GNUNET_TIME_UNIT_MILLISECONDS, 50),
63 &send_done,
64 argclient);
65 break;
66 case 4:
67 ok++;
68 GNUNET_MQ_destroy (mq);
69 GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
70 break;
71 default:
72 GNUNET_assert (0);
73 }
74
75}
76
77
78static void
79clean_up (void *cls)
80{
81 GNUNET_SERVER_destroy (server);
82 server = NULL;
83 GNUNET_CONFIGURATION_destroy (cfg);
84 cfg = NULL;
85}
86
87
88/**
89 * Functions with this signature are called whenever a client
90 * is disconnected on the network level.
91 *
92 * @param cls closure
93 * @param client identification of the client
94 */
95static void
96notify_disconnect (void *cls,
97 struct GNUNET_SERVER_Client *client)
98{
99 if (client == NULL)
100 return;
101 GNUNET_assert (ok == 5);
102 ok = 0;
103 (void) GNUNET_SCHEDULER_add_now (&clean_up, NULL);
104}
105
106
107static struct GNUNET_SERVER_MessageHandler handlers[] = {
108 {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)},
109 {NULL, NULL, 0, 0}
110};
111
112
113static void
114task (void *cls)
115{
116 struct sockaddr_un un;
117 const char *unixpath = "/tmp/testsock";
118 struct sockaddr *sap[2];
119 socklen_t slens[2];
120 struct GNUNET_MQ_Envelope *env;
121 struct GNUNET_MessageHeader *msg;
122
123 memset (&un, 0, sizeof (un));
124 un.sun_family = AF_UNIX;
125 strncpy(un.sun_path, unixpath, sizeof (un.sun_path) - 1);
126#if HAVE_SOCKADDR_UN_SUN_LEN
127 un.sun_len = (u_char) sizeof (un);
128#endif
129
130 sap[0] = (struct sockaddr *) &un;
131 slens[0] = sizeof (un);
132 sap[1] = NULL;
133 slens[1] = 0;
134 server =
135 GNUNET_SERVER_create (NULL, NULL, sap, slens,
136 GNUNET_TIME_relative_multiply
137 (GNUNET_TIME_UNIT_MILLISECONDS, 250), GNUNET_NO);
138 GNUNET_assert (server != NULL);
139 handlers[0].callback_cls = cls;
140 GNUNET_SERVER_add_handlers (server, handlers);
141 GNUNET_SERVER_disconnect_notify (server, &notify_disconnect, cls);
142 cfg = GNUNET_CONFIGURATION_create ();
143
144 GNUNET_CONFIGURATION_set_value_string (cfg, "test", "UNIXPATH", unixpath);
145 GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME",
146 "localhost");
147 mq = GNUNET_CLIENT_connect (cfg,
148 "test",
149 NULL,
150 NULL,
151 NULL);
152 GNUNET_assert (NULL != mq);
153 ok = 2;
154 env = GNUNET_MQ_msg (msg,
155 MY_TYPE);
156 GNUNET_MQ_send (mq,
157 env);
158 env = GNUNET_MQ_msg (msg,
159 MY_TYPE);
160 GNUNET_MQ_send (mq,
161 env);
162}
163
164
165int
166main (int argc, char *argv[])
167{
168 GNUNET_log_setup ("test_server_with_client_unix",
169 "WARNING",
170 NULL);
171 ok = 1;
172 GNUNET_SCHEDULER_run (&task, NULL);
173 return ok;
174}
175
176/* end of test_server_with_client_unix.c */
diff --git a/src/util/test_service.c b/src/util/test_service.c
index d2136b42f..1567c97ce 100644
--- a/src/util/test_service.c
+++ b/src/util/test_service.c
@@ -148,7 +148,7 @@ check (const char *sname)
148 sname); 148 sname);
149 global_ret = 1; 149 global_ret = 1;
150 GNUNET_assert (0 == 150 GNUNET_assert (0 ==
151 GNUNET_SERVICE_ruN_ (3, 151 GNUNET_SERVICE_run_ (3,
152 argv, 152 argv,
153 sname, 153 sname,
154 GNUNET_SERVICE_OPTION_NONE, 154 GNUNET_SERVICE_OPTION_NONE,
diff --git a/src/vpn/gnunet-helper-vpn-windows.c b/src/vpn/gnunet-helper-vpn-windows.c
index a9596752a..e74a0aa2f 100644
--- a/src/vpn/gnunet-helper-vpn-windows.c
+++ b/src/vpn/gnunet-helper-vpn-windows.c
@@ -77,7 +77,7 @@
77static boolean privilege_testing = FALSE; 77static boolean privilege_testing = FALSE;
78 78
79/** 79/**
80 * Maximum size of a GNUnet message (GNUNET_SERVER_MAX_MESSAGE_SIZE) 80 * Maximum size of a GNUnet message (GNUNET_MAX_MESSAGE_SIZE)
81 */ 81 */
82#define MAX_SIZE 65536 82#define MAX_SIZE 65536
83 83
diff --git a/src/vpn/gnunet-helper-vpn.c b/src/vpn/gnunet-helper-vpn.c
index 02889d65b..4ed4e079e 100644
--- a/src/vpn/gnunet-helper-vpn.c
+++ b/src/vpn/gnunet-helper-vpn.c
@@ -53,7 +53,7 @@
53#define DEBUG GNUNET_NO 53#define DEBUG GNUNET_NO
54 54
55/** 55/**
56 * Maximum size of a GNUnet message (GNUNET_SERVER_MAX_MESSAGE_SIZE) 56 * Maximum size of a GNUnet message (GNUNET_MAX_MESSAGE_SIZE)
57 */ 57 */
58#define MAX_SIZE 65536 58#define MAX_SIZE 65536
59 59
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c
index ab0b00d76..d9daaa7e2 100644
--- a/src/vpn/gnunet-service-vpn.c
+++ b/src/vpn/gnunet-service-vpn.c
@@ -1839,7 +1839,7 @@ route_packet (struct DestinationEntry *destination,
1839 1839
1840 mlen = sizeof (struct GNUNET_EXIT_UdpServiceMessage) + 1840 mlen = sizeof (struct GNUNET_EXIT_UdpServiceMessage) +
1841 payload_length - sizeof (struct GNUNET_TUN_UdpHeader); 1841 payload_length - sizeof (struct GNUNET_TUN_UdpHeader);
1842 if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 1842 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1843 { 1843 {
1844 GNUNET_break (0); 1844 GNUNET_break (0);
1845 return; 1845 return;
@@ -1864,7 +1864,7 @@ route_packet (struct DestinationEntry *destination,
1864 1864
1865 mlen = sizeof (struct GNUNET_EXIT_UdpInternetMessage) + 1865 mlen = sizeof (struct GNUNET_EXIT_UdpInternetMessage) +
1866 alen + payload_length - sizeof (struct GNUNET_TUN_UdpHeader); 1866 alen + payload_length - sizeof (struct GNUNET_TUN_UdpHeader);
1867 if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 1867 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1868 { 1868 {
1869 GNUNET_break (0); 1869 GNUNET_break (0);
1870 return; 1870 return;
@@ -1904,7 +1904,7 @@ route_packet (struct DestinationEntry *destination,
1904 1904
1905 mlen = sizeof (struct GNUNET_EXIT_TcpServiceStartMessage) + 1905 mlen = sizeof (struct GNUNET_EXIT_TcpServiceStartMessage) +
1906 payload_length - sizeof (struct GNUNET_TUN_TcpHeader); 1906 payload_length - sizeof (struct GNUNET_TUN_TcpHeader);
1907 if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 1907 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1908 { 1908 {
1909 GNUNET_break (0); 1909 GNUNET_break (0);
1910 return; 1910 return;
@@ -1927,7 +1927,7 @@ route_packet (struct DestinationEntry *destination,
1927 1927
1928 mlen = sizeof (struct GNUNET_EXIT_TcpInternetStartMessage) + 1928 mlen = sizeof (struct GNUNET_EXIT_TcpInternetStartMessage) +
1929 alen + payload_length - sizeof (struct GNUNET_TUN_TcpHeader); 1929 alen + payload_length - sizeof (struct GNUNET_TUN_TcpHeader);
1930 if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 1930 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1931 { 1931 {
1932 GNUNET_break (0); 1932 GNUNET_break (0);
1933 return; 1933 return;
@@ -1963,7 +1963,7 @@ route_packet (struct DestinationEntry *destination,
1963 1963
1964 mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) + 1964 mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) +
1965 payload_length - sizeof (struct GNUNET_TUN_TcpHeader); 1965 payload_length - sizeof (struct GNUNET_TUN_TcpHeader);
1966 if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 1966 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1967 { 1967 {
1968 GNUNET_break (0); 1968 GNUNET_break (0);
1969 return; 1969 return;
@@ -2038,7 +2038,7 @@ route_packet (struct DestinationEntry *destination,
2038 /* update length calculations, as payload_length may have changed */ 2038 /* update length calculations, as payload_length may have changed */
2039 mlen = sizeof (struct GNUNET_EXIT_IcmpServiceMessage) + 2039 mlen = sizeof (struct GNUNET_EXIT_IcmpServiceMessage) +
2040 alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); 2040 alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader);
2041 if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 2041 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2042 { 2042 {
2043 GNUNET_break (0); 2043 GNUNET_break (0);
2044 return; 2044 return;
@@ -2168,7 +2168,7 @@ route_packet (struct DestinationEntry *destination,
2168 /* update length calculations, as payload_length may have changed */ 2168 /* update length calculations, as payload_length may have changed */
2169 mlen = sizeof (struct GNUNET_EXIT_IcmpInternetMessage) + 2169 mlen = sizeof (struct GNUNET_EXIT_IcmpInternetMessage) +
2170 alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); 2170 alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader);
2171 if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 2171 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2172 { 2172 {
2173 GNUNET_break (0); 2173 GNUNET_break (0);
2174 return; 2174 return;
@@ -2217,12 +2217,10 @@ route_packet (struct DestinationEntry *destination,
2217 * and forward the packet. 2217 * and forward the packet.
2218 * 2218 *
2219 * @param cls closure, NULL 2219 * @param cls closure, NULL
2220 * @param client NULL
2221 * @param message message we got from the client (VPN channel interface) 2220 * @param message message we got from the client (VPN channel interface)
2222 */ 2221 */
2223static int 2222static int
2224message_token (void *cls, 2223message_token (void *cls,
2225 void *client,
2226 const struct GNUNET_MessageHeader *message) 2224 const struct GNUNET_MessageHeader *message)
2227{ 2225{
2228 const struct GNUNET_TUN_Layer2PacketHeader *tun; 2226 const struct GNUNET_TUN_Layer2PacketHeader *tun;
diff --git a/src/vpn/gnunet-vpn.c b/src/vpn/gnunet-vpn.c
index 2e7daf7f7..0adbd5c96 100644
--- a/src/vpn/gnunet-vpn.c
+++ b/src/vpn/gnunet-vpn.c
@@ -78,7 +78,7 @@ static int udp;
78/** 78/**
79 * Selected level of verbosity. 79 * Selected level of verbosity.
80 */ 80 */
81static int verbosity; 81static unsigned int verbosity;
82 82
83/** 83/**
84 * Global return value. 84 * Global return value.
@@ -286,33 +286,53 @@ run (void *cls,
286int 286int
287main (int argc, char *const *argv) 287main (int argc, char *const *argv)
288{ 288{
289 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 289 struct GNUNET_GETOPT_CommandLineOption options[] = {
290 {'4', "ipv4", NULL, 290 GNUNET_GETOPT_OPTION_SET_ONE ('4',
291 gettext_noop ("request that result should be an IPv4 address"), 291 "ipv4",
292 0, &GNUNET_GETOPT_set_one, &ipv4}, 292 gettext_noop ("request that result should be an IPv4 address"),
293 {'6', "ipv6", NULL, 293 &ipv4),
294 gettext_noop ("request that result should be an IPv6 address"), 294
295 0, &GNUNET_GETOPT_set_one, &ipv6}, 295 GNUNET_GETOPT_OPTION_SET_ONE ('6',
296 {'d', "duration", "TIME", 296 "ipv6",
297 gettext_noop ("how long should the mapping be valid for new tunnels?"), 297 gettext_noop ("request that result should be an IPv6 address"),
298 1, &GNUNET_GETOPT_set_relative_time, &duration}, 298 &ipv6),
299 {'i', "ip", "IP", 299
300 gettext_noop ("destination IP for the tunnel"), 300 GNUNET_GETOPT_OPTION_SET_RELATIVE_TIME ('d',
301 1, &GNUNET_GETOPT_set_string, &target_ip}, 301 "duration",
302 {'p', "peer", "PEERID", 302 "TIME",
303 gettext_noop ("peer offering the service we would like to access"), 303 gettext_noop ("how long should the mapping be valid for new tunnels?"),
304 1, &GNUNET_GETOPT_set_string, &peer_id}, 304 &duration),
305 {'s', "service", "NAME", 305
306 gettext_noop ("name of the service we would like to access"), 306 GNUNET_GETOPT_OPTION_STRING ('i',
307 1, &GNUNET_GETOPT_set_string, &service_name}, 307 "ip",
308 {'t', "tcp", NULL, 308 "IP",
309 gettext_noop ("service is offered via TCP"), 309 gettext_noop ("destination IP for the tunnel"),
310 0, &GNUNET_GETOPT_set_one, &tcp}, 310 &target_ip),
311 {'u', "udp", NULL, 311
312 gettext_noop ("service is offered via UDP"), 312 GNUNET_GETOPT_OPTION_STRING ('p',
313 0, &GNUNET_GETOPT_set_one, &udp}, 313 "peer",
314 "PEERID",
315 gettext_noop ("peer offering the service we would like to access"),
316 &peer_id),
317
318 GNUNET_GETOPT_OPTION_STRING ('s',
319 "service",
320 "NAME",
321 gettext_noop ("name of the service we would like to access"),
322 &service_name),
323
324 GNUNET_GETOPT_OPTION_SET_ONE ('t',
325 "tcp",
326 gettext_noop ("service is offered via TCP"),
327 &tcp),
328
329 GNUNET_GETOPT_OPTION_SET_ONE ('u',
330 "udp",
331 gettext_noop ("service is offered via UDP"),
332 &udp),
314 333
315 GNUNET_GETOPT_OPTION_VERBOSE (&verbosity), 334 GNUNET_GETOPT_OPTION_VERBOSE (&verbosity),
335
316 GNUNET_GETOPT_OPTION_END 336 GNUNET_GETOPT_OPTION_END
317 }; 337 };
318 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 338 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))